When does the PE loader fill in the IAT?
The IAT is updated at load time by the PE Loader [1], this is called Load-time dynamic linking, as opposed to Run-time dynamic linking, where LoadLibrary/GetProcAddress
are necessary.
Hooking an API not included in Import Address Table
There are several ways to do that actually, and Export Address Table hooking is one of them. However, your hook must be installed before the target application looks up the API you want to hook.
Include Nt/Zw APIs in the IAT
also does anyone know why functions like ZwQuerySystemInformation dont get included in IAT but stuff like Sleep and GetProcAddress Does?
The only reason ZwQuerySystemInformation
is not included in the IAT is because you didn't tell your linker to do it for you. You need need to link against ntdll import library (available by default in VS2017), or you can build you own.
On my system with mingw
and clang
installed, I was able to take the code from [2], remove any GetProcAddress/LoadLibrary
calls, and build it. This gives:
#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;
}
To build, I use:
clang -target x86_64-w64-windows-gnu toto.c -o toto.exe -lntdll
Then, IDA Free 7.0 allows us to see that NtOpenFile
was successfully included in the IAT:

References
[1]: The Rootkit Arsenal, Bill Blunder, Chapter 11, p.480
[2]: Calling NTDLL functions directly, https://resources.infosecinstitute.com/calling-ntdll-functions-directly