Detours is a library that allows you to hook functions and instrument arbitrary win32 function by proxying them and re-writing the function.
Detours works by using a jmp instruction to redirect code execution.
Detours has a whitepaper which goes into further detail.
This uses a trampoline function which is a like a proxy and setups everything properly.
With hooking, we can: look at values that the function uses, make it return a certain value, or execute someone etc.
Example
To demonstrate, lets try hooking a simple message box function.
Copy #include <stdio.h>
#include <stdlib.h>
#include <Windows.h>
int main(void){
getchar();
MessageBox(NULL, L"Hello world!", L"detour", MB_OK);
return 0;
}
We will inject a dll into the process that uses the message box, our dll will look like this.
Copy #include <detours.h>
#include <stdio.h>
#include <windows.h>
static int (WINAPI* NativeMessageBox)(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
) = MessageBox;
int WINAPI MyMessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType) {
return NativeMessageBox(hWnd, L"Hooked", lpCaption, uType);
}
BOOL WINAPI DllMain(HINSTANCE hinst, DWORD dwReason, LPVOID reserved) {
switch (dwReason) {
case DLL_PROCESS_ATTACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)NativeMessageBox, MyMessageBox);
DetourTransactionCommit();
break;
case DLL_THREAD_ATTACH:
break;
case DLL_THREAD_DETACH:
break;
case DLL_PROCESS_DETACH:
DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)NativeMessageBox, MyMessageBox);
DetourTransactionCommit();
break;
}
return TRUE;
}
First, we make a pointer to the original MessageBox
Copy static int (WINAPI* NativeMessageBox)(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType
) = MessageBox;
Then, we create the "hooking function", which is the function that will replace the original message box.
Copy int WINAPI MyMessageBox(
HWND hWnd,
LPCTSTR lpText,
LPCTSTR lpCaption,
UINT uType) {
return NativeMessageBox(hWnd, L"Hooked", lpCaption, uType);
}
Then, when our dll gets attached, we will being hooking with this code.
Copy DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourAttach(&(PVOID&)NativeMessageBox, MyMessageBox);
DetourTransactionCommit();
And when our dll gets detached, we will unhook the code.
Copy DetourTransactionBegin();
DetourUpdateThread(GetCurrentThread());
DetourDetach(&(PVOID&)NativeMessageBox, MyMessageBox);
DetourTransactionCommit();
For our injector, we can use a simple dll injector or use Process hacker to inject a dll. Our next step is to then inject our dll into the target process with the messagebox function and resume execution by entering a key to get through getchar().
When injected, this DLL will change the message that the messagebox popups during execution.