请思归等高手看看hook弹出的MessageBox窗体问题!

outdream 2005-01-04 10:39:59
监控程序的目的是来Hook捕捉XP系统弹出的所有MessageBox窗体。
先写了一个hook的dll,然后做了一个HookSample的窗体程序来做测试,在hook HookSample.exe程序弹出的MessageBox的时候,在关闭MessageBox的时候才能hook到,而不是一弹出MessageBox就能hook到?而且hook不到自己做测试写的其他程序弹出的MessageBox窗体,但是能hook到QQ的消息对话框,但也是在qq消息框关闭之后才能捕捉到。

Hook的DLL主要代码如下:
安装钩子函数:
BOOL SetHookWindows()
{
AFX_MANAGE_STATE(AfxGetStaticModuleState());
HHOOK hhookWindows = ::SetWindowsHookEx (WH_CALLWNDPROC, hkWindowsProc,::AfxGetInstanceHandle(),0);
}
钩子函数:
LRESULT CALLBACK hkWindowsProc( int nCode,WPARAM wParam,LPARAM lParam)
{
LPMSG pmsg = (LPMSG)lParam;
UINT uMsg = pmsg->message;
HWND hWnd = pmsg->hwnd;
char *name=new char[128];
if (pmsg!=NULL)
{
switch(uMsg)
{
case WM_SHOWWINDOW:
GetWindowText(hWnd,name,64);
.....
break;
default:
break;
}
}
return CallNextHookEx(hhookWindows, nCode, wParam, lParam); /*TRUE*/
}
...全文
659 25 打赏 收藏 转发到动态 举报
写回复
用AI写文章
25 条回复
切换为时间正序
请发表友善的回复…
发表回复
alongsoft1129 2005-02-05
  • 打赏
  • 举报
回复
mark
zhjie374 2005-02-05
  • 打赏
  • 举报
回复
我测试了一下,XP是有些东西HOOK不到.只能HOOOK特定进程的.一旦将钩子作为全局,程序就退出了.

98可以,JMP跳转移植性不好
galaxy_fxstar 2005-02-04
  • 打赏
  • 举报
回复
这段代码好强。。。。
zhjie374 2005-02-04
  • 打赏
  • 举报
回复
我也在看!可以交流!
zhjie374@hotmail.com MSN
mocoumary 2005-02-02
  • 打赏
  • 举报
回复
MARK
吹泡泡的小猫 2005-01-31
  • 打赏
  • 举报
回复
看看这篇文章:

Api拦截并不是一个新的技术,很多商业软件都采用这种技术。对windows的Api函数的拦截,不外乎两种方法,第一种是Mr. Jeffrey Richter 的修改exe文件的模块输入节,种方法,很安全,但很复杂,而且有些exe文件,没有Dll的输入符号的列表,有可能出现拦截不到的情况。第二种方法就是常用的JMP XXX的方法,虽然很古老,却很简单实用。
 本文一介绍第二种方法在Win2k下的使用。第二种方法,Win98/me 下因为进入Ring0级的方法很多,有LDT,IDT,Vxd等方法,很容易在内存中动态修改代码,但在Win2k下,这些方法都不能用,写WDM太过复杂,表面上看来很难实现,
其实不然。Win2k为我们提供了一个强大的内存Api操作函数---VirtualProtectEx,WriteProcessMemeory,ReadProcessMemeory,有了它们我们就能在内存中动态修改代码了,其原型为:
BOOL VirtualProtectEx(
HANDLE hProcess, // 要修改内存的进程句柄
LPVOID lpAddress,// 要修改内存的起始地址
DWORD dwSize,// 修改内存的字节
DWORD flNewProtect,// 修改后的内存属性
PDWORD lpflOldProtect// 修改前的内存属性的地址
 );
 BOOL WriteProcessMemory(
HANDLE hProcess,// 要写进程的句柄
LPVOID lpBaseAddress,// 写内存的起始地址
LPVOID lpBuffer,// 写入数据的地址
DWORD nSize,// 要写的字节数
LPDWORD lpNumberOfBytesWritten// 实际写入的子节数
);
BOOL ReadProcessMemory(
HANDLE hProcess,// 要读进程的句柄
LPCVOID lpBaseAddress, // 读内存的起始地址
LPVOID lpBuffer,// 读入数据的地址
DWORD nSize,// 要读入的字节数
LPDWORD lpNumberOfBytesRead// 实际读入的子节数
 );
具体的参数请参看MSDN帮助。在Win2k下因为Dll和所属进程在同一地址空间,这点又和Win9x/me存在所有进程存在共享的地址空间不同,
因此,必须通过钩子函数和远程注入进程的方法,现以一个简单采用钩子函数对MessageBoxA进行拦截例子来说明:
其中Dll文件为:
 HHOOK g_hHook;
 HINSTANCE g_hinstDll;
 FARPROC pfMessageBoxA;
 int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption,UINT uType);
 BYTE OldMessageBoxACode[5],NewMessageBoxACode[5];
 HMODULE hModule ;
 DWORD dwIdOld,dwIdNew;
 BOOL bHook=false;
 void HookOn();
 void HookOff();
 BOOL init();
LRESULT WINAPI MousHook(int nCode,WPARAM wParam,LPARAM lParam);
BOOL APIENTRY DllMain( HANDLE hModule,
DWORDul_reason_for_call,
LPVOID lpReserved
)
{
 switch (ul_reason_for_call)
 {
 case DLL_PROCESS_ATTACH:
 if(!init())
 {
 MessageBoxA(NULL,"Init","ERROR",MB_OK);
 return(false);
 }
 case DLL_THREAD_ATTACH:
 case DLL_THREAD_DETACH:
 case DLL_PROCESS_DETACH:
 if(bHook) UnintallHook();
 break;
 }
 return TRUE;
}
LRESULT WINAPI Hook(int nCode,WPARAM wParam,LPARAM lParam)//空的钩子函数
{

 return(CallNextHookEx(g_hHook,nCode,wParam,lParam));
}
HOOKAPI2_API BOOL InstallHook()//输出安装空的钩子函数
{
g_hinstDll=LoadLibrary("HookApi2.dll");
g_hHook=SetWindowsHookEx(WH_GETMESSAGE,(HOOKPROC)Hook,g_hinstDll,0);
if (!g_hHook)
{
 MessageBoxA(NULL,"SET ERROR","ERROR",MB_OK);
 return(false);
}


return(true);
}
HOOKAPI2_API BOOL UninstallHook()//输出御在钩子函数
{

 return(UnhookWindowsHookEx(g_hHook));
}

BOOL init()//初始化得到MessageBoxA的地址,并生成Jmp XXX(MyMessageBoxA)的跳转指令
{
 hModule=LoadLibrary("user32.dll");
 pfMessageBoxA=GetProcAddress(hModule,"MessageBoxA");
 if(pfMessageBoxA==NULL)
 return false;
 _asm
 {
 lea edi,OldMessageBoxACode
 mov esi,pfMessageBoxA
 cld
 movsd
 movsb
 }
 NewMessageBoxACode[0]=0xe9;//jmp MyMessageBoxA的相对地址的指令
 _asm
 {
 lea eax,MyMessageBoxA
 mov ebx,pfMessageBoxA
 sub eax,ebx
 sub eax,5
 mov dword ptr [NewMessageBoxACode+1],eax
 }
 dwIdNew=GetCurrentProcessId(); //得到所属进程的ID
 dwIdOld=dwIdNew;
 HookOn();//开始拦截
 return(true);
}

int WINAPI MyMessageBoxA(HWND hWnd, LPCTSTR lpText,LPCTSTR lpCaption, UINT uType )//首先关闭拦截,然后才能调用被拦截的Api 函数
{
 int nReturn=0;
 HookOff();
 nReturn=MessageBoxA(hWnd,"Hook",lpCaption,uType);
 HookOn();
 return(nReturn);
}
void HookOn()
{
 HANDLE hProc;
 dwIdOld=dwIdNew;
 hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);//得到所属进程的句柄
 VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为可写
 WriteProcessMemory(hProc,pfMessageBoxA,NewMessageBoxACode,5,0);//将所属进程中MessageBoxA的前5个字节改为JMP 到MyMessageBoxA
 VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);//修改所属进程中MessageBoxA的前5个字节的属性为原来的属性
 bHook=true;
}
void HookOff()//将所属进程中JMP MyMessageBoxA的代码改为Jmp MessageBoxA
{
 HANDLE hProc;
 dwIdOld=dwIdNew;
 hProc=OpenProcess(PROCESS_ALL_ACCESS,0,dwIdOld);
 VirtualProtectEx(hProc,pfMessageBoxA,5,PAGE_READWRITE,&dwIdOld);
 WriteProcessMemory(hProc,pfMessageBoxA,OldMessageBoxACode,5,0);
 VirtualProtectEx(hProc,pfMessageBoxA,5,dwIdOld,&dwIdOld);
 bHook=false;
}
//测试文件:
int APIENTRY WinMain(HINSTANCE hInstance,
HINSTANCE hPrevInstance,
LPSTR lpCmdLine,
int nCmdShow)
{

 if(!InstallHook())
 {
 MessageBoxA(NULL,"Hook Error!","Hook",MB_OK);
 return 1;
 }
MessageBoxA(NULL,"TEST","TEST",MB_OK);//可以看见Test变成了Hook,也可以在其他进程中看见
 if(!UninstallHook())
 {
 MessageBoxA(NULL,"Uninstall Error!","Hook",MB_OK);
 return 1;
 }
 return 0;
}

outdream 2005-01-31
  • 打赏
  • 举报
回复
我现在的做法还是钩子:WH_CALLWNDPROC
消息也是:WM_SHOWWINDOW

因为每次都能钩到有焦点button,所以我就遍历它的父窗口,基本上达到自己的目的
不过总感觉是用的野路子?!!!
223xh 2005-01-31
  • 打赏
  • 举报
回复
这代码一般用来做什么?破解软件是不是要用到?
iamltq 2005-01-22
  • 打赏
  • 举报
回复
学习...
blastzgd 2005-01-21
  • 打赏
  • 举报
回复
同意laiyiling(陌生人|VC_FANS|找工作中)。
使用WH_CBT,处理HCBT_WNDCREATE.
blastzgd 2005-01-21
  • 打赏
  • 举报
回复
同意laiyiling(陌生人|VC_FANS|找工作中)。
使用WH_CBT,处理HCBT_WNDCREATE.
danshuihepan 2005-01-21
  • 打赏
  • 举报
回复
hook API不一定成功,对于用MFC弹出的对话框,HOOK API就不管用!
dandycheung 2005-01-21
  • 打赏
  • 举报
回复
楼上小题大做,HookApi 比用钩子既困难又不稳定,而且搂主要求是系统范围,HookApi 更不适合。
huwei001982 2005-01-21
  • 打赏
  • 举报
回复
仅仅为了达到这样的目的就用 WH_CALLWNDPROC 非常不合适


应该用 Window 核心编程 里的 Hook Api 一章中介绍的技术
outdream 2005-01-21
  • 打赏
  • 举报
回复
再有人回答,我就结贴了!
dandycheung 2005-01-08
  • 打赏
  • 举报
回复
建议你使用 WH_SYSMSGFILTER 类型的钩子,检查 MSGF_DIALOGBOX。
Mr-Chen 2005-01-07
  • 打赏
  • 举报
回复
hHook1 = SetWindowsHookEx(WH_CALLWNDPROC , (HOOKPROC)HookProc, ,::AfxGetInstanceHandle(), 0);
MessageBox....
UnhookWindowsHookEx(hHook1);


LRESULT CALLBACK HookProc(UINT code , WPARAM wParam, LPARAM lParam)
{
CWPSTRUCT *msg = (CWPSTRUCT *)lParam;
if ( msg && msg->hwnd)// && msg->wParam == HCBT_CREATEWND)
{
char strout[1024]="";
char winname[256]="";

::GetWindowText(msg->hwnd,winname,256);
if(msg->message == WM_INITDIALOG)
{
CWnd *mymes;
mymes = CWnd::FromHandle(msg->hwnd);
mymes->GetWindowText(winname,256);

//...
}
return CallNextHookEx(hHook1, code, wParam, lParam);
}
}
outdream 2005-01-07
  • 打赏
  • 举报
回复
怎么没有人回答?
DentistryDoctor 2005-01-05
  • 打赏
  • 举报
回复
<<windows核心编程>>就有现成的Hook MessageBox的示例。
leon7909 2005-01-05
  • 打赏
  • 举报
回复
如果只是为了hook标准的messagebox,为什么不用<<windows核心编程>>里的那个api hook里的源码,但他对不是用MessageBox创建的消息框没作用,他也是关了box后才提示,不过只要改改hook proc就好了.
加载更多回复(5)

15,471

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC 进程/线程/DLL
社区管理员
  • 进程/线程/DLL社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧