One of the ways to do API Hooking is to modify the Import Address Table. Here is a quick example on how to do
hook into the API call MessageBoxW within your own process. The following example hooks into MessageBoxW and
changes the caption to "Awesome" for all your message boxes.
#include <windows.h>
#define MakePtr( cast, ptr, addValue ) (cast)((DWORD_PTR)(ptr)+(DWORD_PTR)(addValue))
typedef int(WINAPI* MB)(HWND, LPCWSTR, LPCWSTR, UINT);
MB OldMessageBox;
int WINAPI MyMessageBox(HWND hwnd, LPCWSTR lpText, LPCWSTR lpCaption, UINT uType)
{
return OldMessageBox(hwnd, lpText, L"Awesome", uType);
}
void ModifyImportAddressTable(HMODULE hMod, MB ep)
{
PIMAGE_DOS_HEADER pDosHeader;
PIMAGE_NT_HEADERS pNTHeader;
PIMAGE_IMPORT_DESCRIPTOR pImportDesc;
PIMAGE_THUNK_DATA pThunk;
DWORD OldAttribute;
pDosHeader = (PIMAGE_DOS_HEADER)hMod;
if (!pDosHeader)
{
pDosHeader = (PIMAGE_DOS_HEADER)GetModuleHandle(NULL);
}
if (!pDosHeader) return;
pNTHeader = MakePtr(PIMAGE_NT_HEADERS, pDosHeader, pDosHeader->e_lfanew);
pImportDesc = MakePtr(PIMAGE_IMPORT_DESCRIPTOR, pDosHeader,
pNTHeader->OptionalHeader.
DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].
VirtualAddress);
while (pImportDesc->Name)
{
PSTR pszModName = MakePtr(PSTR, pDosHeader, pImportDesc->Name);
if (lstrcmpiA(pszModName, "USER32.DLL") == 0)
{
break;
}
pImportDesc++;
}
pThunk = MakePtr(PIMAGE_THUNK_DATA, pDosHeader, pImportDesc->FirstThunk);
while (pThunk->u1.Function)
{
if (pThunk->u1.Function == (DWORD_PTR)ep)
{
if (VirtualProtect(&pThunk->u1.Function, 8, PAGE_READWRITE, &OldAttribute))
{
pThunk->u1.Function = (DWORD_PTR)MyMessageBox;
}
break;
}
pThunk++;
}
}
void ModifyMessageBox()
{
HMODULE hMod = GetModuleHandle(L"USER32.DLL");
if (hMod)
{
OldMessageBox = reinterpret_cast<MB>(GetProcAddress(hMod, "MessageBoxW"));
if (OldMessageBox)
{
ModifyImportAddressTable(GetModuleHandle(NULL), OldMessageBox);
}
}
}