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 |
|
1079 | const fsentry_t *entry_a = (const fsentry_t *) a; |
1080 |
|
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 |
1089 | // qsort() callback that compares two imagefs filesystem entries and sort them by increasing data size |
1090 | 1090 | ||
1091 |
|
1091 | const fsentry_t *entry_a = (const fsentry_t *) a; |
1092 |
|
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 ( |
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 |
|
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 |
|
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 |
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 |
|
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 *) ¤t_fsentry->u.dir.path); // convert from pointer to char array |
1949 | printf (" [DIRECTORY] path = \"%s\"\n", (char *) ¤t_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. |
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 *) ¤t_fsentry->u.file.path); // convert from pointer to char array |
1954 | printf (" [FILE] path = \"%s\"\n", (char *) ¤t_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. |
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 *) ¤t_fsentry->u.symlink.path); // convert from pointer to char array |
1960 | printf (" [SYMLINK] path = \"%s\"\n", (char *) ¤t_fsentry->u.symlink.path); // convert from pointer to char array |
1935 | printf (" [SYMLINK] contents = \"%s\"\n", ((char *) ¤t_fsentry->u.symlink.path) + current_fsentry->u.symlink.sym_offset); // convert from pointer to char array |
1961 | printf (" [SYMLINK] contents = \"%s\"\n", ((char *) ¤t_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 *) ¤t_fsentry->u.device.path); // convert from pointer to char array |
1967 | printf (" [DEVICE] path = \"%s\"\n", (char *) ¤t_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 |
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 |
|
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 |
|
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 *) ¤t_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 |
|
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 | } |