I came upon this question :

Can we hook the Nt or Zw functions using IAT hooking, or just inline hooking?

and it got me wondering, lets say for some reason some function was not in the IAT of our target PE in virtual memory, like the above question which is Zw/NtQuerySystemInformation (I'm still not sure why this is not included in IAT tho), so in this case if we wanted to hook the IAT, would it be possible to hook the export table of kernel32.dll or ntdll.dll and do it like that instead? because i assume this function has to be there at least

so this takes me back to the question, will the loader fill our IAT when its loading the PE into memory by checking the export tables, or when our program uses it? because if its the first case then I assume there is no way to hook the export table right?

also does anyone know why functions like ZwQuerySystemInformation dont get included in IAT but stuff like Sleep and GetProcAddress Does?

2 Answers 2


the Apis like Sleep are documented a header file is provided in the sdk a library to link against is provided by sdk (windows.h ,kernel32.lib)

api s like Zwxxx are internal or advanced user apis they or either undocumented or semidocumented or documented for usage in a kernel mode
these apis are not to be taken for granted to be either forward compatible or backward compatible

so if you use them then all the care that is required is to be taken by the one who is using them

so they are designed to be dynamically called using load library , getting the procedure address , casting the return as a typedeffed function pointer

they dont reside in IAT or loader doesnot resolve them

  • So there is no way to IAT hook or hook the export table of a Zwxxx or Ntxxx function? i mean if the only way to use them is loadlibrary/GetProcAddr then can't we just hook it in the export table of Ntdll and therefore when task manager tries to use it we win?
    – Max
    Commented Sep 8, 2019 at 5:09

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 */
    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");

    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:



[1]: The Rootkit Arsenal, Bill Blunder, Chapter 11, p.480

[2]: Calling NTDLL functions directly, https://resources.infosecinstitute.com/calling-ntdll-functions-directly

  • Thanks for answer! but doesn't ntdll gets mapped into every loaded PE automatically? i mean i don't even need the load the ntdll library to call these functions, i just need to get its handle and use getproc so this means its already there, right?
    – Max
    Commented Sep 8, 2019 at 12:38
  • Yes, ntdll and a bunch of other libraries are automatically loaded. Using LoadLibrary on an already loaded library generally returns its handle (there are corner cases though, keep that in mind if you don't understand why your handle is invalid).
    – plowsec
    Commented Sep 8, 2019 at 15:53
  • @Max does this answer your question? If so, please mark as accepted, or else edit your original question so that we can help you further ;)
    – plowsec
    Commented Sep 10, 2019 at 7:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.