From 632971af15de952f04356e138ab81654add6e10b Mon Sep 17 00:00:00 2001 From: topjohnwu Date: Sun, 21 Nov 2021 05:55:20 -0800 Subject: [PATCH] Properly support v4 image headers --- native/jni/magiskboot/bootimg.cpp | 33 +++++++++++++++++++++++++++---- native/jni/magiskboot/bootimg.hpp | 14 +++++++++++++ 2 files changed, 43 insertions(+), 4 deletions(-) diff --git a/native/jni/magiskboot/bootimg.cpp b/native/jni/magiskboot/bootimg.cpp index 73365cbdf..743bec824 100644 --- a/native/jni/magiskboot/bootimg.cpp +++ b/native/jni/magiskboot/bootimg.cpp @@ -52,7 +52,8 @@ static size_t restore(int fd, const char *filename) { void dyn_img_hdr::print() { uint32_t ver = header_version(); fprintf(stderr, "%-*s [%u]\n", PADDING, "HEADER_VER", ver); - fprintf(stderr, "%-*s [%u]\n", PADDING, "KERNEL_SZ", kernel_size()); + if (!is_vendor) + fprintf(stderr, "%-*s [%u]\n", PADDING, "KERNEL_SZ", kernel_size()); fprintf(stderr, "%-*s [%u]\n", PADDING, "RAMDISK_SZ", ramdisk_size()); if (ver < 3) fprintf(stderr, "%-*s [%u]\n", PADDING, "SECOND_SZ", second_size()); @@ -219,8 +220,8 @@ static format_t check_fmt_lg(uint8_t *buf, unsigned sz) { format_t fmt = check_fmt(buf, sz); if (fmt == LZ4_LEGACY) { // We need to check if it is LZ4_LG - unsigned off = 4; - unsigned block_sz; + uint32_t off = 4; + uint32_t block_sz; while (off + sizeof(block_sz) <= sz) { memcpy(&block_sz, buf + off, sizeof(block_sz)); off += sizeof(block_sz); @@ -292,6 +293,13 @@ name = hdr_addr + off; \ off += hdr->name##_size(); \ off = do_align(off, hdr->page_size()); +#define get_ignore(name) \ +if (hdr->name##_size()) { \ + auto blk_sz = do_align(hdr->name##_size(), hdr->page_size()); \ + ignore_size += blk_sz; \ + off += blk_sz; \ +} + void boot_img::parse_image(uint8_t *addr, format_t type) { hdr = create_hdr(addr, type); @@ -314,6 +322,11 @@ void boot_img::parse_image(uint8_t *addr, format_t type) { get_block(recovery_dtbo); get_block(dtb); + ignore = hdr_addr + off; + get_ignore(signature) + get_ignore(vendor_ramdisk_table) + get_ignore(bootconfig) + if (int dtb_off = find_dtb_offset(kernel, hdr->kernel_size()); dtb_off > 0) { kernel_dtb = kernel + dtb_off; hdr->kernel_dt_size = hdr->kernel_size() - dtb_off; @@ -364,7 +377,13 @@ void boot_img::parse_image(uint8_t *addr, format_t type) { fprintf(stderr, "%-*s [%s]\n", PADDING, "KERNEL_FMT", fmt2name[k_fmt]); } if (auto size = hdr->ramdisk_size()) { - r_fmt = check_fmt_lg(ramdisk, size); + if (hdr->is_vendor && hdr->header_version() >= 4) { + // v4 vendor boot contains multiple ramdisks + // Do not try to mess with it for now + r_fmt = UNKNOWN; + } else { + r_fmt = check_fmt_lg(ramdisk, size); + } if (r_fmt == MTK) { fprintf(stderr, "MTK_RAMDISK_HDR\n"); flags[MTK_RAMDISK] = true; @@ -636,6 +655,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) { file_align(); } + // Directly copy ignored blobs + if (boot.ignore_size) { + // ignore_size should already be aligned + xwrite(fd, boot.ignore, boot.ignore_size); + } + // Proprietary stuffs if (boot.flags[SEANDROID_FLAG]) { xwrite(fd, SEANDROID_MAGIC, 16); diff --git a/native/jni/magiskboot/bootimg.hpp b/native/jni/magiskboot/bootimg.hpp index 6929cb91f..4893848fb 100644 --- a/native/jni/magiskboot/bootimg.hpp +++ b/native/jni/magiskboot/bootimg.hpp @@ -367,6 +367,11 @@ struct dyn_img_hdr { decl_var(header_size, 32) decl_var(dtb_size, 32) + // v4 specific + decl_val(signature_size, uint32_t) + decl_val(vendor_ramdisk_table_size, uint32_t) + decl_val(bootconfig_size, uint32_t) + virtual ~dyn_img_hdr() { free(raw); } @@ -495,6 +500,8 @@ struct dyn_img_v3 : public dyn_img_hdr_boot { struct dyn_img_v4 : public dyn_img_v3 { impl_cls(v4) + + impl_val(signature_size) }; struct dyn_img_hdr_vendor : public dyn_img_hdr { @@ -524,6 +531,9 @@ struct dyn_img_vnd_v3 : public dyn_img_hdr_vendor { struct dyn_img_vnd_v4 : public dyn_img_vnd_v3 { impl_cls(vnd_v4) + + impl_val(vendor_ramdisk_table_size) + impl_val(bootconfig_size) }; #undef __impl_cls @@ -610,6 +620,10 @@ struct boot_img { uint8_t *recovery_dtbo; uint8_t *dtb; + // Pointer to blocks defined in header, but we do not care + uint8_t *ignore; + size_t ignore_size = 0; + boot_img(const char *); ~boot_img();