PE是每个DLL还是每个exe的“IMPORT ADDRESS TABLE”?

有谁知道在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加载器,如果它帮助你理解。