【PE文件】导入表

导入表位置

IMAGE_NT_HEADERS.IMAGE_OPTIONAL_HEADER32.IMAGE_DATA_DIRECTORY_ARRAY[1].VirtualAddress

导入表结构

导入表以一个 IMAGE_IMPORT_DESCRIPTOR(IID)数组开始。每个导入的DLL都对应一个IID结构体。最后以一个全0的IID结构体结束。

 1 struct _IMAGE_IMPORT_DESCRIPTOR
 2 {
 3     0x00 union
 4     {
 5         0x00 DWORD Characteristics;
 6         0x00 PIMAGE_THUNK_DATA OriginalFirstThunk;    //RVA:INT(导入名称表)
 7     } u;
 8     0x04 DWORD TimeDateStamp;
 9     0x08 DWORD ForwarderChain;
10     0x0c DWORD Name;                                  //RVA:DLL 名称
11     0x10 PIMAGE_THUNK_DATA FirstThunk;                //RVA:IAT(导入地址表)
12 };

INT和IAT指向一个相同类型的 IMAGE_THUNK_DATA(ITD)结构体数组,该数组以一个全0结构体结尾。该结构体与导入函数相对应,有多少个ITD结构体就有多少个函数被导入。

 1 struct _IMAGE_THUNK_DATA
 2 {
 3     union
 4     {
 5         0x00 LPBYTE ForwarderString;
 6         0x00 PDWORD Function;
 7         0x00 DWORD Ordinal;                          //函数序号
 8         0x00 PIMAGE_IMPORT_BY_NAME AddressOfData;    //RVA:IMAGE_IMPORT_BY_NAME
 9     } u1;
10 };

当IMAGE_THUNK_DATA 结构体:最高位为1时,表示函数以序号导入,此时低31位被看成函数序号使用。
当IMAGE_THUNK_DATA 结构体:最高位为0时,表示函数以名称导入,此时AddressOfData是一个指向 IMAGE_IMPORT_BY_NAME 结构体的Rva。

1 struct _IMAGE_IMPORT_BY_NAME 
2 {
3     0x00 WORD Hint;           //2字节
4     0x02 BYTE Name[1];        //n字节 函数名称字符串
5 };

PE文件加载前:INT和IAT指向的IMAGE_THUNK_DATA 结构体存储着相同内容(导入函数的名称或序号)
PE文件加载后:IAT指向导入函数的实际调动地址。

posted @ 2019-07-16 01:11  SunsetR  阅读(1036)  评论(0编辑  收藏  举报