APIHook

  1. //////////////////////////////////////////////////////////////
  2. // APIHook.cpp文件
  3. #include "APIHook.h"
  4. #include "Tlhelp32.h"
  5. #include <imagehlp.h>   // 为了调用ImageDirectoryEntryToData函数
  6. #pragma comment(lib, "ImageHlp")
  7. // CAPIHook对象链表的头指针
  8. CAPIHook* CAPIHook::sm_pHeader = NULL;  
  9. CAPIHook::CAPIHook(LPSTR pszModName, LPSTR pszFuncName, PROC pfnHook, BOOL bExcludeAPIHookMod)  
  10. {  
  11. // 保存这个Hook函数的信息
  12.     m_bExcludeAPIHookMod = bExcludeAPIHookMod;  
  13.     m_pszModName = pszModName;  
  14.     m_pszFuncName = pszFuncName;  
  15.     m_pfnHook = pfnHook;  
  16.     m_pfnOrig = ::GetProcAddress(::GetModuleHandle(pszModName), pszFuncName);  
  17. // 将此对象添加到链表中
  18.     m_pNext = sm_pHeader;  
  19.     sm_pHeader = this;  
  20. // 在所有当前已加载的模块中HOOK这个函数
  21.     ReplaceIATEntryInAllMods(m_pszModName, m_pfnOrig, m_pfnHook, bExcludeAPIHookMod);   
  22. }  
  23. CAPIHook::~CAPIHook()  
  24. {  
  25. // 取消对所有模块中函数的HOOK
  26.     ReplaceIATEntryInAllMods(m_pszModName, m_pfnHook, m_pfnOrig, m_bExcludeAPIHookMod);  
  27.     CAPIHook *p = sm_pHeader;  
  28. // 从链表中移除此对象
  29. if(p == this)  
  30.     {  
  31.         sm_pHeader = p-&gt;m_pNext;  
  32.     }  
  33. else
  34.     {  
  35. while(p != NULL)  
  36.         {  
  37. if(p-&gt;m_pNext == this)  
  38.             {  
  39.                 p-&gt;m_pNext = this-&gt;m_pNext;  
  40. break;  
  41.             }  
  42.             p = p-&gt;m_pNext;  
  43.         }  
  44.     }  
  45. }  
  46. void CAPIHook::ReplaceIATEntryInOneMod(LPSTR pszExportMod,   
  47.                    PROC pfnCurrent, PROC pfnNew, HMODULE hModCaller)  
  48. {  
  49. // 取得模块的导入表(import descriptor)首地址。ImageDirectoryEntryToData函数可以直接返回导入表地址
  50. ULONG ulSize;  
  51.     PIMAGE_IMPORT_DESCRIPTOR pImportDesc = (PIMAGE_IMPORT_DESCRIPTOR)  
  52.                 ::ImageDirectoryEntryToData(hModCaller, TRUE,   
  53.                     IMAGE_DIRECTORY_ENTRY_IMPORT, &ulSize);  
  54. if(pImportDesc == NULL) // 这个模块没有导入节表
  55.     {  
  56. return;  
  57.     }  
  58. // 查找包含pszExportMod模块中函数导入信息的导入表项
  59. while(pImportDesc-&gt;Name != 0)  
  60.     {  
  61. LPSTR pszMod = (LPSTR)((DWORD)hModCaller + pImportDesc-&gt;Name);  
  62. if(lstrcmpiA(pszMod, pszExportMod) == 0) // 找到
  63. break;  
  64.         pImportDesc++;  
  65.     }  
  66. if(pImportDesc-&gt;Name == 0) // hModCaller模块没有从pszExportMod模块导入任何函数
  67.     {  
  68. return;  
  69.     }  
  70. // 取得调用者的导入地址表(import address table, IAT)
  71.     PIMAGE_THUNK_DATA pThunk = (PIMAGE_THUNK_DATA)(pImportDesc-&gt;FirstThunk + (DWORD)hModCaller);  
  72. // 查找我们要HOOK的函数,将它的地址用新函数的地址替换掉
  73. while(pThunk-&gt;u1.Function)  
  74.     {  
  75. // lpAddr指向的内存保存了函数的地址
  76.         PDWORD lpAddr = (PDWORD)&(pThunk-&gt;u1.Function);  
  77. if(*lpAddr == (DWORD)pfnCurrent)  
  78.         {  
  79. // 修改页的保护属性
  80. DWORD dwOldProtect;  
  81.             MEMORY_BASIC_INFORMATION mbi;  
  82.             ::VirtualQuery(lpAddr, &mbi, sizeof(mbi));  
  83.             ::VirtualProtect(lpAddr, sizeof(DWORD), PAGE_READWRITE, &dwOldProtect);  
  84. // 修改内存地址  相当于“*lpAddr = (DWORD)pfnNew;”
  85.             ::WriteProcessMemory(::GetCurrentProcess(),   
  86.                         lpAddr, &pfnNew, sizeof(DWORD), NULL);  
  87.             ::VirtualProtect(lpAddr, sizeof(DWORD), dwOldProtect, 0);  
  88. break;  
  89.         }  
  90.         pThunk++;  
  91.     }  
  92. }  
  93. void CAPIHook::ReplaceIATEntryInAllMods(LPSTR pszExportMod,   
  94.                     PROC pfnCurrent, PROC pfnNew, BOOL bExcludeAPIHookMod)  
  95. {  
  96. // 取得当前模块的句柄
  97. HMODULE hModThis = NULL;  
  98. if(bExcludeAPIHookMod)  
  99.     {  
  100.         MEMORY_BASIC_INFORMATION mbi;  
  101. if(::VirtualQuery(ReplaceIATEntryInAllMods, &mbi, sizeof(mbi)) != 0)  
  102.             hModThis = (HMODULE)mbi.AllocationBase;  
  103.     }  
  104. // 取得本进程的模块列表
  105. HANDLE hSnap = ::CreateToolhelp32Snapshot(TH32CS_SNAPMODULE, ::GetCurrentProcessId());  
  106. // 遍历所有模块,分别对它们调用ReplaceIATEntryInOneMod函数,修改导入地址表
  107.     MODULEENTRY32 me = { sizeof(MODULEENTRY32) };  
  108. BOOL bOK = ::Module32First(hSnap, &me);  
  109. while(bOK)  
  110.     {  
  111. // 注意:我们不HOOK当前模块的函数
  112. if(me.hModule != hModThis)  
  113.             ReplaceIATEntryInOneMod(pszExportMod, pfnCurrent, pfnNew, me.hModule);  
  114.         bOK = ::Module32Next(hSnap, &me);  
  115.     }  
  116.     ::CloseHandle(hSnap);  
  117. }  
  118. // 挂钩LoadLibrary和GetProcAddress函数,以便在这些函数被调用以后,挂钩的函数也能够被正确的处理
  119. CAPIHook CAPIHook::sm_LoadLibraryA("Kernel32.dll", "LoadLibraryA",     
  120.                     (PROC)CAPIHook::LoadLibraryA, TRUE);  
  121. CAPIHook CAPIHook::sm_LoadLibraryW("Kernel32.dll", "LoadLibraryW",     
  122.                     (PROC)CAPIHook::LoadLibraryW, TRUE);  
  123. CAPIHook CAPIHook::sm_LoadLibraryExA("Kernel32.dll", "LoadLibraryExA",   
  124.                     (PROC)CAPIHook::LoadLibraryExA, TRUE);  
  125. CAPIHook CAPIHook::sm_LoadLibraryExW("Kernel32.dll", "LoadLibraryExW",   
  126.                     (PROC)CAPIHook::LoadLibraryExW, TRUE);  
  127. CAPIHook CAPIHook::sm_GetProcAddress("Kernel32.dll", "GetProcAddress",   
  128.                     (PROC)CAPIHook::GetProcAddress, TRUE);  
  129. void WINAPI CAPIHook::HookNewlyLoadedModule(HMODULE hModule, DWORD dwFlags)  
  130. {  
  131. // 如果一个新的模块被加载,挂钩各CAPIHook对象要求的API函数
  132. if((hModule != NULL) && ((dwFlags&LOAD_LIBRARY_AS_DATAFILE) == 0))  
  133.     {  
  134.         CAPIHook *p = sm_pHeader;  
  135. while(p != NULL)  
  136.         {  
  137.             ReplaceIATEntryInOneMod(p-&gt;m_pszModName, p-&gt;m_pfnOrig, p-&gt;m_pfnHook, hModule);  
  138.             p = p-&gt;m_pNext;  
  139.         }  
  140.     }  
  141. }  
  142. HMODULE WINAPI CAPIHook::LoadLibraryA(PCSTR pszModulePath)   
  143. {  
  144. HMODULE hModule = ::LoadLibraryA(pszModulePath);  
  145.     HookNewlyLoadedModule(hModule, 0);  
  146. return(hModule);  
  147. }  
  148. HMODULE WINAPI CAPIHook::LoadLibraryW(PCWSTR pszModulePath)   
  149. {  
  150. HMODULE hModule = ::LoadLibraryW(pszModulePath);  
  151.     HookNewlyLoadedModule(hModule, 0);  
  152. return(hModule);  
  153. }  
  154. HMODULE WINAPI CAPIHook::LoadLibraryExA(PCSTR pszModulePath, HANDLE hFile, DWORD dwFlags)   
  155. {  
  156. HMODULE hModule = ::LoadLibraryExA(pszModulePath, hFile, dwFlags);  
  157.     HookNewlyLoadedModule(hModule, dwFlags);  
  158. return(hModule);  
  159. }  
  160. HMODULE WINAPI CAPIHook::LoadLibraryExW(PCWSTR pszModulePath, HANDLE hFile, DWORD dwFlags)   
  161. {  
  162. HMODULE hModule = ::LoadLibraryExW(pszModulePath, hFile, dwFlags);  
  163.     HookNewlyLoadedModule(hModule, dwFlags);  
  164. return(hModule);  
  165. }  
  166. FARPROC WINAPI CAPIHook::GetProcAddress(HMODULE hModule, PCSTR pszProcName)  
  167. {  
  168. // 得到这个函数的真实地址
  169.     FARPROC pfn = ::GetProcAddress(hModule, pszProcName);  
  170. // 看它是不是我们要hook的函数
  171.     CAPIHook *p = sm_pHeader;  
  172. while(p != NULL)  
  173.     {  
  174. if(p-&gt;m_pfnOrig == pfn)  
  175.         {  
  176.             pfn = p-&gt;m_pfnHook;  
  177. break;  
  178.         }  
  179.         p = p-&gt;m_pNext;  
  180.     }  
  181. return pfn;  
  182. }  
  183. </imagehlp.h> 

你可能感兴趣的:(职场,休闲,APIHOOK)