1. #include <Windows.h>
  2. #include <Psapi.h>
  3. #include <string>
  4.  
  5. #if PSAPI_VERSION == 1
  6. #pragma comment(lib, "Psapi.lib")
  7. #endif
  8.  
  9. template <typename DestType, typename SrcType>
  10. DestType* ByteOffset(SrcType* ptr, ptrdiff_t offset)
  11. {
  12.     return reinterpret_cast<DestType*>(reinterpret_cast<unsigned char*>(ptr) + offset);
  13. }
  14.  
  15. bool eat_hook(void* old_function, void* new_function)
  16. {
  17.     HMODULE hModule;
  18.     GetModuleHandleEx(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS, (LPCSTR)old_function, &hModule);
  19.  
  20.     PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)hModule;
  21.     PIMAGE_NT_HEADERS NtHeader = ByteOffset<IMAGE_NT_HEADERS>(DosHeader, DosHeader->e_lfanew);
  22.     if (IMAGE_NT_SIGNATURE != NtHeader->Signature)
  23.     {
  24.         MessageBox(0, "Bad NT header signature", "Error", 0);
  25.         return false;
  26.     }
  27.  
  28.     PIMAGE_EXPORT_DIRECTORY ExportDirectory = ByteOffset<IMAGE_EXPORT_DIRECTORY>(DosHeader,
  29.         NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_EXPORT].VirtualAddress);
  30.    
  31.     DWORD* functions = ByteOffset<DWORD>(DosHeader, ExportDirectory->AddressOfFunctions);
  32.     for (size_t i = 0; i < ExportDirectory->NumberOfFunctions; ++i)
  33.     {
  34.         if (functions[i] == (DWORD)old_function - (DWORD)hModule)
  35.         {
  36.             DWORD oldProtection;
  37.             if (!VirtualProtect(functions + i, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection))
  38.             {
  39.                 MessageBox(0, "VirtualProtect failed", "Error", 0);
  40.                 return false;
  41.             }
  42.  
  43.             functions[i] = reinterpret_cast<DWORD>(new_function) - reinterpret_cast<DWORD>(DosHeader);
  44.  
  45.             if (!VirtualProtect(functions + i, sizeof(DWORD), oldProtection, &oldProtection))
  46.             {
  47.                 MessageBox(0, "VirtualProtect failed", "Error", 0);
  48.                 return false;
  49.             }
  50.  
  51.             return true;
  52.         }
  53.     }
  54.  
  55.     return false;
  56. }
  57.  
  58. bool iat_hook(void* old_function, void* new_function)
  59. {
  60.     HMODULE hModule;
  61.     DWORD sizeNeeded;
  62.     if (0 == EnumProcessModules(GetCurrentProcess(), &hModule, sizeof(hModule), &sizeNeeded))
  63.     {
  64.         MessageBox(0, "EnumProcessModules failed", "Error", 0);
  65.         return false;
  66.     }
  67.  
  68.     PIMAGE_DOS_HEADER DosHeader = (PIMAGE_DOS_HEADER)hModule;
  69.     PIMAGE_NT_HEADERS NtHeader = ByteOffset<IMAGE_NT_HEADERS>(DosHeader, DosHeader->e_lfanew);
  70.     if (IMAGE_NT_SIGNATURE != NtHeader->Signature)
  71.     {
  72.         MessageBox(0, "Bad NT header signature", "Error", 0);
  73.         return false;
  74.     }
  75.    
  76.     PIMAGE_IMPORT_DESCRIPTOR ImportDirectory = ByteOffset<IMAGE_IMPORT_DESCRIPTOR>(DosHeader,
  77.         NtHeader->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_IMPORT].VirtualAddress);
  78.    
  79.     for (size_t i = 0; ImportDirectory[i].Characteristics; ++i)
  80.     {
  81.         PIMAGE_THUNK_DATA thunk = ByteOffset<IMAGE_THUNK_DATA>(hModule, ImportDirectory[i].FirstThunk);
  82.         PIMAGE_THUNK_DATA origThunk = ByteOffset<IMAGE_THUNK_DATA>(hModule, ImportDirectory[i].OriginalFirstThunk);
  83.  
  84.         for (; origThunk->u1.Function; origThunk++, thunk++)
  85.         {
  86.             if (thunk->u1.Function == (DWORD)old_function)
  87.             {
  88.                 DWORD oldProtection;
  89.                 if (!VirtualProtect(&thunk->u1.Function, sizeof(DWORD), PAGE_EXECUTE_READWRITE, &oldProtection))
  90.                 {
  91.                     MessageBox(0, "VirtualProtect failed", "Error", 0);
  92.                     return false;
  93.                 }
  94.  
  95.                 thunk->u1.Function = reinterpret_cast<DWORD>(new_function);
  96.  
  97.                 if (!VirtualProtect(&thunk->u1.Function, sizeof(DWORD), oldProtection, &oldProtection))
  98.                 {
  99.                     MessageBox(0, "VirtualProtect failed", "Error", 0);
  100.                     return false;
  101.                 }
  102.  
  103.                 return true;
  104.             }
  105.         }
  106.     }
  107.  
  108.     return false;
  109. }
  110.  
  111. bool hook(void* old_function, void* new_function)
  112. {
  113.     return eat_hook(old_function, new_function) && iat_hook(old_function, new_function);
  114. }