Subversion Repositories QNX 8.QNX8 IFS tool

Rev

Rev 2 | Rev 4 | Go to most recent revision | Show entire file | Ignore whitespace | Details | Blame | Last modification | View Log | RSS feed

Rev 2 Rev 3
Line 1074... Line 1074...
1074
 
1074
 
1075
static int fsentry_compare_pathnames_cb (const void *a, const void *b)
1075
static int fsentry_compare_pathnames_cb (const void *a, const void *b)
1076
{
1076
{
1077
   // qsort() callback that compares two imagefs filesystem entries and sort them alphabetically by pathname
1077
   // qsort() callback that compares two imagefs filesystem entries and sort them alphabetically by pathname
1078
 
1078
 
1079
   fsentry_t *entry_a = (fsentry_t *) a;
1079
   const fsentry_t *entry_a = (const fsentry_t *) a;
1080
   fsentry_t *entry_b = (fsentry_t *) b;
1080
   const fsentry_t *entry_b = (const fsentry_t *) b;
1081
   const char *pathname_a = (S_ISDIR (entry_a->header.mode) ? entry_a->u.dir.path : (S_ISREG (entry_a->header.mode) ? entry_a->u.file.path : (S_ISLNK (entry_a->header.mode) ? entry_a->u.symlink.path : entry_a->u.device.path)));
1081
   const char *pathname_a = (S_ISDIR (entry_a->header.mode) ? entry_a->u.dir.path : (S_ISREG (entry_a->header.mode) ? entry_a->u.file.path : (S_ISLNK (entry_a->header.mode) ? entry_a->u.symlink.path : entry_a->u.device.path)));
1082
   const char *pathname_b = (S_ISDIR (entry_b->header.mode) ? entry_b->u.dir.path : (S_ISREG (entry_b->header.mode) ? entry_b->u.file.path : (S_ISLNK (entry_b->header.mode) ? entry_b->u.symlink.path : entry_b->u.device.path)));
1082
   const char *pathname_b = (S_ISDIR (entry_b->header.mode) ? entry_b->u.dir.path : (S_ISREG (entry_b->header.mode) ? entry_b->u.file.path : (S_ISLNK (entry_b->header.mode) ? entry_b->u.symlink.path : entry_b->u.device.path)));
1083
   return (strcmp (pathname_a, pathname_b));
1083
   return (strcmp (pathname_a, pathname_b));
1084
}
1084
}
1085
 
1085
 
1086
 
1086
 
1087
static int fsentry_compare_sizes_cb (const void *a, const void *b)
1087
static int fsentry_compare_sizes_cb (const void *a, const void *b)
1088
{
1088
{
1089
   // qsort() callback that compares two imagefs filesystem entries and sort them alphabetically by pathname
1089
   // qsort() callback that compares two imagefs filesystem entries and sort them by increasing data size
1090
 
1090
 
1091
   fsentry_t *entry_a = (fsentry_t *) a;
1091
   const fsentry_t *entry_a = (const fsentry_t *) a;
1092
   fsentry_t *entry_b = (fsentry_t *) b;
1092
   const fsentry_t *entry_b = (const fsentry_t *) b;
1093
   const int32_t size_a = (S_ISREG (entry_a->header.mode) ? entry_a->u.file.size : 0); // only files (i.e. entries wearing the S_IFREG flag) have a separate data block
1093
   const int32_t size_a = (S_ISREG (entry_a->header.mode) ? entry_a->u.file.size : 0); // only files (i.e. entries wearing the S_IFREG flag) have a separate data block
1094
   const int32_t size_b = (S_ISREG (entry_b->header.mode) ? entry_b->u.file.size : 0); // only files (i.e. entries wearing the S_IFREG flag) have a separate data block
1094
   const int32_t size_b = (S_ISREG (entry_b->header.mode) ? entry_b->u.file.size : 0); // only files (i.e. entries wearing the S_IFREG flag) have a separate data block
1095
   return ((int) size_b - (int) size_a);
1095
   return ((int) size_b - (int) size_a);
1096
}
1096
}
1097
 
1097
 
Line 1724... Line 1724...
1724
   startup_trailer_v2_t *startup_trailer_v2 = NULL;
1724
   startup_trailer_v2_t *startup_trailer_v2 = NULL;
1725
   image_header_t *image_header = NULL;
1725
   image_header_t *image_header = NULL;
1726
   size_t imageheader_offset = 0;
1726
   size_t imageheader_offset = 0;
1727
   image_trailer_v1_t *image_trailer_v1 = NULL;
1727
   image_trailer_v1_t *image_trailer_v1 = NULL;
1728
   image_trailer_v2_t *image_trailer_v2 = NULL;
1728
   image_trailer_v2_t *image_trailer_v2 = NULL;
-
 
1729
   size_t imagetrailer_offset = 0;
-
 
1730
   fsentry_t **fsentries = NULL; // mallocated
-
 
1731
   size_t fsentry_count = 0;
1729
   fsentry_t *current_fsentry = NULL;
1732
   fsentry_t *current_fsentry = NULL;
1730
   char recorded_sha512[2 * SHA512_DIGEST_LENGTH + 1] = "";
1733
   char recorded_sha512[2 * SHA512_DIGEST_LENGTH + 1] = "";
1731
   char computed_sha512[2 * SHA512_DIGEST_LENGTH + 1] = "";
1734
   char computed_sha512[2 * SHA512_DIGEST_LENGTH + 1] = "";
1732
   size_t startupfile_blobsize = 0;
1735
   size_t startupfile_blobsize = 0;
-
 
1736
   void *reallocated_ptr;
1733
   size_t bootfile_blobsize = 0;
1737
   size_t bootfile_blobsize = 0;
1734
   size_t current_offset;
1738
   size_t current_offset;
-
 
1739
   size_t fsentry_index;
-
 
1740
   size_t nearest_distance;
-
 
1741
   size_t nearest_index;
1735
   size_t byte_index;
1742
   size_t byte_index;
1736
   uint32_t recorded_checksum;
1743
   uint32_t recorded_checksum;
1737
   uint32_t computed_checksum;
1744
   uint32_t computed_checksum;
1738
   uint8_t *filedata;
1745
   uint8_t *filedata;
1739
   size_t filesize;
1746
   size_t filesize;
Line 1756... Line 1763...
1756
      exit (1);
1763
      exit (1);
1757
   }
1764
   }
1758
   fseek (fp, 0, SEEK_SET);
1765
   fseek (fp, 0, SEEK_SET);
1759
   fread (filedata, 1, filesize, fp);
1766
   fread (filedata, 1, filesize, fp);
1760
   fclose (fp);
1767
   fclose (fp);
1761
 
1768
 
1762
   printf ("IFS file \"%s\" - size 0x%zx (%zd) bytes\n", ifs_pathname, filesize, filesize);
1769
   printf ("IFS file \"%s\" - size 0x%zx (%zd) bytes\n", ifs_pathname, filesize, filesize);
1763
 
1770
 
1764
   // parse file from start to end
1771
   // parse file from start to end
1765
   current_offset = 0;
1772
   current_offset = 0;
1766
   for (;;)
1773
   for (;;)
Line 1813... Line 1820...
1813
         }
1820
         }
1814
         else // old V1 trailer
1821
         else // old V1 trailer
1815
         {
1822
         {
1816
            startup_trailer_v1 = (startup_trailer_v1_t *) &filedata[current_offset + startup_header->startup_size - sizeof (startup_trailer_v1_t)];
1823
            startup_trailer_v1 = (startup_trailer_v1_t *) &filedata[current_offset + startup_header->startup_size - sizeof (startup_trailer_v1_t)];
1817
            startupfile_blobsize = startup_header->startup_size - sizeof (startup_header_t) - sizeof (startup_trailer_v1_t);
1824
            startupfile_blobsize = startup_header->startup_size - sizeof (startup_header_t) - sizeof (startup_trailer_v1_t);
1818
         }
1825
         }
1819
 
1826
 
1820
         current_offset += sizeof (startup_header_t); // jump over the startup header and reach the startup blob
1827
         current_offset += sizeof (startup_header_t); // jump over the startup header and reach the startup blob
1821
         printf ("\n");
1828
         printf ("\n");
1822
         printf ("Startup blob at offset 0x%zx (%zd):\n", current_offset, current_offset);
1829
         printf ("Startup blob at offset 0x%zx (%zd):\n", current_offset, current_offset);
1823
         printf ("   size 0x%zx (%zd) bytes\n", startupfile_blobsize, startupfile_blobsize);
1830
         printf ("   size 0x%zx (%zd) bytes\n", startupfile_blobsize, startupfile_blobsize);
1824
         printf ("   checksum %d\n", update_checksum32 (0, (uint32_t *) &filedata[current_offset], startupfile_blobsize));
1831
         printf ("   checksum %d\n", update_checksum32 (0, (uint32_t *) &filedata[current_offset], startupfile_blobsize));
1825
 
1832
 
1826
         current_offset += startupfile_blobsize; // jump over the startup blob and reach the startup trailer
1833
         current_offset += startupfile_blobsize; // jump over the startup blob and reach the startup trailer
1827
         printf ("\n");
1834
         printf ("\n");
1828
         printf ("Startup trailer at offset 0x%zx (%zd) - version %d:\n", current_offset, current_offset, (startup_header->flags1 & STARTUP_HDR_FLAGS1_TRAILER_V2 ? 2 : 1));
1835
         printf ("Startup trailer at offset 0x%zx (%zd) - version %d:\n", current_offset, current_offset, (startup_header->flags1 & STARTUP_HDR_FLAGS1_TRAILER_V2 ? 2 : 1));
1829
         if (startup_header->flags1 & STARTUP_HDR_FLAGS1_TRAILER_V2)
1836
         if (startup_header->flags1 & STARTUP_HDR_FLAGS1_TRAILER_V2)
1830
         {
1837
         {
1831
            for (byte_index = 0; byte_index < SHA512_DIGEST_LENGTH; byte_index++)
1838
            for (byte_index = 0; byte_index < SHA512_DIGEST_LENGTH; byte_index++)
1832
               sprintf (&recorded_sha512[2 * byte_index], "%02x", startup_trailer_v2->sha512[byte_index]);
1839
               sprintf (&recorded_sha512[2 * byte_index], "%02x", startup_trailer_v2->sha512[byte_index]);
1833
            strcpy (computed_sha512, SHA512 (startup_header, (size_t) ((uint8_t *) startup_trailer_v2 - (uint8_t *) startup_header), NULL));
1840
            strcpy (computed_sha512, SHA512 (startup_header, (size_t) ((uint8_t *) startup_trailer_v2 - (uint8_t *) startup_header), NULL));
1834
            recorded_checksum = startup_trailer_v2->cksum;
1841
            recorded_checksum = startup_trailer_v2->cksum;
1835
            computed_checksum = update_checksum32 (0, (uint32_t *) startup_header, sizeof (startup_header) + startupfile_blobsize + SHA512_DIGEST_LENGTH);
1842
            computed_checksum = update_checksum32 (0, (uint32_t *) startup_header, sizeof (startup_header) + startupfile_blobsize + SHA512_DIGEST_LENGTH);
Line 1842... Line 1849...
1842
         }
1849
         }
1843
         else // old v1 trailer
1850
         else // old v1 trailer
1844
         {
1851
         {
1845
            recorded_checksum = startup_trailer_v1->cksum;
1852
            recorded_checksum = startup_trailer_v1->cksum;
1846
            computed_checksum = update_checksum32 (0, (uint32_t *) startup_header, sizeof (startup_header) + startupfile_blobsize);
1853
            computed_checksum = update_checksum32 (0, (uint32_t *) startup_header, sizeof (startup_header) + startupfile_blobsize);
1847
            printf ("    cksum = 0x%08x (%d) - %s\n", recorded_checksum, recorded_checksum, (computed_checksum == recorded_checksum ? "GOOD" : "BAD"));
1854
            printf ("    cksum = 0x%08x (%d) - %s\n", recorded_checksum, recorded_checksum, (computed_checksum == recorded_checksum ? "GOOD" : "BAD"));
1848
            if (computed_checksum != recorded_checksum)
1855
            if (computed_checksum != recorded_checksum)
1849
               printf ("Computed cksum: 0x%08x (%d)\n", computed_checksum, computed_checksum);
1856
               printf ("Computed cksum: 0x%08x (%d)\n", computed_checksum, computed_checksum);
1850
         }
1857
         }
1851
 
1858
 
1852
         current_offset += (startup_header->flags1 & STARTUP_HDR_FLAGS1_TRAILER_V2 ? sizeof (image_trailer_v2_t) : sizeof (image_trailer_v1_t)); // now reach the next segment
1859
         current_offset += (startup_header->flags1 & STARTUP_HDR_FLAGS1_TRAILER_V2 ? sizeof (startup_trailer_v2_t) : sizeof (startup_trailer_v1_t)); // now reach the next segment
1853
      }
1860
      }
1854
 
1861
 
1855
      // else does an image header start here ?
1862
      // else does an image header start here ?
1856
      else if ((current_offset + sizeof (image_header_t) < filesize) && (memcmp (&filedata[current_offset], "imagefs", 7) == 0))
1863
      else if ((current_offset + sizeof (image_header_t) < filesize) && (memcmp (&filedata[current_offset], "imagefs", 7) == 0))
1857
      {
1864
      {
Line 1888... Line 1895...
1888
            break;
1895
            break;
1889
         }
1896
         }
1890
 
1897
 
1891
         // locate the image trailer at the right offset
1898
         // locate the image trailer at the right offset
1892
         if (image_header->flags & IMAGE_FLAGS_TRAILER_V2)
1899
         if (image_header->flags & IMAGE_FLAGS_TRAILER_V2)
-
 
1900
         {
1893
            image_trailer_v2 = (image_trailer_v2_t *) &filedata[current_offset + image_header->image_size - sizeof (image_trailer_v2_t)];
1901
            imagetrailer_offset = current_offset + image_header->image_size - sizeof (image_trailer_v2_t);
-
 
1902
            image_trailer_v2 = (image_trailer_v2_t *) &filedata[imagetrailer_offset];
-
 
1903
         }
1894
         else // old V1 trailer
1904
         else // old V1 trailer
-
 
1905
         {
1895
            image_trailer_v1 = (image_trailer_v1_t *) &filedata[current_offset + image_header->image_size - sizeof (image_trailer_v1_t)];
1906
            imagetrailer_offset = current_offset + image_header->image_size - sizeof (image_trailer_v1_t);
-
 
1907
            image_trailer_v1 = (image_trailer_v1_t *) &filedata[imagetrailer_offset];
-
 
1908
         }
1896
 
1909
 
1897
         current_offset += sizeof (image_header_t); // jump over the image header and reach the first directory entry
1910
         current_offset += sizeof (image_header_t); // jump over the image header and reach the first directory entry
-
 
1911
 
-
 
1912
         // there may be padding before the first directory entry
1898
         if (image_header->dir_offset - sizeof (image_header_t) > 0)
1913
         if (image_header->dir_offset - sizeof (image_header_t) > 0)
1899
         {
-
 
1900
            hex_printf (&filedata[current_offset], image_header->dir_offset - sizeof (image_header_t), "\n%d extra bytes at offset 0x%zd (%zd):\n", image_header->dir_offset - sizeof (image_header_t), current_offset, current_offset);
1914
            hex_printf (&filedata[current_offset], image_header->dir_offset - sizeof (image_header_t), "\n%d padding bytes at offset 0x%zd (%zd):\n", image_header->dir_offset - sizeof (image_header_t), current_offset, current_offset);
1901
            current_offset += image_header->dir_offset - sizeof (image_header_t);
1915
         current_offset += image_header->dir_offset - sizeof (image_header_t); // padding was processed, jump over it
1902
         }
-
 
1903
 
1916
 
1904
         // dump all directory entries until the last one included
1917
         // dump all directory entries until the last one included
-
 
1918
         fsentries = NULL;
-
 
1919
         fsentry_count = 0;
1905
         while (&filedata[current_offset] < (uint8_t *) image_header + image_header->hdr_dir_size)
1920
         while (&filedata[current_offset] < (uint8_t *) image_header + image_header->hdr_dir_size)
1906
         {
1921
         {
1907
            current_fsentry = (fsentry_t *) &filedata[current_offset];
1922
            current_fsentry = (fsentry_t *) &filedata[current_offset];
1908
 
1923
 
1909
            if (imageheader_offset + image_header->hdr_dir_size - current_offset < sizeof (current_fsentry->header))
1924
            if (imageheader_offset + image_header->hdr_dir_size - current_offset < sizeof (current_fsentry->header))
1910
               break; // end padding reached
1925
               break; // end padding reached
1911
 
1926
 
-
 
1927
            // stack up the filesystem entry pointers in an array while we read them
-
 
1928
            reallocated_ptr = realloc (fsentries, (fsentry_count + 1) * sizeof (fsentry_t *));
-
 
1929
            if (reallocated_ptr == NULL)
-
 
1930
            {
-
 
1931
               fprintf (stderr, "fatal error: out of memory\n");
-
 
1932
               exit (1);
-
 
1933
            }
-
 
1934
            fsentries = reallocated_ptr;
-
 
1935
            fsentries[fsentry_count] = current_fsentry;
-
 
1936
            fsentry_count++;
-
 
1937
 
1912
            printf ("\n");
1938
            printf ("\n");
1913
            printf ("Filesystem entry at offset 0x%zx (%zd) - last one at 0x%zd (%zd):\n", current_offset, current_offset, imageheader_offset + image_header->hdr_dir_size, imageheader_offset + image_header->hdr_dir_size);
1939
            printf ("Filesystem entry at offset 0x%zx (%zd) - last one at 0x%zd (%zd):\n", current_offset, current_offset, imageheader_offset + image_header->hdr_dir_size, imageheader_offset + image_header->hdr_dir_size);
1914
            printf ("   size           = 0x%04x (%d) - size of dirent - %s\n", current_fsentry->header.size, current_fsentry->header.size, (current_offset + current_fsentry->header.size < filesize ? "looks good" : "BAD"));
1940
            printf ("   size           = 0x%04x (%d) - size of dirent - %s\n", current_fsentry->header.size, current_fsentry->header.size, (current_offset + current_fsentry->header.size < filesize ? "looks good" : "BAD"));
1915
            printf ("   extattr_offset = 0x%04x (%d) - %s\n", current_fsentry->header.extattr_offset, current_fsentry->header.extattr_offset, (current_fsentry->header.extattr_offset == 0 ? "no extattr" : "has extattr"));
1941
            printf ("   extattr_offset = 0x%04x (%d) - %s\n", current_fsentry->header.extattr_offset, current_fsentry->header.extattr_offset, (current_fsentry->header.extattr_offset == 0 ? "no extattr" : "has extattr"));
1916
            printf ("   ino            = 0x%08x (%d) - inode number (%s%s%s%s)\n", current_fsentry->header.ino, current_fsentry->header.ino, (current_fsentry->header.ino & 0xE0000000 ? "is" : "nothing special"), (current_fsentry->header.ino & IFS_INO_PROCESSED_ELF ? " PROCESSED_ELF" : ""), (current_fsentry->header.ino & IFS_INO_RUNONCE_ELF ? " RUNONCE_ELF" : ""), (current_fsentry->header.ino & IFS_INO_BOOTSTRAP_EXE ? " BOOTSTRAP_EXE" : ""));
1942
            printf ("   ino            = 0x%08x (%d) - inode number (%s%s%s%s)\n", current_fsentry->header.ino, current_fsentry->header.ino, (current_fsentry->header.ino & 0xE0000000 ? "is" : "nothing special"), (current_fsentry->header.ino & IFS_INO_PROCESSED_ELF ? " PROCESSED_ELF" : ""), (current_fsentry->header.ino & IFS_INO_RUNONCE_ELF ? " RUNONCE_ELF" : ""), (current_fsentry->header.ino & IFS_INO_BOOTSTRAP_EXE ? " BOOTSTRAP_EXE" : ""));
Line 1922... Line 1948...
1922
            if (S_ISDIR (current_fsentry->header.mode))
1948
            if (S_ISDIR (current_fsentry->header.mode))
1923
               printf ("   [DIRECTORY] path = \"%s\"\n", (char *) &current_fsentry->u.dir.path); // convert from pointer to char array
1949
               printf ("   [DIRECTORY] path = \"%s\"\n", (char *) &current_fsentry->u.dir.path); // convert from pointer to char array
1924
            else if (S_ISREG (current_fsentry->header.mode))
1950
            else if (S_ISREG (current_fsentry->header.mode))
1925
            {
1951
            {
1926
               printf ("   [FILE] offset = 0x%08x (%d) - %s\n", current_fsentry->u.file.offset, current_fsentry->u.file.offset, (imageheader_offset + current_fsentry->u.file.offset < filesize ? "looks good" : "BAD (IFS file too short)"));
1952
               printf ("   [FILE] offset = 0x%08x (%d) - %s\n", current_fsentry->u.file.offset, current_fsentry->u.file.offset, (imageheader_offset + current_fsentry->u.file.offset < filesize ? "looks good" : "BAD (IFS file too short)"));
1927
               printf ("   [FILE] size   = 0x%08x (%d) - %s\n", current_fsentry->u.file.offset, current_fsentry->u.file.offset, (imageheader_offset + current_fsentry->u.file.offset + current_fsentry->u.file.size < filesize ? "looks good" : "BAD (IFS file too short)"));
1953
               printf ("   [FILE] size   = 0x%08x (%d) - %s\n", current_fsentry->u.file.size, current_fsentry->u.file.size, (imageheader_offset + current_fsentry->u.file.offset + current_fsentry->u.file.size < filesize ? "looks good" : "BAD (IFS file too short)"));
1928
               printf ("   [FILE] path   = \"%s\"\n", (char *) &current_fsentry->u.file.path); // convert from pointer to char array
1954
               printf ("   [FILE] path   = \"%s\"\n", (char *) &current_fsentry->u.file.path); // convert from pointer to char array
1929
            }
1955
            }
1930
            else if (S_ISLNK (current_fsentry->header.mode))
1956
            else if (S_ISLNK (current_fsentry->header.mode))
1931
            {
1957
            {
1932
               printf ("   [SYMLINK] sym_offset = 0x%04x (%d) - %s\n", current_fsentry->u.symlink.sym_offset, current_fsentry->u.symlink.sym_offset, (sizeof (current_fsentry->header) + 2 * sizeof (uint16_t) + current_fsentry->u.symlink.sym_offset <= current_fsentry->header.size ? "looks good" : "BAD (dirent too short)"));
1958
               printf ("   [SYMLINK] sym_offset = 0x%04x (%d) - %s\n", current_fsentry->u.symlink.sym_offset, current_fsentry->u.symlink.sym_offset, (sizeof (current_fsentry->header) + 2 * sizeof (uint16_t) + current_fsentry->u.symlink.sym_offset <= current_fsentry->header.size ? "looks good" : "BAD (dirent too short)"));
1933
               printf ("   [SYMLINK] sym_size   = 0x%04x (%d) - %s\n", current_fsentry->u.symlink.sym_offset, current_fsentry->u.symlink.sym_offset, (sizeof (current_fsentry->header) + 2 * sizeof (uint16_t) + current_fsentry->u.symlink.sym_offset + current_fsentry->u.symlink.sym_size <= current_fsentry->header.size ? "looks good" : "BAD (dirent too short)"));
1959
               printf ("   [SYMLINK] sym_size   = 0x%04x (%d) - %s\n", current_fsentry->u.symlink.sym_size, current_fsentry->u.symlink.sym_size, (sizeof (current_fsentry->header) + 2 * sizeof (uint16_t) + current_fsentry->u.symlink.sym_offset + current_fsentry->u.symlink.sym_size <= current_fsentry->header.size ? "looks good" : "BAD (dirent too short)"));
1934
               printf ("   [SYMLINK] path       = \"%s\"\n", (char *) &current_fsentry->u.symlink.path); // convert from pointer to char array
1960
               printf ("   [SYMLINK] path       = \"%s\"\n", (char *) &current_fsentry->u.symlink.path); // convert from pointer to char array
1935
               printf ("   [SYMLINK] contents   = \"%s\"\n", ((char *) &current_fsentry->u.symlink.path) + current_fsentry->u.symlink.sym_offset); // convert from pointer to char array
1961
               printf ("   [SYMLINK] contents   = \"%s\"\n", ((char *) &current_fsentry->u.symlink.path) + current_fsentry->u.symlink.sym_offset); // convert from pointer to char array
1936
            }
1962
            }
1937
            else // can only be a device
1963
            else // can only be a device
1938
            {
1964
            {
1939
               printf ("   [DEVICE] dev  = 0x%08x (%d)\n", current_fsentry->u.device.dev, current_fsentry->u.device.dev);
1965
               printf ("   [DEVICE] dev  = 0x%08x (%d)\n", current_fsentry->u.device.dev, current_fsentry->u.device.dev);
1940
               printf ("   [DEVICE] rdev = 0x%08x (%d)\n", current_fsentry->u.device.rdev, current_fsentry->u.device.rdev);
1966
               printf ("   [DEVICE] rdev = 0x%08x (%d)\n", current_fsentry->u.device.rdev, current_fsentry->u.device.rdev);
1941
               printf ("   [DEVICE] path = \"%s\"\n", (char *) &current_fsentry->u.device.path); // convert from pointer to char array
1967
               printf ("   [DEVICE] path = \"%s\"\n", (char *) &current_fsentry->u.device.path); // convert from pointer to char array
1942
            }
1968
            }
1943
 
1969
 
1944
            current_offset += current_fsentry->header.size;
1970
            current_offset += current_fsentry->header.size;
1945
         }
1971
         }
1946
         if (imageheader_offset + image_header->hdr_dir_size - current_offset < sizeof (current_fsentry->header))
1972
         if (imageheader_offset + image_header->hdr_dir_size < current_offset + sizeof (current_fsentry->header))
1947
            hex_printf (&filedata[current_offset], imageheader_offset + image_header->hdr_dir_size - current_offset, "\n%d padding bytes at offset 0x%zx (%zd):\n", imageheader_offset + image_header->hdr_dir_size - current_offset, current_offset, current_offset);
1973
            hex_printf (&filedata[current_offset], imageheader_offset + image_header->hdr_dir_size - current_offset, "\n" "%d padding bytes at offset 0x%zx (%zd):\n", imageheader_offset + image_header->hdr_dir_size - current_offset, current_offset, current_offset);
-
 
1974
         current_offset += imageheader_offset + image_header->hdr_dir_size - current_offset; // padding was processed, jump over it
-
 
1975
 
-
 
1976
         // at this point we are past the directory entries; what is stored now, up to and until the image trailer, is the files' data
-
 
1977
         if (fsentry_count > 0)
-
 
1978
         {
-
 
1979
            while (current_offset < imagetrailer_offset) // and parse data up to the trailer
-
 
1980
            {
-
 
1981
               nearest_distance = SIZE_MAX;
-
 
1982
               nearest_index = SIZE_MAX;
-
 
1983
               for (fsentry_index = 0; fsentry_index < fsentry_count; fsentry_index++)
-
 
1984
                  if (S_ISREG (fsentries[fsentry_index]->header.mode) // if this directory entry a file (i.e. it has a data blob)...
-
 
1985
                      && (imageheader_offset + (size_t) fsentries[fsentry_index]->u.file.offset >= current_offset) // ... AND its data blob is still ahead of our current pointer ...
-
 
1986
                      && (imageheader_offset + (size_t) fsentries[fsentry_index]->u.file.offset - current_offset < nearest_distance)) // ... AND it's the closest to us we've found so far
-
 
1987
                  {
-
 
1988
                     nearest_distance = imageheader_offset + (size_t) fsentries[fsentry_index]->u.file.offset - current_offset; // then remember it
-
 
1989
                     nearest_index = fsentry_index;
-
 
1990
                  }
-
 
1991
               if (nearest_index == SIZE_MAX)
-
 
1992
                  break; // found no file ahead, which means we've parsed the whole file data area, so stop the loop so as to proceed to the image trailer
1948
 
1993
 
-
 
1994
               fsentry_index = nearest_index;
-
 
1995
               current_fsentry = fsentries[fsentry_index]; // quick access to closest fsentry
1949
 
1996
 
-
 
1997
               // there may be padding before the file data
-
 
1998
               if (imageheader_offset + (size_t) current_fsentry->u.file.offset - current_offset > 0)
1950
            // now jump at the first
1999
                  hex_printf (&filedata[current_offset], imageheader_offset + (size_t) current_fsentry->u.file.offset - current_offset, "\n" "%d padding bytes at offset 0x%zx (%zd):\n", imageheader_offset + (size_t) current_fsentry->u.file.offset - current_offset, current_offset, current_offset);
-
 
2000
               current_offset += imageheader_offset + (size_t) current_fsentry->u.file.offset - current_offset; // padding was processed, jump over it
1951
 
2001
 
-
 
2002
               printf ("\n");
-
 
2003
               printf ("File data blob at offset 0x%zx (%zd):\n", current_offset, current_offset);
-
 
2004
               printf ("   corresponding dirent index: %zd/%zd\n", fsentry_index, fsentry_count);
1952
         exit (0);
2005
               printf ("   corresponding inode 0x%08x (%d) - %s%s%s%s\n", current_fsentry->header.ino, current_fsentry->header.ino, (current_fsentry->header.ino & 0xE0000000 ? "is" : "nothing special"), (current_fsentry->header.ino & IFS_INO_PROCESSED_ELF ? " PROCESSED_ELF" : ""), (current_fsentry->header.ino & IFS_INO_RUNONCE_ELF ? " RUNONCE_ELF" : ""), (current_fsentry->header.ino & IFS_INO_BOOTSTRAP_EXE ? " BOOTSTRAP_EXE" : ""));
-
 
2006
               printf ("   corresponding path: \"%s\"\n", (char *) &current_fsentry->u.file.path); // convert from pointer to char array
-
 
2007
               printf ("   size 0x%zx (%zd) bytes\n", (size_t) current_fsentry->u.file.size, (size_t) current_fsentry->u.file.size);
-
 
2008
               printf ("   first 4 bytes: %02x%02x%02x%02x [%c%c%c%c] (%s)\n", (uint8_t) filedata[current_offset + 0], (uint8_t) filedata[current_offset + 1], (uint8_t) filedata[current_offset + 2], (uint8_t) filedata[current_offset + 3], (isprint (filedata[current_offset + 0]) ? filedata[current_offset + 0] : '.'), (isprint (filedata[current_offset + 1]) ? filedata[current_offset + 1] : '.'), (isprint (filedata[current_offset + 2]) ? filedata[current_offset + 2] : '.'), (isprint (filedata[current_offset + 3]) ? filedata[current_offset + 3] : '.'), (memcmp (&filedata[current_offset], "\x7f" "ELF", 4) == 0 ? "ELF binary" : (memcmp (&filedata[current_offset], "#!", 2) == 0 ? "shell script" : "???")));
-
 
2009
               printf ("   checksum %d\n", update_checksum32 (0, (uint32_t *) &filedata[current_offset], current_fsentry->u.file.size));
-
 
2010
 
-
 
2011
               current_offset += current_fsentry->u.file.size; // now jump over this file's data
-
 
2012
            }
-
 
2013
         }
-
 
2014
 
-
 
2015
         // ad this point we're past the last file data, there may be padding before the image trailer
-
 
2016
         if (imagetrailer_offset - current_offset > 0)
-
 
2017
            hex_printf (&filedata[current_offset], imagetrailer_offset - current_offset, "\n" "%d padding bytes at offset %zx (%zd):\n", imagetrailer_offset - current_offset, current_offset, current_offset);
-
 
2018
         current_offset += imagetrailer_offset - current_offset; // padding was processed, jump over it
-
 
2019
 
-
 
2020
         printf ("\n");
-
 
2021
         printf ("Image trailer at offset 0x%zx (%zd) - version %d:\n", current_offset, current_offset, (image_header->flags & IMAGE_FLAGS_TRAILER_V2 ? 2 : 1));
-
 
2022
         if (image_header->flags & IMAGE_FLAGS_TRAILER_V2)
-
 
2023
         {
-
 
2024
            for (byte_index = 0; byte_index < SHA512_DIGEST_LENGTH; byte_index++)
-
 
2025
               sprintf (&recorded_sha512[2 * byte_index], "%02x", image_trailer_v2->sha512[byte_index]);
-
 
2026
            strcpy (computed_sha512, SHA512 (image_header, (size_t) ((uint8_t *) image_trailer_v2 - (uint8_t *) image_header), NULL));
-
 
2027
            recorded_checksum = image_trailer_v2->cksum;
-
 
2028
            computed_checksum = update_checksum32 (0, (uint32_t *) image_header, sizeof (image_header) + image_header->image_size - sizeof (image_trailer_v2_t) + SHA512_DIGEST_LENGTH);
-
 
2029
            printf ("    sha512 = %s - %s\n", recorded_sha512, (strcasecmp (computed_sha512, recorded_sha512) == 0 ? "GOOD" : "BAD"));
-
 
2030
            printf ("    cksum = 0x%08x (%d) - %s\n", recorded_checksum, recorded_checksum, (computed_checksum == recorded_checksum ? "GOOD" : "BAD"));
-
 
2031
            if (strcasecmp (computed_sha512, recorded_sha512) != 0)
-
 
2032
               printf ("Computed SHA-512: %s\n", computed_sha512);
-
 
2033
            if (computed_checksum != recorded_checksum)
-
 
2034
               printf ("Computed cksum: 0x%08x (%d)\n", computed_checksum, computed_checksum);
-
 
2035
         }
-
 
2036
         else // old v1 trailer
-
 
2037
         {
-
 
2038
            recorded_checksum = image_trailer_v1->cksum;
-
 
2039
            computed_checksum = update_checksum32 (0, (uint32_t *) image_header, sizeof (image_header) + image_header->image_size - sizeof (image_trailer_v1_t));
-
 
2040
            printf ("    cksum = 0x%08x (%d) - %s\n", recorded_checksum, recorded_checksum, (computed_checksum == recorded_checksum ? "GOOD" : "BAD"));
-
 
2041
            if (computed_checksum != recorded_checksum)
-
 
2042
               printf ("Computed cksum: 0x%08x (%d)\n", computed_checksum, computed_checksum);
-
 
2043
         }
-
 
2044
 
-
 
2045
         current_offset += (image_header->flags & IMAGE_FLAGS_TRAILER_V2 ? sizeof (image_trailer_v2_t) : sizeof (image_trailer_v1_t)); // now reach the next segment (typically end of file)
1953
      }
2046
      }
1954
 
2047
 
1955
      // else it has to be a boot blob, of which we don't know the size, except that it has to fit in 0xffff bytes and be immediately followed by a startup header
2048
      // else it has to be a boot blob, of which we don't know the size, except that it has to fit in 0xffff bytes and be immediately followed by a startup header
1956
      else
2049
      else
1957
      {
2050
      {
1958
         // so scan for the first startup header magic and version (which makes us 6 bytes to scan for, i.e. "\xeb\x7e\xff\x00" for the magic and "\x01\x00" (LSB) for the version 1)
2051
         // so scan for the first startup header magic and version (which makes us 6 bytes to scan for, i.e. "\xeb\x7e\xff\x00" for the magic and "\x01\x00" (LSB) for the version 1)
Line 1960... Line 2053...
1960
            if (memcmp (&filedata[byte_index], "\xeb\x7e\xff\x00" "\x01\x00", 4 + 2) == 0)
2053
            if (memcmp (&filedata[byte_index], "\xeb\x7e\xff\x00" "\x01\x00", 4 + 2) == 0)
1961
               break; // stop as soon as we find it
2054
               break; // stop as soon as we find it
1962
 
2055
 
1963
         if (byte_index >= filesize - 6)
2056
         if (byte_index >= filesize - 6)
1964
            break; // if not found, stop scanning
2057
            break; // if not found, stop scanning
1965
 
2058
 
1966
         bootfile_blobsize = byte_index - current_offset;
2059
         bootfile_blobsize = byte_index - current_offset;
1967
         printf ("Boot blob at offset 0x%zx (%zd):\n", current_offset, current_offset);
2060
         printf ("Boot blob at offset 0x%zx (%zd):\n", current_offset, current_offset);
1968
         printf ("   size 0x%zx (%zd) bytes\n", bootfile_blobsize, bootfile_blobsize);
2061
         printf ("   size 0x%zx (%zd) bytes\n", bootfile_blobsize, bootfile_blobsize);
1969
         printf ("   checksum %d\n", update_checksum32 (0, (uint32_t *) &filedata[current_offset], bootfile_blobsize));
2062
         printf ("   checksum %d\n", update_checksum32 (0, (uint32_t *) &filedata[current_offset], bootfile_blobsize));
1970
 
2063
 
1971
         current_offset = byte_index; // now reach the next segment
2064
         current_offset = byte_index; // now reach the next segment
1972
      }
2065
      }
1973
   }
2066
   }
1974
 
2067
 
1975
   printf ("End of identifiable data reached.\n");
2068
   // at this point there's nothing left we're able to parse
1976
   if (current_offset < filesize)
2069
   if (current_offset < filesize)
-
 
2070
   {
-
 
2071
      printf ("End of identifiable data reached.\n");
1977
      hex_printf (&filedata[current_offset], filesize - current_offset, "\n%d extra bytes at offset %zx (%zd):\n", filesize - current_offset, current_offset, current_offset);
2072
      hex_printf (&filedata[current_offset], filesize - current_offset, "\n" "%d extra bytes at offset %zx (%zd):\n", filesize - current_offset, current_offset, current_offset);
1978
   printf ("End of file reached at offset 0x%zx (%zd).\n", filesize, filesize);
-
 
-
 
2073
   }
1979
 
2074
 
-
 
2075
   printf ("End of file reached at offset 0x%zx (%zd)\n", filesize, filesize);
-
 
2076
   printf ("IFS dissecation complete.\n");
1980
   return (0);
2077
   return (0);
1981
}
2078
}