4

我正在研究 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-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)

CFF 资源管理器中:

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 元数据。COM 和延迟导入条目似乎也被切换了。

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

4

3 回答 3

7

您不必使用任何未记录的内容。在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 function

于 2011-12-28T16:24:52.747 回答
3

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

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

最后一个条目被描述为 CLR 运行时标头,如果我没记错的话,它曾经有不同的含义(这就是为什么有人称它为 COM 描述符),但现在用于指向 CLR 元数据。

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

于 2011-12-28T16:07:31.503 回答
0

事实上,目录顺序是固定的,如 winnt.h 中所定义。甚至 COM、Delay Import 和 .NET Metadata 在目录表中都有固定的位置!一些工具以自己的名称和顺序显示目录。表示的方式与 PE 规范无关。

于 2011-12-28T17:12:28.593 回答