mirror of
https://github.com/topjohnwu/Magisk.git
synced 2025-10-25 08:29:19 +00:00
Use mmap_data more widely
This commit is contained in:
@@ -148,11 +148,10 @@ void dyn_img_hdr::load_hdr_file() {
|
||||
});
|
||||
}
|
||||
|
||||
boot_img::boot_img(const char *image) {
|
||||
mmap_ro(image, map_addr, map_size);
|
||||
boot_img::boot_img(const char *image) : map(image) {
|
||||
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
||||
for (uint8_t *addr = map_addr; addr < map_addr + map_size; ++addr) {
|
||||
format_t fmt = check_fmt(addr, map_size);
|
||||
for (uint8_t *addr = map.buf; addr < map.buf + map.sz; ++addr) {
|
||||
format_t fmt = check_fmt(addr, map.sz);
|
||||
switch (fmt) {
|
||||
case CHROMEOS:
|
||||
// chromeos require external signing
|
||||
@@ -182,7 +181,6 @@ boot_img::boot_img(const char *image) {
|
||||
}
|
||||
|
||||
boot_img::~boot_img() {
|
||||
munmap(map_addr, map_size);
|
||||
delete hdr;
|
||||
}
|
||||
|
||||
@@ -405,9 +403,9 @@ void boot_img::parse_image(uint8_t *addr, format_t type) {
|
||||
fprintf(stderr, "%-*s [%s]\n", PADDING, "EXTRA_FMT", fmt2name[e_fmt]);
|
||||
}
|
||||
|
||||
if (addr + off < map_addr + map_size) {
|
||||
if (addr + off < map.buf + map.sz) {
|
||||
tail = addr + off;
|
||||
tail_size = map_addr + map_size - tail;
|
||||
tail_size = map.buf + map.sz - tail;
|
||||
|
||||
// Check special flags
|
||||
if (tail_size >= 16 && BUFFER_MATCH(tail, SEANDROID_MAGIC)) {
|
||||
@@ -434,21 +432,18 @@ void boot_img::parse_image(uint8_t *addr, format_t type) {
|
||||
}
|
||||
|
||||
int split_image_dtb(const char *filename) {
|
||||
uint8_t *buf;
|
||||
size_t sz;
|
||||
mmap_ro(filename, buf, sz);
|
||||
run_finally f([=]{ munmap(buf, sz); });
|
||||
auto img = mmap_data(filename);
|
||||
|
||||
if (int off = find_dtb_offset(buf, sz); off > 0) {
|
||||
format_t fmt = check_fmt_lg(buf, sz);
|
||||
if (int off = find_dtb_offset(img.buf, img.sz); off > 0) {
|
||||
format_t fmt = check_fmt_lg(img.buf, img.sz);
|
||||
if (COMPRESSED(fmt)) {
|
||||
int fd = creat(KERNEL_FILE, 0644);
|
||||
decompress(fmt, fd, buf, off);
|
||||
decompress(fmt, fd, img.buf, off);
|
||||
close(fd);
|
||||
} else {
|
||||
dump(buf, off, KERNEL_FILE);
|
||||
dump(img.buf, off, KERNEL_FILE);
|
||||
}
|
||||
dump(buf + off, sz - off, KER_DTB_FILE);
|
||||
dump(img.buf + off, img.sz - off, KER_DTB_FILE);
|
||||
return 0;
|
||||
} else {
|
||||
fprintf(stderr, "Cannot find DTB in %s\n", filename);
|
||||
@@ -546,11 +541,11 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
// Skip DHTB header
|
||||
write_zero(fd, sizeof(dhtb_hdr));
|
||||
} else if (boot.flags[BLOB_FLAG]) {
|
||||
xwrite(fd, boot.map_addr, sizeof(blob_hdr));
|
||||
xwrite(fd, boot.map.buf, sizeof(blob_hdr));
|
||||
} else if (boot.flags[NOOKHD_FLAG]) {
|
||||
xwrite(fd, boot.map_addr, NOOKHD_PRE_HEADER_SZ);
|
||||
xwrite(fd, boot.map.buf, NOOKHD_PRE_HEADER_SZ);
|
||||
} else if (boot.flags[ACCLAIM_FLAG]) {
|
||||
xwrite(fd, boot.map_addr, ACCLAIM_PRE_HEADER_SZ);
|
||||
xwrite(fd, boot.map.buf, ACCLAIM_PRE_HEADER_SZ);
|
||||
}
|
||||
|
||||
// Copy raw header
|
||||
@@ -568,15 +563,13 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
xwrite(fd, boot.z_hdr, boot.z_info.hdr_sz);
|
||||
}
|
||||
if (access(KERNEL_FILE, R_OK) == 0) {
|
||||
size_t raw_size;
|
||||
void *raw_buf;
|
||||
mmap_ro(KERNEL_FILE, raw_buf, raw_size);
|
||||
if (!COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.k_fmt)) {
|
||||
auto m = mmap_data(KERNEL_FILE);
|
||||
if (!COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.k_fmt)) {
|
||||
// Always use zopfli for zImage compression
|
||||
auto fmt = (boot.flags[ZIMAGE_KERNEL] && boot.k_fmt == GZIP) ? ZOPFLI : boot.k_fmt;
|
||||
hdr->kernel_size() = compress(fmt, fd, raw_buf, raw_size);
|
||||
hdr->kernel_size() = compress(fmt, fd, m.buf, m.sz);
|
||||
} else {
|
||||
hdr->kernel_size() = xwrite(fd, raw_buf, raw_size);
|
||||
hdr->kernel_size() = xwrite(fd, m.buf, m.sz);
|
||||
}
|
||||
|
||||
if (boot.flags[ZIMAGE_KERNEL]) {
|
||||
@@ -587,7 +580,7 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
} else {
|
||||
// Pad zeros to make sure the zImage file size does not change
|
||||
// Also ensure the last 4 bytes are the uncompressed vmlinux size
|
||||
uint32_t sz = raw_size;
|
||||
uint32_t sz = m.sz;
|
||||
write_zero(fd, boot.hdr->kernel_size() - hdr->kernel_size() - sizeof(sz));
|
||||
xwrite(fd, &sz, sizeof(sz));
|
||||
}
|
||||
@@ -595,8 +588,6 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
// zImage size shall remain the same
|
||||
hdr->kernel_size() = boot.hdr->kernel_size();
|
||||
}
|
||||
|
||||
munmap(raw_buf, raw_size);
|
||||
}
|
||||
if (boot.flags[ZIMAGE_KERNEL]) {
|
||||
// Copy zImage tail and adjust size accordingly
|
||||
@@ -616,15 +607,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
xwrite(fd, boot.r_hdr, sizeof(mtk_hdr));
|
||||
}
|
||||
if (access(RAMDISK_FILE, R_OK) == 0) {
|
||||
size_t raw_size;
|
||||
void *raw_buf;
|
||||
mmap_ro(RAMDISK_FILE, raw_buf, raw_size);
|
||||
if (!skip_comp && !COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.r_fmt)) {
|
||||
hdr->ramdisk_size() = compress(boot.r_fmt, fd, raw_buf, raw_size);
|
||||
auto m = mmap_data(RAMDISK_FILE);
|
||||
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.r_fmt)) {
|
||||
hdr->ramdisk_size() = compress(boot.r_fmt, fd, m.buf, m.sz);
|
||||
} else {
|
||||
hdr->ramdisk_size() = xwrite(fd, raw_buf, raw_size);
|
||||
hdr->ramdisk_size() = xwrite(fd, m.buf, m.sz);
|
||||
}
|
||||
munmap(raw_buf, raw_size);
|
||||
file_align();
|
||||
}
|
||||
|
||||
@@ -638,15 +626,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
// extra
|
||||
off.extra = lseek(fd, 0, SEEK_CUR);
|
||||
if (access(EXTRA_FILE, R_OK) == 0) {
|
||||
size_t raw_size;
|
||||
void *raw_buf;
|
||||
mmap_ro(EXTRA_FILE, raw_buf, raw_size);
|
||||
if (!skip_comp && !COMPRESSED_ANY(check_fmt(raw_buf, raw_size)) && COMPRESSED(boot.e_fmt)) {
|
||||
hdr->extra_size() = compress(boot.e_fmt, fd, raw_buf, raw_size);
|
||||
auto m = mmap_data(EXTRA_FILE);
|
||||
if (!skip_comp && !COMPRESSED_ANY(check_fmt(m.buf, m.sz)) && COMPRESSED(boot.e_fmt)) {
|
||||
hdr->extra_size() = compress(boot.e_fmt, fd, m.buf, m.sz);
|
||||
} else {
|
||||
hdr->extra_size() = xwrite(fd, raw_buf, raw_size);
|
||||
hdr->extra_size() = xwrite(fd, m.buf, m.sz);
|
||||
}
|
||||
munmap(raw_buf, raw_size);
|
||||
file_align();
|
||||
}
|
||||
|
||||
@@ -696,8 +681,8 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
// Pad image to original size if not chromeos (as it requires post processing)
|
||||
if (!boot.flags[CHROMEOS_FLAG]) {
|
||||
off_t current = lseek(fd, 0, SEEK_CUR);
|
||||
if (current < boot.map_size) {
|
||||
write_zero(fd, boot.map_size - current);
|
||||
if (current < boot.map.sz) {
|
||||
write_zero(fd, boot.map.sz - current);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -708,18 +693,16 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
******************/
|
||||
|
||||
// Map output image as rw
|
||||
uint8_t *new_addr;
|
||||
size_t new_size;
|
||||
mmap_rw(out_img, new_addr, new_size);
|
||||
auto out = mmap_data(out_img, true);
|
||||
|
||||
// MTK headers
|
||||
if (boot.flags[MTK_KERNEL]) {
|
||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(new_addr + off.kernel);
|
||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf + off.kernel);
|
||||
m_hdr->size = hdr->kernel_size();
|
||||
hdr->kernel_size() += sizeof(mtk_hdr);
|
||||
}
|
||||
if (boot.flags[MTK_RAMDISK]) {
|
||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(new_addr + off.ramdisk);
|
||||
auto m_hdr = reinterpret_cast<mtk_hdr *>(out.buf + off.ramdisk);
|
||||
m_hdr->size = hdr->ramdisk_size();
|
||||
hdr->ramdisk_size() += sizeof(mtk_hdr);
|
||||
}
|
||||
@@ -732,28 +715,28 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
HASH_CTX ctx;
|
||||
boot.flags[SHA256_FLAG] ? SHA256_init(&ctx) : SHA_init(&ctx);
|
||||
uint32_t size = hdr->kernel_size();
|
||||
HASH_update(&ctx, new_addr + off.kernel, size);
|
||||
HASH_update(&ctx, out.buf + off.kernel, size);
|
||||
HASH_update(&ctx, &size, sizeof(size));
|
||||
size = hdr->ramdisk_size();
|
||||
HASH_update(&ctx, new_addr + off.ramdisk, size);
|
||||
HASH_update(&ctx, out.buf + off.ramdisk, size);
|
||||
HASH_update(&ctx, &size, sizeof(size));
|
||||
size = hdr->second_size();
|
||||
HASH_update(&ctx, new_addr + off.second, size);
|
||||
HASH_update(&ctx, out.buf + off.second, size);
|
||||
HASH_update(&ctx, &size, sizeof(size));
|
||||
size = hdr->extra_size();
|
||||
if (size) {
|
||||
HASH_update(&ctx, new_addr + off.extra, size);
|
||||
HASH_update(&ctx, out.buf + off.extra, size);
|
||||
HASH_update(&ctx, &size, sizeof(size));
|
||||
}
|
||||
uint32_t ver = hdr->header_version();
|
||||
if (ver == 1 || ver == 2) {
|
||||
size = hdr->recovery_dtbo_size();
|
||||
HASH_update(&ctx, new_addr + hdr->recovery_dtbo_offset(), size);
|
||||
HASH_update(&ctx, out.buf + hdr->recovery_dtbo_offset(), size);
|
||||
HASH_update(&ctx, &size, sizeof(size));
|
||||
}
|
||||
if (ver == 2) {
|
||||
size = hdr->dtb_size();
|
||||
HASH_update(&ctx, new_addr + off.dtb, size);
|
||||
HASH_update(&ctx, out.buf + off.dtb, size);
|
||||
HASH_update(&ctx, &size, sizeof(size));
|
||||
}
|
||||
memset(id, 0, BOOT_ID_SIZE);
|
||||
@@ -764,12 +747,12 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
hdr->print();
|
||||
|
||||
// Copy main header
|
||||
memcpy(new_addr + off.header, hdr->raw_hdr(), hdr->hdr_size());
|
||||
memcpy(out.buf + off.header, hdr->raw_hdr(), hdr->hdr_size());
|
||||
|
||||
if (boot.flags[AVB_FLAG]) {
|
||||
// Copy and patch AVB structures
|
||||
auto footer = reinterpret_cast<AvbFooter*>(new_addr + new_size - sizeof(AvbFooter));
|
||||
auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(new_addr + off.vbmeta);
|
||||
auto footer = reinterpret_cast<AvbFooter*>(out.buf + out.sz - sizeof(AvbFooter));
|
||||
auto vbmeta = reinterpret_cast<AvbVBMetaImageHeader*>(out.buf + off.vbmeta);
|
||||
memcpy(footer, boot.avb_footer, sizeof(AvbFooter));
|
||||
footer->original_image_size = __builtin_bswap64(off.total);
|
||||
footer->vbmeta_offset = __builtin_bswap64(off.vbmeta);
|
||||
@@ -780,15 +763,13 @@ void repack(const char *src_img, const char *out_img, bool skip_comp) {
|
||||
|
||||
if (boot.flags[DHTB_FLAG]) {
|
||||
// DHTB header
|
||||
auto d_hdr = reinterpret_cast<dhtb_hdr *>(new_addr);
|
||||
auto d_hdr = reinterpret_cast<dhtb_hdr *>(out.buf);
|
||||
memcpy(d_hdr, DHTB_MAGIC, 8);
|
||||
d_hdr->size = off.total - sizeof(dhtb_hdr);
|
||||
SHA256_hash(new_addr + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum);
|
||||
SHA256_hash(out.buf + sizeof(dhtb_hdr), d_hdr->size, d_hdr->checksum);
|
||||
} else if (boot.flags[BLOB_FLAG]) {
|
||||
// Blob header
|
||||
auto b_hdr = reinterpret_cast<blob_hdr *>(new_addr);
|
||||
auto b_hdr = reinterpret_cast<blob_hdr *>(out.buf);
|
||||
b_hdr->size = off.total - sizeof(blob_hdr);
|
||||
}
|
||||
|
||||
munmap(new_addr, new_size);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user