如何定位导出表?
- 在扩展PE头(IMAGE_OPTIONAL_HEADER)的最后一个结构体成员有16张表(导出表、导入表、资源表等)。
- 所以能从其中找到IMAGE_DIRECTORY_ENTRY_EXPORT(其中存放了导出表的位置)。
导出表结构
typedef struct _IMAGE_EXPORT_DIRECTORY {
DWORD Characteristics;
DWORD TimeDateStamp;
WORD MajorVersion;
WORD MinorVersion;
DWORD Name;
DWORD Base;
DWORD NumberOfFunctions;
DWORD NumberOfNames;
DWORD AddressOfFunctions; // RVA from base of image
DWORD AddressOfNames; // RVA from base of image
DWORD AddressOfNameOrdinals; // RVA from base of image
} IMAGE_EXPORT_DIRECTORY, *PIMAGE_EXPORT_DIRECTORY;
成员 |
说明 |
Characteristics |
未使用 |
TimeDateStamp |
时间戳 |
MajorVersion |
未使用 |
MinorVersion |
未使用 |
Name |
指向该导出表文件名字符串 |
Base |
导出函数起始序号 |
NumberOfFunctions |
所有导出函数的个数 |
NumberOfNames |
以函数名字导出的函数个数 |
AddressOfFunctions |
导出函数地址表RVA |
AddressOfNames |
导出函数名称表RVA |
AddressOfNameOrdinals |
导出函数序号表RVA |
定位导出表
首先找到扩展PE头
- 扩展PE头的最后一个成员是一个结构体数组,数组中有16个成员也就是16张表,每个结构体宽度是8个字节。
- 导出表就在第一个结构体中。
- 从后往前数8行,每行16个字节,每个结构体宽度是8个字节。
找到导出表
- 导出表真正的位置由前4个字节决定。
- 导出表真正的数据一共有多少由后4个字节决定。
- 注意这里是RVA,如果内存对齐和文件对齐不同,需要将RVA转换为FOV。