经常在调试程序中需要捕捉某一按钮事件,分析按钮对应的代码(如“登陆”,“注册”等)
近来无事,自己写个程序来看看MFC的消息分发流程,然后总结地写了这文章:
示例程序MfcTest,下载链接:http://download.csdn.net/detail/ccnyou/4358961
编译环境VC6+WinXP
使用工具:OD(OllyDbg)
程序截图
对应按钮代码:
void CMfcTestDlg::OnButton1()
{
// TODO: Add your control notification handler code here
MessageBoxA("OnButton1","",0);
}
首先,载入OD,F9完成程序初始化
OD命令:bp TranslateMessage MSG==WM_LBUTTONUP
然后单击
暂停在:
77D18BF6 > 8BFF MOV EDI,EDI
此时栈窗口如下:
0012FD8C 77D274F9 /CALL 到 TranslateMessage 来自 USER32.77D274F4
0012FD90 0040306C \pMsg = WM_LBUTTONUP hw = 2403D4 ("Button1") Keys = 0 X = 63. Y = 9.
0012FD94 0040306C MfcTest.0040306C
0012FD98 00403074 MfcTest.00403074
0012FD9C 0040306C MfcTest.0040306C
按Ctrl+F9执行到返回,回到USER32领空,看到
77D274F4 E8 FD16FFFF CALL USER32.TranslateMessage
77D274F9 56 PUSH ESI ; MfcTest.0040306C
77D274FA E8 0215FFFF CALL USER32.DispatchMessageW
77D274FF 5B POP EBX
按F7,进入DispatchMessageW
此时按下Alt+M,打开Memory map窗口,在.text按F2下断,F9运行,离开主程序领空后,立刻又在.text按F2下断,F9运行,发现程序依次调用
00401502 .- FF25 30204000 JMP DWORD PTR DS:[<&MFC42.#5300_?Process>; MFC42.#5300_?ProcessMessageFilter@CWinThread@@UAEHHPAUtagMSG@@@Z
004014FC .- FF25 2C204000 JMP DWORD PTR DS:[<&MFC42.#3346_?GetMain>; MFC42.#3346_?GetMainWnd@CWinThread@@UAEPAVCWnd@@XZ
…
最后一个调用的是
00401670 .- FF25 24214000 JMP DWORD PTR DS:[<&MFC42.#4425_?OnCmdMs>; MFC42.#4425_?OnCmdMsg@CDialog@@UAEHIHPAXPAUAFX_CMDHANDLERINFO@@@Z
在此下断,F8离开主领空,.text按F2下断,F9运行,立刻来到关键代码处
00401470 . 6A 00 PUSH 0
00401472 . 68 FC304000 PUSH MfcTest.004030FC
00401477 . 68 20304000 PUSH MfcTest.00403020 ; ASCII "OnButton1"
0040147C . E8 37020000 CALL <JMP.&MFC42.#4224_?MessageBoxA@CWnd>
00401481 . C3 RETN
好的,拿到地址,可以直接IDA分析了^_^