绑定导入表(Bound Import Table)是文件中的一个数据结构,用于存储已经绑定(即完成绑定导入)的外部函数的信息。
本节必须掌握的知识点:
绑定导入表数据结构
实例分析
4.2.1 绑定导入表数据结构
绑定导入是指在程序加载时,将程序所依赖的外部函数的地址与程序的IAT(Import Address Table,导入地址表)进行绑定的过程。这样,程序就可以直接通过IAT中的函数指针来调用这些外部函数,而无需再进行动态链接的过程。
绑定导入可以分为静态绑定和动态绑定两种方式:
●静态绑定:
在编译时,链接器将外部函数的地址直接嵌入到程序的IAT中。
静态绑定生成的可执行文件会包含被依赖函数的实际地址,因此在程序加载时无需进行额外的动态链接操作。
静态绑定的优点是加载速度快,无需运行时动态链接库的支持。但缺点是可执行文件的大小会增加,并且无法在运行时动态地加载新的函数或库。
●动态绑定:
在程序加载时,操作系统会根据IAT中的函数名称来查找并绑定外部函数的实际地址。
动态绑定通过操作系统的动态链接器(如Windows的LoadLibrary和GetProcAddress函数)来实现。
动态绑定的优点是可执行文件的大小较小,可以在运行时动态加载新的函数或库。但缺点是加载过程相对较慢,因为需要进行额外的符号解析和地址重定位操作。
绑定导入的具体实现方式取决于操作系统和编程语言。在Windows环境下,可以使用PE文件格式、IAT表和动态链接库(DLL)来实现绑定导入。在Linux环境下,可以使用ELF文件格式和动态链接器(ld.so)来实现绑定导入。
当可执行文件被绑定时,IAT 中的IMAGE_THUNK_DATA结构将被导入函数的实际地址覆盖。磁盘上的可执行文件具有其 IAT 中其他 DLL 中 API 的实际内存中地址。加载绑定的可执行文件时,Windows 加载程序可以绕过查找每个导入的 API 并将其写入 IAT 的步骤。正确的地址已经在那里了!
您可能对可执行绑定的安全性持怀疑态度。毕竟,如果绑定可执行文件并且它导入的 DLL 发生变化怎么办?比如kernel32.dll,在Windows 2000中其加载到进程空间的基地址为 0x77e60000,而在Windows XP SP3中其加载地址则是0x7c800000。发生这种情况时,IAT 中的所有地址都无效。在为PE加入绑定导入机制的时候,微软就已经考虑到了这个问题,所以假定PE加载前对IAT的修正都是正确的。那么PE的加载速度是加快的,即使绑定以后的EXE程序在其他的兼容系统中运行时,其地址出现错误,PE加载也有检测错误的机制。如果地址检测出错误, PE加载器会重新接管这项工作,加载时对IAT进行修正。
微软提供了一个绑定工具bind.exe程序,该程序可以把导入表中IAT表项IMAGE_ THUNK_DATA32的内容都静态替换成虚拟内存地址,然后在数据目录表的第12项指定的位 置声明这些更改。Windows在加载目标PE相关的动态链接库时,会首先检査这些地址是否正确合法,这些检查包括当前系统的DLL版本是否符合绑定导入结构中描述的版本号,如果不符合或者DLL需要被重新定位,加载器就会去遍历OriginalFirstThunk指向的数组(也就是 INT),计算新的地址。如果导入表是单桥结构,此时的遍历会失效,所以说单桥结构无法实 施静态绑定操作。
![]()
注意
绑定导入是一种静态链接的方式,因此在程序运行期间无法更改绑定的外部函数地址。如果需要在运行时动态加载新的函数或库,可以考虑使用延迟加载或手动加载的方式。
1185



被折叠的 条评论
为什么被折叠?



