diff options
Diffstat (limited to 'utils/atj2137/atjboottool/atjboottool.c')
-rw-r--r-- | utils/atj2137/atjboottool/atjboottool.c | 37 |
1 files changed, 32 insertions, 5 deletions
diff --git a/utils/atj2137/atjboottool/atjboottool.c b/utils/atj2137/atjboottool/atjboottool.c index d0ad1b468b..b68ada980e 100644 --- a/utils/atj2137/atjboottool/atjboottool.c +++ b/utils/atj2137/atjboottool/atjboottool.c @@ -27,6 +27,7 @@ #include <stdarg.h> #include <ctype.h> #include <sys/stat.h> +#include <zlib.h> #include "misc.h" #include "fwu.h" #include "afi.h" @@ -100,7 +101,26 @@ static int unpack_afi_fw_cb(const char *filename, uint8_t *buf, size_t size) FILE *f = fopen(name, "wb"); if(f) { - fwrite(buf, size, 1, f); + if (0 != memcmp(buf, "\x1f\x8b\x8\0\0\0\0\0\0\xb", 10)) + fwrite(buf, size, 1, f); + else + { + uint8_t buf_out[8192]; + z_stream zs; + int err = Z_OK; + cprintf(GREEN, "inflating... "); + memset(&zs, 0, sizeof(zs)); + zs.next_in = buf + 10; + zs.avail_in = size - 10; + inflateInit2(&zs, -MAX_WBITS); /* raw */ + while (err == Z_OK) + { + zs.next_out = buf_out; + zs.avail_out = sizeof(buf_out); + err = inflate(&zs, Z_NO_FLUSH); + fwrite(buf_out, 1, sizeof(buf_out) - zs.avail_out, f); + } + } fclose(f); cprintf(RED, "Ok\n"); return 0; @@ -119,10 +139,10 @@ static int do_afi(uint8_t *buf, size_t size) return afi_unpack(buf, size, &unpack_afi_fw_cb); } -static int do_fw(uint8_t *buf, size_t size) +static int do_fw(uint8_t *buf, size_t size, bool big_endian) { build_out_prefix(".unpack", "", true); - return fw_unpack(buf, size, &unpack_afi_fw_cb); + return fw_unpack(buf, size, &unpack_afi_fw_cb, big_endian); } static void usage(void) { @@ -135,6 +155,7 @@ static void usage(void) printf(" --fwu Unpack a FWU firmware file\n"); printf(" --afi Unpack a AFI archive file\n"); printf(" --fw Unpack a FW archive file\n"); + printf(" --fw251 Big-endian FW archive used on Flip80251\n"); printf(" --atj2127 Force ATJ2127 decryption mode\n"); printf("The default is to try to guess the format.\n"); printf("If several formats are specified, all are tried.\n"); @@ -147,6 +168,7 @@ int main(int argc, char **argv) bool try_fwu = false; bool try_afi = false; bool try_fw = false; + bool big_endian = false; enum fwu_mode_t fwu_mode = FWU_AUTO; while(1) @@ -159,11 +181,12 @@ int main(int argc, char **argv) {"fwu", no_argument, 0, 'u'}, {"afi", no_argument, 0, 'a'}, {"fw", no_argument, 0, 'w'}, + {"fw251", no_argument, 0, 'b'}, {"atj2127", no_argument, 0, '2'}, {0, 0, 0, 0} }; - int c = getopt_long(argc, argv, "hdco:a2", long_options, NULL); + int c = getopt_long(argc, argv, "hdco:a2b", long_options, NULL); if(c == -1) break; switch(c) @@ -192,6 +215,10 @@ int main(int argc, char **argv) case 'w': try_fw = true; break; + case 'b': + try_fw = true; + big_endian = true; + break; case '2': fwu_mode = FWU_ATJ2127; break; @@ -238,7 +265,7 @@ int main(int argc, char **argv) else if(try_afi || afi_check(buf, size)) ret = do_afi(buf, size); else if(try_fw || fw_check(buf, size)) - ret = do_fw(buf, size); + ret = do_fw(buf, size, big_endian); else { cprintf(GREY, "No valid format found\n"); |