在 PE 格式中,我们有导入表目录(通过IMAGE_DIRECTORY_ENTRY_IMPORT
)和 IAT 目录(通过以下方式访问)IMAGE_DIRECTORY_ENTRY_IAT
)
两者都是可选标头数据目录的一部分。
使用导入表,加载器动态加载并解析必要的库和函数。
这是通过迭代导入地址表 RVA(Thunk 表)来完成的,该表是导入表的一部分。
那么,如果我们使用导入目录进行导入解析,我们需要 IAT 目录做什么?
我一直在读微软PE规范 http://msdn.microsoft.com/library/windows/hardware/gg463125但找不到答案。另外,SO中有一些问题,但大多数都使用IAT来引用Thunk表而不是IAT目录。
Thanks
EDIT
我认为导入地址表(导入表目录中的一个字段)和导入地址表(称为 IAT 目录)之间存在混淆。
我的问题是关于 IAT 目录的。
再次感谢
您链接的 PE 规范第 5.4.4 章对此进行了很好的描述。它们是相同的表:
导入地址表的结构和内容与导入查找表的结构和内容相同,直到文件被绑定。在绑定期间,导入地址表中的条目将被导入符号的 32 位(对于 PE32)或 64 位(对于 PE32+)地址覆盖。这些地址是符号的实际内存地址,尽管从技术上讲它们仍然被称为“虚拟地址”。加载器通常处理绑定
也许解释一下为什么这样做很重要。 PE 文件通过直接映射到内存来加载到进程中。底层操作系统原语是内存映射文件。这提供了几个重要的优化:
可执行文件使用的内存不必由分页文件支持。如果操作系统需要 RAM 用于另一个进程,则可以简单地丢弃映射到可执行文件的页面。当进程产生页面错误时从PE文件再次重新加载。
进程为其可执行代码使用的 RAM 可以由该进程的任何实例共享。换句话说,当您多次启动 Notepad.exe 时,只有oneRAM 中代码的副本。每个进程共享相同的页面。这对于 DLL 来说最为重要,尤其是每个进程中使用的操作系统 DLL,如 ntdll.dll、kernel32.dll 和 user32.dll(等等)。
当加载程序使用导入函数的实际地址填充 IAT 时,操作系统会重新映射 IAT 的页面,并由分页文件支持它们。因此每个进程都可以有自己的一组导入地址。包含代码和导入表的其余页面仍然是共享的。
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)