diff options
author | Felix Fietkau <nbd@nbd.name> | 2019-02-12 16:24:14 +0100 |
---|---|---|
committer | Felix Fietkau <nbd@nbd.name> | 2019-02-12 16:41:38 +0100 |
commit | 8f4e31ea6eeb3ff70aea8cda53d4ec66ac460ae0 (patch) | |
tree | 95e4f526ca0a17a209f4e9463c32df7e2a7a4a95 | |
parent | d5681e45f047188bfa6897504c7c6888a57361a7 (diff) | |
download | upstream-8f4e31ea6eeb3ff70aea8cda53d4ec66ac460ae0.tar.gz upstream-8f4e31ea6eeb3ff70aea8cda53d4ec66ac460ae0.tar.bz2 upstream-8f4e31ea6eeb3ff70aea8cda53d4ec66ac460ae0.zip |
fwtool: add support for extracting the truncated data part to stdout
This allows extracing the firmware + metadata from a signed firmware without
altering the original image file
Signed-off-by: Felix Fietkau <nbd@nbd.name>
-rw-r--r-- | package/system/fwtool/src/fwtool.c | 25 |
1 files changed, 23 insertions, 2 deletions
diff --git a/package/system/fwtool/src/fwtool.c b/package/system/fwtool/src/fwtool.c index 505fafcf7a..3adc1e0249 100644 --- a/package/system/fwtool/src/fwtool.c +++ b/package/system/fwtool/src/fwtool.c @@ -43,6 +43,7 @@ struct data_buf { static FILE *signature_file, *metadata_file, *firmware_file; static int file_mode = MODE_DEFAULT; static bool truncate_file; +static bool write_truncated; static bool quiet = false; static uint32_t crc_table[256]; @@ -64,6 +65,7 @@ usage(const char *progname) " -s <file>: Extract signature file from firmware image\n" " -i <file>: Extract metadata file from firmware image\n" " -t: Remove extracted chunks from firmare image (using -s, -i)\n" + " -T: Output firmware image without extracted chunks to stdout (using -s, -i)\n" " -q: Quiet (suppress error messages)\n" "\n", progname); return 1; @@ -280,8 +282,10 @@ extract_data(const char *name) struct fwimage_trailer tr; struct data_buf dbuf = {}; uint32_t crc32 = ~0; + int data_len = 0; int ret = 1; void *buf; + bool metadata_keep = false; firmware_file = open_file(name, false); if (!firmware_file) { @@ -301,6 +305,9 @@ extract_data(const char *name) do { char *tmp = dbuf.cur; + if (write_truncated && dbuf.prev) + fwrite(dbuf.prev, 1, BUFLEN, stdout); + dbuf.cur = dbuf.prev; dbuf.prev = tmp; @@ -317,7 +324,6 @@ extract_data(const char *name) } while (dbuf.cur_len == BUFLEN); while (1) { - int data_len; if (extract_tail(&dbuf, &tr, sizeof(tr))) break; @@ -349,6 +355,7 @@ extract_data(const char *name) } else if (tr.type == FWIMAGE_INFO) { if (!metadata_file) { dbuf.file_len += data_len + sizeof(tr); + metadata_keep = true; break; } @@ -368,6 +375,17 @@ extract_data(const char *name) if (!ret && truncate_file) ftruncate(fileno(firmware_file), dbuf.file_len); + if (write_truncated) { + if (dbuf.prev) + fwrite(dbuf.prev, 1, BUFLEN, stdout); + if (dbuf.cur) + fwrite(dbuf.cur, 1, dbuf.cur_len, stdout); + if (metadata_keep) { + fwrite(buf, data_len, 1, stdout); + fwrite(&tr, sizeof(tr), 1, stdout); + } + } + out: free(buf); free(dbuf.cur); @@ -392,7 +410,7 @@ int main(int argc, char **argv) crc32_filltable(crc_table); - while ((ch = getopt(argc, argv, "i:I:qs:S:t")) != -1) { + while ((ch = getopt(argc, argv, "i:I:qs:S:tT")) != -1) { ret = 0; switch(ch) { case 'S': @@ -410,6 +428,9 @@ int main(int argc, char **argv) case 't': truncate_file = true; break; + case 'T': + write_truncated = true; + break; case 'q': quiet = true; break; |