Skip to content

Instantly share code, notes, and snippets.

@duketwo
Created December 8, 2022 02:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save duketwo/7964798230d2baef951602528ee0b9ce to your computer and use it in GitHub Desktop.
Save duketwo/7964798230d2baef951602528ee0b9ce to your computer and use it in GitHub Desktop.
IAT-Hooking
#include <iostream>
#include <Windows.h>
#include <winternl.h>
#define OUT
// define MessageBoxA prototype
using PrototypeMessageBox = int (WINAPI*)(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType);
// remember memory address of the original MessageBoxA routine
PrototypeMessageBox originalMsgBox = MessageBoxA;
// detour
int hookedMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType)
{
MessageBoxW(NULL, L"Hello from the hook", L"o7", 0);
// exec orig
return originalMsgBox(hWnd, lpText, lpCaption, uType);
}
void installIATHook(LPCSTR libName, const char* funcName, void* pointer, OUT void* & original) {
LPVOID imageBase = GetModuleHandleA(NULL);
PIMAGE_DOS_HEADER dosHeaders = (PIMAGE_DOS_HEADER)imageBase;
PIMAGE_NT_HEADERS ntHeaders = (PIMAGE_NT_HEADERS)((DWORD_PTR)imageBase + dosHeaders->e_lfanew);
PIMAGE_IMPORT_DESCRIPTOR importDescriptor = NULL;
IMAGE_DATA_DIRECTORY importsDirectory = ntHeaders->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT];
importDescriptor = (PIMAGE_IMPORT_DESCRIPTOR)(importsDirectory.VirtualAddress + (DWORD_PTR)imageBase);
LPCSTR libraryName = NULL;
HMODULE library = NULL;
PIMAGE_IMPORT_BY_NAME functionName = NULL;
while (importDescriptor->Name != NULL)
{
libraryName = (LPCSTR)importDescriptor->Name + (DWORD_PTR)imageBase;
if (_stricmp(libraryName, libName) != 0) {
importDescriptor++;
continue;
}
library = LoadLibraryA(libraryName);
if (library)
{
PIMAGE_THUNK_DATA originalFirstThunk = NULL, firstThunk = NULL;
originalFirstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor->OriginalFirstThunk);
firstThunk = (PIMAGE_THUNK_DATA)((DWORD_PTR)imageBase + importDescriptor->FirstThunk);
while (originalFirstThunk->u1.AddressOfData != NULL)
{
functionName = (PIMAGE_IMPORT_BY_NAME)((DWORD_PTR)imageBase + originalFirstThunk->u1.AddressOfData);
// find func address
if (std::string(functionName->Name).compare(funcName) == 0)
{
SIZE_T bytesWritten = 0;
DWORD oldProtect = 0;
VirtualProtect((LPVOID)(&firstThunk->u1.Function), 8, PAGE_READWRITE, &oldProtect);
original = (void* )firstThunk->u1.Function;
// swap func address with address of given pointer
firstThunk->u1.Function = (DWORD_PTR)pointer;
}
++originalFirstThunk;
++firstThunk;
}
}
importDescriptor++;
}
}
int main()
{
// message box before IAT unhooking
MessageBoxA(NULL, "Hello Before Hooking", "Hello Before Hooking", 0);
void* hookedFunc = (void*)hookedMessageBox;
void* original = 0L;
installIATHook("user32.dll", "MessageBoxA", hookedFunc, original);
std::cout << "Original Ptr: " << original << " HookedFunc Ptr: " << hookedFunc << std::endl;
// message box after IAT hooking
MessageBoxA(NULL, "Hello after Hooking", "Hello after Hooking", 0);
// restoring the hook
installIATHook("user32.dll", "MessageBoxA", original, hookedFunc);
std::cout << "Original Ptr: " << original << " HookedFunc Ptr: " << hookedFunc << std::endl;
MessageBoxA(NULL, "Hello after Unhooking", "Hello after Unhooking", 0);
return 0;
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment