mirror of
https://github.com/topjohnwu/Magisk.git
synced 2024-12-25 14:47:38 +00:00
Add compress, decompress, cleanup command
This commit is contained in:
parent
65dc99744e
commit
a4ce9f6f05
@ -359,6 +359,7 @@ int decomp(file_t type, const char *to, const unsigned char *from, size_t size)
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Output will be to.ext
|
||||
int comp(file_t type, const char *to, const unsigned char *from, size_t size) {
|
||||
char name[PATH_MAX];
|
||||
switch (type) {
|
||||
@ -388,3 +389,75 @@ int comp(file_t type, const char *to, const unsigned char *from, size_t size) {
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void decomp_file(char *from) {
|
||||
int ok = 1;
|
||||
unsigned char *file;
|
||||
size_t size;
|
||||
mmap_ro(from, &file, &size);
|
||||
file_t type = check_type(file);
|
||||
char *ext;
|
||||
ext = strrchr(from, '.');
|
||||
if (ext == NULL)
|
||||
error(1, "Bad filename extention");
|
||||
|
||||
// File type and extension should match
|
||||
switch (type) {
|
||||
case GZIP:
|
||||
if (strcmp(ext, ".gz") != 0)
|
||||
ok = 0;
|
||||
break;
|
||||
case XZ:
|
||||
if (strcmp(ext, ".xz") != 0)
|
||||
ok = 0;
|
||||
break;
|
||||
case LZMA:
|
||||
if (strcmp(ext, ".lzma") != 0)
|
||||
ok = 0;
|
||||
break;
|
||||
case BZIP2:
|
||||
if (strcmp(ext, ".bz2") != 0)
|
||||
ok = 0;
|
||||
break;
|
||||
case LZ4:
|
||||
if (strcmp(ext, ".lz4") != 0)
|
||||
ok = 0;
|
||||
break;
|
||||
default:
|
||||
error(1, "Provided file \'%s\' is not a supported archive format", from);
|
||||
}
|
||||
if (ok) {
|
||||
// If all match, strip out the suffix
|
||||
*ext = '\0';
|
||||
decomp(type, from, file, size);
|
||||
*ext = '.';
|
||||
unlink(from);
|
||||
} else {
|
||||
error(1, "Bad filename extention \'%s\'", ext);
|
||||
}
|
||||
munmap(file, size);
|
||||
}
|
||||
|
||||
void comp_file(const char *method, const char *from) {
|
||||
file_t type;
|
||||
if (strcmp(method, "gzip") == 0) {
|
||||
type = GZIP;
|
||||
} else if (strcmp(method, "xz") == 0) {
|
||||
type = XZ;
|
||||
} else if (strcmp(method, "lzma") == 0) {
|
||||
type = LZMA;
|
||||
} else if (strcmp(method, "lz4") == 0) {
|
||||
type = LZ4;
|
||||
} else if (strcmp(method, "bzip2") == 0) {
|
||||
type = BZIP2;
|
||||
} else {
|
||||
error(1, "Only support following methods: " SUP_LIST);
|
||||
}
|
||||
unsigned char *file;
|
||||
size_t size;
|
||||
mmap_ro(from, &file, &size);
|
||||
comp(type, from, file, size);
|
||||
munmap(file, size);
|
||||
unlink(from);
|
||||
}
|
||||
|
||||
|
@ -28,6 +28,10 @@
|
||||
#define RAMDISK_FILE "ramdisk.cpio"
|
||||
#define SECOND_FILE "second"
|
||||
#define DTB_FILE "dtb"
|
||||
#define NEW_BOOT "new-boot.img"
|
||||
|
||||
#define SUP_LIST "gzip, xz, lzma, lz4, bzip2"
|
||||
#define SUP_NUM 5
|
||||
|
||||
typedef enum {
|
||||
UNKNOWN,
|
||||
@ -44,6 +48,12 @@ typedef enum {
|
||||
QCDT,
|
||||
} file_t;
|
||||
|
||||
extern char *SUP_EXT_LIST[SUP_NUM];
|
||||
extern file_t SUP_TYPE_LIST[SUP_NUM];
|
||||
// Cannot declare in header, but place a copy here for convenience
|
||||
// char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4" };
|
||||
// file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4 };
|
||||
|
||||
// Global variables
|
||||
extern unsigned char *kernel, *ramdisk, *second, *dtb;
|
||||
extern boot_img_hdr hdr;
|
||||
@ -57,6 +67,7 @@ void hexpatch(const char *image, const char *from, const char *to);
|
||||
void cpio(const char *filename);
|
||||
void error(int rc, const char *msg, ...);
|
||||
void parse_img(unsigned char *orig, size_t size);
|
||||
void cleanup();
|
||||
|
||||
// Compressions
|
||||
void gzip(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||
@ -64,7 +75,9 @@ void lzma(int mode, const char* filename, const unsigned char* buf, size_t size)
|
||||
void lz4(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||
void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size);
|
||||
int comp(file_t type, const char *to, const unsigned char *from, size_t size);
|
||||
void comp_file(const char *method, const char *from);
|
||||
int decomp(file_t type, const char *to, const unsigned char *from, size_t size);
|
||||
void decomp_file(char *from);
|
||||
|
||||
// Utils
|
||||
void mmap_ro(const char *filename, unsigned char **buf, size_t *size);
|
||||
@ -73,5 +86,6 @@ file_t check_type(const unsigned char *buf);
|
||||
void mem_align(size_t *pos, size_t align);
|
||||
void file_align(int fd, size_t align);
|
||||
int open_new(const char *filename);
|
||||
void print_info();
|
||||
|
||||
#endif
|
||||
|
@ -1,8 +1,3 @@
|
||||
#include <stdio.h>
|
||||
#include <stdarg.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
|
||||
#include "magiskboot.h"
|
||||
|
||||
/********************
|
||||
@ -10,13 +5,23 @@
|
||||
*********************/
|
||||
|
||||
static void usage(char *arg0) {
|
||||
fprintf(stderr, "Boot Image Unpack/Repack Tool\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "%s --unpack <bootimage>\n", arg0);
|
||||
fprintf(stderr, " Unpack <bootimage> into current directory\n\n");
|
||||
fprintf(stderr, " Unpack <bootimage> to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n\n");
|
||||
fprintf(stderr, "%s --repack <bootimage>\n", arg0);
|
||||
fprintf(stderr, " Repack kernel, dtb, ramdisk... from current directory to new-image.img\n <bootimage> is the image you've just unpacked\n\n");
|
||||
fprintf(stderr, "%s --hexpatch <bootimage> <hexpattern1> <hexpattern2>\n", arg0);
|
||||
fprintf(stderr, " Search <hexpattern1> in <bootimage>, and replace with <hexpattern2>\n\n");
|
||||
fprintf(stderr, " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n");
|
||||
fprintf(stderr, " to new-image.img. <bootimage> is the original boot image you've just unpacked.\n");
|
||||
fprintf(stderr, " If file ramdisk.cpio exists, it will auto re-compress with the same method\n");
|
||||
fprintf(stderr, " used in <bootimage>, or it will attempt to find ramdisk.cpio.[ext], and repack\n");
|
||||
fprintf(stderr, " directly with the compressed file\n\n");
|
||||
fprintf(stderr, "%s --hexpatch <file> <hexpattern1> <hexpattern2>\n", arg0);
|
||||
fprintf(stderr, " Search <hexpattern1> in <file>, and replace with <hexpattern2>\n\n");
|
||||
fprintf(stderr, "%s --compress[=method] <file>\n", arg0);
|
||||
fprintf(stderr, " Compress <file> with [method], or gzip if not specified.\n Supported methods: " SUP_LIST "\n\n");
|
||||
fprintf(stderr, "%s --decompress <file>\n", arg0);
|
||||
fprintf(stderr, " Auto check file type, and decompress <file> accordingly\n Supported methods: " SUP_LIST "\n\n");
|
||||
fprintf(stderr, "%s --cleanup\n", arg0);
|
||||
fprintf(stderr, " Cleanup the current working directory\n\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
@ -30,21 +35,34 @@ void error(int rc, const char *msg, ...) {
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
if (argc < 3)
|
||||
usage(argv[0]);
|
||||
|
||||
if (strcmp(argv[1], "--unpack") == 0) {
|
||||
unpack(argv[2]);
|
||||
} else if (strcmp(argv[1], "--repack") == 0) {
|
||||
repack(argv[2]);
|
||||
} else if (strcmp(argv[1], "--hexpatch") == 0) {
|
||||
if (argc < 5)
|
||||
printf("MagiskBoot (by topjohnwu) - Boot Image Modification Tool\n");
|
||||
if (argc < 3) {
|
||||
if (strcmp(argv[1], "--cleanup") == 0) {
|
||||
cleanup();
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
hexpatch(argv[2], argv[3], argv[4]);
|
||||
}
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
if (strcmp(argv[1], "--unpack") == 0) {
|
||||
unpack(argv[2]);
|
||||
} else if (strcmp(argv[1], "--repack") == 0) {
|
||||
repack(argv[2]);
|
||||
} else if (strcmp(argv[1], "--hexpatch") == 0) {
|
||||
if (argc < 5)
|
||||
usage(argv[0]);
|
||||
hexpatch(argv[2], argv[3], argv[4]);
|
||||
} else if (strcmp(argv[1], "--decompress") == 0) {
|
||||
decomp_file(argv[2]);
|
||||
} else if (strstr(argv[1], "--compress") != NULL) {
|
||||
char *method;
|
||||
method = strchr(argv[1], '=');
|
||||
if (method == NULL) method = "gzip";
|
||||
else method++;
|
||||
comp_file(method, argv[2]);
|
||||
} else {
|
||||
usage(argv[0]);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
}
|
||||
|
@ -8,54 +8,9 @@ int mtk_kernel = 0, mtk_ramdisk = 0;
|
||||
file_t boot_type, ramdisk_type, dtb_type;
|
||||
|
||||
static void check_headers() {
|
||||
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
|
||||
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
|
||||
printf("SECOND [%d] @ 0x%08x\n", hdr.second_size, hdr.second_addr);
|
||||
printf("DTB [%d] @ 0x%08x\n", hdr.dt_size, hdr.tags_addr);
|
||||
printf("PAGESIZE [%d]\n", hdr.page_size);
|
||||
if (hdr.os_version != 0) {
|
||||
int a,b,c,y,m = 0;
|
||||
int os_version, os_patch_level;
|
||||
os_version = hdr.os_version >> 11;
|
||||
os_patch_level = hdr.os_version & 0x7ff;
|
||||
|
||||
a = (os_version >> 14) & 0x7f;
|
||||
b = (os_version >> 7) & 0x7f;
|
||||
c = os_version & 0x7f;
|
||||
printf("OS_VERSION [%d.%d.%d]\n", a, b, c);
|
||||
|
||||
y = (os_patch_level >> 4) + 2000;
|
||||
m = os_patch_level & 0xf;
|
||||
printf("PATCH_LEVEL [%d-%02d]\n", y, m);
|
||||
}
|
||||
printf("NAME [%s]\n", hdr.name);
|
||||
printf("CMDLINE [%s]\n", hdr.cmdline);
|
||||
|
||||
// Check ramdisk compression type
|
||||
ramdisk_type = check_type(ramdisk);
|
||||
|
||||
switch (ramdisk_type) {
|
||||
case GZIP:
|
||||
printf("COMPRESSION [%s]\n", "gzip");
|
||||
break;
|
||||
case LZOP:
|
||||
printf("COMPRESSION [%s]\n", "lzop");
|
||||
break;
|
||||
case XZ:
|
||||
printf("COMPRESSION [%s]\n", "xz");
|
||||
break;
|
||||
case LZMA:
|
||||
printf("COMPRESSION [%s]\n", "lzma");
|
||||
break;
|
||||
case BZIP2:
|
||||
printf("COMPRESSION [%s]\n", "bzip2");
|
||||
break;
|
||||
case LZ4:
|
||||
printf("COMPRESSION [%s]\n", "lz4");
|
||||
break;
|
||||
default:
|
||||
error(1, "Unknown ramdisk format!");
|
||||
}
|
||||
|
||||
// Check MTK
|
||||
if (check_type(kernel) == MTK) {
|
||||
printf("MTK header found in kernel\n");
|
||||
@ -70,6 +25,9 @@ static void check_headers() {
|
||||
if (boot_type == ELF && hdr.dt_size) {
|
||||
dtb_type = check_type(dtb);
|
||||
}
|
||||
|
||||
// Print info
|
||||
print_info();
|
||||
}
|
||||
|
||||
static void elf_header_check(void *elf, int is64) {
|
||||
|
@ -24,17 +24,16 @@ void repack(const char* image) {
|
||||
size_t size;
|
||||
unsigned char *orig;
|
||||
char name[PATH_MAX];
|
||||
#define EXT_NUM 6
|
||||
char *ext_list[EXT_NUM] = { "gz", "lzo", "xz", "lzma", "bz2", "lz4" };
|
||||
|
||||
// Load original image
|
||||
mmap_ro(image, &orig, &size);
|
||||
|
||||
// Parse original image
|
||||
printf("\nParsing boot image: [%s]\n\n", image);
|
||||
parse_img(orig, size);
|
||||
|
||||
// Create new image
|
||||
int fd = open_new("new-boot.img");
|
||||
int fd = open_new(NEW_BOOT);
|
||||
|
||||
// Set all sizes to 0
|
||||
hdr.kernel_size = 0;
|
||||
@ -62,27 +61,34 @@ void repack(const char* image) {
|
||||
|
||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||
// If we found raw cpio, compress to original format
|
||||
|
||||
// Before we start, clean up previous compressed files
|
||||
for (int i = 0; i < SUP_NUM; ++i) {
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||
unlink(name);
|
||||
}
|
||||
|
||||
size_t cpio_size;
|
||||
unsigned char *cpio;
|
||||
mmap_ro(RAMDISK_FILE, &cpio, &cpio_size);
|
||||
|
||||
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
|
||||
error(1, "Unsupported format! Please compress manually!");
|
||||
error(1, "Unsupported ramdisk format!");
|
||||
|
||||
munmap(cpio, cpio_size);
|
||||
}
|
||||
|
||||
int found = 0;
|
||||
for (int i = 0; i < EXT_NUM; ++i) {
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]);
|
||||
for (int i = 0; i < SUP_NUM; ++i) {
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||
if (access(name, R_OK) == 0) {
|
||||
ramdisk_type = SUP_TYPE_LIST[i];
|
||||
found = 1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!found)
|
||||
error(1, "No ramdisk exists!");
|
||||
|
||||
hdr.ramdisk_size += restore(name, fd);
|
||||
file_align(fd, hdr.page_size);
|
||||
|
||||
@ -99,6 +105,8 @@ void repack(const char* image) {
|
||||
}
|
||||
|
||||
// Write header back
|
||||
printf("\nRepack to boot image: [%s]\n\n", NEW_BOOT);
|
||||
print_info();
|
||||
lseek(fd, 0, SEEK_SET);
|
||||
write(fd, &hdr, sizeof(hdr));
|
||||
|
||||
|
@ -13,6 +13,7 @@ void unpack(const char* image) {
|
||||
mmap_ro(image, &orig, &size);
|
||||
|
||||
// Parse image
|
||||
printf("\nParsing boot image: [%s]\n\n", image);
|
||||
parse_img(orig, size);
|
||||
|
||||
if (boot_type == CHROMEOS) {
|
||||
@ -34,19 +35,10 @@ void unpack(const char* image) {
|
||||
ramdisk += 512;
|
||||
hdr.ramdisk_size -= 512;
|
||||
}
|
||||
|
||||
if (decomp(ramdisk_type, RAMDISK_FILE, ramdisk, hdr.ramdisk_size)) {
|
||||
printf("Unsupported format! Please decompress manually!\n");
|
||||
switch (ramdisk_type) {
|
||||
case LZOP:
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo");
|
||||
break;
|
||||
default:
|
||||
// Never happens
|
||||
break;
|
||||
}
|
||||
// Dump the compressed ramdisk
|
||||
dump(ramdisk, hdr.ramdisk_size, name);
|
||||
dump(ramdisk, hdr.ramdisk_size, RAMDISK_FILE ".unsupport");
|
||||
error(1, "Unsupported ramdisk format! Dumped to %s", RAMDISK_FILE ".unsupport");
|
||||
}
|
||||
|
||||
if (hdr.second_size) {
|
||||
|
@ -1,6 +1,9 @@
|
||||
#include "magiskboot.h"
|
||||
#include "elf.h"
|
||||
|
||||
char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4" };
|
||||
file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4 };
|
||||
|
||||
void mmap_ro(const char *filename, unsigned char **buf, size_t *size) {
|
||||
int fd = open(filename, O_RDONLY);
|
||||
if (fd < 0)
|
||||
@ -75,3 +78,63 @@ int open_new(const char *filename) {
|
||||
error(1, "Unable to create %s", filename);
|
||||
return fd;
|
||||
}
|
||||
|
||||
void print_info() {
|
||||
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
|
||||
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
|
||||
printf("SECOND [%d] @ 0x%08x\n", hdr.second_size, hdr.second_addr);
|
||||
printf("DTB [%d] @ 0x%08x\n", hdr.dt_size, hdr.tags_addr);
|
||||
printf("PAGESIZE [%d]\n", hdr.page_size);
|
||||
if (hdr.os_version != 0) {
|
||||
int a,b,c,y,m = 0;
|
||||
int os_version, os_patch_level;
|
||||
os_version = hdr.os_version >> 11;
|
||||
os_patch_level = hdr.os_version & 0x7ff;
|
||||
|
||||
a = (os_version >> 14) & 0x7f;
|
||||
b = (os_version >> 7) & 0x7f;
|
||||
c = os_version & 0x7f;
|
||||
printf("OS_VERSION [%d.%d.%d]\n", a, b, c);
|
||||
|
||||
y = (os_patch_level >> 4) + 2000;
|
||||
m = os_patch_level & 0xf;
|
||||
printf("PATCH_LEVEL [%d-%02d]\n", y, m);
|
||||
}
|
||||
printf("NAME [%s]\n", hdr.name);
|
||||
printf("CMDLINE [%s]\n", hdr.cmdline);
|
||||
|
||||
switch (ramdisk_type) {
|
||||
case GZIP:
|
||||
printf("COMPRESSION [%s]\n", "gzip");
|
||||
break;
|
||||
case XZ:
|
||||
printf("COMPRESSION [%s]\n", "xz");
|
||||
break;
|
||||
case LZMA:
|
||||
printf("COMPRESSION [%s]\n", "lzma");
|
||||
break;
|
||||
case BZIP2:
|
||||
printf("COMPRESSION [%s]\n", "bzip2");
|
||||
break;
|
||||
case LZ4:
|
||||
printf("COMPRESSION [%s]\n", "lz4");
|
||||
break;
|
||||
default:
|
||||
fprintf(stderr, "Unknown ramdisk format!\n");
|
||||
}
|
||||
}
|
||||
|
||||
void cleanup() {
|
||||
printf("Cleaning up...\n");
|
||||
char name[PATH_MAX];
|
||||
unlink(KERNEL_FILE);
|
||||
unlink(RAMDISK_FILE);
|
||||
unlink(RAMDISK_FILE ".unsupport");
|
||||
unlink(SECOND_FILE);
|
||||
unlink(DTB_FILE);
|
||||
unlink(NEW_BOOT);
|
||||
for (int i = 0; i < SUP_NUM; ++i) {
|
||||
sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]);
|
||||
unlink(name);
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user