I am working on a PE dissector and have come across something rather unusual. The names and order of directories in PE format seem different depending on where you look:
From PEReader (perdr) :
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 // Export Directory #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 // Import Directory #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 // Resource Directory #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 // Exception Directory #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 // Security Directory #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 // Base Relocation Table #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 // Debug Directory #define IMAGE_DIRECTORY_ENTRY_ARCHITECTURE 7 // Architecture Specific Data #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 // RVA of GP #define IMAGE_DIRECTORY_ENTRY_TLS 9 // TLS Directory #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 // Load Configuration Directory #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 // Bound Import Directory in headers #define IMAGE_DIRECTORY_ENTRY_IAT 12 // Import Address Table #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 // Delay Load Import Descriptors #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 // COM Runtime descriptor
In PEInfo (fixed to 0-base):
0 Export 1 Import 2 Resource 3 Exception 4 Security 5 Base Reloc 6 Debug 7 Copyright 8 Global Ptr 9 TLS 10 Load Config 11 Bound Import 12 IAT 13 COM 14 Delay Import 15 (reserved)
In CFF Explorer :
0 Export 1 Import 2 Resource 3 Exception 4 Security 5 Relocation 6 Debug 7 Architecture 8 (reserved) 9 TLS 10 Configuration 11 Bound Import 12 IAT 13 Delay Import 14 .NET MetaData
From WINE winnt.h :
#define IMAGE_DIRECTORY_ENTRY_EXPORT 0 #define IMAGE_DIRECTORY_ENTRY_IMPORT 1 #define IMAGE_DIRECTORY_ENTRY_RESOURCE 2 #define IMAGE_DIRECTORY_ENTRY_EXCEPTION 3 #define IMAGE_DIRECTORY_ENTRY_SECURITY 4 #define IMAGE_DIRECTORY_ENTRY_BASERELOC 5 #define IMAGE_DIRECTORY_ENTRY_DEBUG 6 #define IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 #define IMAGE_DIRECTORY_ENTRY_GLOBALPTR 8 #define IMAGE_DIRECTORY_ENTRY_TLS 9 #define IMAGE_DIRECTORY_ENTRY_LOAD_CONFIG 10 #define IMAGE_DIRECTORY_ENTRY_BOUND_IMPORT 11 #define IMAGE_DIRECTORY_ENTRY_IAT 12 #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14
Here they are presented in table form:
+------+-------------------+-------------------+-------------------+-------------------+ | Dir# | WINE winnt.h | PEReader | PEInfo | CFF Explorer | +------+-------------------+-------------------+-------------------+-------------------+ | 0 | Export | Export | Export | Export | | 1 | Import | Import | Import | Import | | 2 | Resource | Resource | Resource | Resource | | 3 | Exception | Exception | Exception | Exception | | 4 | Security | Security | Security | Security | | 5 | Relocation | Relocation | Relocation | Relocation | | 6 | Debug | Debug | Debug | Debug | | 7 | Copyright | Architecture | Copyright | Architecture | | 8 | Global Ptr | Global Ptr | Global Ptr | (reserved) | | 9 | TLS | TLS | TLS | TLS | | 10 | Load Config | Load Config | Load Config | Load Config | | 11 | Bound Import | Bound Import | Bound Import | Bound Import | | 12 | IAT | IAT | IAT | IAT | | 13 | Delay Import | Delay Import | COM | Delay Import | | 14 | COM Descriptor | COM Descriptor | Delay Import | .NET MetaData | | 15 | - | - | (reserved) | - | +------+-------------------+-------------------+-------------------+-------------------+
The numbering and order of them does not seem to fit properly. In both PEReader and winnt.h, record 14 is a COM descriptor, but in CFF Explorer it appears as .NET MetaData. It seems that both COM and Delay Import entries are also included.
It seems strange that some of these tools will get it wrong. Which one is correct? Is a new definition missing?
source share