导入表 IMPORT_DESCRIPTOR

typedef struct _IMAGE_IMPORT_DESCRIPTOR {
    union {
        DWORD   Characteristics;            // 0 for terminating null import descriptor
        DWORD   OriginalFirstThunk;         // 包含指向IMAGE_DATA(输入名称表)RVA 的结构数组
    };
    DWORD   TimeDateStamp;                  //当可执行文件不与被导入的DLL进行绑定时,此字段为0
    DWORD   ForwarderChain;                 //第一个被转向的API索引
    DWORD   Name;                           //指向被导入的DLL 名称
    DWORD   FirstThunk;                     //指向输入地址表(IAT)RVA,IAT是一个IMAGE_THUNK_DATA结构的数组
} IMAGE_IMPORT_DESCRIPTOR;
typedef IMAGE_IMPORT_DESCRIPTOR UNALIGNED *PIMAGE_IMPORT_DESCRIPTOR;

有多少个导入DLL就有多少个IMAGE_IMPORT_DESCRIPTOR结构体



在PE文件没有导入到内存之前,OriginalFirstThunk和FirstThunk 结构都是一个东西,但是导入内存后,系统会根据OriginalFirstThunk对FirstThunk指向的表重新写入真实函数的地址。就是IAT了。


比如,如果该PE文件从10个不同的DLL中引入函数,那么这个数组就有11个成员。

第11个数组以一个全0的成员结尾。

那么.rdata段的内容应该就是IMAGE_IMPORT_DESCRIPTOR?结构数组了,我们这里用到user32.dll库,第一个元素的成员1的地址是不是就是.rdata的首地址呢?
?    
不是这样的,这里有个规律,我们导入了多少个函数,那么就要空出8乘以导入函数个数个字符的空间(为什么要空些空间呢?要放什么呢?一会便可知晓),
在其后才是IMAGE_IMPORT_DESCRIPTOR结构成员的首地址。
在这里我们导入了1个函数,那么应该空1 8 = 8个字符,.rdata段的首地址是600h,
那么IMAGE_IMPORT_DESCRIPTOR结构成员的首地址应该是608h。
原文地址:https://www.cnblogs.com/IMyLife/p/4826084.html