有谁知道Windows上PE可执行格式的“导入地址表”是“per dll”还是“per exe”?
2 回答
任何 PE 都可以有一个导入地址表,因此 DLL 和 EXE 都可以拥有它们。这是有道理的,因为两者都可以在其他二进制文件上具有依赖项(导入)。除非您正在执行动态加载 ( LoadLibrary
/ GetProcAddress
),否则在调用另一个模块时您将拥有一个导入地址表。
您可以将该dumpbin
实用程序与 Visual Studio 一起使用来查看 PE 的导入:
user32.dll 上的示例:
C:\Windows\System32> dumpbin /imports user32.dll
Microsoft (R) COFF/PE Dumper 版本 10.00.30319.01 版权所有 (C) Microsoft Corporation。版权所有。
文件 user32.dll 的转储
文件类型:DLL
部分包含以下导入:
ntdll.dll 7DC60000 Import Address Table 7DCCACEC Import Name Table 0 time date stamp 0 Index of first forwarder reference 15A NtOpenKey 7A9 wcscat_s 7AD wcscpy_s ...
...对于notepad.exe ...
C:\Windows\System32> dumpbin /imports notepad.exe
Microsoft (R) COFF/PE Dumper 版本 10.00.30319.01 版权所有 (C) Microsoft Corporation。版权所有。
文件 notepad.exe 的转储
文件类型:可执行图像
部分包含以下导入:
ADVAPI32.dll 1001000 Import Address Table 100A234 Import Name Table FFFFFFFF time date stamp FFFFFFFF Index of first forwarder reference 77C71C82 27E RegSetValueExW 77C7BCD5 26E RegQueryValueExW 77C7BED4 230 RegCloseKey ...
简短的回答:
IAT(导入地址表)是每个 PE 文件(dll 和 exe)。
长答案:
当加载器加载 exe 文件时,它会将 PE 的每个部分复制到进程内存,除非为此部分设置了 IMAGE_SCN_MEM_DISCARDABLE。IAT 位于 .idata 部分 ( msdn ):
PE 文件的 .idata 部分包含加载程序确定目标函数的地址并将它们修补到可执行映像中所需的信息。.idata 部分(或导入表,我更喜欢称之为)...
没有为 idata 部分设置 IMAGE_SCN_MEM_DISCARDABLE。因此 - idata 部分复制到内存,并且 exe 和 dll 都有这个部分 - 意味着 IAT 是 per PE。
我在这里写了一个简单的 dll 加载器,如果它帮助你理解的话。