From 6e44b5cd40a11ae2f08127702aebc881b4422156 Mon Sep 17 00:00:00 2001 From: TJ Date: Fri, 8 Apr 2016 04:24:40 +0100 Subject: [PATCH] Report all internal sub-image headers too --- firmware_header_dump.c | 159 +++++++++++++++++++++++++++-------------- 1 file changed, 107 insertions(+), 52 deletions(-) diff --git a/firmware_header_dump.c b/firmware_header_dump.c index 0976d57..daf5802 100644 --- a/firmware_header_dump.c +++ b/firmware_header_dump.c @@ -33,6 +33,8 @@ static const char *help = \ static unsigned int MESSAGE_SIZE = 1024; +static char *image_type[] = {"IMGDEF", "ROMD", "HPNA"}; + static void pr_usage(int verbose) { @@ -126,60 +128,113 @@ main(int argc, char **argv) if (filename) { if ((fd = open(filename, fd_mode)) > 0) { - if ( (buffer = heap_and_reap(NULL, header_len, 1)) != NULL) { - ssize_t qty; - if ( (qty = read(fd, buffer, header_len)) < header_len) { - if (!opt_quiet) - fprintf(stderr, "warning: only able to read %ld of %ld bytes\n", qty, header_len); - header_len = qty; - } - } else { - close(fd); - pr_error_exit(0, "unable to allocate memory (%ld bytes)\n", header_len); - } - PFILE_TAG header = (PFILE_TAG) buffer; - printf("%04lx Tag Version: %s\n" - "%04lx Signature 1: %s\n" - "%04lx Signature 2: %s\n" - "%04lx Chip ID: %s\n" - "%04lx Board ID: %s\n" - "%04lx Big Endian: %s\n" - "%04lx Image Len: %s (0x%08lx)\n" - "%04lx CFE Address: %s (0x%08lx)\n" - "%04lx CFE Len: %s (0x%08lx)\n" - "%04lx Root FS Address: %s (0x%08lx)\n" - "%04lx Root FS Len: %s (0x%08lx)\n" - "%04lx Kernel Address: %s (0x%08lx)\n" - "%04lx Kernel Len: %s (0x%08lx)\n" - "%04lx Image Sequence: %s (0x%08x)\n" - "%04lx External Version: %s\n" - "%04lx Internal Version: %s\n" - "%04lx Image Next: %u\n" - "%04lx Image Validation Token: 0x%0x\n" - "%04lx Tag Validation Token: 0x%0x\n" - "", - offsetof(struct _FILE_TAG, tagVersion), header->tagVersion, - offsetof(struct _FILE_TAG, signiture_1), header->signiture_1, - offsetof(struct _FILE_TAG, signiture_2), header->signiture_2, - offsetof(struct _FILE_TAG, chipId), header->chipId, - offsetof(struct _FILE_TAG, boardId), header->boardId, - offsetof(struct _FILE_TAG, bigEndian), *header->bigEndian == '1' ? "Yes" : "No", - offsetof(struct _FILE_TAG, totalImageLen), header->totalImageLen, atol(header->totalImageLen), - offsetof(struct _FILE_TAG, cfeAddress), header->cfeAddress, atol(header->cfeAddress), - offsetof(struct _FILE_TAG, cfeLen), header->cfeLen, atol(header->cfeLen), - offsetof(struct _FILE_TAG, rootfsAddress), header->rootfsAddress, atol(header->rootfsAddress), - offsetof(struct _FILE_TAG, rootfsLen), header->rootfsLen, atol(header->rootfsLen), - offsetof(struct _FILE_TAG, kernelAddress), header->kernelAddress, atol(header->kernelAddress), - offsetof(struct _FILE_TAG, kernelLen), header->kernelLen, atol(header->kernelLen), - offsetof(struct _FILE_TAG, imageSequence), header->imageSequence, atoi(header->imageSequence), - offsetof(struct _FILE_TAG, externalversion), header->externalversion, - offsetof(struct _FILE_TAG, internalversion), header->internalversion, - offsetof(struct _FILE_TAG, imageNext), (unsigned int)*(unsigned char *)(header->imageNext), - offsetof(struct _FILE_TAG, imageValidationToken), ntohl( *((unsigned int *)(header->imageValidationToken)) ), - offsetof(struct _FILE_TAG, tagValidationToken), ntohl( *((unsigned int *)(header->tagValidationToken)) ) - ); + unsigned int offset = 0; + unsigned int count = 0; + unsigned int next = 1; + + while (next) { + unsigned long len = 0; + if (count) // switch struct type after initial file header + header_len = sizeof(IMAGE_TAG); + + lseek(fd, offset, SEEK_SET); + printf("Header Offset: 0x%08x\n", offset); + + if ( (buffer = heap_and_reap(NULL, header_len, 1)) != NULL) { + ssize_t qty; + if ( (qty = read(fd, buffer, header_len)) < header_len) { + if (!opt_quiet) + fprintf(stderr, "warning: only able to read %ld of %ld bytes\n", qty, header_len); + header_len = qty; + } + + PFILE_TAG pfile = (PFILE_TAG) buffer; + PIMAGE_TAG pimage = (PIMAGE_TAG) buffer; + + if (!count) { + next = *(unsigned char *)(pfile->imageNext); + len = atol(pfile->totalImageLen); + offset = 0x20000; + } else { + next = *(unsigned char *)(pimage->imageNext); + len = atol(pimage->imageLen); + } + + if (!count) { + printf("Image Offset: 0x%08x\n", 0x20000); + + printf("%04lx Tag Version: %s\n" + "%04lx Signature 1: %s\n" + "%04lx Signature 2: %s\n" + "%04lx Chip ID: %s\n" + "%04lx Board ID: %s\n" + "%04lx Big Endian: %s\n" + "%04lx Image Len: %s (0x%08lx)\n" + "%04lx CFE Address: %s (0x%08lx)\n" + "%04lx CFE Len: %s (0x%08lx)\n" + "%04lx Root FS Address: %s (0x%08lx)\n" + "%04lx Root FS Len: %s (0x%08lx)\n" + "%04lx Kernel Address: %s (0x%08lx)\n" + "%04lx Kernel Len: %s (0x%08lx)\n" + "%04lx Image Sequence: %s (0x%08x)\n" + "%04lx External Version: %s\n" + "%04lx Internal Version: %s\n" + "%04lx Image Next: %u\n" + "%04lx Image Validation Token: 0x%08x\n" + "%04lx Tag Validation Token: 0x%08x\n" + "\n", + offsetof(struct _FILE_TAG, tagVersion), pfile->tagVersion, + offsetof(struct _FILE_TAG, signiture_1), pfile->signiture_1, + offsetof(struct _FILE_TAG, signiture_2), pfile->signiture_2, + offsetof(struct _FILE_TAG, chipId), pfile->chipId, + offsetof(struct _FILE_TAG, boardId), pfile->boardId, + offsetof(struct _FILE_TAG, bigEndian), *pfile->bigEndian == '1' ? "Yes" : "No", + offsetof(struct _FILE_TAG, totalImageLen), pfile->totalImageLen, len, + offsetof(struct _FILE_TAG, cfeAddress), pfile->cfeAddress, atol(pfile->cfeAddress), + offsetof(struct _FILE_TAG, cfeLen), pfile->cfeLen, atol(pfile->cfeLen), + offsetof(struct _FILE_TAG, rootfsAddress), pfile->rootfsAddress, atol(pfile->rootfsAddress), + offsetof(struct _FILE_TAG, rootfsLen), pfile->rootfsLen, atol(pfile->rootfsLen), + offsetof(struct _FILE_TAG, kernelAddress), pfile->kernelAddress, atol(pfile->kernelAddress), + offsetof(struct _FILE_TAG, kernelLen), pfile->kernelLen, atol(pfile->kernelLen), + offsetof(struct _FILE_TAG, imageSequence), pfile->imageSequence, atoi(pfile->imageSequence), + offsetof(struct _FILE_TAG, externalversion), pfile->externalversion, + offsetof(struct _FILE_TAG, internalversion), pfile->internalversion, + offsetof(struct _FILE_TAG, imageNext), next, + offsetof(struct _FILE_TAG, imageValidationToken), ntohl( *((unsigned int *)(pfile->imageValidationToken)) ), + offsetof(struct _FILE_TAG, tagValidationToken), ntohl( *((unsigned int *)(pfile->tagValidationToken)) ) + ); + + } else { + printf("Image Offset: 0x%08lx\n", offset + sizeof(IMAGE_TAG)); + printf("%04lx imageNext: %u\n" + "%04lx imageType: %s (%lu)\n" + "%04lx imageSignature: %u\n" + "%04lx imageLen: %s (0x%08lx)\n" + "%04lx imageValidationToken: 0x%08x\n" + "%04lx tagValidationToken: 0x%08x\n" + "\n", + offsetof(struct _IMAGE_TAG, imageNext), next, + offsetof(struct _IMAGE_TAG, imageType), image_type[atol(pimage->imageType)], atol(pimage->imageType), + offsetof(struct _IMAGE_TAG, imageSignature), (unsigned int)*pimage->imageSignature, + offsetof(struct _IMAGE_TAG, imageLen), pimage->imageLen, len, + offsetof(struct _IMAGE_TAG, imageValidationToken), ntohl( *((unsigned int *)(pimage->imageValidationToken)) ), + offsetof(struct _IMAGE_TAG, tagValidationToken), ntohl( *((unsigned int *)(pimage->tagValidationToken)) ) + ); + } + + offset += len; + + heap_and_reap(buffer, 0, 0); + + ++count; + + } else { + close(fd); + pr_error_exit(0, "unable to allocate memory (%ld bytes)\n", header_len); + } + } heap_and_reap(buffer, 0, 0); close(fd); } else { -- 2.17.1