MyHookClass
根据择善视频,记录截获 MessageBoxW 的 Hook 函数,封装成 MyHookClass. 是个WIN32控制台程序。
1 // HookDemo.cpp : 定义控制台应用程序的入口点。 2 // 3 4 #include "stdafx.h" 5 #include "windows.h" 6 7 //全局变量 8 9 BYTE g_oldByte[5] = { 0 }; 10 PROC g_pfnOld; 11 12 class MyHookClass 13 { 14 public: 15 MyHookClass(); 16 ~MyHookClass(); 17 18 /** 19 * Inline 挂钩函数 20 * @return 挂钩是否成功 21 */ 22 BOOL Hook(PROC pHookAddr, PROC pHookFunc); 23 BOOL Hook(char *szModualName, char *szFuncName, PROC pHookFunc); 24 BOOL UnHook(); 25 26 private: 27 // 用于UnHook的一个地址 28 PROC m_pfnOld; 29 // 用于UnHook的内容 30 BYTE m_oldByte[5]; 31 }; 32 33 MyHookClass::MyHookClass() 34 { 35 g_pfnOld = nullptr; 36 ZeroMemory(m_oldByte, 5); 37 } 38 39 MyHookClass::~MyHookClass() 40 { 41 UnHook(); 42 } 43 44 BOOL MyHookClass::Hook(PROC pHookAddr, PROC pHookFunc) 45 { 46 // MessageBox 是一个宏,没有具体的符号导出 47 // 获取 MessageBoxW 的 API 首地址 48 // 起始地址 49 //g_pfnOld = GetProcAddress(GetModuleHandle(L"user32.dll"), pHookFunc); 50 m_pfnOld = pHookFunc; 51 if (!m_pfnOld) 52 { 53 return FALSE; 54 } 55 // 保存以便恢复 56 ReadProcessMemory(GetCurrentProcess(), g_pfnOld, g_oldByte, 5, nullptr); 57 58 // call MyMessageBox 59 // 0xE9 MessageBox 的首地址 60 // 0xE9 是一个机器码,这个机器码的作用是无条件跳转(JMP) 61 // 0xE9 + 地址(4个字节)= 5个字节 62 BYTE newByte[5] = { 0 }; 63 newByte[0] = 0xE9; // 无条件跳转(JMP) 64 // 目标地址 65 PROC pfnMy = (PROC)pHookAddr; 66 67 *(DWORD *)(newByte + 1) = (DWORD)pfnMy - (DWORD)g_pfnOld - 5; 68 WriteProcessMemory(GetCurrentProcess(), g_pfnOld, newByte, 5, nullptr); 69 70 return TRUE; 71 72 } 73 74 BOOL MyHookClass::UnHook() 75 { 76 // 恢复 API 地址 77 WriteProcessMemory(GetCurrentProcess(), g_pfnOld, g_oldByte, 5, nullptr); 78 return TRUE; 79 80 } 81 82 83 BOOL Hook(); 84 BOOL UnHook(); 85 86 int WINAPI MyMessageBox( 87 _In_opt_ HWND hWnd, 88 _In_opt_ LPCTSTR lpText, 89 _In_opt_ LPCTSTR lpCaption, 90 _In_ UINT uType 91 ) 92 { 93 printf("你想调用系统的MessageBox,但被我截获"); 94 return 1; 95 96 } 97 98 BOOL Hook() 99 { 100 // MessageBox 是一个宏,没有具体的符号导出 101 // 获取 MessageBoxW 的 API 首地址 102 // 起始地址 103 g_pfnOld = GetProcAddress(GetModuleHandle(L"user32.dll"),"MessageBoxW"); 104 if (!g_pfnOld) 105 { 106 return FALSE; 107 } 108 // 保存以便恢复 109 ReadProcessMemory(GetCurrentProcess(), g_pfnOld, g_oldByte, 5, nullptr); 110 111 // call MyMessageBox 112 // 0xE9 MessageBox 的首地址 113 // 0xE9 是一个机器码,这个机器码的作用是无条件跳转(JMP) 114 // 0xE9 + 地址(4个字节)= 5个字节 115 BYTE newByte[5] = {0}; 116 newByte[0] = 0xE9; // 无条件跳转(JMP) 117 // 目标地址 118 PROC pfnMy = (PROC)MyMessageBox; 119 120 *(DWORD *)(newByte + 1) = (DWORD)pfnMy - (DWORD)g_pfnOld - 5; 121 WriteProcessMemory(GetCurrentProcess(), g_pfnOld, newByte, 5, nullptr); 122 123 return TRUE; 124 } 125 126 BOOL UnHook() 127 { 128 // 恢复 API 地址 129 WriteProcessMemory(GetCurrentProcess(),g_pfnOld, g_oldByte, 5, nullptr); 130 return TRUE; 131 132 } 133 134 int _tmain(int argc, _TCHAR* argv[]) 135 { 136 //Hook(); 137 //MessageBoxW(nullptr,L"Hello",L"Mark",MB_OK); 138 //UnHook(); 139 //MessageBoxW(nullptr, L"Hello", L"Mark", MB_OK); 140 MyHookClass myhook; 141 g_pfnOld = GetProcAddress(GetModuleHandle(L"user32.dll"), "MessageBoxW"); 142 myhook.Hook((PROC)MyMessageBox, g_pfnOld); 143 MessageBoxW(nullptr,L"Hello",L"Mark",MB_OK); 144 myhook.UnHook(); 145 MessageBoxW(nullptr, L"Hello", L"Mark", MB_OK); 146 system("pause"); 147 return 0; 148 }

浙公网安备 33010602011771号