IAT,Import Address Table,导入地址表。IAT是一种表格,用来记录程序正在使用哪些库中的哪些函数。IAT保存的内容与Windows操作系统的核心进程、内存、DLL结构等有关。
DLL
DLL,Dynamic Link Library,动态链接库。
- 不要把库包含到程序中,单独组成DLL文件,需要时调用即可.
- 内存映射技术使加载后的DLL代码,资源在多个进程中实现共享.
- 更新库时只要替换相关DLL文件即可.
加载DLL文件时有两种方式 : 一种是”显式链接”(Explicit Linking),程序使用DLL时加载,使用完毕后释放内存;另一种是”隐式链接(Implicit Linking)”,程序开始时即一同加载DLL,程序终止时再释放占用的内存.
实际操作中无法保证DLL一定会被加载到PE头指定的ImageBase处,但是EXE文件(生成的进程主体)却能准确加载到自身的ImageBase中,因为它拥有自己的虚拟空间。
IMAGE_IMPORT_DESCRIPTOR
IMAGE_IMPORT_DESCRIPTOR结构体中记录着PE文件要导入那些库文件.
- Import : 导入,向库提供服务(函数)
- Export : 导出,从库向其他PE文件提供服务(函数)
执行一个普通程序时往往需要导入多个库,导入多少库就存在着多少个IMAGE_IMPORT_DESCRIPTOR结构体,这些结构体形成了数组,且结构体数组最后以NULL结构体结束。
IMAGE_IMPORT_DESCRIPTOR
中的重要成员:
项目 | 含义 |
---|---|
OriginalFirstThunk | INT的地址(RNA) |
Name | 库名称字符串的地址(RVA) |
FirstThunk | IAT的地址(RVA) |
- PE头中提到了提到的table是数组
- INT与IAT是长整型数组(4字节),以NULL结束(未另外明确指出大小)
- INT中各元素的值为
IMAGE_IMPORT_BY_NAME
结构体指针(有时IAT也拥有相同的值) - INT与IAT的大小应相同
** PE装载器把导入函数输入至IAT的顺序**
- 读取IID的NAME 成员,获取扩名称字符串
- 装载相应库: LoadLibrary(“kernel32.dll”)
- 读取OriginalFirstThunk成员,获取INT 地址
- 逐一读取INT 数组中的值,获取相应的 IMAGE_IMPORT_BY_NAME地址(RVA)
- 使用IMAGE_IMPORT_BY_NAME 的Hint 或者是Name 项,获取相应函数的起始地址。 ->GetProcAddress(“GetCurrentThreadId”)
- 读取IID的FistrThunk 成员,获得IAT 地址。
- 将上面获得的函数地址输入相应IAT 数组值。
- 重复4-7步骤,到INT 结束。(遇到NULL时)
IMAGE_IMPORT_DESCRIPTOR
结构体数组存在于PE体中,但查找其位置的信息在PE头中,IMAGE_OPTIONAL_HEADER32.DataDirectory[1].VirtualAddress
的值即是IMAGE_IMPORT_DESCRIPTOR
结构体数组的起始地址(RVA值)。IMAGE_IMPORT_DESCRIPTOR
结构体数组也称为IMPORT Directory Table
By@ https://b404.xyz/2017/03/18/IAT/