连载20:可选头字段解释(下)
2020-03-10 本文已影响0人
码农UP2U
前两篇介绍了关于可选头的部分字段,本篇接着介绍可选头的剩余部分字段。
可选头剩余的字段介绍
可选头剩余的字段还有两个,最后一个字段体现了可选头中真正可选的部分了
- DWORD NumberOfRvaAndSizes:数据目录项的个数,该个数定义在 winnt.h 头文件中,其定义如下:
#define IMAGE_NUMBEROF_DIRECTORY_ENTRIES 16
根据该定义可以知道,数据目录的个数有 16 个。
- IMAGE_DATA_DIRECTORY DataDirectory[IMAGE_NUMBEROF_DIRECTORY_ENTRIES]:数据目录表,由 NumberOfRvaAndSize 个 IMAGE_DATA_DIRECOTRY 结构体组成的数组。该数组中包含了导入表、导出表、资源、重定位表等数据目录的 RVA 和大小。
IMAGE_DATA_DIRECTORY 的定义如下:
//
// Directory format.
//
typedef struct _IMAGE_DATA_DIRECTORY {
DWORD VirtualAddress;
DWORD Size;
} IMAGE_DATA_DIRECTORY, *PIMAGE_DATA_DIRECTORY;
结构体中的字段含义如下:
- VirtualAddress:数据目录项的 Rva
- Size:给出了该数据目录项的大小(以字节为单位)
因为它是一个数组,所有构成了一个数据目录表,然后各个数据目录的具体内容将根据该表的 Rva 来得到,该表中存储的内容有响应的索引,索引的定义如下:
// 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
比如,最上面的 0 表示的是导出表的索引,也就是在数据目录表的第 0 项中存放着导出表的 Rva 和 Size。
数据目录表的长度是 16,但是并不是每一项都有数据,比如通常 EXE 文件是没有导出表的,因此在数据目录表中的第 0 项的位置为全 0。也就是说,在 PE 文件中,有哪些数据,就会在对应的数据目录表中填入相应的 Rva 和 Size,而不需要的位置则为 0。那么,从这里来看,数据目录表中是否有值就是可选的了。
微信中搜索 “码农UP2U” 关注我的公众号吧!!!