diff --git a/jni/magiskboot/compress.c b/jni/magiskboot/compress.c index 89c8eaa75..ea85d43e0 100644 --- a/jni/magiskboot/compress.c +++ b/jni/magiskboot/compress.c @@ -362,25 +362,33 @@ 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) { char name[PATH_MAX]; + const char *ext = strrchr(to, '.'); + if (ext == NULL) ext = to; + strcpy(name, to); switch (type) { case GZIP: - sprintf(name, "%s.%s", to, "gz"); + if (strcmp(ext, ".gz") != 0) + sprintf(name, "%s.%s", to, "gz"); gzip(1, name, from, size); break; case XZ: - sprintf(name, "%s.%s", to, "xz"); + if (strcmp(ext, ".xz") != 0) + sprintf(name, "%s.%s", to, "xz"); lzma(1, name, from, size); break; case LZMA: - sprintf(name, "%s.%s", to, "lzma"); + if (strcmp(ext, ".lzma") != 0) + sprintf(name, "%s.%s", to, "lzma"); lzma(2, name, from, size); break; case BZIP2: - sprintf(name, "%s.%s", to, "bz2"); + if (strcmp(ext, ".bz2") != 0) + sprintf(name, "%s.%s", to, "bz2"); bzip2(1, name, from, size); break; case LZ4: - sprintf(name, "%s.%s", to, "lz4"); + if (strcmp(ext, ".lz4") != 0) + sprintf(name, "%s.%s", to, "lz4"); lz4(1, name, from, size); break; default: @@ -390,7 +398,7 @@ int comp(file_t type, const char *to, const unsigned char *from, size_t size) { return 0; } -void decomp_file(char *from) { +void decomp_file(char *from, const char *to) { int ok = 1; unsigned char *file; size_t size; @@ -428,17 +436,22 @@ void decomp_file(char *from) { } if (ok) { // If all match, strip out the suffix - *ext = '\0'; - decomp(type, from, file, size); - *ext = '.'; - unlink(from); + if (!to) { + *ext = '\0'; + to = from; + } + decomp(type, to, file, size); + if (to == from) { + *ext = '.'; + unlink(from); + } } else { error(1, "Bad filename extention \'%s\'", ext); } munmap(file, size); } -void comp_file(const char *method, const char *from) { +void comp_file(const char *method, const char *from, const char *to) { file_t type; if (strcmp(method, "gzip") == 0) { type = GZIP; @@ -456,8 +469,11 @@ void comp_file(const char *method, const char *from) { unsigned char *file; size_t size; mmap_ro(from, &file, &size); - comp(type, from, file, size); + if (!to) + to = from; + comp(type, to, file, size); munmap(file, size); - unlink(from); + if (to == from) + unlink(from); } diff --git a/jni/magiskboot/cpio.c b/jni/magiskboot/cpio.c index f1268c49f..8c69eea16 100644 --- a/jni/magiskboot/cpio.c +++ b/jni/magiskboot/cpio.c @@ -266,13 +266,13 @@ static void cpio_extract(const char *entry, const char *filename, vector *v) { cpio_file *f; vec_for_each(v, f) { if (strcmp(f->filename, entry) == 0 && S_ISREG(f->mode)) { - printf("Extracting [%s] to [%s]\n", entry, filename); + printf("Extracting [%s] to [%s]\n\n", entry, filename); int fd = open_new(filename); write(fd, f->data, f->filesize); fchmod(fd, f->mode); fchown(fd, f->uid, f->gid); close(fd); - return; + exit(0); } } error(1, "Cannot find the file entry [%s]", entry); @@ -374,18 +374,17 @@ static void cpio_backup(const char *orig, vector *v) { cpio_vec_destroy(o); } -static void cpio_restore(vector *v) { +static int cpio_restore(vector *v) { cpio_file *f, *n; + int ret = 1; vec_for_each(v, f) { if (strstr(f->filename, ".backup") != NULL) { + ret = 0; f->remove = 1; if (strcmp(f->filename, ".backup") == 0) continue; if (strcmp(f->filename, ".backup/.rmlist") == 0) { - int pos = 0; - while(pos < f->filesize) { + for (int pos = 0; pos < f->filesize; pos += strlen(f->data + pos) + 1) cpio_rm(0, f->data + pos, v); - pos += strlen(f->data + pos) + 1; - } continue; } n = calloc(sizeof(*n), 1); @@ -404,10 +403,11 @@ static void cpio_restore(vector *v) { cpio_rm(0, "sbin/magic_mask.sh", v); cpio_rm(0, "init.magisk.rc", v); cpio_rm(0, "magisk", v); + return ret; } int cpio_commands(const char *command, int argc, char *argv[]) { - int recursive = 0; + int recursive = 0, ret = 0; command_t cmd; char *incpio = argv[0]; ++argv; @@ -453,7 +453,7 @@ int cpio_commands(const char *command, int argc, char *argv[]) { cpio_forceencrypt(&v); break; case RESTORE: - cpio_restore(&v); + ret = cpio_restore(&v); break; case BACKUP: cpio_backup(argv[0], &v); @@ -475,5 +475,5 @@ int cpio_commands(const char *command, int argc, char *argv[]) { } dump_cpio(incpio, &v); cpio_vec_destroy(&v); - return 0; + exit(ret); } diff --git a/jni/magiskboot/magiskboot.h b/jni/magiskboot/magiskboot.h index d6218f9aa..376d4f5d7 100644 --- a/jni/magiskboot/magiskboot.h +++ b/jni/magiskboot/magiskboot.h @@ -90,7 +90,7 @@ void vec_destroy(vector *v); for (size_t _i = 0; _i < (v)->size; ++_i, e = (v)->data[_i]) // Global variables -extern unsigned char *kernel, *ramdisk, *second, *dtb; +extern unsigned char *kernel, *ramdisk, *second, *dtb, *extra; extern boot_img_hdr hdr; extern file_t boot_type, ramdisk_type, dtb_type; extern int mtk_kernel, mtk_ramdisk; @@ -110,9 +110,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); +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); -void decomp_file(char *from); +void decomp_file(char *from, const char *to); // Utils void mmap_ro(const char *filename, unsigned char **buf, size_t *size); diff --git a/jni/magiskboot/main.c b/jni/magiskboot/main.c index 9037bd106..1938766d7 100644 --- a/jni/magiskboot/main.c +++ b/jni/magiskboot/main.c @@ -34,12 +34,12 @@ static void usage(char *arg0) { fprintf(stderr, " --cpio-restore \n Restore ramdisk from ramdisk backup within \n"); fprintf(stderr, "\n"); - fprintf(stderr, "%s --compress[=method] \n", arg0); - fprintf(stderr, " Compress with [method], or gzip if not specified.\n Supported methods: " SUP_LIST "\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 \n", arg0); - fprintf(stderr, " Auto check file type, and decompress accordingly\n Supported methods: " SUP_LIST "\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); @@ -81,13 +81,13 @@ int main(int argc, char *argv[]) { } else if (argc > 2 && strcmp(argv[1], "--repack") == 0) { repack(argv[2], argc > 3 ? argv[3] : NEW_BOOT); } else if (argc > 2 && strcmp(argv[1], "--decompress") == 0) { - decomp_file(argv[2]); + decomp_file(argv[2], argc > 3 ? argv[3] : NULL); } else if (argc > 2 && strncmp(argv[1], "--compress", 10) == 0) { char *method; method = strchr(argv[1], '='); if (method == NULL) method = "gzip"; else method++; - comp_file(method, argv[2]); + comp_file(method, argv[2], argc > 3 ? argv[3] : NULL); } else if (argc > 4 && strcmp(argv[1], "--hexpatch") == 0) { hexpatch(argv[2], argv[3], argv[4]); } else if (argc > 2 && strncmp(argv[1], "--cpio", 6) == 0) { diff --git a/jni/magiskboot/parseimg.c b/jni/magiskboot/parseimg.c index b5c921340..f2beb26ba 100644 --- a/jni/magiskboot/parseimg.c +++ b/jni/magiskboot/parseimg.c @@ -2,7 +2,7 @@ #include "elf.h" #include "magiskboot.h" -unsigned char *kernel, *ramdisk, *second, *dtb; +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; @@ -186,7 +186,7 @@ static void parse_elf(unsigned char *base) { check_headers(); } -static void parse_aosp(unsigned char *base) { +static void parse_aosp(unsigned char *base, size_t size) { printf("IMG [AOSP]\n"); @@ -220,12 +220,16 @@ static void parse_aosp(unsigned char *base) { 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; - for(base = orig; base < (orig + size); base += 256) { + 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; @@ -234,7 +238,7 @@ void parse_img(unsigned char *orig, size_t size) { // Don't override CHROMEOS if (boot_type != CHROMEOS) boot_type = AOSP; - parse_aosp(base); + parse_aosp(base, size); return; case ELF: boot_type = ELF; diff --git a/jni/magiskboot/repack.c b/jni/magiskboot/repack.c index a4e6bc1cb..4a69fea6a 100644 --- a/jni/magiskboot/repack.c +++ b/jni/magiskboot/repack.c @@ -104,6 +104,14 @@ void repack(const char* orig_image, const char* out_image) { 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(extra, 16, fd); + } + } + // Write header back printf("Repack to boot image: [%s]\n\n", out_image); print_info();