PE目录的名称

我正在研究PE解剖器,遇到了一些相当不寻常的事情。 PE格式的目录的名称和顺序似乎根据你的外观而有所不同:

来自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 

在PEInfo中 (更正为0):

 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) 

在CFF资源pipe理器中 :

 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 

来自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 /* (MIPS GP) */ #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 /* Import Address Table */ #define IMAGE_DIRECTORY_ENTRY_DELAY_IMPORT 13 #define IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR 14 

在这里,他们是一个表格:

 +------+-------------------+-------------------+-------------------+-------------------+ | Dir# | WINE's 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) | - | +------+-------------------+-------------------+-------------------+-------------------+ 

这些编号和顺序似乎不合适。 在PEReader和winnt.h中,条目14是COM描述符,但是在CFF Explorer中显示为.NET MetaData。 COM和延迟导入条目似乎也得到了切换。

这些工具中有几个会出错,这似乎很奇怪。 哪一个是正确的? 我错过了一个更新的定义吗?

你不必使用任何无证的东西。 在Windows SDK附带的WinNT.h文件(一旦安装,在我的机器上它在C:\ Program Files文件(x86)\ Microsoft SDKs \ Windows \ v7.0A \ Include)中找到正确的:

 // Directory Entries #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 // IMAGE_DIRECTORY_ENTRY_COPYRIGHT 7 // (X86 usage) #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 

WINE和PEReader的定义只是(正确地我相信)从这个.h文件借用。

这里还有一个提到: ImageDirectoryEntryToDataEx函数

PE规格由MS记录,您最好的选择是他们在pecoff.doc中提供的信息:

http://msdn.microsoft.com/en-us/windows/hardware/gg463119.aspx

最后一项被描述为CLR Runtime Header,如果我没有记错的话它有不同的含义(这就是为什么有人把它称为COM描述符),但是现在被用来指向CLR元数据。

最后三个的顺序是IAT,DelayImport,CLR。 其他任何事情都是错的,目录显然不会奇迹般地转移。

事实上,目录顺序是固定的,如winnt.h中所定义。 即使COM,延迟导入和.NET元数据在目录表中都有一个固定的位置! 一些工具用自己的名字和顺序显示目录。 所代表的方式与PE规范无关。