From 9f91c8b59d030548772e50ceeac2025f7e34886f Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Thu, 2 Mar 2017 21:59:37 +0800 Subject: [PATCH] Improvements --- jni/magiskboot/compress.c | 54 ++++++++++++++++ jni/magiskboot/magiskboot.h | 6 +- jni/magiskboot/parseimg.c | 121 ++++++++++++++++++++++-------------- jni/magiskboot/repack.c | 55 ++++------------ jni/magiskboot/unpack.c | 44 ++++--------- 5 files changed, 158 insertions(+), 122 deletions(-) diff --git a/jni/magiskboot/compress.c b/jni/magiskboot/compress.c index e779ec42a..b174f63a6 100644 --- a/jni/magiskboot/compress.c +++ b/jni/magiskboot/compress.c @@ -341,3 +341,57 @@ void bzip2(int mode, const char* filename, unsigned char* buf, size_t size) { } close(fd); } + +int decomp(file_t type, const char *to, unsigned char *from, size_t size) { + switch (type) { + case GZIP: + gzip(0, to, from, size); + break; + case XZ: + lzma(0, to, from, size); + break; + case LZMA: + lzma(0, to, from, size); + break; + case BZIP2: + bzip2(0, to, from, size); + break; + case LZ4: + lz4(0, to, from, size); + break; + default: + // Unsupported + return 1; + } + return 0; +} + +int comp(file_t type, const char *to, unsigned char *from, size_t size) { + char name[PATH_MAX]; + switch (type) { + case GZIP: + sprintf(name, "%s.%s", to, "gz"); + gzip(1, name, from, size); + break; + case XZ: + sprintf(name, "%s.%s", to, "xz"); + lzma(1, name, from, size); + break; + case LZMA: + sprintf(name, "%s.%s", to, "lzma"); + lzma(2, name, from, size); + break; + case BZIP2: + sprintf(name, "%s.%s", to, "bz2"); + bzip2(1, name, from, size); + break; + case LZ4: + sprintf(name, "%s.%s", to, "lz4"); + lz4(1, name, from, size); + break; + default: + // Unsupported + return 1; + } + return 0; +} diff --git a/jni/magiskboot/magiskboot.h b/jni/magiskboot/magiskboot.h index fc62b38a3..45972ad4b 100644 --- a/jni/magiskboot/magiskboot.h +++ b/jni/magiskboot/magiskboot.h @@ -30,7 +30,7 @@ #define DTB_FILE "dtb" typedef enum { - DONTCARE, + UNKNOWN, CHROMEOS, AOSP, ELF, @@ -40,6 +40,7 @@ typedef enum { LZMA, BZIP2, LZ4, + MTK, QCDT, } file_t; @@ -55,11 +56,14 @@ void repack(const char *image); void hexpatch(char *image, char *from, char *to); void error(int rc, const char *msg, ...); void parse_img(unsigned char *orig, size_t size); +file_t check_type(unsigned char *buf); // Compressions void gzip(int mode, const char* filename, unsigned char* buf, size_t size); void lzma(int mode, const char* filename, unsigned char* buf, size_t size); void lz4(int mode, const char* filename, unsigned char* buf, size_t size); void bzip2(int mode, const char* filename, unsigned char* buf, size_t size); +int comp(file_t type, const char *to, unsigned char *from, size_t size); +int decomp(file_t type, const char *to, unsigned char *from, size_t size); #endif diff --git a/jni/magiskboot/parseimg.c b/jni/magiskboot/parseimg.c index 8aea15e29..0ab95d3c6 100644 --- a/jni/magiskboot/parseimg.c +++ b/jni/magiskboot/parseimg.c @@ -13,6 +13,37 @@ boot_img_hdr hdr; int mtk_kernel = 0, mtk_ramdisk = 0; file_t boot_type, ramdisk_type, dtb_type; +file_t check_type(unsigned char *buf) { + if (memcmp(buf, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) { + return CHROMEOS; + } else if (memcmp(buf, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) { + return AOSP; + } else if (memcmp(buf, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) { + return ELF; + } else if (memcmp(buf, "\x1f\x8b\x08\x00", 4) == 0) { + return GZIP; + } else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) { + return LZOP; + } else if (memcmp(buf, "\xfd""7zXZ\x00", 6) == 0) { + return XZ; + } else if (memcmp(buf, "\x5d\x00\x00", 3) == 0 + && (buf[12] == (unsigned char) '\xff' || buf[12] == (unsigned char) '\x00')) { + return LZMA; + } else if (memcmp(buf, "BZh", 3) == 0) { + return BZIP2; + } else if ( ( memcmp(buf, "\x04\x22\x4d\x18", 4) == 0 + || memcmp(buf, "\x03\x21\x4c\x18", 4) == 0) + || memcmp(buf, "\x02\x21\x4c\x18", 4) == 0) { + return LZ4; + } else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) { + return MTK; + } else if (memcmp(buf, "QCDT", 4) == 0) { + return QCDT; + } else { + return UNKNOWN; + } +} + 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); @@ -37,56 +68,44 @@ static void check_headers() { printf("NAME [%s]\n", hdr.name); printf("CMDLINE [%s]\n", hdr.cmdline); - // Check compression - if (memcmp(ramdisk, "\x1f\x8b\x08\x00", 4) == 0) { - // gzip header - printf("COMPRESSION [gzip]\n"); - ramdisk_type = GZIP; - } else if (memcmp(ramdisk, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) { - // lzop header - printf("COMPRESSION [lzop]\n"); - ramdisk_type = LZOP; - } else if (memcmp(ramdisk, "\xfd""7zXZ\x00", 6) == 0) { - // xz header - printf("COMPRESSION [xz]\n"); - ramdisk_type = XZ; - } else if (memcmp(ramdisk, "\x5d\x00\x00", 3) == 0 - && (ramdisk[12] == (unsigned char) '\xff' || ramdisk[12] == (unsigned char) '\x00')) { - // lzma header - printf("COMPRESSION [lzma]\n"); - ramdisk_type = LZMA; - } else if (memcmp(ramdisk, "BZh", 3) == 0) { - // bzip2 header - printf("COMPRESSION [bzip2]\n"); - ramdisk_type = BZIP2; - } else if ( ( memcmp(ramdisk, "\x04\x22\x4d\x18", 4) == 0 - || memcmp(ramdisk, "\x03\x21\x4c\x18", 4) == 0) - || memcmp(ramdisk, "\x02\x21\x4c\x18", 4) == 0) { - // lz4 header - printf("COMPRESSION [lz4]\n"); - ramdisk_type = LZ4; + ramdisk_type = check_type(ramdisk); - } else { - error(1, "Unknown ramdisk format!"); + 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 (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) { + if (check_type(kernel) == MTK) { printf("MTK header found in kernel\n"); mtk_kernel = 1; } - if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) { + if (check_type(ramdisk) == MTK) { printf("MTK header found in ramdisk\n"); mtk_ramdisk = 1; } - // Check dtb + // Check dtb if ELF boot if (boot_type == ELF && hdr.dt_size) { - if (memcmp(dtb, "QCDT", 4) == 0) { - dtb_type = QCDT; - } else if (memcmp(dtb, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) { - dtb_type = ELF; - } + dtb_type = check_type(dtb); } } @@ -292,16 +311,22 @@ static void parse_aosp() { void parse_img(unsigned char *orig, size_t size) { for(base = orig; base < (orig + size); base += 256) { - if (memcmp(base, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) { - boot_type = CHROMEOS; - } else if (memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) { - if (boot_type != CHROMEOS) boot_type = AOSP; - parse_aosp(); - return; - } else if (memcmp(base, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) { - boot_type = ELF; - parse_elf(); - return; + switch (check_type(base)) { + case CHROMEOS: + boot_type = CHROMEOS; + continue; + case AOSP: + // Don't override CHROMEOS + if (boot_type != CHROMEOS) + boot_type = AOSP; + parse_aosp(); + return; + case ELF: + boot_type = ELF; + parse_elf(); + return; + default: + continue; } } error(1, "No boot image magic found!"); diff --git a/jni/magiskboot/repack.c b/jni/magiskboot/repack.c index 2407edea2..c19d56126 100644 --- a/jni/magiskboot/repack.c +++ b/jni/magiskboot/repack.c @@ -82,7 +82,7 @@ void repack(const char* image) { } if (access(RAMDISK_FILE, R_OK) == 0) { - // If we found raw cpio, recompress to original format + // If we found raw cpio, compress to original format int rfd = open(RAMDISK_FILE, O_RDONLY); if (rfd < 0) error(1, "Cannot open " RAMDISK_FILE); @@ -91,52 +91,23 @@ void repack(const char* image) { lseek(rfd, 0, SEEK_SET); unsigned char *cpio = mmap(NULL, cpio_size, PROT_READ, MAP_SHARED, rfd, 0); - switch (ramdisk_type) { - case GZIP: - sprintf(name, "%s.%s", RAMDISK_FILE, "gz"); - gzip(1, name, cpio, cpio_size); - break; - case LZOP: - sprintf(name, "%s.%s", RAMDISK_FILE, "lzo"); - error(1, "Unsupported format! Please compress manually!"); - break; - case XZ: - sprintf(name, "%s.%s", RAMDISK_FILE, "xz"); - lzma(1, name, cpio, cpio_size); - break; - case LZMA: - sprintf(name, "%s.%s", RAMDISK_FILE, "lzma"); - lzma(2, name, cpio, cpio_size); - break; - case BZIP2: - sprintf(name, "%s.%s", RAMDISK_FILE, "bz2"); - bzip2(1, name, cpio, cpio_size); - break; - case LZ4: - sprintf(name, "%s.%s", RAMDISK_FILE, "lz4"); - lz4(1, name, cpio, cpio_size); - break; - default: - // Never happens - break; - } + if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size)) + error(1, "Unsupported format! Please compress manually!\n"); munmap(cpio, cpio_size); close(rfd); - } else { - // If no raw cpio found, find compressed ones - int found = 0; - for (int i = 0; i < EXT_NUM; ++i) { - sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]); - if (access(name, R_OK) == 0) { - found = 1; - break; - } - } - if (!found) { - error(1, "No ramdisk exists!"); + } + + int found = 0; + for (int i = 0; i < EXT_NUM; ++i) { + sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]); + if (access(name, R_OK) == 0) { + found = 1; + break; } } + if (!found) + error(1, "No ramdisk exists!"); hdr.ramdisk_size += restore(name); page_align(); diff --git a/jni/magiskboot/unpack.c b/jni/magiskboot/unpack.c index 4e3621959..1a25008af 100644 --- a/jni/magiskboot/unpack.c +++ b/jni/magiskboot/unpack.c @@ -41,36 +41,18 @@ void unpack(const char* image) { hdr.ramdisk_size -= 512; } - switch (ramdisk_type) { - case GZIP: - sprintf(name, "%s.%s", RAMDISK_FILE, "gz"); - gzip(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size); - break; - case LZOP: - sprintf(name, "%s.%s", RAMDISK_FILE, "lzo"); - printf("Unsupported format! Please decompress manually!\n"); - // Dump the compressed ramdisk - dump(ramdisk, hdr.ramdisk_size, name); - break; - case XZ: - sprintf(name, "%s.%s", RAMDISK_FILE, "xz"); - lzma(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size); - break; - case LZMA: - sprintf(name, "%s.%s", RAMDISK_FILE, "lzma"); - lzma(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size); - break; - case BZIP2: - sprintf(name, "%s.%s", RAMDISK_FILE, "bz2"); - bzip2(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size); - break; - case LZ4: - sprintf(name, "%s.%s", RAMDISK_FILE, "lz4"); - lz4(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size); - break; - default: - // Never happens - break; + 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); } if (hdr.second_size) { @@ -79,7 +61,7 @@ void unpack(const char* image) { } if (hdr.dt_size) { - if (boot_type == ELF && (dtb_type != QCDT && dtb_type != ELF )) { + if (boot_type == ELF && (dtb_type != QCDT && dtb_type != ELF)) { printf("Non QC dtb found in ELF kernel, recreate kernel\n"); gzip(1, KERNEL_FILE, kernel, hdr.kernel_size); int kfp = open(KERNEL_FILE, O_WRONLY | O_APPEND);