IAT Hook
- IAT Hook 工作原理
IAT Hook是通过修改IAT中保存的API地址来钩取某个API函数。
在进程中调用某个API函数,是在目标进程中的导入表中查找函数地址来进行调用,不同于GetProcAddress函数。此函数是在模块的导出表中进行查找函数地址的。
所以我们可以注入动态库到目标进程,来实现对目标API的钩取。关于动态库的注入可以参考其他博文。
- 代码实现
1 // include 2 #include "stdio.h" 3 #include "wchar.h" 4 #include "windows.h" 5 6 7 // typedef 8 typedef BOOL (WINAPI *PFSETWINDOWTEXTW)(HWND hWnd, LPWSTR lpString); 9 10 11 12 FARPROC OldFunction = NULL; 13 14 15 // 修改后再显示 16 BOOL WINAPI MySetWindowTextW(HWND hWnd, LPWSTR lpString) 17 { 18 wchar_t* pNum = L"康老捞伙荤坷腊磨迫备"; 19 wchar_t temp[2] = {0,}; 20 int i = 0, nLen = 0, nIndex = 0; 21 22 nLen = wcslen(lpString); 23 for(i = 0; i < nLen; i++) 24 { 25 26 if( L'0' <= lpString[i] && lpString[i] <= L'9' ) 27 { 28 temp[0] = lpString[i]; 29 nIndex = _wtoi(temp); 30 lpString[i] = pNum[nIndex]; 31 } 32 } 33 34 35 return ((PFSETWINDOWTEXTW)OldFunction)(hWnd, lpString); 36 } 37 38 39 // hook_iat 40 // 泅犁 橇肺技胶狼 IAT 甫 八祸秦辑 41 // pfnOrg 蔼阑 pfnNew 蔼栏肺 函版矫糯 42 BOOL HOOKIAT(LPCSTR szDllName, PROC OldFunction, PROC NewFunction) 43 { 44 HMODULE ModuleHandle; 45 LPCSTR szLibName; 46 PIMAGE_IMPORT_DESCRIPTOR pImportDesc; 47 PIMAGE_THUNK_DATA pThunk; 48 DWORD dwOldProtect, dwRVA; 49 PBYTE AddressOfImage; 50 51 // DOSHeader 52 ModuleHandle = GetModuleHandle(NULL); 53 AddressOfImage = (PBYTE)ModuleHandle; 54 55 // AddressOfImage = VA to PE signature (IMAGE_NT_HEADERS) 56 AddressOfImage += *((DWORD*)&AddressOfImage[0x3C]); 57 58 // dwRVA = RVA to IMAGE_IMPORT_DESCRIPTOR Table 59 dwRVA = *((DWORD*)&AddressOfImage[0x80]); 60 61 // pImportDesc = VA to IMAGE_IMPORT_DESCRIPTOR Table 62 pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)((DWORD)ModuleHandle +dwRVA); 63 64 for( ; pImportDesc->Name; pImportDesc++ ) 65 { 66 // szLibName = VA to IMAGE_IMPORT_DESCRIPTOR.Name 67 szLibName = (LPCSTR)((DWORD)ModuleHandle + pImportDesc->Name); 68 if( !_stricmp(szLibName, szDllName) ) 69 { 70 // pThunk = IMAGE_IMPORT_DESCRIPTOR.FirstThunk 71 // = VA to IAT(Import Address Table) 72 pThunk = (PIMAGE_THUNK_DATA)((DWORD)ModuleHandle + 73 pImportDesc->FirstThunk); 74 75 // pThunk->u1.Function API函数的虚拟地址 76 for( ; pThunk->u1.Function; pThunk++ ) 77 { 78 if( pThunk->u1.Function == (DWORD)OldFunction) 79 { 80 // 修改内存页为可读可写可执行 81 VirtualProtect((LPVOID)&pThunk->u1.Function, 82 4, 83 PAGE_EXECUTE_READWRITE, 84 &dwOldProtect); 85 86 // 修改函数地址 87 pThunk->u1.Function = (DWORD)NewFunction; 88 89 VirtualProtect((LPVOID)&pThunk->u1.Function, 90 4, 91 dwOldProtect, 92 &dwOldProtect); 93 94 return TRUE; 95 } 96 } 97 } 98 } 99 100 return FALSE; 101 } 102 103 104 105 BOOL WINAPI DllMain(HINSTANCE hinstDLL, DWORD fdwReason, LPVOID lpvReserved) 106 { 107 switch( fdwReason ) 108 { 109 case DLL_PROCESS_ATTACH : 110 111 OldFunction = GetProcAddress(GetModuleHandle(L"user32.dll"), 112 "SetWindowTextW"); 113 114 //HOOK 115 HOOKIAT("user32.dll", OldFunction, (PROC)MySetWindowTextW); 116 break; 117 118 case DLL_PROCESS_DETACH : 119 //UNHOOK 120 HOOKIAT("user32.dll", (PROC)MySetWindowTextW, OldFunction); 121 break; 122 } 123 124 return TRUE; 125 }
参考《逆向工程核心原理》