2008-03-26
| Table of Contents: |
| Rate This Article: | Add This Article To: |
( Page 4 of 4 )
Tour a PE file's resource section
Let's reinforce our understanding of the resource section's organization by touring an example PE file, such as Windows XP's notepad.exe. To prepare for the tour, I dumped the contents of this file's resource section to another file and
used the old MS-DOS DEBUG program to present that file's content, beginning with the root directory:
0C53:0100 00 00 00 00 00 00 00 00-00 00 00 00 00 00 08 00 ................
0C53:0110 03 00 00 00 50 00 00 80-04 00 00 00 A8 00 00 80 ....P...........
0C53:0120 05 00 00 00 C0 00 00 80-06 00 00 00 F0 00 00 80 ................
0C53:0130 09 00 00 00 20 01 00 80-0E 00 00 00 40 01 00 80 .... .......@...
0C53:0140 10 00 00 00 58 01 00 80-18 00 00 00 70 01 00 80 ....X.......p...
| Note |
|---|
DEBUG presents content in a sequence of rows, where each row begins with an address presented in a 16-bit
segment:16-bit offset format. Furthermore, each row presents 16 byte-values followed by the ASCII values corresponding to
those bytes. (The ASCII values are handy for observing string data.) Addresses and byte values are shown in hexadecimal.
|
The root directory begins at 0C53:0100 with its four-byte Characteristics field. This field is
followed by a four-byte TimeDateStamp field, a two-byte MajorVersion field, and a two-byte MinorVersion field. All of these fields contain 0s and aren't relevant to retrieving resources.
The two-byte NumberOfNamedEntries field comes next (beginning at 0C53:010C). This field contains 0,
which means that there are no named resource type directories. Immediately following NumberOfNamedEntries is the
two-byte NumberOfIdEntries field, which contains 8 -- there are eight type directories identified by integer
IDs.
| Note |
|---|
| PE files store multi-byte values such that the least-significant byte is stored first. |
The eight type directories are described by eight IMAGE_RESOURCE_DIRECTORY structures that begin at 0C53:0110. The first four bytes of each structure store the contents of the Name field; the next
four structure bytes store the OffsetToData field's value. Table 2 presents and interprets the contents of all
eight structures.
| Structure Address | Name Field Value | OffsetToData Field Value | Interpretation |
|---|---|---|---|
0C53:0110 | 00000003 | 80000050 | Name's value identifies the RT_ICON resource type. OffsetToData's value identifies an offset to the
icon type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+50=0C53:0150.
|
0C53:0118 | 00000004 | 800000A8 | Name's value identifies the RT_MENU resource type. OffsetToData's value identifies an offset to the
menu type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+A8=0C53:01A8.
|
0C53:0120 | 00000005 | 800000C0 | Name's value identifies the RT_DIALOG resource type. OffsetToData's value identifies an offset to
the dialog type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+C0=0C53:01C0.
|
0C53:0128 | 00000006 | 800000F0 | Name's value identifies the RT_STRING resource type. OffsetToData's value identifies an offset to
the string type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+F0=0C53:01F0.
|
0C53:0130 | 00000009 | 80000120 | Name's value identifies the RT_ACCELERATOR resource type. OffsetToData's value identifies an offset
to the accelerator type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+120=0C53:0220.
|
0C53:0138 | 0000000E | 80000140 | Name's value identifies the RT_GROUP_ICON resource type. OffsetToData's value identifies an offset
to the group icon type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+140=0C53:0240.
|
0C53:0140 | 00000010 | 80000158 | Name's value identifies the RT_VERSION resource type. OffsetToData's value identifies an offset to
the version type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+158=0C53:0258.
|
0C53:0148 | 00000018 | 80000170 | Name's value identifies the RT_MANIFEST resource type. OffsetToData's value identifies an offset to
the manifest type directory's IMAGE_RESOURCE_DIRECTORY structure, which is located at 0C53:0100+170=0C53:0270.
|
Table 2: Root directory resource type directory entries
For brevity, we'll tour only the RT_GROUP_ICON and RT_ICON type directories, the group icon and icon instance directories
pointed to by these type directories, and the resource data areas pointed to by these instance directories. Furthermore,
because notepad.exe contains several RT_ICON resources, we'll look at only one icon instance directory and its
associated data area.
The group icon type directory begins at 0C53:0240. According to the following DEBUG output, NumberOfNamedEntries (at 0C53:024C) is 0; NumberOfIdEntries (at 0C53:024E) identifies one type directory entry. This entry's Name field (at 0C53:0250)
specifies integer ID 2 as the identity of a group icon instance directory:
0C53:0240 00 00 00 00 00 00 00 00-00 00 00 00 00 00 01 00 ................
0C53:0250 02 00 00 00 68 03 00 80 ....h...
Additionally, the entry's OffsetToData field (at 0C53:0254) identifies an offset to the group icon
instance directory's IMAGE_RESOURCE_DIRECTORY structure. After removing the most-significant bit from 80000368, adding 368 to 0C53:0100 yields the address of this structure -- 0C53:0468:
0C53:0460 00 00 00 00 00 00 00 00 ........
0C53:0470 00 00 00 00 00 00 01 00-09 04 00 00 F0 04 00 00 ................
Unlike a resource type directory, which can access multiple resource instance directories via the type directory's entries, a
resource instance directory will only access a single data area via its single directory entry. This is verified above by the
contents of the group icon instance directory's NumberOfIdEntries field, which is located at 0C53:476.
The group icon instance directory's single entry begins at 0C53:0478. Its Name field contains 00000409, which provides the 409 integer ID for this group icon. Its OffsetToData field contains 000004F0, which (because the most-significant bit isn't set) locates the group icon's IMAGE_RESOURCE_DATA_ENTRY structure.
The IMAGE_RESOURCE_DATA_ENTRY structure's address is 0C53:0100+4F0, or 0C53:05F0. As indicated by the following DEBUG output, the structure's four-byte OffsetToData field contains 000119F8, and the structure's four-byte Size field
contains 00000084 -- the other two fields don't matter:
0C53:05F0 F8 19 01 00 84 00 00 00-00 00 00 00 00 00 00 00 ................
Unlike previous offsets, 000119F8 is an RVA. You cannot add this value to 0C53:0100 as is. Instead,
you first need to subtract the resource section's starting RVA, which happens to be B000, from this value. You
then add the difference to 0C53:0100. This calculation results in 0C53:6AF8 as the address of the
group icon's resource data:
0C53:6AF0 00 00 01 00 09 00 30 30 ......00
0C53:6B00 10 00 01 00 04 00 68 06-00 00 01 00 20 20 10 00 ......h..... ..
0C53:6B10 01 00 04 00 E8 02 00 00-02 00 10 10 10 00 01 00 ................
0C53:6B20 04 00 28 01 00 00 03 00-30 30 00 00 01 00 08 00 ..(.....00......
0C53:6B30 A8 0E 00 00 04 00 20 20-00 00 01 00 08 00 A8 08 ...... ........
0C53:6B40 00 00 05 00 10 10 00 00-01 00 08 00 68 05 00 00 ............h...
0C53:6B50 06 00 30 30 00 00 01 00-20 00 A8 25 00 00 07 00 ..00.... ..%....
0C53:6B60 20 20 00 00 01 00 20 00-A8 10 00 00 08 00 10 10 .... .........
0C53:6B70 00 00 01 00 20 00 68 04-00 00 09 00 .... .h.....
If you recall the previous section on resource data formats, an RT_GROUP_ICON resource's data is formatted into an ICOHEADER structure followed by an array of ICODIRENTRY structures. The header's two-byte wNumImages field (located above at 0C53:6AFC) identifies the number of array entries, which happens
to be nine.
Each ICODIRENTRY structure contains a two-byte wID field that stores the integer ID of the
associated RT_ICON resource. Each RT_ICON describes one of the related images that are stored in an .ico file --
multiple images are stored to account for different screen resolutions. Table 3 lists the addresses and values of the group
icon's wID fields.
| Address | Value |
|---|---|
0C53:6B0A | 1 |
0C53:6B18 | 2 |
0C53:6B26 | 3 |
0C53:6B34 | 4 |
0C53:6B42 | 5 |
0C53:6B50 | 6 |
0C53:6B5E | 7 |
0C53:6B6C | 8 |
0C53:6B7A | 9 |
Table 3: ICODIRENTRY wID field addresses and their ID values
The icon type directory begins at 0C53:0150. According to the following DEBUG output, NumberOfIdEntries (at 0C53:015E) identifies nine type directory entries, whose Name fields store integer IDs -- there are no named entries. All nine entries ultimately reference resource data that's associated
with the previous group icon resource:
0C53:0150 00 00 00 00 00 00 00 00-00 00 00 00 00 00 09 00 ................
0C53:0160 01 00 00 00 88 01 00 80-02 00 00 00 A0 01 00 80 ................
0C53:0170 03 00 00 00 B8 01 00 80-04 00 00 00 D0 01 00 80 ................
0C53:0180 05 00 00 00 E8 01 00 80-06 00 00 00 00 02 00 80 ................
0C53:0190 07 00 00 00 18 02 00 80-08 00 00 00 30 02 00 80 ............0...
0C53:01A0 09 00 00 00 48 02 00 80 ....H...
The first directory entry (at 0C53:0160) identifies an icon resource whose integer ID is 1. This entry
corresponds to the ICODIRENTRY structure whose wID field also contains 1. The directory entry's OffsetToData field contains 80000188, which locates the icon instance directory's IMAGE_RESOURCE_DIRECTORY structure at 0C53:0288:
0C53:0280 00 00 00 00 00 00 00 00 ........
0C53:0290 00 00 00 00 00 00 01 00-09 04 00 00 B0 03 00 00 ................
The NumberOfIdEntries field (at 0C53:0296) identifies a single resource instance directory entry
(as it should be). The entry's Name field (at 0C53:0298) specifies 409 as the icon's ID. Also, the
entry's OffsetToData field specifies 000003B0, which is added to 0C53:0100 to
determine the IMAGE_RESOURCE_DATA_ENTRY structure's address:
0C53:04B0 10 B8 00 00 68 06 00 00-00 00 00 00 00 00 00 00 ....h...........
To determine the resource data's address, you need to subtract B000 from the 0000B810 RVA, and add
the result to 0C53:0100. The resulting address is 0C53:0910. The 16 bytes beginning at this address
specify part of a BITMAPINFOHEADER structure, which is identified by the initial 28 byte value
(indicating the structure's size):
0C53:0910 28 00 00 00 30 00 00 00-60 00 00 00 01 00 04 00 (...0...`.......
![]() |
|


