#include #include #include // 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; // hooked function with malicious code that eventually calls the original MessageBoxA int hookedMessageBox(HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType) { MessageBoxW(NULL, L"Ola Hooked from a Rogue Senor .o.", L"Ola Senor o/", 0); // execute the original NessageBoxA return originalMsgBox(hWnd, lpText, lpCaption, uType); } int main() { // message box before IAT unhooking MessageBoxA(NULL, "Hello Before Hooking", "Hello Before Hooking", 0); 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; 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 MessageBoxA address if (std::string(functionName->Name).compare("MessageBoxA") == 0) { SIZE_T bytesWritten = 0; DWORD oldProtect = 0; VirtualProtect((LPVOID)(&firstThunk->u1.Function), 8, PAGE_READWRITE, &oldProtect); // swap MessageBoxA address with address of hookedMessageBox firstThunk->u1.Function = (DWORD_PTR)hookedMessageBox; } ++originalFirstThunk; ++firstThunk; } } importDescriptor++; } // message box after IAT hooking MessageBoxA(NULL, "Hello after Hooking", "Hello after Hooking", 0); return 0; }