diff --git a/jni/magiskboot/Android.mk b/jni/magiskboot/Android.mk index 14f4ee7c6..368948f1e 100644 --- a/jni/magiskboot/Android.mk +++ b/jni/magiskboot/Android.mk @@ -12,10 +12,8 @@ LOCAL_C_INCLUDES := \ LOCAL_SRC_FILES := \ main.c \ - unpack.c \ - repack.c \ + bootimg.c \ hexpatch.c \ - parseimg.c \ compress.c \ boot_utils.c \ cpio.c \ diff --git a/jni/magiskboot/boot_utils.c b/jni/magiskboot/boot_utils.c index a47d6d09b..bc6e89d2c 100644 --- a/jni/magiskboot/boot_utils.c +++ b/jni/magiskboot/boot_utils.c @@ -82,55 +82,6 @@ int open_new(const char *filename) { return xopen(filename, O_WRONLY | O_CREAT | O_TRUNC, 0644); } -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; - case LZ4_LEGACY: - printf("COMPRESSION [%s]\n", "lz4_legacy"); - break; - default: - fprintf(stderr, "Unknown ramdisk format!\n"); - } - printf("\n"); -} - void cleanup() { printf("Cleaning up...\n"); char name[PATH_MAX]; diff --git a/jni/magiskboot/bootimg.c b/jni/magiskboot/bootimg.c new file mode 100644 index 000000000..63c7c9d02 --- /dev/null +++ b/jni/magiskboot/bootimg.c @@ -0,0 +1,310 @@ +#include "bootimg.h" +#include "magiskboot.h" + +static unsigned char *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) { + int fd = open_new(filename); + xwrite(fd, buf, size); + close(fd); +} + +static size_t restore(const char *filename, int fd) { + int ifd = xopen(filename, O_RDONLY); + size_t size = lseek(ifd, 0, SEEK_END); + lseek(ifd, 0, SEEK_SET); + xsendfile(fd, ifd, NULL, size); + close(ifd); + return size; +} + +static void restore_buf(int fd, const void *buf, size_t size) { + xwrite(fd, buf, size); +} + +static 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; + case LZ4_LEGACY: + printf("COMPRESSION [%s]\n", "lz4_legacy"); + break; + default: + fprintf(stderr, "Unknown ramdisk format!\n"); + } + printf("\n"); +} + +int parse_img(unsigned char *orig, size_t size) { + unsigned char *base, *end; + size_t pos = 0; + int ret = 0; + for(base = orig, end = orig + size; base < end; base += 256, size -= 256) { + switch (check_type(base)) { + case CHROMEOS: + // The caller should know it's chromeos, as it needs additional signing + ret = 2; + continue; + case ELF32: + exit(3); + case ELF64: + exit(4); + case AOSP: + // Read the header + memcpy(&hdr, base, sizeof(hdr)); + pos += hdr.page_size; + + // Kernel position + kernel = base + pos; + pos += hdr.kernel_size; + mem_align(&pos, hdr.page_size); + + // Ramdisk position + ramdisk = base + pos; + pos += hdr.ramdisk_size; + mem_align(&pos, hdr.page_size); + + if (hdr.second_size) { + // Second position + second = base + pos; + pos += hdr.second_size; + mem_align(&pos, hdr.page_size); + } + + if (hdr.dt_size) { + // dtb position + dtb = base + pos; + pos += hdr.dt_size; + mem_align(&pos, hdr.page_size); + } + + if (pos < size) { + extra = base + pos; + } + + // Check ramdisk compression type + ramdisk_type = check_type(ramdisk); + + // Check MTK + if (check_type(kernel) == MTK) { + printf("MTK header found in kernel\n"); + mtk_kernel = 1; + } + if (ramdisk_type == MTK) { + printf("MTK header found in ramdisk\n"); + mtk_ramdisk = 1; + ramdisk_type = check_type(ramdisk + 512); + } + + // Print info + print_info(); + return ret; + default: + continue; + } + } + LOGE(1, "No boot image magic found!\n"); +} + +void unpack(const char* image) { + size_t size; + unsigned char *orig; + mmap_ro(image, &orig, &size); + + // Parse image + printf("Parsing boot image: [%s]\n\n", image); + int ret = parse_img(orig, size); + + // Dump kernel + if (mtk_kernel) { + kernel += 512; + hdr.kernel_size -= 512; + } + dump(kernel, hdr.kernel_size, KERNEL_FILE); + + // Dump ramdisk + if (mtk_ramdisk) { + ramdisk += 512; + hdr.ramdisk_size -= 512; + } + 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"); + } + + if (hdr.second_size) { + // Dump second + dump(second, hdr.second_size, SECOND_FILE); + } + + if (hdr.dt_size) { + // Dump dtb + dump(dtb, hdr.dt_size, DTB_FILE); + } + + munmap(orig, size); + exit(ret); +} + +void repack(const char* orig_image, const char* out_image) { + size_t size; + unsigned char *orig; + char name[PATH_MAX]; + + // There are possible two MTK headers + mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr; + size_t mtk_kernel_off, mtk_ramdisk_off; + + // Load original image + mmap_ro(orig_image, &orig, &size); + + // Parse original image + printf("Parsing boot image: [%s]\n\n", orig_image); + parse_img(orig, size); + + printf("Repack to boot image: [%s]\n\n", out_image); + + // Create new image + int fd = open_new(out_image); + + // Set all sizes to 0 + hdr.kernel_size = 0; + hdr.ramdisk_size = 0; + hdr.second_size = 0; + hdr.dt_size = 0; + + // Skip a page for header + write_zero(fd, hdr.page_size); + + // Restore kernel + if (mtk_kernel) { + mtk_kernel_off = lseek(fd, 0, SEEK_CUR); + restore_buf(fd, kernel, 512); + memcpy(&mtk_kernel_hdr, kernel, sizeof(mtk_kernel_hdr)); + } + hdr.kernel_size = restore(KERNEL_FILE, fd); + file_align(fd, hdr.page_size, 1); + + // Restore ramdisk + if (mtk_ramdisk) { + mtk_ramdisk_off = lseek(fd, 0, SEEK_CUR); + restore_buf(fd, ramdisk, 512); + memcpy(&mtk_ramdisk_hdr, ramdisk, sizeof(mtk_ramdisk_hdr)); + } + 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; SUP_EXT_LIST[i]; ++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)) + LOGE(1, "Unsupported ramdisk format!\n"); + + munmap(cpio, cpio_size); + } + + int found = 0; + for (int i = 0; SUP_EXT_LIST[i]; ++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) + LOGE(1, "No ramdisk exists!\n"); + hdr.ramdisk_size = restore(name, fd); + file_align(fd, hdr.page_size, 1); + + // Restore second + if (access(SECOND_FILE, R_OK) == 0) { + hdr.second_size = restore(SECOND_FILE, fd); + file_align(fd, hdr.page_size, 1); + } + + // Restore dtb + if (access(DTB_FILE, R_OK) == 0) { + hdr.dt_size = restore(DTB_FILE, fd); + file_align(fd, hdr.page_size, 1); + } + + // 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 ) { + restore_buf(fd, extra, 16); + } + } + + // Write headers back + if (mtk_kernel) { + lseek(fd, mtk_kernel_off, SEEK_SET); + mtk_kernel_hdr.size = hdr.kernel_size; + hdr.kernel_size += 512; + restore_buf(fd, &mtk_kernel_hdr, sizeof(mtk_kernel_hdr)); + } + if (mtk_ramdisk) { + lseek(fd, mtk_ramdisk_off, SEEK_SET); + mtk_ramdisk_hdr.size = hdr.ramdisk_size; + hdr.ramdisk_size += 512; + restore_buf(fd, &mtk_ramdisk_hdr, sizeof(mtk_ramdisk_hdr)); + } + // Main header + lseek(fd, 0, SEEK_SET); + restore_buf(fd, &hdr, sizeof(hdr)); + + // Print new image info + print_info(); + + munmap(orig, size); + close(fd); +} + diff --git a/jni/magiskboot/magiskboot.h b/jni/magiskboot/magiskboot.h index d63029b04..172e1b7a6 100644 --- a/jni/magiskboot/magiskboot.h +++ b/jni/magiskboot/magiskboot.h @@ -62,17 +62,11 @@ extern char *SUP_LIST[]; extern char *SUP_EXT_LIST[]; extern file_t SUP_TYPE_LIST[]; -// Global variables -extern unsigned char *kernel, *ramdisk, *second, *dtb, *extra; -extern boot_img_hdr hdr; -extern file_t ramdisk_type; -extern int mtk_kernel, mtk_ramdisk; - // Main entries 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); -void parse_img(unsigned char *orig, size_t size); +int parse_img(unsigned char *orig, size_t size); int cpio_commands(const char *command, int argc, char *argv[]); void cleanup(); @@ -95,6 +89,5 @@ 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); int open_new(const char *filename); -void print_info(); #endif diff --git a/jni/magiskboot/parseimg.c b/jni/magiskboot/parseimg.c deleted file mode 100644 index 4d53c7f47..000000000 --- a/jni/magiskboot/parseimg.c +++ /dev/null @@ -1,91 +0,0 @@ -#include "bootimg.h" -#include "magiskboot.h" - -unsigned char *kernel, *ramdisk, *second, *dtb, *extra; -boot_img_hdr hdr; -int mtk_kernel = 0, mtk_ramdisk = 0; -file_t ramdisk_type; - -static void check_headers() { - // Check ramdisk compression type - ramdisk_type = check_type(ramdisk); - - // Check MTK - if (check_type(kernel) == MTK) { - printf("MTK header found in kernel\n"); - mtk_kernel = 1; - } - if (ramdisk_type == MTK) { - printf("MTK header found in ramdisk\n"); - mtk_ramdisk = 1; - ramdisk_type = check_type(ramdisk + 512); - } - - // Print info - print_info(); -} - -static void parse_aosp(unsigned char *base, size_t size) { - - // printf("IMG [AOSP]\n"); - - size_t pos = 0; - - // Read the header - memcpy(&hdr, base, sizeof(hdr)); - pos += hdr.page_size; - - // Kernel position - kernel = base + pos; - pos += hdr.kernel_size; - mem_align(&pos, hdr.page_size); - - // Ramdisk position - ramdisk = base + pos; - pos += hdr.ramdisk_size; - mem_align(&pos, hdr.page_size); - - if (hdr.second_size) { - // Second position - second = base + pos; - pos += hdr.second_size; - mem_align(&pos, hdr.page_size); - } - - if (hdr.dt_size) { - // dtb position - dtb = base + pos; - pos += hdr.dt_size; - mem_align(&pos, hdr.page_size); - } - - if (pos < size) { - extra = base + pos; - } - - check_headers(); -} - -void parse_img(unsigned char *orig, size_t size) { - unsigned char *base, *end; - for(base = orig, end = orig + size; base < end; base += 256, size -= 256) { - switch (check_type(base)) { - case CHROMEOS: - // The caller should know it's chromeos, as it needs additional signing - close(open_new("chromeos")); - continue; - case ELF32: - exit(2); - return; - case ELF64: - exit(3); - return; - case AOSP: - parse_aosp(base, size); - return; - default: - continue; - } - } - LOGE(1, "No boot image magic found!\n"); -} diff --git a/jni/magiskboot/repack.c b/jni/magiskboot/repack.c deleted file mode 100644 index 26a9a22b5..000000000 --- a/jni/magiskboot/repack.c +++ /dev/null @@ -1,136 +0,0 @@ -#include "magiskboot.h" - -static size_t restore(const char *filename, int fd) { - int ifd = xopen(filename, O_RDONLY); - size_t size = lseek(ifd, 0, SEEK_END); - lseek(ifd, 0, SEEK_SET); - xsendfile(fd, ifd, NULL, size); - close(ifd); - return size; -} - -static void restore_buf(int fd, const void *buf, size_t size) { - xwrite(fd, buf, size); -} - -void repack(const char* orig_image, const char* out_image) { - size_t size; - unsigned char *orig; - char name[PATH_MAX]; - - // There are possible two MTK headers - mtk_hdr mtk_kernel_hdr, mtk_ramdisk_hdr; - size_t mtk_kernel_off, mtk_ramdisk_off; - - // Load original image - mmap_ro(orig_image, &orig, &size); - - // Parse original image - printf("Parsing boot image: [%s]\n\n", orig_image); - parse_img(orig, size); - - printf("Repack to boot image: [%s]\n\n", out_image); - - // Create new image - int fd = open_new(out_image); - - // Set all sizes to 0 - hdr.kernel_size = 0; - hdr.ramdisk_size = 0; - hdr.second_size = 0; - hdr.dt_size = 0; - - // Skip a page for header - write_zero(fd, hdr.page_size); - - // Restore kernel - if (mtk_kernel) { - mtk_kernel_off = lseek(fd, 0, SEEK_CUR); - restore_buf(fd, kernel, 512); - memcpy(&mtk_kernel_hdr, kernel, sizeof(mtk_kernel_hdr)); - } - hdr.kernel_size = restore(KERNEL_FILE, fd); - file_align(fd, hdr.page_size, 1); - - // Restore ramdisk - if (mtk_ramdisk) { - mtk_ramdisk_off = lseek(fd, 0, SEEK_CUR); - restore_buf(fd, ramdisk, 512); - memcpy(&mtk_ramdisk_hdr, ramdisk, sizeof(mtk_ramdisk_hdr)); - } - 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; SUP_EXT_LIST[i]; ++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)) - LOGE(1, "Unsupported ramdisk format!\n"); - - munmap(cpio, cpio_size); - } - - int found = 0; - for (int i = 0; SUP_EXT_LIST[i]; ++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) - LOGE(1, "No ramdisk exists!\n"); - hdr.ramdisk_size = restore(name, fd); - file_align(fd, hdr.page_size, 1); - - // Restore second - if (access(SECOND_FILE, R_OK) == 0) { - hdr.second_size = restore(SECOND_FILE, fd); - file_align(fd, hdr.page_size, 1); - } - - // Restore dtb - if (access(DTB_FILE, R_OK) == 0) { - hdr.dt_size = restore(DTB_FILE, fd); - file_align(fd, hdr.page_size, 1); - } - - // 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 ) { - restore_buf(fd, extra, 16); - } - } - - // Write headers back - if (mtk_kernel) { - lseek(fd, mtk_kernel_off, SEEK_SET); - mtk_kernel_hdr.size = hdr.kernel_size; - hdr.kernel_size += 512; - restore_buf(fd, &mtk_kernel_hdr, sizeof(mtk_kernel_hdr)); - } - if (mtk_ramdisk) { - lseek(fd, mtk_ramdisk_off, SEEK_SET); - mtk_ramdisk_hdr.size = hdr.ramdisk_size; - hdr.ramdisk_size += 512; - restore_buf(fd, &mtk_ramdisk_hdr, sizeof(mtk_ramdisk_hdr)); - } - // Main header - lseek(fd, 0, SEEK_SET); - restore_buf(fd, &hdr, sizeof(hdr)); - - // Print new image info - print_info(); - - munmap(orig, size); - close(fd); -} diff --git a/jni/magiskboot/unpack.c b/jni/magiskboot/unpack.c deleted file mode 100644 index 68e2376ca..000000000 --- a/jni/magiskboot/unpack.c +++ /dev/null @@ -1,48 +0,0 @@ -#include "magiskboot.h" - -static void dump(unsigned char *buf, size_t size, const char *filename) { - int fd = open_new(filename); - xwrite(fd, buf, size); - close(fd); -} - -void unpack(const char* image) { - size_t size; - unsigned char *orig; - mmap_ro(image, &orig, &size); - - // Parse image - printf("Parsing boot image: [%s]\n\n", image); - parse_img(orig, size); - - // Dump kernel - if (mtk_kernel) { - kernel += 512; - hdr.kernel_size -= 512; - } - dump(kernel, hdr.kernel_size, KERNEL_FILE); - - // Dump ramdisk - if (mtk_ramdisk) { - ramdisk += 512; - hdr.ramdisk_size -= 512; - } - 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"); - } - - if (hdr.second_size) { - // Dump second - dump(second, hdr.second_size, SECOND_FILE); - } - - if (hdr.dt_size) { - // Dump dtb - dump(dtb, hdr.dt_size, DTB_FILE); - } - - munmap(orig, size); -} - diff --git a/scripts/boot_patch.sh b/scripts/boot_patch.sh index d91a07edf..1afc93905 100644 --- a/scripts/boot_patch.sh +++ b/scripts/boot_patch.sh @@ -119,15 +119,19 @@ chmod +x ./* ui_print_wrap "- Unpacking boot image" ./magiskboot --unpack "$BOOTIMAGE" +CHROMEOS=false case $? in 1 ) abort_wrap "! Unable to unpack boot image" ;; 2 ) + CHROMEOS=true + ;; + 3 ) ui_print_wrap "! Sony ELF32 format detected" abort_wrap "! Please use BootBridge from @AdrianDC to flash Magisk" ;; - 3 ) + 4 ) ui_print_wrap "! Sony ELF64 format detected" abort_wrap "! Stock kernel cannot be patched, please use a custom kernel" esac @@ -234,7 +238,7 @@ ui_print_wrap "- Repacking boot image" ./magiskboot --repack "$BOOTIMAGE" || abort_wrap "! Unable to repack boot image!" # Sign chromeos boot -if [ -f chromeos ]; then +if $CHROMEOS; then echo > empty ./chromeos/futility vbutil_kernel --pack new-boot.img.signed \