C++ Win32 API Hook类
HookApi.h
#include <windows.h> #ifndef _HOOKAPI_H #define _HOOKAPI_H class CHOOKAPI { public: LPVOID pOldFunEntry, pNewFunEntry ; // 初始函数地址、HOOK后的函数地址 BYTE bOldByte[5], bNewByte[5] ; // 原始字节、目标字节 public: CHOOKAPI () {} ~CHOOKAPI() {} // 实现HOOK API void Hook ( PSTR szModuleName, PSTR szFunName, FARPROC pFun ) { HMODULE hMod = ::GetModuleHandleA ( szModuleName ) ; if ( hMod != NULL ) { pNewFunEntry = (LPVOID)pFun ; pOldFunEntry = (LPVOID)GetProcAddress ( hMod, szFunName ) ; bNewByte[0] = 0xE9 ; *((PDWORD)(&(bNewByte[1]))) = (DWORD)pNewFunEntry - (DWORD)pOldFunEntry - 5 ; DWORD dwProtect, dwWriteByte, dwReadByte ; VirtualProtect ( (LPVOID)pOldFunEntry, 5, PAGE_READWRITE, &dwProtect ); ReadProcessMemory ( GetCurrentProcess(), (LPVOID)pOldFunEntry, bOldByte, 5, &dwReadByte ) ; WriteProcessMemory ( GetCurrentProcess(), (LPVOID)pOldFunEntry, bNewByte, 5, &dwWriteByte ) ; VirtualProtect ( (LPVOID)pOldFunEntry, 5, dwProtect, NULL ) ; } } // 重新HOOK void ReHook () { DWORD dwProtect, dwWriteByte ; VirtualProtect ( pOldFunEntry, 5, PAGE_READWRITE, &dwProtect ); WriteProcessMemory ( GetCurrentProcess(), pOldFunEntry, bNewByte, 5, &dwWriteByte ) ; VirtualProtect ( pOldFunEntry, 5, dwProtect, NULL ) ; } // 撤消HOOK void UnHook () { DWORD dwProtect, dwWriteByte ; VirtualProtect ( pOldFunEntry, 5, PAGE_READWRITE, &dwProtect ); WriteProcessMemory ( GetCurrentProcess(), pOldFunEntry, bOldByte, 5, &dwWriteByte ) ; VirtualProtect ( pOldFunEntry, 5, dwProtect, NULL ) ; } } ; #endif
调用测试:
#include "stdafx.h" #include "HookApi.h" CHOOKAPI HookItem ; // 定义MessageBoxA函数原型 typedef int (WINAPI* PFNMessageBoxA)( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) ; // 自定义的MessageBoxA函数 // 实现对原始MessageBoxA的输入、输出参数的监控,甚至是取消调用 int WINAPI New_MessageBoxA( HWND hWnd, LPCSTR lpText, LPCSTR lpCaption, UINT uType ) { // 撤消HOOK HookItem.UnHook () ; // 此处可以观察/修改调用参数,甚至可以取消调用直接返回。 // …… // 取得原函数地址 PFNMessageBoxA pfnMessageBoxA = (PFNMessageBoxA)HookItem.pOldFunEntry ; // 调用原函数,修改输入参数 int ret = pfnMessageBoxA ( hWnd, "这是HOOK函数过程的消息框", "[测试]", uType ) ; // 此处可以查看/修改调用原函数的返回值 // …… // 重新HOOK HookItem.ReHook () ; return ret ; } int main(int argc, char* argv[]) { // 原始API MessageBoxA ( 0, "正常消息框", "测试", 0 ) ; // HOOK API HookItem.Hook ( "USER32.dll", "MessageBoxA", (FARPROC)New_MessageBoxA ) ; // 调用API,测试 MessageBoxA ( 0, "正常消息框", "测试", 0 ) ; // 撤消HOOK HookItem.UnHook () ; printf("Hello World!\n"); return 0; }