Windows API Hooking
Last updated
Last updated
This lab is a quick look into how userland WinAPIs can be hooked. A MessageBoxA
function will be hooked in this instance, but it could be any.
API hooking is a technique by which we can instrument and modify the behavior and flow of APIcalls. https://resources.infosecinstitute.com/api-hooking/
Windows API hooking is one of the techniques used by AV/EDR solutions to determine if code is malicious. You can read some of my notes on bypassing EDRs by leveraging unhooking - Bypassing Cylance and other AVs/EDRs by Unhooking Windows APIs
For this lab, I will write a simple C++ program that will work follows:
Get memory address of the MessageBoxA
function
Read the first 6 bytes of the MessageBoxA
- will need these bytes for unhooking the function
Create a HookedMessageBox
function that will be executed when the original MessageBoxA
is called
Get memory address of the HookedMessageBox
Patch / redirect MessageBoxA
to HookedMessageBox
Call MessageBoxA
. Code gets redirected to HookedMessageBox
HookedMessageBox
executes its code, prints the supplied arguments, unhooks the MessageBoxA
and transfers the code control to the actual MessageBoxA
Pop the message box before the function is hooked - just to make sure it works and to prove that no functions are hooked so far - it's the first instruction of the program:
Get the memory address of the MessageBoxA
function:
If we dissasemble the bytes at that address, we can definitely see that there is code for MessageBoxA
:
Note the first 6 bytes 8b ff 55 8b ec 6a
(mind the endian-ness). We need to save these bytes for future when we want to unhook MessageBoxA
:
Let's now build the patch (hook) bytes:
...that will translate into the following assembly instructions:
We can now patch the MessageBoxA
- memory pane in the bottom right shows the patch being written to the beginning of MessageBoxA
function and the top right shows the beginning of the same function is re-written with a push 3e1474h; ret
instructions:
If we disassemble the address 3e1474h
, we can see it contains a jmp to our HookedMessageBox
:
The HookedMessageBox
intercepts and prints out the arguments supplied to MessageBoxA
, then unhooks
by swaping back the first 6 bytes to the original bytes of the MessageBoxAMessageBoxA
function and then calls the MessageBoxA
with the supplied arguments:
Once the function is hooked, we can call the MessageBoxA(NULL, "hi", "hi", MB_OK);
which will invoke the HookedMessageBox
, print the intercepted values and display the original message box: