为什么不能使用绝对地址调用函数?
- 操作系统的版本不同
- kernel32.dll的版本不同
- DLL重定向(ImageBase在不同程序内存空间是不一样的)
输入表IAT
Import Address Table(IAT)
IAT中的内容与Windows操作系统的核心进程、内存、DLL结构等有关,理解了IAT,就掌握了Windows操作系统的根基
IAT是一种表格结构,标记程序需要使用哪些库中的哪些函数
IMAGE_IMPORT_DESCRIPTOR
该结构体记录PE文件要导入哪些库文件。PE程序往往需要导入多个库,导入多少个库就存在多少个IMAGE_IMPORT_DESCRIPTOR结构体,多个结构体组成数组,以NULL结构体结束。
- OriginalFirstThunk(DWORD),INT的地址(RVA)
- Name(DWORD),库文件名字符串的地址(RVA)
- FirstThunk(DWORD),IAT的地址(RVA)
INT与IAT是DWORD数组,以NULL结束。INT与IAT的各元素指向相同地址。
IAT(Import Address Table)、INT(import Name Table)
PE装载器
- 读取IID的name成员,获取库名称字符串,例如“kernel32.dll”。
- 装载相应的库,类似LoadLibrary(“kernel32.dll”)。
- 读取IID的OriginalFirstThunk成员,获取INT地址
- 读取INT,逐一获得IMAGE_IMPORT_BY_NAME的地址(RVA)。
- 使用IMAGE_IMPORT_BY_NAME的Hint或者Name项,获得函数的起始地址。类似GetProcAddress(“ExitProcess”)
- 读取IID的FirstThunk成员,获得IAT地址
- 将第5步获得的函数地址写入IAT数组相应位置
- 重复步骤4到7,指导INT结束