Hook MessageBox 进阶 跨进程Hook

转载注明出处

http://blog.csdn.net/xugangjava/article/details/14001685

以前的文章(http://blog.csdn.net/xugangjava/article/details/7455851)中介绍了如何Hook 系统的MessageBox的函数不过只限于本进程,

本文主要介绍如何Hook其他进程的MessageBox函数。

这里我用SetWindowsHookEx 来实现,SetWindowsHookEx最后一个参数设置为0 ,表示拦截所有进程的相关消息。在回调函数中安装Hook就可以达到目的。

对原有代码稍作修改dllmain.cpp修改如下

[cpp]  view plain copy
  1. // dllmain.cpp : 定义 DLL 应用程序的入口点。  
  2. #include "stdafx.h"  
  3. #include "detours.h"  
  4. #include <stdlib.h>  
  5. #include <iostream>  
  6. using namespace std;  
  7.   
  8.   
  9. PVOID g_pOldMessageBoxW=NULL;  
  10. PVOID g_pOldMessageBoxA=NULL;  
  11.   
  12. typedef int (WINAPI *PfuncMessageBoxA)(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType);  
  13. typedef int (WINAPI *PfuncMessageBoxW)( HWND hWnd, LPCWSTR lpText,LPCWSTR lpCaption,UINT uType);  
  14.   
  15. int WINAPI ZwNewMessageBoxA(HWND hWnd,LPCSTR lpText,LPCSTR lpCaption,UINT uType)  
  16. {  
  17.     return ((PfuncMessageBoxA)g_pOldMessageBoxA)(hWnd, "Hook This!","My hook",uType);  
  18. }  
  19. int WINAPI ZwNewMessageBoxW(HWND hWnd, LPCWSTR lpText,LPCWSTR lpCaption,UINT uType)  
  20. {  
  21.     return ((PfuncMessageBoxW)g_pOldMessageBoxW)(hWnd,L"Hook This!",L"My hook",uType);  
  22. }  
  23.   
  24. //共享代码段  
  25. #pragma data_seg("SHARED")   
  26. HHOOK g_hMessageHook=NULL;  
  27. BOOL g_bStopHook=FALSE;  
  28. BOOL g_bHookInstalled=FALSE;  
  29. #pragma data_seg()           
  30. #pragma comment(linker, "/section:SHARED,RWS")  
  31.   
  32.   
  33. BOOL APIENTRY SetHook()  
  34. {  
  35.     //如果已经安装就return  
  36.     if(g_bHookInstalled)return TRUE;  
  37.     //输出到控制台  
  38.     cout<<"let't us install hook of messagebox"<<endl;  
  39.     DetourTransactionBegin();  
  40.     DetourUpdateThread(GetCurrentThread());  
  41.     g_pOldMessageBoxA=DetourFindFunction("User32.dll","MessageBoxA");  
  42.     g_pOldMessageBoxW=DetourFindFunction("User32.dll","MessageBoxW");  
  43.     DetourAttach(&g_pOldMessageBoxA,ZwNewMessageBoxA);  
  44.     DetourAttach(&g_pOldMessageBoxW,ZwNewMessageBoxW);  
  45.     LONG ret=DetourTransactionCommit();  
  46.     g_bHookInstalled=TRUE;  
  47.     return g_bHookInstalled;  
  48. }  
  49.   
  50.   
  51. BOOL APIENTRY DropHook()  
  52. {  
  53.     //如果已经卸载就return  
  54.     if(!g_bHookInstalled)return TRUE;  
  55.     //输出控制台  
  56.     cout<<"let't us drop hook of messagebox"<<endl;  
  57.     DetourTransactionBegin();  
  58.     DetourUpdateThread(GetCurrentThread());  
  59.     DetourDetach(&g_pOldMessageBoxA, ZwNewMessageBoxA);  
  60.     DetourDetach(&g_pOldMessageBoxW, ZwNewMessageBoxW);  
  61.     LONG ret=DetourTransactionCommit();  
  62.     g_bHookInstalled=FALSE;  
  63.     return ret==NO_ERROR;  
  64. }  
  65.   
  66. static HMODULE s_hDll;  
  67.   
  68. //查找函数地址  
  69. HMODULE WINAPI ModuleFromAddress(PVOID pv)  
  70. {  
  71.     MEMORY_BASIC_INFORMATION mbi;  
  72.     if(::VirtualQuery(pv, &mbi, sizeof(mbi)) != 0)  
  73.     {  
  74.         return (HMODULE)mbi.AllocationBase;  
  75.     }  
  76.     else  
  77.     {  
  78.         return NULL;  
  79.     }  
  80. }  
  81.   
  82.   
  83. static LRESULT CALLBACK MessageHookProc(int nCode,WPARAM wParam,LPARAM lParam)  
  84. {  
  85.     wchar_t Dir[_MAX_DIR];  
  86.     wchar_t FullPath[MAX_PATH]; // [sp+200h] [bp-614h]@1  
  87.     wchar_t Ext[_MAX_EXT];  
  88.     wchar_t Filename[_MAX_FNAME];  
  89.     wchar_t Drive[_MAX_DRIVE];    
  90.     GetModuleFileNameW(0, FullPath, MAX_PATH);  
  91.     _wsplitpath_s(FullPath, Drive, _MAX_DRIVE, Dir, _MAX_DIR, Filename, _MAX_FNAME, Ext, _MAX_EXT);  
  92.     //这里我只注入python进程  注入所有进程对系统影响很大 弄得我经常需要注销  
  93.     if(!_wcsicmp(Filename, L"python")){  
  94.         //安装钩子  
  95.         if(!g_bStopHook){    
  96.             SetHook();  
  97.         }  
  98.         //卸载钩子  
  99.         else{  
  100.             DropHook();  
  101.         }  
  102.     }  
  103.     return CallNextHookEx(g_hMessageHook,nCode,wParam,lParam);  
  104. }  
  105.   
  106. //导出函数 加载全局钩子  
  107. extern "C" __declspec(dllexportBOOL SetGoableHook()  
  108. {  
  109.     g_bStopHook=FALSE;  
  110.     g_hMessageHook=SetWindowsHookEx(WH_GETMESSAGE,  
  111.         MessageHookProc,  
  112.         ModuleFromAddress(MessageHookProc),0);  
  113.     return TRUE;  
  114. }  
  115.   
  116. //导出函数 卸载全局钩子  
  117. extern "C" __declspec(dllexportBOOL DropGoableHook()  
  118. {  
  119.     g_bStopHook=TRUE;  
  120.     return TRUE;  
  121. }  
  122.   
  123. HMODULE WINAPI Detoured()  
  124. {  
  125.     return s_hDll;  
  126. }  
  127.   
  128. BOOL APIENTRY DllMain( HMODULE hModule,  
  129.                        DWORD  ul_reason_for_call,  
  130.                        LPVOID lpReserved  
  131.                      )  
  132. {  
  133.     switch (ul_reason_for_call)  
  134.     {  
  135.     case DLL_PROCESS_ATTACH:  
  136.         s_hDll = hModule;  
  137.         DisableThreadLibraryCalls(hModule);  
  138.         break;  
  139.     case DLL_PROCESS_DETACH:  
  140.         UnhookWindowsHookEx(g_hMessageHook);  
  141.         break;  
  142.     }  
  143.     return TRUE;  
  144. }  
好了我们下一步编写一个MFC程序来加载和卸载我们的钩子

在对话框上面添加两个按钮

Hook MessageBox 进阶 跨进程Hook_第1张图片

按钮事件处理函数如下

[cpp]  view plain copy
  1. typedef BOOL  (WINAPIV  *SetGoableHook)();  
  2. typedef VOID  (WINAPIV  *DropGoableHook)();  
  3.   
  4.   
  5. void CTestHookDlg::OnBnClickedSethook()  
  6. {  
  7.     HINSTANCE hDLL=::LoadLibrary(L"Hook.dll");  
  8.     SetGoableHook func=(SetGoableHook)GetProcAddress(hDLL,"SetGoableHook");  
  9.     func();  
  10. }  
  11.   
  12. void CTestHookDlg::OnBnClickedDropHook()  
  13. {  
  14.     HINSTANCE hDLL=::LoadLibrary(L"Hook.dll");  
  15.     DropGoableHook func=(DropGoableHook)GetProcAddress(hDLL,"DropGoableHook");  
  16.     func();  
  17. }  

Ok 了 下面我们来测试我们的钩子,依然使用python命令行来进行演示

1.进入python交互界面后,点击SetDoableHook按钮,然后敲入如下命令,弹出MessageBox点确定这个进程就触发了WH_GETMESSAGE 

进入我们的回调函数,我们的钩子已经加载成功了。

好的再次调用MessageBox

Hook MessageBox 进阶 跨进程Hook_第2张图片

发现python 进程的MessageBox已经被我们替换掉了,因为这个是命令行程序,第一次调用弹出只是为了该进程进入我们的WH_GETMESSAGE 回调MessageHookProc。

对不同类型进程Hook的时候可以使用不同的参数 WH_CALLWNDPROCRET,WH_KEYBOARD_LL,WH_MOUSE_LL来进行Hook。

同理 卸载钩子

Hook MessageBox 进阶 跨进程Hook_第3张图片

有不对的地方欢迎大家指正。

源码地址

http://download.csdn.net/detail/xugangjava/6488007

你可能感兴趣的:(Hook MessageBox 进阶 跨进程Hook)