导入表
记录一下我对导入表的理解
根据数据目录的第二个元素的VirtualAddress就可以查找到导入表

导入表的结构如上图所示,其中可以将PIMAGE_THUNK看成大小为4个字节的数据类型,存放了RVA
1.根据联合体的属性,可以将第一个成员看成时 PIMAGE_THUNK_DATA OriginalFirstThunk,这里面存的时RVA,指向了导入名称表INT
导入名称表可以看成是每个单元为4个字节的表,当表中的数据的最高位为1时,将该数据减去0x80000000,可以得到导入的函数的序号,当表中的数据的最高位不为1时,可以将他也看成时RVA,指向了导入的函数的名称和在对应的DLL中导出函数表的索引。INT表的结构如下所示。

2.DWORD TimeDataStamp,其中可以存放0或-1,细节之后再讲。
3.DWORD Name,其中存放了RVA,指向了所对应的DLL库的名称。
4.PIMAGE_THUNK_DATA FirstThunk,其中存放了RVA,指向了IAT表。
5.IAT表在加载前和加载后时不同的
加载前:IAT表和INT表存放的数据数完全一样的,但IAT表和INT表都有独立的内存空间
加载后:IAT表存放要导入的函数的地址,由于部分DLL库需要重定位,直接在IAT表中存放导入函数的地址会发生错误,所以让IAT表在加载的过程中,根据INT表得到的序号和函数的名称,来得到函数的正确地址,修改IAT表中的数据,所以IAT表和INT表中的每项都是对应的。
6.但IAT表也有例外的情况——当导入表中的TimeDataStamp时间戳为-1时,在加载前IAT就已经存放了要导入的函数的地址。这种方法的优点是省去了在加载中修改IAT表的过程,加快了加载的速度,缺点就是,当DLL库需要重定位或者进行更新修改了,IAT表仍需要进行修改。这种方法就引出的表:绑定导入表。
7.绑定导入表的结构如下所示:

绑定导入表也可以通过数据目录来定位
TimeDataStamp为时间戳,若绑定导入表中的时间戳和对应的DLL的File_Header中的时间戳不同时,DLL可能进行了更新修改,此时IAT、表就需要进行修改
OffsetModuleName表示模块名所在的地址,具体位置的计算方法为绑定导入表的首地址加上Offset,结果为RVA
NumberOfModuleForwarderRefs表对应的DLL所依赖的DLL的个数

浙公网安备 33010602011771号