Report all internal sub-image headers too
authorTJ <hacker@iam.tj>
Fri, 8 Apr 2016 03:24:40 +0000 (04:24 +0100)
committerTJ <hacker@iam.tj>
Fri, 8 Apr 2016 03:24:40 +0000 (04:24 +0100)
firmware_header_dump.c

index 0976d57..daf5802 100644 (file)
@@ -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 {