有谁知道在Windows上的PE可执行文件格式的“导入地址表”是“每个DLL”还是“每个EXE”?
任何PE都可以有一个导入地址表,所以DLL和EXE都可以拥有它们。 这是有道理的,因为两者都可以在其他二进制文件上具有依赖关系(导入)。 除非你正在进行动态加载( LoadLibrary
/ GetProcAddress
),否则调用另一个模块时将会有一个导入地址表。
您可以在Visual Studio中使用dumpbin
实用程序来查看PE的导入:
user32.dll的一个例子:
C:\ Windows \ System32> dumpbin /导入user32.dll
Microsoft(R)COFF / PE Dumper Version 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 Version 10.00.30319.01版权所有(C)Microsoft Corporation。 版权所有。
转储文件notepad.exe
文件类型:EXECUTABLE IMAGE
部分包含以下导入:
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部分(或导入表,我喜欢称之为)…
IMAGE_SCN_MEM_DISCARDABLE未设置为idata部分。 因此,idata部分复制到内存,exe和dll都有这个部分 – 意味着IAT是每个PE。
我写了一个简单的DLL加载器,如果它帮助你理解。