Data Directories
The Data Directories (IMAGE_DATA_DIRECTORY) is the last member of the Optional Header. It is an array with a data type of IMAGE_DATA_DIRECTORY, and contains up to 16 structures.
For context and review, remember that the Optional Header itself is the last (and most important) part of the NT Headers within a PE file.
PE-Bear parses the Data Directories for us:
![View of the Data Directories parsed with PE-Bear](https://offwhitesecurity.dev/wp-content/uploads/2023/10/Data-directories.webp)
The array has a size of IMAGE_NUMBEROF_DIRECTORY_ENTRIES:
IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES];
Which is set to a constant of 16:
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
Each IMAGE_DATA_DIRECTORY struct has two members, VirtualAddress and Size:
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
- VirtualAddress is a relative virtual address (RVA) that points to the start of the data directory.
- Size is the size of the data directory in bytes.
Table of Data Directories
Data directories contain information used by the PE loader. Each data directory has an index and a specified offset:
Index | Offset (PE/PE32+) | Name | Description |
---|---|---|---|
0 | 96/112 | IMAGE_DIRECTORY_ENTRY_EXPORT | Export table |
1 | 104/120 | IMAGE_DIRECTORY_ENTRY_IMPORT | Import table |
2 | 112/128 | IMAGE_DIRECTORY_ENTRY_RESOURCE | Resource table |
3 | 120/136 | IMAGE_DIRECTORY_ENTRY_EXCEPTION | Exception table |
4 | 128/144 | IMAGE_DIRECTORY_ENTRY_SECURITY | Certificate table |
5 | 136/152 | IMAGE_DIRECTORY_ENTRY_BASERELOC | Base relocation table |
6 | 144/160 | IMAGE_DIRECTORY_ENTRY_DEBUG | Debugging information |
7 | 152/168 | IMAGE_DIRECTORY_ENTRY_ARCHITECTURE / IMAGE_DIRECTORY_ENTRY_COPYRIGHT | Architecture-specific data address Used in x86 |
8 | 160/176 | IMAGE_DIRECTORY_ENTRY_GLOBALPTR | Global pointer register RVA |
9 | 168/184 | IMAGE_DIRECTORY_ENTRY_TLS | Thread local storage (TLS) table |
10 | 176/192 | IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG | Load configuration table |
11 | 184/200 | IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT | Bound import table |
12 | 192/208 | IMAGE_DIRECTORY_ENTRY_IAT | Import address table |
13 | 200/216 | IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT | Delay import descriptor |
14 | 208/224 | IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR | CLR header; present if file contains a .NET assembly |
15 | 216/232 | Reserved |
Of these, the most important are the Export Directory (IMAGE_DIRECTORY_ENTRY_EXPORT – index 0) and the Import Address Table (IMAGE_DIRECTORY_ENTRY_IAT).
Export Directory
The export directory is typically found in DLLs that export functions. It’s a data structure that contains the addresses of the exported functions and variables. These addresses can then be used by other executable files in order to access the exported functions, variables, and data.
Import Address Table
The import address table (IAT) contains information about functions imported from other executables. The addresses in the table are used to access the functions and data from the other executable files.