1625-5 王子昂 总结《2017年10月5日》 【连续第370天总结】
A. IAT导入地址表
B.
IAT,导入地址表,用来记录程序正在使用哪些库中的哪些函数
DLL
动态链接库,是Win特有的系统。
早在DOS时代还没有DLL时,只有库一说。当需要使用库函数时,编译器会将库函数一起插入到应用程序中。
到了Win时代,由于GUI拥有大量的库函数来支持环境,这样插入会造成大量资源浪费(内存和磁盘空间),于是引入了动态链接库。
内存映射技术使得加载后的DLL代码、资源在多个进程中实现共享
加载DLL的方式有两种:显式链接为程序使用DLL时加载,使用完毕后立即释放。隐式链接为程序运行时加载DLL,结束后释放内存。
IAT
IAT提供的机制就与隐式链接有关。
当调用库函数时,汇编代码实际为call a,而a处的代码是jmp b
a是.text节区的内存区域(确切说是IAT内存区域),b就是真正的库函数地址。
当运行程序时,PE装载器负责将b的地址写入a中
不直接将call b的原因一方面是DLL的版本不同、b在DLL中的地址也相应不同,因此并不固定;另一方面DLL重定位功能使得DLL不一定装载入Image Base地址中
DLL重定位:如果a.dll已经装载入了10000000地址,而b的Image Base也为10000000,那么将会自动为b换一个地址装载。
IMAGE_IMPORT_DESCRIPTOR结构体
结构体中记载了PE文件要导入哪些库文件。
每个结构体中包含一个库文件的INT地址数组、Name数组和IAT地址数组,以NULL结束
装载顺序
- 读取IID的Name成员,获取库名称字符串(如“Kernel32.dll”)
- 装载相应库,通过LoadLibrary(“Kernel32.dll”)
3.读取IID的OriginalFirstThunk成员,获取INT地址
4.逐一读取INT中数组的值,获取相应IMAGE_IMPORT_BY_NAME地址
5.使用IMAGE_IMPORT_BY_NAME的HINT或NAME项,获取相应函数的起始地址,通过GetProcAdress(“GetCurrentThreadld”)
6.读取IID的FirstThunk成员,获得IAT地址
7.将上面获得的函数地址放入相应的IAT数组值
8.重复4-7步骤,将所有INT装载(以NULL结束)
C. 明日计划
EAT