Welcome to my blog dear reader. This is another post in my Windows PE analysis series.
The DataDirectory is the final 128 bytes of the OptionalHeader, which in turn is the final member of the PE header IMAGE_NT_HEADERS as discussed in a previous post.
The DataDirectory is an array of 16 IMAGE_DATA_DIRECTORY structures, 8 bytes apiece, each relating to an important data structure in the PE file. The structure has 2 members which contain the location and size of the data structure in question:
IMAGE_DATA_DIRECTORY STRUCT
VirtualAddress DWORD //relative virtual address (RVA) of the data structure
isize DWORD //contains the size in bytes of the data structure
IMAGE_DATA_DIRECTORY ENDS
The 16 directories to which these structures refer are themselves defined in winnt.h as shown below.
IMAGE_DIRECTORY_ENTRY_EXPORT DWORD
IMAGE_DIRECTORY_ENTRY_IMPORT DWORD
IMAGE_DIRECTORY_ENTRY_RESOURCE DWORD
IMAGE_DIRECTORY_ENTRY_EXCEPTION DWORD
IMAGE_DIRECTORY_ENTRY_SECURITY DWORD
IMAGE_DIRECTORY_ENTRY_BASERELOC DWORD
IMAGE_DIRECTORY_ENTRY_DEBUG DWORD
IMAGE_DIRECTORY_ENTRY_COPYRIGHT DWORD
IMAGE_DIRECTORY_ENTRY_GLOBALPTR DWORD
IMAGE_DIRECTORY_ENTRY_TLS DWORD
IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG DWORD
IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT DWORD
IMAGE_DIRECTORY_ENTRY_IAT DWORD
IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT DWORD
IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR DWORD
IMAGE_NUMBEROF_DIRECTORY_ENTRIES DWORD
This directory is described in details in the table below. Take note that the offset is relative to the start of the DataDirectory.
Offset | Size | Field Name | Description | Possible Values |
00h | DWORD | Export VirtualAddress | Starting RVA of the export table | |
04h | DWORD | Export Size | Size of the export table |
|
08h | DWORD | Import VirtualAddress | Starting RVA of the import table | |
0Ch | DWORD | Import Size | Size of the import table | |
10h | DWORD | Resource VirtualAddress | Starting RVA of the resource table |
|
14h | DWORD | Resource Size | Size of the resource table |
|
18h | DWORD | Exception VirtualAddress | Starting RVA of the exception table |
|
1Ch | DWORD | Exception Size | Size of the exception table | |
20h | DWORD | Certificate VirtualAddress | Starting RVA of the certificate table |
|
24h | DWORD | Certificate Size | Size of the certificate table | |
28h | DWORD | BaseRelocation VirtualAddress | Starting RVA of the BaseRelocation table | |
2Ch | DWORD | BaseRelocation Size | Size of the BaseRelocation table | |
30h | DWORD | Debug VirtualAddress | Starting RVA of the debug directory | |
34h | DWORD | Debug Size | Size of the debug directory |
|
38h | DWORD | Architecture VirtualAddress | Starting RVA of architecture-specific data |
|
3Ch | DWORD | Architecture Size | Size of the architecture-specific data |
|
40h | DWORD | GlobalPtr VirtualAddress | Starting RVA of the GlobalPtr register |
|
44h | DWORD | GlobalPtr Size | Size of the GlobalPtr register |
|
48h | DWORD | TLS VirtualAddress | Starting RVA of the thread local storage (TLS) table | |
4Ch | DWORD | TLS Size | Size of the TLS table |
|
50h | DWORD | LoadConfig VirtualAddress | Starting RVA of the load configuration table |
|
54h | DWORD | LoadConfig Size | Size of the load configuration table |
|
58h | DWORD | BoundImport VirtualAddress | Starting RVA of the bound import table | |
5Ch | DWORD | BoundImport Size | Size of the bound import table | |
60h | DWORD | IAT VirtualAddress | Starting RVA of the import address table (IAT) |
|
64h | DWORD | IAT Size | Size of the import address table |
|
68h | DWORD | DelayImport VirtualAddress | Starting RVA of the delay load import descriptor |
|
6Ch | DWORD | DelayImport Size | Size of the delay load import descriptor |
|
70h | DWORD | Reserved |
|
|
The IMAGE_DATA_DIRECTORY array makes it easy for the PE loader to find a particular section of the image without needing to go through each of the image sections and compare section names as it parses the image sections.
The data directory for our example executable contains only 4 members (highlighted). The 12 unused ones are shown filled with zeros as shown below using LordPE.
For example, in the above picture the "import table" fields contain the Relative Virtual Address (RVA) and size of the IMAGE_IMPORT_DESCRIPTOR array - the Import Directory. In the hex editor, the picture below shows the PE header with the data directory outlined in red. Each box represents one IMAGE_DATA_DIRECTORY structure, the first DWORD being VirtualAddress and the last being isize.
The Import Directory is highlighted in pink. The first 4 bytes are the RVA 2D000h (in reverse order). The size of the Import Directory is 181Eh bytes. The position of these data directories from the beginning of the PE header is always the same i.e. the DWORD 80 bytes from the beginning of the PE header is always the RVA to the Import Directory.
To locate a particular directory, you determine the relative address from the data directory. Then use the virtual address to determine which section the directory is in. Once you determine which section contains the directory, the section header for that section is then used to find the exact offset.
Post a Comment