Improvements

This commit is contained in:
topjohnwu 2017-03-02 21:59:37 +08:00
parent 2b3b087c29
commit 9f91c8b59d
5 changed files with 158 additions and 122 deletions

View File

@ -341,3 +341,57 @@ void bzip2(int mode, const char* filename, unsigned char* buf, size_t size) {
}
close(fd);
}
int decomp(file_t type, const char *to, unsigned char *from, size_t size) {
switch (type) {
case GZIP:
gzip(0, to, from, size);
break;
case XZ:
lzma(0, to, from, size);
break;
case LZMA:
lzma(0, to, from, size);
break;
case BZIP2:
bzip2(0, to, from, size);
break;
case LZ4:
lz4(0, to, from, size);
break;
default:
// Unsupported
return 1;
}
return 0;
}
int comp(file_t type, const char *to, unsigned char *from, size_t size) {
char name[PATH_MAX];
switch (type) {
case GZIP:
sprintf(name, "%s.%s", to, "gz");
gzip(1, name, from, size);
break;
case XZ:
sprintf(name, "%s.%s", to, "xz");
lzma(1, name, from, size);
break;
case LZMA:
sprintf(name, "%s.%s", to, "lzma");
lzma(2, name, from, size);
break;
case BZIP2:
sprintf(name, "%s.%s", to, "bz2");
bzip2(1, name, from, size);
break;
case LZ4:
sprintf(name, "%s.%s", to, "lz4");
lz4(1, name, from, size);
break;
default:
// Unsupported
return 1;
}
return 0;
}

View File

@ -30,7 +30,7 @@
#define DTB_FILE "dtb"
typedef enum {
DONTCARE,
UNKNOWN,
CHROMEOS,
AOSP,
ELF,
@ -40,6 +40,7 @@ typedef enum {
LZMA,
BZIP2,
LZ4,
MTK,
QCDT,
} file_t;
@ -55,11 +56,14 @@ void repack(const char *image);
void hexpatch(char *image, char *from, char *to);
void error(int rc, const char *msg, ...);
void parse_img(unsigned char *orig, size_t size);
file_t check_type(unsigned char *buf);
// Compressions
void gzip(int mode, const char* filename, unsigned char* buf, size_t size);
void lzma(int mode, const char* filename, unsigned char* buf, size_t size);
void lz4(int mode, const char* filename, unsigned char* buf, size_t size);
void bzip2(int mode, const char* filename, unsigned char* buf, size_t size);
int comp(file_t type, const char *to, unsigned char *from, size_t size);
int decomp(file_t type, const char *to, unsigned char *from, size_t size);
#endif

View File

@ -13,6 +13,37 @@ boot_img_hdr hdr;
int mtk_kernel = 0, mtk_ramdisk = 0;
file_t boot_type, ramdisk_type, dtb_type;
file_t check_type(unsigned char *buf) {
if (memcmp(buf, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 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, "\x1f\x8b\x08\x00", 4) == 0) {
return GZIP;
} else if (memcmp(buf, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
return LZOP;
} else if (memcmp(buf, "\xfd""7zXZ\x00", 6) == 0) {
return XZ;
} else if (memcmp(buf, "\x5d\x00\x00", 3) == 0
&& (buf[12] == (unsigned char) '\xff' || buf[12] == (unsigned char) '\x00')) {
return LZMA;
} else if (memcmp(buf, "BZh", 3) == 0) {
return BZIP2;
} else if ( ( memcmp(buf, "\x04\x22\x4d\x18", 4) == 0
|| memcmp(buf, "\x03\x21\x4c\x18", 4) == 0)
|| memcmp(buf, "\x02\x21\x4c\x18", 4) == 0) {
return LZ4;
} else if (memcmp(buf, "\x88\x16\x88\x58", 4) == 0) {
return MTK;
} else if (memcmp(buf, "QCDT", 4) == 0) {
return QCDT;
} else {
return UNKNOWN;
}
}
static void check_headers() {
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_addr);
@ -37,56 +68,44 @@ static void check_headers() {
printf("NAME [%s]\n", hdr.name);
printf("CMDLINE [%s]\n", hdr.cmdline);
// Check compression
if (memcmp(ramdisk, "\x1f\x8b\x08\x00", 4) == 0) {
// gzip header
printf("COMPRESSION [gzip]\n");
ramdisk_type = GZIP;
} else if (memcmp(ramdisk, "\x89\x4c\x5a\x4f\x00\x0d\x0a\x1a\x0a", 9) == 0) {
// lzop header
printf("COMPRESSION [lzop]\n");
ramdisk_type = LZOP;
} else if (memcmp(ramdisk, "\xfd""7zXZ\x00", 6) == 0) {
// xz header
printf("COMPRESSION [xz]\n");
ramdisk_type = XZ;
} else if (memcmp(ramdisk, "\x5d\x00\x00", 3) == 0
&& (ramdisk[12] == (unsigned char) '\xff' || ramdisk[12] == (unsigned char) '\x00')) {
// lzma header
printf("COMPRESSION [lzma]\n");
ramdisk_type = LZMA;
} else if (memcmp(ramdisk, "BZh", 3) == 0) {
// bzip2 header
printf("COMPRESSION [bzip2]\n");
ramdisk_type = BZIP2;
} else if ( ( memcmp(ramdisk, "\x04\x22\x4d\x18", 4) == 0
|| memcmp(ramdisk, "\x03\x21\x4c\x18", 4) == 0)
|| memcmp(ramdisk, "\x02\x21\x4c\x18", 4) == 0) {
// lz4 header
printf("COMPRESSION [lz4]\n");
ramdisk_type = LZ4;
ramdisk_type = check_type(ramdisk);
} else {
error(1, "Unknown ramdisk format!");
switch (ramdisk_type) {
case GZIP:
printf("COMPRESSION [%s]\n", "gzip");
break;
case LZOP:
printf("COMPRESSION [%s]\n", "lzop");
break;
case XZ:
printf("COMPRESSION [%s]\n", "xz");
break;
case LZMA:
printf("COMPRESSION [%s]\n", "lzma");
break;
case BZIP2:
printf("COMPRESSION [%s]\n", "bzip2");
break;
case LZ4:
printf("COMPRESSION [%s]\n", "lz4");
break;
default:
error(1, "Unknown ramdisk format!");
}
// Check MTK
if (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) {
if (check_type(kernel) == MTK) {
printf("MTK header found in kernel\n");
mtk_kernel = 1;
}
if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) {
if (check_type(ramdisk) == MTK) {
printf("MTK header found in ramdisk\n");
mtk_ramdisk = 1;
}
// Check dtb
// Check dtb if ELF boot
if (boot_type == ELF && hdr.dt_size) {
if (memcmp(dtb, "QCDT", 4) == 0) {
dtb_type = QCDT;
} else if (memcmp(dtb, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
dtb_type = ELF;
}
dtb_type = check_type(dtb);
}
}
@ -292,16 +311,22 @@ static void parse_aosp() {
void parse_img(unsigned char *orig, size_t size) {
for(base = orig; base < (orig + size); base += 256) {
if (memcmp(base, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) {
boot_type = CHROMEOS;
} else if (memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) {
if (boot_type != CHROMEOS) boot_type = AOSP;
parse_aosp();
return;
} else if (memcmp(base, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
boot_type = ELF;
parse_elf();
return;
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();
return;
case ELF:
boot_type = ELF;
parse_elf();
return;
default:
continue;
}
}
error(1, "No boot image magic found!");

View File

@ -82,7 +82,7 @@ void repack(const char* image) {
}
if (access(RAMDISK_FILE, R_OK) == 0) {
// If we found raw cpio, recompress to original format
// If we found raw cpio, compress to original format
int rfd = open(RAMDISK_FILE, O_RDONLY);
if (rfd < 0)
error(1, "Cannot open " RAMDISK_FILE);
@ -91,52 +91,23 @@ void repack(const char* image) {
lseek(rfd, 0, SEEK_SET);
unsigned char *cpio = mmap(NULL, cpio_size, PROT_READ, MAP_SHARED, rfd, 0);
switch (ramdisk_type) {
case GZIP:
sprintf(name, "%s.%s", RAMDISK_FILE, "gz");
gzip(1, name, cpio, cpio_size);
break;
case LZOP:
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo");
error(1, "Unsupported format! Please compress manually!");
break;
case XZ:
sprintf(name, "%s.%s", RAMDISK_FILE, "xz");
lzma(1, name, cpio, cpio_size);
break;
case LZMA:
sprintf(name, "%s.%s", RAMDISK_FILE, "lzma");
lzma(2, name, cpio, cpio_size);
break;
case BZIP2:
sprintf(name, "%s.%s", RAMDISK_FILE, "bz2");
bzip2(1, name, cpio, cpio_size);
break;
case LZ4:
sprintf(name, "%s.%s", RAMDISK_FILE, "lz4");
lz4(1, name, cpio, cpio_size);
break;
default:
// Never happens
break;
}
if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
error(1, "Unsupported format! Please compress manually!\n");
munmap(cpio, cpio_size);
close(rfd);
} else {
// If no raw cpio found, find compressed ones
int found = 0;
for (int i = 0; i < EXT_NUM; ++i) {
sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]);
if (access(name, R_OK) == 0) {
found = 1;
break;
}
}
if (!found) {
error(1, "No ramdisk exists!");
}
int found = 0;
for (int i = 0; i < EXT_NUM; ++i) {
sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]);
if (access(name, R_OK) == 0) {
found = 1;
break;
}
}
if (!found)
error(1, "No ramdisk exists!");
hdr.ramdisk_size += restore(name);
page_align();

View File

@ -41,36 +41,18 @@ void unpack(const char* image) {
hdr.ramdisk_size -= 512;
}
switch (ramdisk_type) {
case GZIP:
sprintf(name, "%s.%s", RAMDISK_FILE, "gz");
gzip(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
break;
case LZOP:
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo");
printf("Unsupported format! Please decompress manually!\n");
// Dump the compressed ramdisk
dump(ramdisk, hdr.ramdisk_size, name);
break;
case XZ:
sprintf(name, "%s.%s", RAMDISK_FILE, "xz");
lzma(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
break;
case LZMA:
sprintf(name, "%s.%s", RAMDISK_FILE, "lzma");
lzma(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
break;
case BZIP2:
sprintf(name, "%s.%s", RAMDISK_FILE, "bz2");
bzip2(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
break;
case LZ4:
sprintf(name, "%s.%s", RAMDISK_FILE, "lz4");
lz4(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
break;
default:
// Never happens
break;
if (decomp(ramdisk_type, RAMDISK_FILE, ramdisk, hdr.ramdisk_size)) {
printf("Unsupported format! Please decompress manually!\n");
switch (ramdisk_type) {
case LZOP:
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo");
break;
default:
// Never happens
break;
}
// Dump the compressed ramdisk
dump(ramdisk, hdr.ramdisk_size, name);
}
if (hdr.second_size) {
@ -79,7 +61,7 @@ void unpack(const char* image) {
}
if (hdr.dt_size) {
if (boot_type == ELF && (dtb_type != QCDT && dtb_type != ELF )) {
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);