From b5360467202c877107ee97538cdb5a741fcd56d1 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Tue, 12 Sep 2017 15:27:28 +0800 Subject: [PATCH] MagiskBoot refactor --- jni/magiskboot/boot_utils.c | 68 ++++++++++++++++++++++++++++++------- jni/magiskboot/bootimg.c | 52 ++++++++++------------------ jni/magiskboot/compress.c | 39 ++++++++++----------- jni/magiskboot/cpio.c | 23 ++++++++----- jni/magiskboot/hexpatch.c | 2 +- jni/magiskboot/magic.h | 34 +++++++++++++++++++ jni/magiskboot/magiskboot.h | 44 +++++++----------------- jni/magiskboot/main.c | 2 +- 8 files changed, 157 insertions(+), 107 deletions(-) create mode 100644 jni/magiskboot/magic.h diff --git a/jni/magiskboot/boot_utils.c b/jni/magiskboot/boot_utils.c index 463764d99..6e37329a6 100644 --- a/jni/magiskboot/boot_utils.c +++ b/jni/magiskboot/boot_utils.c @@ -4,7 +4,7 @@ char *SUP_LIST[] = { "gzip", "xz", "lzma", "bzip2", "lz4", "lz4_legacy", NULL }; char *SUP_EXT_LIST[] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4", NULL }; file_t SUP_TYPE_LIST[] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY, 0 }; -void mmap_ro(const char *filename, unsigned char **buf, size_t *size) { +void mmap_ro(const char *filename, void **buf, size_t *size) { int fd = xopen(filename, O_RDONLY); *size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); @@ -12,7 +12,7 @@ void mmap_ro(const char *filename, unsigned char **buf, size_t *size) { close(fd); } -void mmap_rw(const char *filename, unsigned char **buf, size_t *size) { +void mmap_rw(const char *filename, void **buf, size_t *size) { int fd = xopen(filename, O_RDWR); *size = lseek(fd, 0, SEEK_END); lseek(fd, 0, SEEK_SET); @@ -20,7 +20,7 @@ void mmap_rw(const char *filename, unsigned char **buf, size_t *size) { close(fd); } -file_t check_type(const unsigned char *buf) { +file_t check_type(const void *buf) { if (memcmp(buf, CHROMEOS_MAGIC, 8) == 0) { return CHROMEOS; } else if (memcmp(buf, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) { @@ -29,28 +29,72 @@ file_t check_type(const unsigned char *buf) { return ELF32; } else if (memcmp(buf, ELF64_MAGIC, 5) == 0) { return ELF64; - } else if (memcmp(buf, "\x1f\x8b\x08\x00", 4) == 0) { + } else if (memcmp(buf, GZIP_MAGIC, 4) == 0) { return GZIP; - } else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) { + } else if (memcmp(buf, LZOP_MAGIC, 9) == 0) { return LZOP; - } else if (memcmp(buf, "\xfd""7zXZ\x00", 6) == 0) { + } else if (memcmp(buf, XZ_MAGIC, 6) == 0) { return XZ; - } else if (memcmp(buf, "\x5d\x00\x00", 3) == 0 - && (buf[12] == (unsigned char) '\xff' || buf[12] == (unsigned char) '\x00')) { + } else if (memcmp(buf, "\x5d\x00\x00", 3) == 0 + && (((char *)buf)[12] == '\xff' || ((char *)buf)[12] == '\x00')) { return LZMA; - } else if (memcmp(buf, "BZh", 3) == 0) { + } else if (memcmp(buf, BZIP_MAGIC, 3) == 0) { return BZIP2; - } else if (memcmp(buf, "\x04\x22\x4d\x18", 4) == 0) { + } else if (memcmp(buf, LZ4_MAGIC, 4) == 0) { return LZ4; - } else if (memcmp(buf, "\x02\x21\x4c\x18", 4) == 0) { + } else if (memcmp(buf, LZ4_LEG_MAGIC, 4) == 0) { return LZ4_LEGACY; - } else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) { + } else if (memcmp(buf, MTK_MAGIC, 4) == 0) { return MTK; + } else if (memcmp(buf, DTB_MAGIC, 4) == 0) { + return DTB; } else { return UNKNOWN; } } +void get_type_name(file_t type, char *name) { + char *s; + switch (type) { + case CHROMEOS: + s = "chromeos"; + break; + case AOSP: + s = "aosp"; + break; + case GZIP: + s = "gzip"; + break; + case LZOP: + s = "lzop"; + break; + case XZ: + s = "xz"; + break; + case LZMA: + s = "lzma"; + break; + case BZIP2: + s = "bzip2"; + break; + case LZ4: + s = "lz4"; + break; + case LZ4_LEGACY: + s = "lz4_legacy"; + break; + case MTK: + s = "mtk"; + break; + case DTB: + s = "dtb"; + break; + default: + s = "raw"; + } + strcpy(name, s); +} + void write_zero(int fd, size_t size) { size_t pos = lseek(fd, 0, SEEK_CUR); ftruncate(fd, pos + size); diff --git a/jni/magiskboot/bootimg.c b/jni/magiskboot/bootimg.c index 286a10ad7..d2b87c766 100644 --- a/jni/magiskboot/bootimg.c +++ b/jni/magiskboot/bootimg.c @@ -1,12 +1,12 @@ #include "bootimg.h" #include "magiskboot.h" -static unsigned char *kernel, *ramdisk, *second, *dtb, *extra; +static void *kernel, *ramdisk, *second, *dtb, *extra; static boot_img_hdr hdr; static int mtk_kernel = 0, mtk_ramdisk = 0; static file_t ramdisk_type; -static void dump(unsigned char *buf, size_t size, const char *filename) { +static void dump(void *buf, size_t size, const char *filename) { int fd = open_new(filename); xwrite(fd, buf, size); close(fd); @@ -36,12 +36,12 @@ static void print_info() { 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; fprintf(stderr, "OS_VERSION [%d.%d.%d]\n", a, b, c); - + y = (os_patch_level >> 4) + 2000; m = os_patch_level & 0xf; fprintf(stderr, "PATCH_LEVEL [%d-%02d]\n", y, m); @@ -49,33 +49,15 @@ static void print_info() { fprintf(stderr, "NAME [%s]\n", hdr.name); fprintf(stderr, "CMDLINE [%s]\n", hdr.cmdline); - switch (ramdisk_type) { - case GZIP: - fprintf(stderr, "COMPRESSION [%s]\n", "gzip"); - break; - case XZ: - fprintf(stderr, "COMPRESSION [%s]\n", "xz"); - break; - case LZMA: - fprintf(stderr, "COMPRESSION [%s]\n", "lzma"); - break; - case BZIP2: - fprintf(stderr, "COMPRESSION [%s]\n", "bzip2"); - break; - case LZ4: - fprintf(stderr, "COMPRESSION [%s]\n", "lz4"); - break; - case LZ4_LEGACY: - fprintf(stderr, "COMPRESSION [%s]\n", "lz4_legacy"); - break; - default: - fprintf(stderr, "Unknown ramdisk format!\n"); - } + char cmp[16]; + + get_type_name(ramdisk_type, cmp); + fprintf(stderr, "RAMDISK_COMP [%s]\n", cmp); fprintf(stderr, "\n"); } -int parse_img(unsigned char *orig, size_t size) { - unsigned char *base, *end; +int parse_img(void *orig, size_t size) { + void *base, *end; size_t pos = 0; int ret = 0; for(base = orig, end = orig + size; base < end; base += 256, size -= 256) { @@ -147,7 +129,7 @@ int parse_img(unsigned char *orig, size_t size) { void unpack(const char* image) { size_t size; - unsigned char *orig; + void *orig; mmap_ro(image, &orig, &size); // Parse image @@ -168,8 +150,8 @@ void unpack(const char* image) { } if (decomp(ramdisk_type, RAMDISK_FILE, ramdisk, hdr.ramdisk_size)) { // Dump the compressed ramdisk - dump(ramdisk, hdr.ramdisk_size, RAMDISK_FILE ".unsupport"); - LOGE(1, "Unsupported ramdisk format! Dumped to %s\n", RAMDISK_FILE ".unsupport"); + dump(ramdisk, hdr.ramdisk_size, RAMDISK_FILE ".raw"); + LOGE(1, "Unknown ramdisk format! Dumped to %s\n", RAMDISK_FILE ".raw"); } if (hdr.second_size) { @@ -188,7 +170,7 @@ void unpack(const char* image) { void repack(const char* orig_image, const char* out_image) { size_t size; - unsigned char *orig; + void *orig; char name[PATH_MAX]; // There are possible two MTK headers @@ -241,7 +223,7 @@ void repack(const char* orig_image, const char* out_image) { } size_t cpio_size; - unsigned char *cpio; + void *cpio; mmap_ro(RAMDISK_FILE, &cpio, &cpio_size); if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size)) @@ -278,8 +260,8 @@ void repack(const char* orig_image, const char* out_image) { // Check extra info, currently only for LG Bump and Samsung SEANDROIDENFORCE if (extra) { - if (memcmp(extra, "SEANDROIDENFORCE", 16) == 0 || - memcmp(extra, "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79", 16) == 0 ) { + if (memcmp(extra, "SEANDROIDENFORCE", 16) == 0 || + memcmp(extra, LG_BUMP_MAGIC, 16) == 0 ) { restore_buf(fd, extra, 16); } } diff --git a/jni/magiskboot/compress.c b/jni/magiskboot/compress.c index a4d14b59f..0893b65c6 100644 --- a/jni/magiskboot/compress.c +++ b/jni/magiskboot/compress.c @@ -31,7 +31,7 @@ static void report(const int mode, const char* filename) { } // Mode: 0 = decode; 1 = encode -void gzip(int mode, const char* filename, const unsigned char* buf, size_t size) { +void gzip(int mode, const char* filename, const void *buf, size_t size) { size_t ret = 0, flush, have, pos = 0; z_stream strm; unsigned char out[CHUNK]; @@ -102,7 +102,7 @@ void gzip(int mode, const char* filename, const unsigned char* buf, size_t size) // Mode: 0 = decode xz/lzma; 1 = encode xz; 2 = encode lzma -void lzma(int mode, const char* filename, const unsigned char* buf, size_t size) { +void lzma(int mode, const char* filename, const void *buf, size_t size) { size_t have, pos = 0; lzma_ret ret = 0; lzma_stream strm = LZMA_STREAM_INIT; @@ -167,14 +167,14 @@ void lzma(int mode, const char* filename, const unsigned char* buf, size_t size) } // Mode: 0 = decode; 1 = encode -void lz4(int mode, const char* filename, const unsigned char* buf, size_t size) { +void lz4(int mode, const char* filename, const void *buf, size_t size) { LZ4F_decompressionContext_t dctx; LZ4F_compressionContext_t cctx; LZ4F_frameInfo_t info; size_t outCapacity, avail_in, ret = 0, pos = 0; size_t have, read; - unsigned char *out = NULL; + void *out = NULL; report(mode, filename); int fd = open_new(filename); @@ -190,7 +190,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size) default: LOGE(1, "Unsupported lz4 mode!\n"); } - + if (LZ4F_isError(ret)) LOGE(1, "Context creation error: %s\n", LZ4F_getErrorName(ret)); @@ -277,7 +277,7 @@ void lz4(int mode, const char* filename, const unsigned char* buf, size_t size) } // Mode: 0 = decode; 1 = encode -void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size) { +void bzip2(int mode, const char* filename, const void* buf, size_t size) { size_t ret = 0, action, have, pos = 0; bz_stream strm; char out[CHUNK]; @@ -345,7 +345,7 @@ void bzip2(int mode, const char* filename, const unsigned char* buf, size_t size } // Mode: 0 = decode; 1 = encode -void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t size) { +void lz4_legacy(int mode, const char* filename, const void* buf, size_t size) { size_t pos = 0; int have; char *out; @@ -372,12 +372,13 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t } do { + const char *buff = buf; switch(mode) { case 0: - block_size = buf[pos]; - block_size += (buf[pos + 1]<<8); - block_size += (buf[pos + 2]<<16); - block_size += ((unsigned)buf[pos + 3])<<24; + block_size = buff[pos]; + block_size += (buff[pos + 1]<<8); + block_size += (buff[pos + 2]<<16); + block_size += ((unsigned)buff[pos + 3])<<24; pos += 4; if (block_size > LZ4_COMPRESSBOUND(LZ4_LEGACY_BLOCKSIZE)) LOGE(1, "lz4_legacy block size too large!\n"); @@ -395,10 +396,10 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t if (have == 0) LOGE(1, "lz4_legacy compression error\n"); pos += insize; - block_size_le[0] = (unsigned char)have; - block_size_le[1] = (unsigned char)(have >> 8); - block_size_le[2] = (unsigned char)(have >> 16); - block_size_le[3] = (unsigned char)(have >> 24); + block_size_le[0] = have & 0xff; + block_size_le[1] = (have >> 8) & 0xff; + block_size_le[2] = (have >> 16) & 0xff; + block_size_le[3] = (have >> 24) & 0xff; write_file(fd, block_size_le, 4, filename); break; } @@ -410,7 +411,7 @@ void lz4_legacy(int mode, const char* filename, const unsigned char* buf, size_t close(fd); } -int decomp(file_t type, const char *to, const unsigned char *from, size_t size) { +int decomp(file_t type, const char *to, const void *from, size_t size) { switch (type) { case GZIP: gzip(0, to, from, size); @@ -438,7 +439,7 @@ int decomp(file_t type, const char *to, const unsigned char *from, size_t size) } // Output will be to.ext -int comp(file_t type, const char *to, const unsigned char *from, size_t size) { +int comp(file_t type, const char *to, const void *from, size_t size) { char name[PATH_MAX]; const char *ext = strrchr(to, '.'); if (ext == NULL) ext = to; @@ -483,7 +484,7 @@ int comp(file_t type, const char *to, const unsigned char *from, size_t size) { void decomp_file(char *from, const char *to) { int ok = 1; - unsigned char *file; + void *file; size_t size; mmap_ro(from, &file, &size); file_t type = check_type(file); @@ -556,7 +557,7 @@ void comp_file(const char *method, const char *from, const char *to) { fprintf(stderr, "\n"); exit(1); } - unsigned char *file; + void *file; size_t size; mmap_ro(from, &file, &size); if (!to) diff --git a/jni/magiskboot/cpio.c b/jni/magiskboot/cpio.c index c90c0168c..082fe7a78 100644 --- a/jni/magiskboot/cpio.c +++ b/jni/magiskboot/cpio.c @@ -177,21 +177,28 @@ static void cpio_add(mode_t mode, const char *entry, const char *filename, struc } static void cpio_test(struct vector *v) { - #define MAGISK_PATCH 0x1 - #define OTHER_PATCH 0x2 - int ret = 0; + #define STOCK_BOOT 0x0 + #define MAGISK_PATCH 0x1 + #define OTHER_PATCH 0x2 + int ret = STOCK_BOOT; cpio_file *f; - const char *OTHER_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", "init.supersu.rc", NULL }; + const char *OTHER_LIST[] = { "sbin/launch_daemonsu.sh", "sbin/su", "init.xposed.rc", "boot/sbin/launch_daemonsu.sh", NULL }; + const char *MAGISK_LIST[] = { "init.magisk.rc", "overlay/init.magisk.rc", NULL }; vec_for_each(v, f) { for (int i = 0; OTHER_LIST[i]; ++i) { - if (strcmp(f->filename, OTHER_LIST[i]) == 0) + if (strcmp(f->filename, OTHER_LIST[i]) == 0) { ret |= OTHER_PATCH; + // Already find other files, abort + exit(OTHER_PATCH); + } + } + for (int i = 0; MAGISK_LIST[i]; ++i) { + if (strcmp(f->filename, MAGISK_LIST[i]) == 0) + ret = MAGISK_PATCH; } - if (strcmp(f->filename, "init.magisk.rc") == 0) - ret |= MAGISK_PATCH; } cpio_vec_destroy(v); - exit((ret & OTHER_PATCH) ? OTHER_PATCH : (ret & MAGISK_PATCH)); + exit(ret); } static int check_verity_pattern(const char *s) { diff --git a/jni/magiskboot/hexpatch.c b/jni/magiskboot/hexpatch.c index 0d67503a9..b707116dd 100644 --- a/jni/magiskboot/hexpatch.c +++ b/jni/magiskboot/hexpatch.c @@ -12,7 +12,7 @@ static void hex2byte(const char *hex, unsigned char *str) { void hexpatch(const char *image, const char *from, const char *to) { int patternsize = strlen(from) / 2, patchsize = strlen(to) / 2; size_t filesize; - unsigned char *file, *pattern, *patch; + void *file, *pattern, *patch; mmap_rw(image, &file, &filesize); pattern = xmalloc(patternsize); patch = xmalloc(patchsize); diff --git a/jni/magiskboot/magic.h b/jni/magiskboot/magic.h new file mode 100644 index 000000000..0ab3ea1d0 --- /dev/null +++ b/jni/magiskboot/magic.h @@ -0,0 +1,34 @@ +#ifndef _MAGIC_H_ +#define _MAGIC_H_ + +typedef enum { + UNKNOWN, + CHROMEOS, + AOSP, + ELF32, + ELF64, + GZIP, + LZOP, + XZ, + LZMA, + BZIP2, + LZ4, + LZ4_LEGACY, + MTK, + DTB +} file_t; + +#define CHROMEOS_MAGIC "CHROMEOS" +#define ELF32_MAGIC "\x7f""ELF\x01" +#define ELF64_MAGIC "\x7f""ELF\x02" +#define GZIP_MAGIC "\x1f\x8b\x08\x00" +#define LZOP_MAGIC "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a" +#define XZ_MAGIC "\xfd""7zXZ\x00" +#define BZIP_MAGIC "BZh" +#define LZ4_MAGIC "\x04\x22\x4d\x18" +#define LZ4_LEG_MAGIC "\x02\x21\x4c\x18" +#define MTK_MAGIC "\x88\x16\x88\x58" +#define DTB_MAGIC "\xd0\x0d\xfe\xed" +#define LG_BUMP_MAGIC "\x41\xa9\xe4\x67\x74\x4d\x1d\x1b\xa4\x29\xf2\xec\xea\x65\x52\x79" + +#endif diff --git a/jni/magiskboot/magiskboot.h b/jni/magiskboot/magiskboot.h index 22a7559cc..4f1890614 100644 --- a/jni/magiskboot/magiskboot.h +++ b/jni/magiskboot/magiskboot.h @@ -16,10 +16,7 @@ #include "sha1.h" #include "magisk.h" #include "utils.h" - -#define CHROMEOS_MAGIC "CHROMEOS" -#define ELF32_MAGIC "\x7f""ELF\x01" -#define ELF64_MAGIC "\x7f""ELF\x02" +#include "magic.h" #define KERNEL_FILE "kernel" #define RAMDISK_FILE "ramdisk.cpio" @@ -30,22 +27,6 @@ #define str(a) #a #define xstr(a) str(a) -typedef enum { - UNKNOWN, - CHROMEOS, - AOSP, - ELF32, - ELF64, - GZIP, - LZOP, - XZ, - LZMA, - BZIP2, - LZ4, - LZ4_LEGACY, - MTK -} file_t; - extern char *SUP_LIST[]; extern char *SUP_EXT_LIST[]; extern file_t SUP_TYPE_LIST[]; @@ -54,25 +35,26 @@ extern file_t SUP_TYPE_LIST[]; void unpack(const char *image); void repack(const char* orig_image, const char* out_image); void hexpatch(const char *image, const char *from, const char *to); -int parse_img(unsigned char *orig, size_t size); +int parse_img(void *orig, size_t size); int cpio_commands(const char *command, int argc, char *argv[]); void cleanup(); // Compressions -void gzip(int mode, const char* filename, const unsigned char* buf, size_t size); -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); -void lz4_legacy(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 gzip(int mode, const char* filename, const void *buf, size_t size); +void lzma(int mode, const char* filename, const void *buf, size_t size); +void lz4(int mode, const char* filename, const void *buf, size_t size); +void bzip2(int mode, const char* filename, const void *buf, size_t size); +void lz4_legacy(int mode, const char* filename, const void *buf, size_t size); +int comp(file_t type, const char *to, const void *from, size_t size); void comp_file(const char *method, const char *from, const char *to); -int decomp(file_t type, const char *to, const unsigned char *from, size_t size); +int decomp(file_t type, const char *to, const void *from, size_t size); void decomp_file(char *from, const char *to); // Utils -void mmap_ro(const char *filename, unsigned char **buf, size_t *size); -void mmap_rw(const char *filename, unsigned char **buf, size_t *size); -file_t check_type(const unsigned char *buf); +void mmap_ro(const char *filename, void **buf, size_t *size); +void mmap_rw(const char *filename, void **buf, size_t *size); +file_t check_type(const void *buf); +void get_type_name(file_t type, char *name); void write_zero(int fd, size_t size); void mem_align(size_t *pos, size_t align); void file_align(int fd, size_t align, int out); diff --git a/jni/magiskboot/main.c b/jni/magiskboot/main.c index d3c5a3430..dd7379064 100644 --- a/jni/magiskboot/main.c +++ b/jni/magiskboot/main.c @@ -67,7 +67,7 @@ int main(int argc, char *argv[]) { } else if (argc > 2 && strcmp(argv[1], "--sha1") == 0) { char sha1[21], *buf; size_t size; - mmap_ro(argv[2], (unsigned char **) &buf, &size); + mmap_ro(argv[2], (void **) &buf, &size); SHA1(sha1, buf, size); for (int i = 0; i < 20; ++i) printf("%02x", sha1[i]);