PE文件中的输入表

前言

PE文件中的输入表含有三个重要结构IID,IDT,IAT。PE文件为需要加载的DLL文件创建一个IID结构,一个DLL与一个IID对应。IDT是输入名称表,IAT输入地址表,在没有绑定输入的情况下磁盘中的文件IDT与IAT相同。

函数隐式链接

我们一般在调用函数的时候都是直接用函数的名称,例如Message()这种其在底层汇编指令上并不是直接调用Message()函数的地址而是调用IAT中对应函数的地址(也就是函数的地址实际存放在IAT中)。一般在PE文件加载进入内存时,windows加载器会根据IDT(如果IDT为空就根据IAT)的函数信息在对应的DLL中查询实际函数的地址,然后重写到IAT中。也就是在加载到内存前IAT与IDT存储的都是输入函数的信息,并不包含函数的实际地址。只有当windows加载器将PE文件加载到内存后IAT中才会存放函数的实际地址,而我们实际调用函数的指令会指向这对应的IAT中函数的位置,完成函数的调用。这种方式称为函数隐式链接(是由windows加载器完成的)。

函数显式链接

如果我们调用函数的时候不直接使用函数名称,而是使用LoadLibrary()和GetProcAddress()函数在运行时动态获取函数的地址,这种函数调用根本不依赖于IAT,称为显示链接。

函数绑定输入

对于函数隐式链接而言,因为需要在PE文件加载到内存时通过INT中的函数信息从DLL中获取函数的地址然后写到IAT中,这效率很低。如果我们能让PE文件在没加载到内存时就确定对应IAT中函数的地址的话就可以大大提高效率,这种就称为绑定输入函数。为了防止绑定输入的函数对应的dll发生改变造成函数调用出错,PE文件有对应的绑定输入表可以通过数据目录表访问,在PE文件加载到内存时windows加载器会依据绑定输入表中的信息与加载的dll的信息进行对比,如果发现不一致则会重新改写IAT。

隐式,显式,绑定输入在HOOK中的使用

因为显式链接不依赖与IAT所以IAT_HOOK对其进行无效,对于EAT_HOOK来说对三种形式都有效。

区分动态/静态编译 与 显式/隐式链接

注意动态编译是指将对应Dll中的信息保存到PE文件的IID中,然后调用的函数信息存在IAT和IDT中。当PE文件加载到内存中时将IID对应的DLL加入到内存中进一步完成函数的调用。而静态编译是将函数对应的dll中的代码全部整合到PE文件中,这样函数的调用就不依赖于DLL也不会形成对应的IID。(不要将动态/静态编译 与 显示/隐式链接搞混)

猜你喜欢

转载自www.cnblogs.com/revercc/p/13376172.html