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 }

 

posted @ 2015-05-18 15:56  壬子木  阅读(188)  评论(0)    收藏  举报