Import Adress Table (IAT) Hooking
Last updated
Last updated
Windows portable executable contains a structure called Import Address Table (IAT)
IAT contains pointers to information that is critical for an executable to do its job:
a list of DLLs it depends on for providing the expected functionality
a list of function names and their addresses from those DLLs that may be called by the binary at some point
It is possible to hook function pointers specified in the IAT by overwriting the target function's address with a rogue function address and optionally to execute the originally intended function
Below is a simplified diagram that attempts to visualize the flow of events before and after a function
(MessageBoxA
in this example, but could be any) is hooked:
Before hooking
the target program calls a WinAPI MessageBoxA
function
the program looks up the MessageBoxA
address in the IAT
code execution jumps to the kernel32!MessageBoxA
address resolved in step 2 where legitimate code for displaying the MessageBoxA
(green box) lives
After hooking
the target program calls MessageBoxA
like before hooking
the program looks up the MessageBoxA
address in the IAT
this time, because the IAT has been tampered with, the MessageBoxA
address in the IAT is pointing to a rogue hookedMessageBox
function (red box)
the program jumps to the hookedMessageBox
retrieved in step 3
hookedMessageBox
intercepts the MessageBoxA
parameters and executes some malicous code
hookedMessageBox
calls the legitimate kernel32!MessageBoxA
routine
In this lab I'm going to write a simple executable that will hook MessageBoxA
in its process memory space by leveraging the IAT hooking technique and redirect it to a function called hookedMessageBox
as per above visualisation and then transfer the code execution back to the intended MessageBoxA
routine.
IAT hooking is usually performed by a DLL injected into a target process, but for the sake of simplicity and illustration, in this lab, the IAT hooking is implemented in the local process.
To hook the MessageBoxA
we need to:
Save memory address of the original MessageBoxA
Define a MessageBoxA
function prototype
Create a hookedMessageBox
(rogue MessageBoxA
) function with the above prototype. This is the function that intercepts the original MessageBoxA
call, executes some malicious code (in my case, it invokes a MessageBoxW
) and transfers code execution to the original MessageBoxA
routine for which the address is retrieved in step 1
Parse IAT table until address of MessageBoxA
is found
More about PE parsing in Parsing PE File Headers with C++
More about Import Address Table parsing in Reflective DLL Injection
Replace MessageBoxA
address with address of the hookedMessageBox
As a reminder, we can check the IAT of any binary using CFF Explorer or any other PE parser. Below highlighted is one of the IAT entries - the target function MessageBoxA
that will be patched during runtime and swapped with hookedMessageBox
:
Below is the code and key comments showing how IAT hooking could be implemented:
Our binary's base address (ImageBase) in memory is at 0x00007FF69C010000
:
Before IAT manipulation, MessageBoxA
points to 0x00007ffe78071d30
:
If interested, we can manually work out that MessageBoxA
is located at 0x00007ffe78071d30
by:
adding the ImageBase 0x00007FF69C010000
and Relative Virtual Address (RVA) of the First Thunk of MessageBoxA
0x000271d0
which equals to 0x00007FF69C0371D0
dereferrencing 0x00007FF69C0371D0
Dereferrencing 0x00007FF69C0371D0 (0x00007FF69C010000 + 0x000271d0)
reveals the MessageBoxA
location in memory 0x00007ffe78071d30
:
Now, our hookedMessageBox
is located at 0x00007ff396d5440
:
After the IAT manipulation code executes, MessageBoxA
points to hookedMessageBox
at 0x00007ff396d5440
Once the function pointers are swapped, we can see that calling the MessageBoxA
with an argument Hello after Hooking
does not print Hello after Hooking
, rather, the message text is that seen in the hookedMessageBox
routine, confirming that the IAT hook was successful and the rouge function was called first:
Below shows the entire flow of key events that happen in this program:
Before hooking, MessageBoxA
is called with an argument Hello Before Hooking
and the program displays the message as expected
After IAT hooking, MessageBoxA
is called with an argument Hello after Hooking
, but the program gets redirected to a hookedMessageBox
function and displays Ola Hooked from a Rogue Senor .o.
Finally, hookedMessageBox
calls the original MessageBoxA
which prints out the intended Hello after Hooking