PE格式,IAT目录有什么用处

在PE格式中,我们有导入表目录(由IMAGE_DIRECTORY_ENTRY_IMPORT访问)和IAT目录(由IMAGE_DIRECTORY_ENTRY_IAT访问)都是可选标题数据目录的一部分。

使用导入表,加载程序dynamic加载并parsing必要的库和函数。 这是通过遍历导入表中的导入地址表RVA(Thunk Table)来完成的。

那么,如果我们使用导入目录进行parsing,那么我们需要IAT目录呢?

我一直在阅读Microsoft PE规范,但找不到答案。 另外,在SO中也有一些问题,但是其中大多数使用IAT来指代Thunk Table而不是IAT Directory。

谢谢

编辑

我认为导入地址表(导入表目录中的一个字段)和导入地址表(称为IAT目录)之间存在混淆。 我的问题是关于IAT目录。

再次感谢

在你所链接的PE规范5.4.4章节中有详细描述。 他们是相同的表格:

导入地址表的结构和内容与导入查找表的结构和内容相同,直到文件被绑定。 绑定期间,导入地址表中的条目将被导入的符号的32位(对于PE32)或64位(对于PE32 +)地址覆盖。 这些地址是符号的实际内存地址,尽管在技术上它们仍然被称为“虚拟地址”。加载器通常处理绑定

解释为什么这样做是很重要的。 PE文件通过直接映射到内存来加载进程。 底层操作系统原语是一个内存映射文件。 这提供了几个重要的优化:

  • 可执行文件使用的内存不必由页面文件支持。 如果操作系统需要另一个进程的内存,那么映射到可执行文件的页面可能会被丢弃。 当进程生成页面错误时,要从PE文件重新加载。

  • 进程为其可执行代码使用的RAM可以由进程的任何实例共享。 换句话说,当你多次启动Notepad.exe时,RAM中只有一个代码副本。 每个进程共享相同的页面。 这对DLL尤其重要,特别是在每个进程中使用的操作系统DLL,如ntdll.dll,kernel32.dll和user32.dll(等等)。

当加载程序用导入函数的实际地址填充IAT时,操作系统会重新映射IAT的页面,并使页面支持页面文件。 所以每个进程都可以拥有自己的一组导入地址。 包含代码和导入表的其余页面仍然是共享的。

IMAGE_DIRECTORY_ENTRY_IMPORT最终导致多个IAT thunk,它们存储在一个内存区域,该区域从[IMAGE_DIRECTORY_ENTRY_IAT].Size开始,大小为[IMAGE_DIRECTORY_ENTRY_IAT].Size

我猜这是有用的,当所有的部分默认加载为只读,你可以使用IMAGE_DIRECTORY_ENTRY_IAT使IAT(但不是ILT)thunks可写。

下面的文章和它的第一部分是PE可执行文件信息的一个很好的来源:

从2002年3月号的MSDN Magazine:Inside Windows

深入了解Win32可移植可执行文件格式,第2部分