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

View File

@ -13,6 +13,37 @@ boot_img_hdr hdr;
int mtk_kernel = 0, mtk_ramdisk = 0; int mtk_kernel = 0, mtk_ramdisk = 0;
file_t boot_type, ramdisk_type, dtb_type; 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() { static void check_headers() {
printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr); printf("KERNEL [%d] @ 0x%08x\n", hdr.kernel_size, hdr.kernel_addr);
printf("RAMDISK [%d] @ 0x%08x\n", hdr.ramdisk_size, hdr.ramdisk_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("NAME [%s]\n", hdr.name);
printf("CMDLINE [%s]\n", hdr.cmdline); printf("CMDLINE [%s]\n", hdr.cmdline);
// Check compression ramdisk_type = check_type(ramdisk);
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;
} else { 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!"); error(1, "Unknown ramdisk format!");
} }
// Check MTK // Check MTK
if (memcmp(kernel, "\x88\x16\x88\x58", 4) == 0) { if (check_type(kernel) == MTK) {
printf("MTK header found in kernel\n"); printf("MTK header found in kernel\n");
mtk_kernel = 1; mtk_kernel = 1;
} }
if (memcmp(ramdisk, "\x88\x16\x88\x58", 4) == 0) { if (check_type(ramdisk) == MTK) {
printf("MTK header found in ramdisk\n"); printf("MTK header found in ramdisk\n");
mtk_ramdisk = 1; mtk_ramdisk = 1;
} }
// Check dtb // Check dtb if ELF boot
if (boot_type == ELF && hdr.dt_size) { if (boot_type == ELF && hdr.dt_size) {
if (memcmp(dtb, "QCDT", 4) == 0) { dtb_type = check_type(dtb);
dtb_type = QCDT;
} else if (memcmp(dtb, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) {
dtb_type = ELF;
}
} }
} }
@ -292,16 +311,22 @@ static void parse_aosp() {
void parse_img(unsigned char *orig, size_t size) { void parse_img(unsigned char *orig, size_t size) {
for(base = orig; base < (orig + size); base += 256) { for(base = orig; base < (orig + size); base += 256) {
if (memcmp(base, CHROMEOS_MAGIC, CHROMEOS_MAGIC_SIZE) == 0) { switch (check_type(base)) {
case CHROMEOS:
boot_type = CHROMEOS; boot_type = CHROMEOS;
} else if (memcmp(base, BOOT_MAGIC, BOOT_MAGIC_SIZE) == 0) { continue;
if (boot_type != CHROMEOS) boot_type = AOSP; case AOSP:
// Don't override CHROMEOS
if (boot_type != CHROMEOS)
boot_type = AOSP;
parse_aosp(); parse_aosp();
return; return;
} else if (memcmp(base, ELF_MAGIC, ELF_MAGIC_SIZE) == 0) { case ELF:
boot_type = ELF; boot_type = ELF;
parse_elf(); parse_elf();
return; return;
default:
continue;
} }
} }
error(1, "No boot image magic found!"); 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 (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); int rfd = open(RAMDISK_FILE, O_RDONLY);
if (rfd < 0) if (rfd < 0)
error(1, "Cannot open " RAMDISK_FILE); error(1, "Cannot open " RAMDISK_FILE);
@ -91,40 +91,13 @@ void repack(const char* image) {
lseek(rfd, 0, SEEK_SET); lseek(rfd, 0, SEEK_SET);
unsigned char *cpio = mmap(NULL, cpio_size, PROT_READ, MAP_SHARED, rfd, 0); unsigned char *cpio = mmap(NULL, cpio_size, PROT_READ, MAP_SHARED, rfd, 0);
switch (ramdisk_type) { if (comp(ramdisk_type, RAMDISK_FILE, cpio, cpio_size))
case GZIP: error(1, "Unsupported format! Please compress manually!\n");
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;
}
munmap(cpio, cpio_size); munmap(cpio, cpio_size);
close(rfd); close(rfd);
} else { }
// If no raw cpio found, find compressed ones
int found = 0; int found = 0;
for (int i = 0; i < EXT_NUM; ++i) { for (int i = 0; i < EXT_NUM; ++i) {
sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]); sprintf(name, "%s.%s", RAMDISK_FILE, ext_list[i]);
@ -133,10 +106,8 @@ void repack(const char* image) {
break; break;
} }
} }
if (!found) { if (!found)
error(1, "No ramdisk exists!"); error(1, "No ramdisk exists!");
}
}
hdr.ramdisk_size += restore(name); hdr.ramdisk_size += restore(name);
page_align(); page_align();

View File

@ -41,37 +41,19 @@ void unpack(const char* image) {
hdr.ramdisk_size -= 512; hdr.ramdisk_size -= 512;
} }
if (decomp(ramdisk_type, RAMDISK_FILE, ramdisk, hdr.ramdisk_size)) {
printf("Unsupported format! Please decompress manually!\n");
switch (ramdisk_type) { switch (ramdisk_type) {
case GZIP:
sprintf(name, "%s.%s", RAMDISK_FILE, "gz");
gzip(0, RAMDISK_FILE, ramdisk, hdr.ramdisk_size);
break;
case LZOP: case LZOP:
sprintf(name, "%s.%s", RAMDISK_FILE, "lzo"); 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; break;
default: default:
// Never happens // Never happens
break; break;
} }
// Dump the compressed ramdisk
dump(ramdisk, hdr.ramdisk_size, name);
}
if (hdr.second_size) { if (hdr.second_size) {
// Dump second // Dump second