#include #include #include #if PSAPI_VERSION == 1 #pragma comment(lib, "Psapi.lib") #endif template DestType* ByteOffset(SrcType* ptr, ptrdiff_t offset) { return reinterpret_cast(reinterpret_cast(ptr) + offset); } bool eat_hook(void* old_function, void* new_function) { HMODULE hModule; GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)old_function, &hModule); PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)hModule; PIMAGE_NT_HEADERS NtHeader = ByteOffset(DosHeader, DosHeader->e_lfanew); if (IMAGE_NT_SIGNATURE != NtHeader->Signature) { MessageBox(0, "Bad NT header signature", "Error", 0); return false; } PIMAGE_EXPORT_DIRECTORY ExportDirectory = ByteOffset(DosHeader, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress); DWORD* functions = ByteOffset(DosHeader, ExportDirectory->AddressOfFunctions); for (size_t i = 0; i < ExportDirectory->NumberOfFunctions; ++i) { if (functions[i] == (DWORD)old_function - (DWORD)hModule) { DWORD oldProtection; if (!VirtualProtect(functions + i, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection)) { MessageBox(0, "VirtualProtect failed", "Error", 0); return false; } functions[i] = reinterpret_cast(new_function) - reinterpret_cast(DosHeader); if (!VirtualProtect(functions + i, sizeof(DWORD), oldProtection, &oldProtection)) { MessageBox(0, "VirtualProtect failed", "Error", 0); return false; } return true; } } return false; } bool iat_hook(void* old_function, void* new_function) { HMODULE hModule; DWORD sizeNeeded; if (0 == EnumProcessModules(GetCurrentProcess(), &hModule, sizeof(hModule), &sizeNeeded)) { MessageBox(0, "EnumProcessModules failed", "Error", 0); return false; } PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)hModule; PIMAGE_NT_HEADERS NtHeader = ByteOffset(DosHeader, DosHeader->e_lfanew); if (IMAGE_NT_SIGNATURE != NtHeader->Signature) { MessageBox(0, "Bad NT header signature", "Error", 0); return false; } PIMAGE_IMPORT_DESCRIPTOR ImportDirectory = ByteOffset(DosHeader, NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress); for (size_t i = 0; ImportDirectory[i].Characteristics; ++i) { PIMAGE_THUNK_DATA thunk = ByteOffset(hModule, ImportDirectory[i].FirstThunk); PIMAGE_THUNK_DATA origThunk = ByteOffset(hModule, ImportDirectory[i].OriginalFirstThunk); for (; origThunk->u1.Function; origThunk++, thunk++) { if (thunk->u1.Function == (DWORD)old_function) { DWORD oldProtection; if (!VirtualProtect(&thunk->u1.Function, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection)) { MessageBox(0, "VirtualProtect failed", "Error", 0); return false; } thunk->u1.Function = reinterpret_cast(new_function); if (!VirtualProtect(&thunk->u1.Function, sizeof(DWORD), oldProtection, &oldProtection)) { MessageBox(0, "VirtualProtect failed", "Error", 0); return false; } return true; } } } return false; } bool hook(void* old_function, void* new_function) { return eat_hook(old_function, new_function) && iat_hook(old_function, new_function); }