Skip to content

Data Directories

The Optional header ends with an array of 16 IMAGE_DATA_DIRECTORY entries, each an RVA and a size, that point to the file's important tables. Each directory has its own page:

# Directory What it holds CLI GUI node
0 Export Functions a DLL exposes, forwarders --exports DIR_ENTRY_EXPORT
1 Import DLLs and functions the file needs --imports DIR_ENTRY_IMPORT
2 Resource Icons, version info, manifests, payloads --resources DIR_ENTRY_RESOURCE
3 Exception x64/ARM64 function table and unwind data --exception DIR_ENTRY_EXCEPTION
4 Security Authenticode signatures (file offset, not RVA) --security DIR_ENTRY_SECURITY
5 Base relocation Fix-ups for loading at another base; rebase preview --basereloc DIR_ENTRY_BASERELOC
6 Debug PDB path, POGO, repro --debug DIR_ENTRY_DEBUG
7 Architecture Reserved, must be zero --dirs Data Directories
8 Global pointer GP register value (MIPS/IA-64) --dirs Data Directories
9 TLS Thread-local storage and callbacks --tls DIR_ENTRY_TLS
10 Load config CFG, SafeSEH, security cookie --loadconfig DIR_ENTRY_LOAD_CONFIG
11 Bound import Pre-resolved import timestamps --bound-imports DIR_ENTRY_BOUND_IMPORT
12 IAT Import address table --dirs, --imports Data Directories / Import FT
13 Delay import Imports loaded on first call --delay-imports DIR_ENTRY_DELAY_IMPORT
14 COM descriptor .NET CLR header and metadata --net DIR_ENTRY_COM_DESCRIPTOR
15 Reserved Must be zero --dirs Data Directories

Tip

ppee-cli --dirs prints the whole table; Optional Header → Data Directories shows it in the GUI. Architecture (7) and Reserved (15) must be zero, and Global Pointer (8) must have size 0. In the GUI a violation is marked as an error in the Data Directories list, so it stands out; in JSON, compare DataDirectory[7|8|15] yourself.

Windows screenshot: The Data Directories list: each directory's RVA, size and the section it lands in, with empty directories greyed out

The Data Directories list: each directory's RVA, size and the section it lands in, with empty directories greyed out

Optional Header → Data Directories for a shellcode loader (86c6bd80….exe). Seven directories are present, each with the section it lands in; the empty ones are greyed out. No Security entry means the file is unsigned, and no TLS means nothing runs before the entry point, so steps 1 and 3 of the triage below are already answered.

A triage order for unknown samples

Step Directory Question it answers
1 Security Signed? By whom? Modified after signing?
2 Import + Delay Import What can it do? Is it packed (tiny import table)?
3 TLS Does code run before the entry point?
4 Resource Embedded payloads, fake version info, lure icons?
5 COM Descriptor Is it .NET? Obfuscated? Mixed-mode?
6 Export How is a DLL started? Sideloading or proxying?
7 Debug PDB path for attribution; stripped?
8 Load Config + Exception Real compiler output, or protector-damaged tables?
9 Base Relocation ASLR-capable? Dump or rebase analysis

The same data is available to scripts (ppee-cli --json) and to AI assistants (MCP), so this order can be automated. See the CI policy gates for a ready-made example.

References