From 727abbea8f1e23f99679e03a864da68530663f62 Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Fri, 28 Apr 2017 03:15:48 +0800 Subject: [PATCH] Cleanup magiskboot --- jni/magiskboot/Android.mk | 13 ++- jni/magiskboot/compress.c | 2 +- jni/magiskboot/cpio.c | 44 ++++---- jni/magiskboot/elf.h | 151 --------------------------- jni/magiskboot/magiskboot.h | 46 +++------ jni/magiskboot/main.c | 95 ++++++++--------- jni/magiskboot/parseimg.c | 196 ++++-------------------------------- jni/magiskboot/repack.c | 4 +- jni/magiskboot/unpack.c | 17 +--- jni/magiskboot/utils.c | 46 ++------- 10 files changed, 129 insertions(+), 485 deletions(-) delete mode 100644 jni/magiskboot/elf.h diff --git a/jni/magiskboot/Android.mk b/jni/magiskboot/Android.mk index dd18769ea..85240ae8c 100644 --- a/jni/magiskboot/Android.mk +++ b/jni/magiskboot/Android.mk @@ -4,12 +4,23 @@ include $(CLEAR_VARS) LOCAL_MODULE := magiskboot LOCAL_STATIC_LIBRARIES := libz liblzma liblz4 libbz2 LOCAL_C_INCLUDES := \ + jni/utils \ jni/ndk-compression/zlib/ \ jni/ndk-compression/xz/src/liblzma/api/ \ jni/ndk-compression/lz4/lib/ \ jni/ndk-compression/bzip2/ -LOCAL_SRC_FILES := main.c unpack.c repack.c hexpatch.c parseimg.c compress.c utils.c cpio.c sha1.c +LOCAL_SRC_FILES := \ + main.c \ + unpack.c \ + repack.c \ + hexpatch.c \ + parseimg.c \ + compress.c \ + utils.c \ + cpio.c \ + sha1.c \ + ../utils/vector.c LOCAL_CFLAGS += -DZLIB_CONST include $(BUILD_EXECUTABLE) diff --git a/jni/magiskboot/compress.c b/jni/magiskboot/compress.c index b2f7aa66a..917b69a09 100644 --- a/jni/magiskboot/compress.c +++ b/jni/magiskboot/compress.c @@ -556,7 +556,7 @@ void comp_file(const char *method, const char *from, const char *to) { } else if (strcmp(method, "bzip2") == 0) { type = BZIP2; } else { - error(1, "Only support following methods: " SUP_LIST); + error(1, "Only support following methods: "); } unsigned char *file; size_t size; diff --git a/jni/magiskboot/cpio.c b/jni/magiskboot/cpio.c index 84750a592..5aaca43f3 100644 --- a/jni/magiskboot/cpio.c +++ b/jni/magiskboot/cpio.c @@ -1,5 +1,6 @@ #include "magiskboot.h" #include "cpio.h" +#include "vector.h" static uint32_t x8u(char *hex) { uint32_t val, inpos = 8, outpos; @@ -25,13 +26,13 @@ static void cpio_free(cpio_file *f) { } } -static void cpio_vec_insert(vector *v, cpio_file *n) { +static void cpio_vec_insert(struct vector *v, cpio_file *n) { cpio_file *f, *t; int shift = 0; // Insert in alphabet order vec_for_each(v, f) { if (shift) { - vec_entry(v)[_i] = t; + vec_entry(v)[_] = t; t = f; continue; } @@ -39,11 +40,11 @@ static void cpio_vec_insert(vector *v, cpio_file *n) { if (strcmp(f->filename, n->filename) == 0) { // Replace, then all is done cpio_free(f); - vec_entry(v)[_i] = n; + vec_entry(v)[_] = n; return; } else if (strcmp(f->filename, n->filename) > 0) { // Insert, then start shifting - vec_entry(v)[_i] = n; + vec_entry(v)[_] = n; t = f; shift = 1; } @@ -59,7 +60,7 @@ static int cpio_compare(const void *a, const void *b) { } // Parse cpio file to a vector of cpio_file -static void parse_cpio(const char *filename, vector *v) { +static void parse_cpio(const char *filename, struct vector *v) { printf("Loading cpio: [%s]\n\n", filename); int fd = open(filename, O_RDONLY); if (fd < 0) @@ -104,7 +105,7 @@ static void parse_cpio(const char *filename, vector *v) { vec_sort(v, cpio_compare); } -static void dump_cpio(const char *filename, vector *v) { +static void dump_cpio(const char *filename, struct vector *v) { printf("\nDump cpio: [%s]\n\n", filename); int fd = open_new(filename); unsigned inode = 300000; @@ -143,7 +144,7 @@ static void dump_cpio(const char *filename, vector *v) { close(fd); } -static void cpio_vec_destroy(vector *v) { +static void cpio_vec_destroy(struct vector *v) { // Free each cpio_file cpio_file *f; vec_for_each(v, f) { @@ -152,7 +153,7 @@ static void cpio_vec_destroy(vector *v) { vec_destroy(v); } -static void cpio_rm(int recursive, const char *entry, vector *v) { +static void cpio_rm(int recursive, const char *entry, struct vector *v) { cpio_file *f; vec_for_each(v, f) { if ((recursive && strncmp(f->filename, entry, strlen(entry)) == 0) @@ -166,7 +167,7 @@ static void cpio_rm(int recursive, const char *entry, vector *v) { } } -static void cpio_mkdir(mode_t mode, const char *entry, vector *v) { +static void cpio_mkdir(mode_t mode, const char *entry, struct vector *v) { cpio_file *f = calloc(sizeof(*f), 1); f->mode = S_IFDIR | mode; f->namesize = strlen(entry) + 1; @@ -176,7 +177,7 @@ static void cpio_mkdir(mode_t mode, const char *entry, vector *v) { printf("Create directory [%s] (%04o)\n",entry, mode); } -static void cpio_add(mode_t mode, const char *entry, const char *filename, vector *v) { +static void cpio_add(mode_t mode, const char *entry, const char *filename, struct vector *v) { int fd = open(filename, O_RDONLY); if (fd < 0) error(1, "Cannot open %s", filename); @@ -194,7 +195,7 @@ static void cpio_add(mode_t mode, const char *entry, const char *filename, vecto printf("Add entry [%s] (%04o)\n", entry, mode); } -static void cpio_test(vector *v) { +static void cpio_test(struct vector *v) { #define MAGISK_PATCH 0x1 #define SUPERSU_PATCH 0x2 int ret = 0; @@ -221,7 +222,7 @@ static int check_verity_pattern(const char *s) { return pos; } -static void cpio_dmverity(vector *v) { +static void cpio_dmverity(struct vector *v) { cpio_file *f; size_t read, write; int skip; @@ -243,7 +244,7 @@ static void cpio_dmverity(vector *v) { } } -static void cpio_forceencrypt(vector *v) { +static void cpio_forceencrypt(struct vector *v) { cpio_file *f; size_t read, write; #define ENCRYPT_LIST_SIZE 2 @@ -267,7 +268,7 @@ static void cpio_forceencrypt(vector *v) { } } -static void cpio_extract(const char *entry, const char *filename, vector *v) { +static void cpio_extract(const char *entry, const char *filename, struct vector *v) { cpio_file *f; vec_for_each(v, f) { if (strcmp(f->filename, entry) == 0 && S_ISREG(f->mode)) { @@ -283,8 +284,8 @@ static void cpio_extract(const char *entry, const char *filename, vector *v) { error(1, "Cannot find the file entry [%s]", entry); } -static void cpio_backup(const char *orig, vector *v) { - vector o_body, *o = &o_body, bak; +static void cpio_backup(const char *orig, struct vector *v) { + struct vector o_body, *o = &o_body, bak; cpio_file *m, *n, *dir, *rem; char chk1[21], chk2[21], buf[PATH_MAX]; int res, doBak; @@ -329,14 +330,14 @@ static void cpio_backup(const char *orig, vector *v) { // Something is missing in new ramdisk, backup! ++i; doBak = 1; - printf("Entry [%s] is missing\n", m->filename); + printf("Backup missing entry: "); } else if (res == 0) { ++i; ++j; if (m->filesize == n->filesize && memcmp(m->data, n->data, m->filesize) == 0) continue; // Not the same! doBak = 1; - printf("Entry [%s] missmatch\n", m->filename); + printf("Backup mismatch entry: "); } else { // Someting new in ramdisk, record in rem ++j; @@ -344,13 +345,14 @@ static void cpio_backup(const char *orig, vector *v) { rem->data = realloc(rem->data, rem->filesize + n->namesize); memcpy(rem->data + rem->filesize, n->filename, n->namesize); rem->filesize += n->namesize; - printf("Entry [%s] is new\n", n->filename); + printf("Record new entry: [%s] -> [.backup/.rmlist]\n", n->filename); } if (doBak) { m->namesize += 8; m->filename = realloc(m->filename, m->namesize); strcpy(buf, m->filename); sprintf(m->filename, ".backup/%s", buf); + printf("[%s] -> [%s]\n", buf, m->filename); vec_push_back(&bak, m); // NULL the original entry, so it won't be freed vec_entry(o)[i - 1] = NULL; @@ -376,7 +378,7 @@ static void cpio_backup(const char *orig, vector *v) { cpio_vec_destroy(o); } -static int cpio_restore(vector *v) { +static int cpio_restore(struct vector *v) { cpio_file *f, *n; int ret = 1; vec_for_each(v, f) { @@ -441,7 +443,7 @@ int cpio_commands(const char *command, int argc, char *argv[]) { cmd = NONE; return 1; } - vector v; + struct vector v; vec_init(&v); parse_cpio(incpio, &v); switch(cmd) { diff --git a/jni/magiskboot/elf.h b/jni/magiskboot/elf.h deleted file mode 100644 index 5b34f52f1..000000000 --- a/jni/magiskboot/elf.h +++ /dev/null @@ -1,151 +0,0 @@ - -#ifndef _ELF_H_ -#define _ELF_H_ - -#include - -/* -** ELF structure -** -** +-----------------+ -** | ELF magic | | 4 bytes -** +------------ + -** | ELF class | | 1 byte -** +------------ + -** | ELF header | -** +-----------------+ -** ~ -** +-----------------+ -** | program header | kernel info -** +-----------------+ -** | program header | ramdisk info -** +-----------------+ -** | program header | dtb info -** +-----------------+ -** | program header | (possible) cmdline info -** +-----------------+ -** ~ -** +-----------------+ -** | section header | cmdline info -** +-----------------+ -** ~ -** +-----------------+ -** | | -** | Data | -** | | -** +-----------------+ - -*/ - -typedef uint32_t elf32_addr; -typedef uint16_t elf32_half; -typedef uint32_t elf32_off; -typedef uint32_t elf32_word; - -typedef uint64_t elf64_addr; -typedef uint16_t elf64_half; -typedef uint64_t elf64_off; -typedef uint32_t elf64_word; -typedef uint64_t elf64_xword; - -#define ELF_MAGIC "\x7f""ELF" -#define ELF_MAGIC_SIZE 4 - -#define EI_CLASS 4 -#define EI_DATA 5 -#define EI_VERSION 6 -#define EI_OSABI 7 -#define EI_PAD 8 - -#define ELFCLASSNONE 0 -#define ELFCLASS32 1 -#define ELFCLASS64 2 -#define ELFCLASSNUM 3 - -#define ET_EXEC 2 -#define EM_ARM 40 -#define EI_NIDENT 16 - -typedef struct elf32_ehdr { - unsigned char e_ident[EI_NIDENT]; - elf32_half e_type; - elf32_half e_machine; - elf32_word e_version; - elf32_addr e_entry; /* Entry point */ - elf32_off e_phoff; - elf32_off e_shoff; - elf32_word e_flags; - elf32_half e_ehsize; - elf32_half e_phentsize; - elf32_half e_phnum; - elf32_half e_shentsize; - elf32_half e_shnum; - elf32_half e_shstrndx; -} elf32_ehdr; - -typedef struct elf64_ehdr { - unsigned char e_ident[EI_NIDENT]; /* ELF "magic number" */ - elf64_half e_type; - elf64_half e_machine; - elf64_word e_version; - elf64_addr e_entry; /* Entry point virtual address */ - elf64_off e_phoff; /* Program header table file offset */ - elf64_off e_shoff; /* Section header table file offset */ - elf64_word e_flags; - elf64_half e_ehsize; - elf64_half e_phentsize; - elf64_half e_phnum; - elf64_half e_shentsize; - elf64_half e_shnum; - elf64_half e_shstrndx; -} elf64_ehdr; - -typedef struct elf32_phdr { - elf32_word p_type; - elf32_off p_offset; - elf32_addr p_vaddr; - elf32_addr p_paddr; - elf32_word p_filesz; - elf32_word p_memsz; - elf32_word p_flags; - elf32_word p_align; -} elf32_phdr; - -typedef struct elf64_phdr { - elf64_word p_type; - elf64_word p_flags; - elf64_off p_offset; /* Segment file offset */ - elf64_addr p_vaddr; /* Segment virtual address */ - elf64_addr p_paddr; /* Segment physical address */ - elf64_xword p_filesz; /* Segment size in file */ - elf64_xword p_memsz; /* Segment size in memory */ - elf64_xword p_align; /* Segment alignment, file & memory */ -} elf64_phdr; - -typedef struct elf32_shdr { - elf32_word s_name; - elf32_word s_type; - elf32_word s_flags; - elf32_addr s_addr; - elf32_off s_offset; - elf32_word s_size; - elf32_word s_link; - elf32_word s_info; - elf32_word s_addralign; - elf32_word s_entsize; -} elf32_shdr; - -typedef struct elf64_shdr { - elf64_word s_name; /* Section name, index in string tbl */ - elf64_word s_type; /* Type of section */ - elf64_xword s_flags; /* Miscellaneous section attributes */ - elf64_addr s_addr; /* Section virtual addr at execution */ - elf64_off s_offset; /* Section file offset */ - elf64_xword s_size; /* Size of section in bytes */ - elf64_word s_link; /* Index of another section */ - elf64_word s_info; /* Additional section information */ - elf64_xword s_addralign; /* Section alignment */ - elf64_xword s_entsize; /* Entry size if section holds table */ -} elf64_shdr; - -#endif diff --git a/jni/magiskboot/magiskboot.h b/jni/magiskboot/magiskboot.h index 3cca95ad2..64a502225 100644 --- a/jni/magiskboot/magiskboot.h +++ b/jni/magiskboot/magiskboot.h @@ -16,8 +16,9 @@ #include "bootimg.h" #include "sha1.h" -#define CHROMEOS_MAGIC "CHROMEOS" -#define CHROMEOS_MAGIC_SIZE 8 +#define CHROMEOS_MAGIC "CHROMEOS" +#define ELF32_MAGIC "\x7f""ELF\x01" +#define ELF64_MAGIC "\x7f""ELF\x02" #define KERNEL_FILE "kernel" #define RAMDISK_FILE "ramdisk.cpio" @@ -25,11 +26,15 @@ #define DTB_FILE "dtb" #define NEW_BOOT "new-boot.img" +#define str(a) #a +#define xstr(a) str(a) + typedef enum { UNKNOWN, CHROMEOS, AOSP, - ELF, + ELF32, + ELF64, GZIP, LZOP, XZ, @@ -37,8 +42,7 @@ typedef enum { BZIP2, LZ4, LZ4_LEGACY, - MTK, - QCDT, + MTK } file_t; typedef enum { @@ -54,38 +58,14 @@ typedef enum { RESTORE } command_t; -#define SUP_LIST "gzip, xz, lzma, bzip2, lz4, lz4_legacy" -#define SUP_NUM 6 - -// Cannot declare in header, but place a copy here for convenience -// char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4" }; -// file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY }; -extern char *SUP_EXT_LIST[SUP_NUM]; -extern file_t SUP_TYPE_LIST[SUP_NUM]; - -// Vector -typedef struct vector { - size_t size; - size_t cap; - void **data; -} vector; -void vec_init(vector *v); -void vec_push_back(vector *v, void *p); -void vec_sort(vector *v, int (*compar)(const void *, const void *)); -void vec_destroy(vector *v); - -#define vec_size(v) (v)->size -#define vec_cap(v) (v)->cap -#define vec_entry(v) (v)->data -// vec_for_each(vector *v, void *e) -#define vec_for_each(v, e) \ - e = (v)->data[0]; \ - for (size_t _i = 0; _i < (v)->size; ++_i, e = (v)->data[_i]) +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 boot_type, ramdisk_type, dtb_type; +extern file_t ramdisk_type; extern int mtk_kernel, mtk_ramdisk; // Main entries diff --git a/jni/magiskboot/main.c b/jni/magiskboot/main.c index 24ecc086d..d96d7a052 100644 --- a/jni/magiskboot/main.c +++ b/jni/magiskboot/main.c @@ -5,50 +5,55 @@ *********************/ static void usage(char *arg0) { - fprintf(stderr, "%s --unpack \n", arg0); - fprintf(stderr, " Unpack to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n"); - fprintf(stderr, "\n"); - - fprintf(stderr, "%s --repack [outbootimg]\n", arg0); - fprintf(stderr, " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n"); - fprintf(stderr, " to [outbootimg], or new-boot.img if not specified.\n"); - fprintf(stderr, " It will compress ramdisk.cpio with the same method used in \n"); - fprintf(stderr, " if exists, or attempt to find ramdisk.cpio.[ext], and repack\n"); - fprintf(stderr, " directly with the compressed ramdisk file\n"); - fprintf(stderr, "\n"); - - fprintf(stderr, "%s --hexpatch \n", arg0); - fprintf(stderr, " Search in , and replace with \n"); - fprintf(stderr, "\n"); - - fprintf(stderr, "%s --cpio- [flags...] [params...]\n", arg0); - fprintf(stderr, " Do cpio related cmds to (modifications are done directly)\n Supported commands:\n"); - fprintf(stderr, " --cpio-rm [-r] \n Remove entry from cpio, flag -r to remove recursively\n"); - fprintf(stderr, " --cpio-mkdir \n Create directory as an \n"); - fprintf(stderr, " --cpio-add \n Add as an ; replaces if already exists\n"); - fprintf(stderr, " --cpio-extract \n Extract to \n"); - fprintf(stderr, " --cpio-test \n Return value: 0/not patched 1/Magisk 2/SuperSU\n"); - fprintf(stderr, " --cpio-patch-dmverity \n Remove dm-verity\n"); - fprintf(stderr, " --cpio-patch-forceencrypt \n Change forceencrypt flag to encryptable\n"); - fprintf(stderr, " --cpio-backup \n Create ramdisk backups into from \n"); - fprintf(stderr, " --cpio-restore \n Restore ramdisk from ramdisk backup within \n"); - fprintf(stderr, "\n"); - - fprintf(stderr, "%s --compress[=method] [outfile]\n", arg0); - fprintf(stderr, " Compress with [method] (default: gzip), optionally to [outfile]\n Supported methods: " SUP_LIST "\n"); - fprintf(stderr, "\n"); - - fprintf(stderr, "%s --decompress [outfile]\n", arg0); - fprintf(stderr, " Detect method and decompress , optionally to [outfile]\n Supported methods: " SUP_LIST "\n"); - fprintf(stderr, "\n"); - - fprintf(stderr, "%s --sha1 \n", arg0); - fprintf(stderr, " Print the SHA1 checksum for \n"); - fprintf(stderr, "\n"); - - fprintf(stderr, "%s --cleanup\n", arg0); - fprintf(stderr, " Cleanup the current working directory\n"); - fprintf(stderr, "\n"); + fprintf(stderr, + "%s --unpack \n" + " Unpack to kernel, ramdisk.cpio, (second), (dtb) into the\n current directory\n" + "\n" + "%s --repack [outbootimg]\n" + " Repack kernel, ramdisk.cpio[.ext], second, dtb... from current directory\n" + " to [outbootimg], or new-boot.img if not specified.\n" + " It will compress ramdisk.cpio with the same method used in \n" + " if exists, or attempt to find ramdisk.cpio.[ext], and repack\n" + " directly with the compressed ramdisk file\n" + "\n" + "%s --hexpatch \n" + " Search in , and replace with \n" + "\n" + "%s --cpio- [flags...] [params...]\n" + " Do cpio related cmds to (modifications are done directly)\n Supported commands:\n" + " --cpio-rm [-r] \n Remove entry from cpio, flag -r to remove recursively\n" + " --cpio-mkdir \n Create directory as an \n" + " --cpio-add \n Add as an ; replaces if already exists\n" + " --cpio-extract \n Extract to \n" + " --cpio-test \n Return value: 0/not patched 1/Magisk 2/SuperSU\n" + " --cpio-patch-dmverity \n Remove dm-verity\n" + " --cpio-patch-forceencrypt \n Change forceencrypt flag to encryptable\n" + " --cpio-backup \n Create ramdisk backups into from \n" + " --cpio-restore \n Restore ramdisk from ramdisk backup within \n" + "\n" + "%s --compress[=method] [outfile]\n" + " Compress with [method] (default: gzip), optionally to [outfile]\n Supported methods: " + , arg0, arg0, arg0, arg0, arg0); + for (int i = 0; SUP_LIST[i]; ++i) + fprintf(stderr, "%s ", SUP_LIST[i]); + fprintf(stderr, + "\n" + "\n" + "%s --decompress [outfile]\n" + " Detect method and decompress , optionally to [outfile]\n Supported methods: " + , arg0); + for (int i = 0; SUP_LIST[i]; ++i) + fprintf(stderr, "%s ", SUP_LIST[i]); + fprintf(stderr, + "\n" + "\n" + "%s --sha1 \n" + " Print the SHA1 checksum for \n" + "\n" + "%s --cleanup\n" + " Cleanup the current working directory\n" + "\n" + , arg0, arg0); exit(1); } @@ -63,7 +68,7 @@ void error(int rc, const char *msg, ...) { } int main(int argc, char *argv[]) { - printf("MagiskBoot (by topjohnwu) - Boot Image Modification Tool\n\n"); + printf("MagiskBoot v" xstr(MAGISK_VERSION) " (by topjohnwu) - Boot Image Modification Tool\n\n"); if (argc > 1 && strcmp(argv[1], "--cleanup") == 0) { cleanup(); diff --git a/jni/magiskboot/parseimg.c b/jni/magiskboot/parseimg.c index 59877434e..73d73d6e7 100644 --- a/jni/magiskboot/parseimg.c +++ b/jni/magiskboot/parseimg.c @@ -1,11 +1,10 @@ #include "bootimg.h" -#include "elf.h" #include "magiskboot.h" unsigned char *kernel, *ramdisk, *second, *dtb, *extra; boot_img_hdr hdr; int mtk_kernel = 0, mtk_ramdisk = 0; -file_t boot_type, ramdisk_type, dtb_type; +file_t ramdisk_type; static void check_headers() { // Check ramdisk compression type @@ -22,174 +21,13 @@ static void check_headers() { ramdisk_type = check_type(ramdisk + 512); } - // Check dtb if ELF boot - 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) { - - size_t e_size, mach, ver, p_size, p_num, s_size, s_num; - size_t r_e_size, r_p_size, r_s_size; - - if (is64) { - e_size = ((elf64_ehdr *) elf)->e_ehsize; - mach = ((elf64_ehdr *) elf)->e_machine; - ver = ((elf64_ehdr *) elf)->e_version; - p_size = ((elf64_ehdr *) elf)->e_phentsize; - p_num = ((elf64_ehdr *) elf)->e_phnum; - s_size = ((elf64_ehdr *) elf)->e_shentsize; - s_num = ((elf64_ehdr *) elf)->e_shnum; - r_e_size = sizeof(elf64_ehdr); - r_p_size = sizeof(elf64_phdr); - r_s_size = sizeof(elf64_shdr); - } else { - e_size = ((elf32_ehdr *) elf)->e_ehsize; - mach = ((elf32_ehdr *) elf)->e_machine; - ver = ((elf32_ehdr *) elf)->e_version; - p_size = ((elf32_ehdr *) elf)->e_phentsize; - p_num = ((elf32_ehdr *) elf)->e_phnum; - s_size = ((elf32_ehdr *) elf)->e_shentsize; - s_num = ((elf32_ehdr *) elf)->e_shnum; - r_e_size = sizeof(elf32_ehdr); - r_p_size = sizeof(elf32_phdr); - r_s_size = sizeof(elf32_shdr); - } - - if (e_size != r_e_size) - error(1, "Header size not %d", r_e_size); - - if (mach != EM_ARM) - error(1, "ELF machine is not ARM"); - - if (ver != 1) - error(1, "Unknown ELF version"); - - if (p_size != r_p_size) - error(1, "Program header size not %d", r_p_size); - - if (p_num < 2 || p_num > 4) - error(1, "Unexpected number of elements: %d", p_num); - - if (s_num && s_size != r_s_size) - error(1, "Section header size not %d", r_s_size); - - if (s_num > 1) - error(1, "More than one section header"); -} - -static void elf_set(int i, unsigned char *base, size_t size, size_t offset, size_t addr) { - if (size <= 4096) { - // Possible cmdline - memset(hdr.cmdline, 0, BOOT_ARGS_SIZE); - strncpy((char *) hdr.cmdline, (char *) (base + offset), BOOT_ARGS_SIZE); - hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0'; - return; - } - switch(i) { - case 0: - // kernel - kernel = base + offset; - hdr.kernel_size = size; - hdr.kernel_addr = addr; - break; - case 1: - // ramdisk - ramdisk = base + offset; - hdr.ramdisk_size = size; - hdr.ramdisk_addr = addr; - break; - case 2: - // dtb - dtb = base + offset; - hdr.dt_size = size; - hdr.tags_addr = addr; - break; - } -} - -static void parse_elf(unsigned char *base) { - - // Reset boot image header - memset(&hdr, 0, sizeof(hdr)); - - // Hardcode header magic and pagesize - memcpy(hdr.magic, BOOT_MAGIC, BOOT_MAGIC_SIZE); - hdr.page_size = 4096; - - switch(base[EI_CLASS]) { - - case ELFCLASS32: { - - elf32_ehdr *elf32; - elf32_phdr *ph32; - elf32_shdr *sh32; - - printf("IMAGE [ELF32]\n"); - - elf32 = (elf32_ehdr *) base; - - elf_header_check(elf32, 0); - - ph32 = (elf32_phdr *) (base + elf32->e_phoff); - sh32 = (elf32_shdr *) (base + elf32->e_shoff); - - for (int i = 0; i < elf32->e_phnum; ++i) { - elf_set(i, base, ph32[i].p_filesz, ph32[i].p_offset, ph32[i].p_paddr); - } - - if (elf32->e_shnum) { - // cmdline - memset(hdr.cmdline, 0, BOOT_ARGS_SIZE); - strncpy((char *) hdr.cmdline, (char *) (base + sh32->s_offset + 8), BOOT_ARGS_SIZE); - hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0'; - } - - break; - } - - case ELFCLASS64: { - - elf64_ehdr *elf64; - elf64_phdr *ph64; - elf64_shdr *sh64; - - printf("IMAGE [ELF64]\n"); - - elf64 = (elf64_ehdr *) base; - - elf_header_check(elf64, 1); - - ph64 = (elf64_phdr *) (base + elf64->e_phoff); - sh64 = (elf64_shdr *) (base + elf64->e_shoff); - - for (int i = 0; i < elf64->e_phnum; ++i) { - elf_set(i, base, ph64[i].p_filesz, ph64[i].p_offset, ph64[i].p_paddr); - } - - if (elf64->e_shnum) { - // cmdline - memset(hdr.cmdline, 0, BOOT_ARGS_SIZE); - strncpy((char *) hdr.cmdline, (char *) (base + sh64->s_offset + 8), BOOT_ARGS_SIZE); - hdr.cmdline[strcspn((char*) hdr.cmdline, "\n")] = '\0'; - } - break; - } - - default: - error(1, "ELF format error!"); - } - - check_headers(); -} - static void parse_aosp(unsigned char *base, size_t size) { - printf("IMG [AOSP]\n"); + // printf("IMG [AOSP]\n"); size_t pos = 0; @@ -232,21 +70,21 @@ 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: - boot_type = CHROMEOS; - continue; - case AOSP: - // Don't override CHROMEOS - if (boot_type != CHROMEOS) - boot_type = AOSP; - parse_aosp(base, size); - return; - case ELF: - boot_type = ELF; - parse_elf(base); - return; - default: - continue; + 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; } } error(1, "No boot image magic found!"); diff --git a/jni/magiskboot/repack.c b/jni/magiskboot/repack.c index f69892a06..40ba5e44f 100644 --- a/jni/magiskboot/repack.c +++ b/jni/magiskboot/repack.c @@ -69,7 +69,7 @@ void repack(const char* orig_image, const char* out_image) { // 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) { + for (int i = 0; SUP_EXT_LIST[i]; ++i) { sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]); unlink(name); } @@ -85,7 +85,7 @@ void repack(const char* orig_image, const char* out_image) { } int found = 0; - for (int i = 0; i < SUP_NUM; ++i) { + 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]; diff --git a/jni/magiskboot/unpack.c b/jni/magiskboot/unpack.c index 18c1c9de8..be3bb136d 100644 --- a/jni/magiskboot/unpack.c +++ b/jni/magiskboot/unpack.c @@ -16,11 +16,6 @@ void unpack(const char* image) { printf("Parsing boot image: [%s]\n\n", image); parse_img(orig, size); - if (boot_type == CHROMEOS) { - // The caller should know it's chromeos, as it needs additional signing - dump(orig, 0, "chromeos"); - } - char name[PATH_MAX]; // Dump kernel @@ -47,16 +42,8 @@ void unpack(const char* image) { } if (hdr.dt_size) { - 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); - write(kfp, dtb, hdr.dt_size); - close(kfp); - } else { - // Dump dtb - dump(dtb, hdr.dt_size, DTB_FILE); - } + // Dump dtb + dump(dtb, hdr.dt_size, DTB_FILE); } munmap(orig, size); diff --git a/jni/magiskboot/utils.c b/jni/magiskboot/utils.c index a06511843..391141ca0 100644 --- a/jni/magiskboot/utils.c +++ b/jni/magiskboot/utils.c @@ -1,8 +1,8 @@ #include "magiskboot.h" -#include "elf.h" -char *SUP_EXT_LIST[SUP_NUM] = { "gz", "xz", "lzma", "bz2", "lz4", "lz4" }; -file_t SUP_TYPE_LIST[SUP_NUM] = { GZIP, XZ, LZMA, BZIP2, LZ4, LZ4_LEGACY }; +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) { int fd = open(filename, O_RDONLY); @@ -25,12 +25,14 @@ void mmap_rw(const char *filename, unsigned char **buf, size_t *size) { } file_t check_type(const unsigned char *buf) { - if (memcmp(buf, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) { + if (memcmp(buf, CHROMEOS_MAGIC, 8) == 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, ELF32_MAGIC, 5) == 0) { + return ELF32; + } else if (memcmp(buf, ELF64_MAGIC, 5) == 0) { + return ELF64; } 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) { @@ -48,8 +50,6 @@ file_t check_type(const unsigned char *buf) { return LZ4_LEGACY; } else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) { return MTK; - } else if (memcmp(buf, "QCDT", 4) == 0) { - return QCDT; } else { return UNKNOWN; } @@ -147,36 +147,8 @@ void cleanup() { unlink(SECOND_FILE); unlink(DTB_FILE); unlink(NEW_BOOT); - for (int i = 0; i < SUP_NUM; ++i) { + for (int i = 0; SUP_EXT_LIST[i]; ++i) { sprintf(name, "%s.%s", RAMDISK_FILE, SUP_EXT_LIST[i]); unlink(name); } } - -void vec_init(vector *v) { - vec_size(v) = 0; - vec_cap(v) = 1; - vec_entry(v) = malloc(sizeof(void*)); -} - -void vec_push_back(vector *v, void *p) { - if (v == NULL) return; - if (vec_size(v) == vec_cap(v)) { - vec_cap(v) *= 2; - vec_entry(v) = realloc(vec_entry(v), sizeof(void*) * vec_cap(v)); - } - vec_entry(v)[vec_size(v)] = p; - ++vec_size(v); -} - -void vec_sort(vector *v, int (*compar)(const void *, const void *)) { - qsort(vec_entry(v), vec_size(v), sizeof(void*), compar); -} - -void vec_destroy(vector *v) { - // Will not free each entry! - // Manually free each entry, then call this function - vec_size(v) = 0; - vec_cap(v) = 0; - free(v->data); -}