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个字符,.rdata段的首地址是600h,
那么IMAGE_IMPORT_DESCRIPTOR结构成员的首地址应该是608h。