Move image parsing out of header searching
This commit is contained in:
parent
b4c2a9f49f
commit
da3394f34e
@ -47,16 +47,11 @@ boot_img::~boot_img() {
|
|||||||
#define CHROMEOS_RET 2
|
#define CHROMEOS_RET 2
|
||||||
#define ELF32_RET 3
|
#define ELF32_RET 3
|
||||||
#define ELF64_RET 4
|
#define ELF64_RET 4
|
||||||
#define pos_align() pos = do_align(pos, hdr.page_size())
|
|
||||||
|
|
||||||
int boot_img::parse_image(const char * image) {
|
int boot_img::parse_file(const char *image) {
|
||||||
mmap_ro(image, (void **) &map_addr, &map_size);
|
mmap_ro(image, (void **) &map_addr, &map_size);
|
||||||
|
|
||||||
// Parse image
|
|
||||||
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
fprintf(stderr, "Parsing boot image: [%s]\n", image);
|
||||||
for (uint8_t *head = map_addr; head < map_addr + map_size; ++head) {
|
for (uint8_t *head = map_addr; head < map_addr + map_size; ++head) {
|
||||||
size_t pos = 0;
|
|
||||||
|
|
||||||
switch (check_fmt(head, map_size)) {
|
switch (check_fmt(head, map_size)) {
|
||||||
case CHROMEOS:
|
case CHROMEOS:
|
||||||
// The caller should know it's chromeos, as it needs additional signing
|
// The caller should know it's chromeos, as it needs additional signing
|
||||||
@ -67,117 +62,122 @@ int boot_img::parse_image(const char * image) {
|
|||||||
flags |= SEANDROID_FLAG;
|
flags |= SEANDROID_FLAG;
|
||||||
fprintf(stderr, "DHTB_HDR\n");
|
fprintf(stderr, "DHTB_HDR\n");
|
||||||
break;
|
break;
|
||||||
case ELF32:
|
|
||||||
exit(ELF32_RET);
|
|
||||||
case ELF64:
|
|
||||||
exit(ELF64_RET);
|
|
||||||
case BLOB:
|
case BLOB:
|
||||||
flags |= BLOB_FLAG;
|
flags |= BLOB_FLAG;
|
||||||
fprintf(stderr, "TEGRA_BLOB\n");
|
fprintf(stderr, "TEGRA_BLOB\n");
|
||||||
b_hdr = new blob_hdr();
|
b_hdr = new blob_hdr();
|
||||||
memcpy(b_hdr, head, sizeof(blob_hdr));
|
memcpy(b_hdr, head, sizeof(blob_hdr));
|
||||||
|
head += sizeof(blob_hdr) - 1;
|
||||||
break;
|
break;
|
||||||
case AOSP:
|
case AOSP:
|
||||||
// Read the header
|
return parse_image(head);
|
||||||
if (((boot_img_hdr*) head)->page_size >= 0x02000000) {
|
|
||||||
flags |= PXA_FLAG;
|
|
||||||
fprintf(stderr, "PXA_BOOT_HDR\n");
|
|
||||||
hdr.set_hdr(new boot_img_hdr_pxa());
|
|
||||||
memcpy(*hdr, head, sizeof(boot_img_hdr_pxa));
|
|
||||||
} else if (memcmp(((boot_img_hdr*) head)->cmdline, NOOKHD_MAGIC, 12) == 0
|
|
||||||
|| memcmp(((boot_img_hdr*) head)->cmdline, NOOKHD_NEW_MAGIC, 26) == 0) {
|
|
||||||
flags |= NOOKHD_FLAG;
|
|
||||||
fprintf(stderr, "NOOKHD_GREEN_LOADER\n");
|
|
||||||
head += NOOKHD_PRE_HEADER_SZ - 1;
|
|
||||||
continue;
|
|
||||||
} else if (memcmp(((boot_img_hdr*) head)->name, ACCLAIM_MAGIC, 10) == 0) {
|
|
||||||
flags |= ACCLAIM_FLAG;
|
|
||||||
fprintf(stderr, "ACCLAIM_BAUWKSBOOT\n");
|
|
||||||
head += ACCLAIM_PRE_HEADER_SZ - 1;
|
|
||||||
continue;
|
|
||||||
} else {
|
|
||||||
hdr.set_hdr(new boot_img_hdr());
|
|
||||||
memcpy(*hdr, head, sizeof(boot_img_hdr));
|
|
||||||
}
|
|
||||||
pos += hdr.page_size();
|
|
||||||
|
|
||||||
flags |= hdr.id()[SHA_DIGEST_SIZE] ? SHA256_FLAG : 0;
|
/* Unsupported */
|
||||||
|
case ELF32:
|
||||||
print_hdr();
|
exit(ELF32_RET);
|
||||||
|
case ELF64:
|
||||||
kernel = head + pos;
|
exit(ELF64_RET);
|
||||||
pos += hdr->kernel_size;
|
|
||||||
pos_align();
|
|
||||||
|
|
||||||
ramdisk = head + pos;
|
|
||||||
pos += hdr->ramdisk_size;
|
|
||||||
pos_align();
|
|
||||||
|
|
||||||
second = head + pos;
|
|
||||||
pos += hdr->second_size;
|
|
||||||
pos_align();
|
|
||||||
|
|
||||||
extra = head + pos;
|
|
||||||
pos += hdr.extra_size();
|
|
||||||
pos_align();
|
|
||||||
|
|
||||||
recov_dtbo = head + pos;
|
|
||||||
pos += hdr.recovery_dtbo_size();
|
|
||||||
pos_align();
|
|
||||||
|
|
||||||
if (pos < map_size) {
|
|
||||||
tail = head + pos;
|
|
||||||
tail_size = map_size - (tail - map_addr);
|
|
||||||
}
|
|
||||||
|
|
||||||
// Check tail info, currently only for LG Bump and Samsung SEANDROIDENFORCE
|
|
||||||
if (tail_size >= 16 && memcmp(tail, SEANDROID_MAGIC, 16) == 0) {
|
|
||||||
flags |= SEANDROID_FLAG;
|
|
||||||
} else if (tail_size >= 16 && memcmp(tail, LG_BUMP_MAGIC, 16) == 0) {
|
|
||||||
flags |= LG_BUMP_FLAG;
|
|
||||||
}
|
|
||||||
|
|
||||||
find_dtb();
|
|
||||||
|
|
||||||
k_fmt = check_fmt(kernel, hdr->kernel_size);
|
|
||||||
r_fmt = check_fmt(ramdisk, hdr->ramdisk_size);
|
|
||||||
|
|
||||||
// Check MTK
|
|
||||||
if (k_fmt == MTK) {
|
|
||||||
fprintf(stderr, "MTK_KERNEL_HDR\n");
|
|
||||||
flags |= MTK_KERNEL;
|
|
||||||
k_hdr = new mtk_hdr();
|
|
||||||
memcpy(k_hdr, kernel, sizeof(mtk_hdr));
|
|
||||||
fprintf(stderr, "KERNEL [%u]\n", k_hdr->size);
|
|
||||||
fprintf(stderr, "NAME [%s]\n", k_hdr->name);
|
|
||||||
kernel += 512;
|
|
||||||
hdr->kernel_size -= 512;
|
|
||||||
k_fmt = check_fmt(kernel, hdr->kernel_size);
|
|
||||||
}
|
|
||||||
if (r_fmt == MTK) {
|
|
||||||
fprintf(stderr, "MTK_RAMDISK_HDR\n");
|
|
||||||
flags |= MTK_RAMDISK;
|
|
||||||
r_hdr = new mtk_hdr();
|
|
||||||
memcpy(r_hdr, ramdisk, sizeof(mtk_hdr));
|
|
||||||
fprintf(stderr, "RAMDISK [%u]\n", r_hdr->size);
|
|
||||||
fprintf(stderr, "NAME [%s]\n", r_hdr->name);
|
|
||||||
ramdisk += 512;
|
|
||||||
hdr->ramdisk_size -= 512;
|
|
||||||
r_fmt = check_fmt(ramdisk, hdr->ramdisk_size);
|
|
||||||
}
|
|
||||||
|
|
||||||
fprintf(stderr, "KERNEL_FMT [%s]\n", fmt2name[k_fmt]);
|
|
||||||
fprintf(stderr, "RAMDISK_FMT [%s]\n", fmt2name[r_fmt]);
|
|
||||||
|
|
||||||
return flags & CHROMEOS_FLAG ? CHROMEOS_RET : 0;
|
|
||||||
default:
|
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
LOGE("No boot image magic found!\n");
|
LOGE("No boot image magic found!\n");
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define pos_align() pos = do_align(pos, hdr.page_size())
|
||||||
|
int boot_img::parse_image(uint8_t *head) {
|
||||||
|
auto hp = (boot_img_hdr*) head;
|
||||||
|
if (hp->page_size >= 0x02000000) {
|
||||||
|
fprintf(stderr, "PXA_BOOT_HDR\n");
|
||||||
|
hdr.set_hdr(new boot_img_hdr_pxa());
|
||||||
|
memcpy(*hdr, head, sizeof(boot_img_hdr_pxa));
|
||||||
|
} else {
|
||||||
|
if (memcmp(hp->cmdline, NOOKHD_MAGIC, 12) == 0 ||
|
||||||
|
memcmp(hp->cmdline, NOOKHD_NEW_MAGIC, 26) == 0) {
|
||||||
|
flags |= NOOKHD_FLAG;
|
||||||
|
fprintf(stderr, "NOOKHD_GREEN_LOADER\n");
|
||||||
|
head += NOOKHD_PRE_HEADER_SZ;
|
||||||
|
} else if (memcmp(hp->name, ACCLAIM_MAGIC, 10) == 0) {
|
||||||
|
flags |= ACCLAIM_FLAG;
|
||||||
|
fprintf(stderr, "ACCLAIM_BAUWKSBOOT\n");
|
||||||
|
head += ACCLAIM_PRE_HEADER_SZ;
|
||||||
|
}
|
||||||
|
hdr.set_hdr(new boot_img_hdr());
|
||||||
|
memcpy(*hdr, head, sizeof(boot_img_hdr));
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t pos = hdr.page_size();
|
||||||
|
|
||||||
|
flags |= hdr.id()[SHA_DIGEST_SIZE] ? SHA256_FLAG : 0;
|
||||||
|
|
||||||
|
print_hdr();
|
||||||
|
|
||||||
|
kernel = head + pos;
|
||||||
|
pos += hdr->kernel_size;
|
||||||
|
pos_align();
|
||||||
|
|
||||||
|
ramdisk = head + pos;
|
||||||
|
pos += hdr->ramdisk_size;
|
||||||
|
pos_align();
|
||||||
|
|
||||||
|
second = head + pos;
|
||||||
|
pos += hdr->second_size;
|
||||||
|
pos_align();
|
||||||
|
|
||||||
|
extra = head + pos;
|
||||||
|
pos += hdr.extra_size();
|
||||||
|
pos_align();
|
||||||
|
|
||||||
|
recov_dtbo = head + pos;
|
||||||
|
pos += hdr.recovery_dtbo_size();
|
||||||
|
pos_align();
|
||||||
|
|
||||||
|
if (head + pos < map_addr + map_size) {
|
||||||
|
tail = head + pos;
|
||||||
|
tail_size = map_size - (tail - map_addr);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Check tail info, currently only for LG Bump and Samsung SEANDROIDENFORCE
|
||||||
|
if (tail_size >= 16 && memcmp(tail, SEANDROID_MAGIC, 16) == 0) {
|
||||||
|
flags |= SEANDROID_FLAG;
|
||||||
|
} else if (tail_size >= 16 && memcmp(tail, LG_BUMP_MAGIC, 16) == 0) {
|
||||||
|
flags |= LG_BUMP_FLAG;
|
||||||
|
}
|
||||||
|
|
||||||
|
find_dtb();
|
||||||
|
|
||||||
|
k_fmt = check_fmt(kernel, hdr->kernel_size);
|
||||||
|
r_fmt = check_fmt(ramdisk, hdr->ramdisk_size);
|
||||||
|
|
||||||
|
// Check MTK
|
||||||
|
if (k_fmt == MTK) {
|
||||||
|
fprintf(stderr, "MTK_KERNEL_HDR\n");
|
||||||
|
flags |= MTK_KERNEL;
|
||||||
|
k_hdr = new mtk_hdr();
|
||||||
|
memcpy(k_hdr, kernel, sizeof(mtk_hdr));
|
||||||
|
fprintf(stderr, "KERNEL [%u]\n", k_hdr->size);
|
||||||
|
fprintf(stderr, "NAME [%s]\n", k_hdr->name);
|
||||||
|
kernel += 512;
|
||||||
|
hdr->kernel_size -= 512;
|
||||||
|
k_fmt = check_fmt(kernel, hdr->kernel_size);
|
||||||
|
}
|
||||||
|
if (r_fmt == MTK) {
|
||||||
|
fprintf(stderr, "MTK_RAMDISK_HDR\n");
|
||||||
|
flags |= MTK_RAMDISK;
|
||||||
|
r_hdr = new mtk_hdr();
|
||||||
|
memcpy(r_hdr, ramdisk, sizeof(mtk_hdr));
|
||||||
|
fprintf(stderr, "RAMDISK [%u]\n", r_hdr->size);
|
||||||
|
fprintf(stderr, "NAME [%s]\n", r_hdr->name);
|
||||||
|
ramdisk += 512;
|
||||||
|
hdr->ramdisk_size -= 512;
|
||||||
|
r_fmt = check_fmt(ramdisk, hdr->ramdisk_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
fprintf(stderr, "KERNEL_FMT [%s]\n", fmt2name[k_fmt]);
|
||||||
|
fprintf(stderr, "RAMDISK_FMT [%s]\n", fmt2name[r_fmt]);
|
||||||
|
|
||||||
|
return (flags & CHROMEOS_FLAG) ? CHROMEOS_RET : 0;
|
||||||
|
}
|
||||||
|
|
||||||
void boot_img::find_dtb() {
|
void boot_img::find_dtb() {
|
||||||
for (uint32_t i = 0; i < hdr->kernel_size; ++i) {
|
for (uint32_t i = 0; i < hdr->kernel_size; ++i) {
|
||||||
if (memcmp(kernel + i, DTB_MAGIC, 4))
|
if (memcmp(kernel + i, DTB_MAGIC, 4))
|
||||||
@ -251,7 +251,7 @@ void boot_img::print_hdr() {
|
|||||||
|
|
||||||
int unpack(const char *image) {
|
int unpack(const char *image) {
|
||||||
boot_img boot {};
|
boot_img boot {};
|
||||||
int ret = boot.parse_image(image);
|
int ret = boot.parse_file(image);
|
||||||
int fd;
|
int fd;
|
||||||
|
|
||||||
// Dump kernel
|
// Dump kernel
|
||||||
@ -293,7 +293,7 @@ void repack(const char* orig_image, const char* out_image) {
|
|||||||
off_t header_off, kernel_off, ramdisk_off, second_off, extra_off;
|
off_t header_off, kernel_off, ramdisk_off, second_off, extra_off;
|
||||||
|
|
||||||
// Parse original image
|
// Parse original image
|
||||||
boot.parse_image(orig_image);
|
boot.parse_file(orig_image);
|
||||||
|
|
||||||
// Reset sizes
|
// Reset sizes
|
||||||
boot.hdr->kernel_size = 0;
|
boot.hdr->kernel_size = 0;
|
||||||
|
@ -132,17 +132,16 @@ struct blob_hdr {
|
|||||||
} __attribute__((packed));
|
} __attribute__((packed));
|
||||||
|
|
||||||
// Flags
|
// Flags
|
||||||
#define MTK_KERNEL 0x0001
|
#define MTK_KERNEL 1 << 1
|
||||||
#define MTK_RAMDISK 0x0002
|
#define MTK_RAMDISK 1 << 2
|
||||||
#define CHROMEOS_FLAG 0x0004
|
#define CHROMEOS_FLAG 1 << 3
|
||||||
#define PXA_FLAG 0x0008
|
#define DHTB_FLAG 1 << 4
|
||||||
#define DHTB_FLAG 0x0010
|
#define SEANDROID_FLAG 1 << 5
|
||||||
#define SEANDROID_FLAG 0x0020
|
#define LG_BUMP_FLAG 1 << 6
|
||||||
#define LG_BUMP_FLAG 0x0040
|
#define SHA256_FLAG 1 << 7
|
||||||
#define SHA256_FLAG 0x0080
|
#define BLOB_FLAG 1 << 8
|
||||||
#define BLOB_FLAG 0x0100
|
#define NOOKHD_FLAG 1 << 9
|
||||||
#define NOOKHD_FLAG 0x0200
|
#define ACCLAIM_FLAG 1 << 10
|
||||||
#define ACCLAIM_FLAG 0x0400
|
|
||||||
|
|
||||||
struct dyn_img_hdr {
|
struct dyn_img_hdr {
|
||||||
|
|
||||||
@ -260,7 +259,8 @@ struct boot_img {
|
|||||||
|
|
||||||
~boot_img();
|
~boot_img();
|
||||||
|
|
||||||
int parse_image(const char *);
|
int parse_file(const char *);
|
||||||
|
int parse_image(uint8_t *);
|
||||||
void find_dtb();
|
void find_dtb();
|
||||||
void print_hdr();
|
void print_hdr();
|
||||||
};
|
};
|
||||||
|
Loading…
Reference in New Issue
Block a user