PE loader什么时候填IAT?
IAT 在加载时由 PE 加载器 [1] 更新,这称为加载时动态链接,而不是运行时动态链接,在LoadLibrary/GetProcAddress必要时。
挂钩未包含在导入地址表中的 API
实际上有几种方法可以做到这一点,导出地址表挂钩就是其中之一。但是,您的钩子必须在目标应用程序查找您要钩子的 API 之前安装。
在 IAT 中包含 Nt/Zw API
还有谁知道为什么像 ZwQuerySystemInformation 这样的函数没有包含在 IAT 中,但是像 Sleep 和 GetProcAddress 这样的东西呢?
ZwQuerySystemInformation未包含在 IAT 中的唯一原因是您没有告诉链接器为您执行此操作。您需要链接到 ntdll 导入库(在 VS2017 中默认可用),或者您可以构建自己的库。
在我安装mingw并clang安装的系统上,我能够从 [2] 中获取代码,删除任何GetProcAddress/LoadLibrary调用并构建它。这给出:
#include <stdio.h>
#include <windows.h>
#include <winternl.h>
int main(void) {
/* load the ntdll.dll */
PVOID Info;
/* create the string in the right format */
UNICODE_STRING filename;
RtlInitUnicodeString(&filename, L"C:\\temp.txt");
/* initialize OBJECT_ATTRIBUTES */
OBJECT_ATTRIBUTES obja;
InitializeObjectAttributes(&obja, &filename, OBJ_CASE_INSENSITIVE, NULL, NULL);
/* call NtOpenFile */
IO_STATUS_BLOCK iostatusblock;
HANDLE file = NULL;
NTSTATUS stat = NtOpenFile(&file, FILE_WRITE_DATA, &obja, NULL, NULL, NULL);
if(NT_SUCCESS(stat)) {
printf("File successfully opened.\n");
}
else {
printf("File could not be opened.\n");
}
getchar();
return 0;
}
要构建,我使用:
clang -target x86_64-w64-windows-gnu toto.c -o toto.exe -lntdll
然后,IDA Free 7.0允许我们看到它NtOpenFile已成功包含在 IAT 中:

参考
[1]:Rootkit 军械库,Bill Blunder,第 11 章,第 480 页
[2]:直接调用NTDLL函数,https ://resources.infosecinstitute.com/calling-ntdll-functions-directly