Created
December 8, 2022 02:39
-
-
Save duketwo/7964798230d2baef951602528ee0b9ce to your computer and use it in GitHub Desktop.
IAT-Hooking
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#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