<< CCProxy6.61溢出漏洞分析 Category: 黑客技术文章 ms08053 >>
关于消息断点下断    [ 2008-10-16 3:31:07 PM | Author: kyo327 | From: Original ]
其实这个CCDebuger 早就在教程里说过了。
只是如果用代码段内存断点的方法 实在是太累了。下一次断,F9后看看如果不是消息处理函数 还得重新的代码区下断,有时候要重复这样的工作几十次才能走到真正的消息处理函数部分

还有一种办法 可能大家都没注意。
就是run跟踪,我现在才发现run跟踪很强大。

在下玩消息断点后,直接打开RUN跟踪,然后添加所有函数入口,然后再点button,断下来后,直接按ctrl+f12让程序跑起来。

这时候再打开RUN跟踪 统计当前模块 或者选择 统计全局模块 找到代码段中的地址即可。

VC6.0
release模式
MFC42.#4424_?OnCmdMsg@CCmdTarget@@UAEHIHP中
MOV EDX,DWORD PTR DS:[EAX+14]


debug模式
名称=#3657_?OnCmdMsg@CCmdTarget@@UAEHIHPAXPAUAFX_CMDHANDLERINFO@@@Z
MOV EDX,DWORD PTR DS:[ECX+14]




[ Edited by kyo327 at 2008-11-26 5:43:28 PM ]

Comments RSS Feed http://www.kyospace.com/feedcomm.asp?logID=294

Quote kyo327 Posted at 2008-11-24 2:55:36 PM
对于对话框程序,在这个函数函数入口处设置断点最好(请记住这个函数:CCmdTarget::OnCmdMsg()),因为:
一、不用设置条件断点,只有在发生WM_COMMAND消息后,才运行到此。
二、而且再继续往下运行到73D3229F PUSH DWORD PTR DS:[EAX+14],就得到了消息函数的地址。
或者,也可以往下到 73D322A9 CALL MFC42.73D3233C语句时F7跟进,再往下执行几条语句,就很容易来到WM_COMMAND消息函数代码处。见下面说明。

跟进73D3233C,执行几条语句,经过几次跳转后,很快就定位到了按钮事件代码处:
73D3233C PUSH EBP
73D3233D MOV EBP,ESP
...
73D3234E CMP EAX,28
73D32351 JBE SHORT MFC42.73D32390
73D32353 SUB EAX,29
73D32356 JE MFC42.73D8E55B
73D3235C SUB EAX,3
73D3235F JNZ MFC42.73D8E52F

73D3239E SUB EAX,0A
73D323A1 > JE SHORT MFC42.73D323D2
73D323A3 DEC EAX
73D323A4 JE MFC42.73D8E4FD
73D323AA SUB EAX,16
73D323AD JE SHORT MFC42.73D323C8
73D323AF SUB EAX,3
73D323B2 JNZ MFC42.73D8E4E7

73D323D2 MOV ECX,DWORD PTR SS:[EBP+8] ; Case C of Switch XXXXXXXX
73D323D5 CALL DWORD PTR SS:[EBP+14] ; D1.?OnButton1@CD1Dlg@@IAEXXZ D1Dlg.obj 进入按钮函数代码
73D323D8 ^ JMP SHORT MFC42.73D3237B
其实上面一段代码就是_AfxDispatchCmdMsg函数。

18. _AfxDispatchCmdMsg()函数(反汇编代码见上), 找到按钮消息函数处
AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode,
AFX_PMSG pfn, void* pExtra, UINT nSig, AFX_CMDHANDLERINFO* pHandlerInfo)
{ union MessageMapFunctions mmf;
mmf.pfn = pfn;
BOOL bResult = TRUE;
switch (nSig)
{
case AfxSig_vv:
// normal command or control notification
ASSERT(CN_COMMAND == 0); // CN_COMMAND same as BN_CLICKED
ASSERT(pExtra == NULL);
(pTarget->*mmf.pfn_COMMAND)(); //从这里执行下面的CD2Dlg::OnButton1()函数
break;
case AfxSig_bv:
...
...
}
这里,通过调用全局函数_AfxDispatchCmdMsg,来调用具体的消息处理函数。这样便完成了从产生消息到调用消息响应函数的全过程。其参数分别介绍如下。
pTarget:该参数是指向处理消息的对象。
nID:该参数是命令ID。
nCode:该参数是通知消息等,对于一个命令消息,该变量将赋值为CN_COMMAND(相当于0)。
pfn:该参数是消息处理函数地址。
pExtra:该参数用于存放一些有用的信息,它取决于当前正被处理的消息类型。如果是控件通知WM_NOTIFY,则是指向NMHDR的AFX_NOTIFY结构的指针;如果是菜单项和工具栏更新,则它是指向CCmdUI派生类的指针;如果是其他类型,则为空。
nSig:该参数定义消息处理函数的调用变量。在AFXMSG_.H中,为nSig预定义了60多个值,例如,nSig值为iww,则在调用消息处理函数前,使OnWndMsg()格式化wParam和lParam为两个UINT变量,返回值为整型。
pHandlerInfo:该参数是一个指针,指向AFX_CMDHANDLERINFO结构。
前6个参数(除了pExtra以外)都是输入参数,而参数pExtra和pHandlerInfo既可以用作输出参数,也可以用作输入参数。
该函数主要完成的任务是:首先,它检查参数pHandlerInfo是否空,如果不空,则用pTarget和pfn填充它所指向的结构,并且返回TRUE;其次,如果pHandlerInfo空,则进行消息处理函数的调用。它根据参数nSig的值,把参数pfn的类型转换为要调用的消息处理函数的类型。
如果在视图中没有找到相应的消息处理函数,则将会交由文档类来进行处理。

Quote kyo327 Posted at 2008-11-26 3:26:12 PM
对于VC8来说

下面程序相当于 CCmdTarget::OnCmdMsg()函数
004390D0 |> \FF75 14 PUSH DWORD PTR SS:[EBP+14] ; /Arg7
004390D3 |. FF70 10 PUSH DWORD PTR DS:[EAX+10] ; |Arg6
004390D6 |. FF75 10 PUSH DWORD PTR SS:[EBP+10] ; |Arg5
004390D9 |. FF70 14 PUSH DWORD PTR DS:[EAX+14] ; |Arg4
004390DC |. FF75 0C PUSH DWORD PTR SS:[EBP+C] ; |Arg3
004390DF |. FF75 08 PUSH DWORD PTR SS:[EBP+8] ; |Arg2
004390E2 |. 57 PUSH EDI ; |Arg1
004390E3 |. E8 B0FDFFFF CALL mbpoll.00438E98
004390E8 \.^ EB DF JMP SHORT 004390C9

而004390D9 |. FF70 14 PUSH DWORD PTR DS:[EAX+14] 中存放的就是按钮处理程序的入口地址。

如果把库文件静态编译进去的话下面的方法最快找到关键点

搜索PUSH DWORD PTR DS:[EAX+14]即可


Post Comment
Topic Locked or You don't have the Permission. No Comment Allowed.
Here is kyo's blog © 2004-2005 
Processed in 0.125000 second(s)