如何在IDA中找到MFC程序的消息处理函数

比起用Win32SDK写的程序,要分析MFC应用程序要麻烦不少。在前者,只要找到注册窗口类的地方就知道其WinProc的位置。那里是程序的控制中心,只要顺藤摸瓜就可以找到你感兴趣的地方。对于用MFC写的程序,这一切都变得复杂起来了。这时,所有的消息都是通过一套复杂的机制来完成分发的。他们是通过分发数据表来找到最终函数地址的. 详细请参阅MFC的源代码。

常见的消息分发数据是由以下的宏来生成的:
  ON_WM_SIZE()
  ON_NOTIFY(TCN_SELCHANGE, ID_TABBOARD, OnBoardSelchange)
  ON_WM_LBUTTONDBLCLK()
  ON_WM_LBUTTONDOWN()
  ON_WM_RBUTTONDOWN()
  ON_WM_TIMER()
  ON_COMMAND(ID_REDRAW_ALL, OnRedrawAll)


这里简单说一下如何找到二类消息的处理函数。一类是WM_XXX型消息,如WM_LBUTTONDOWN,另一类是WM_COMMAND型消息.

对于第一类,它的调用栈是:
CMyView::OnLButtonDown  <--最终目标
CWnd::OnWndMsg    <--找到这个函数就接近最终目标了
CWnd::WindowProc
AxfCallWndProc
AxfWndProc
AxfWndProcBase

以WM_LBUTTONDOWN为例

#define ON_WM_LBUTTONDOWN() /
  { WM_LBUTTONDOWN, 0, 0, 0, AfxSig_vwp, /
    (AFX_PMSG)(AFX_PMSGW)(void (AFX_MSG_CALL CWnd::*)(UINT, CPoint))&OnLButtonDown },
AfxSig_vwp = 0x31

对于VC6.0 Release 版本,可搜索 C0 24 F0 83 C0 2F 48  83 F8 30 0F 87 C6 02 找到CWnd::OnWndMsg。
进入CWnd::OnWndMsg后,找到 case 0x30(IDA 中的case 0x30其实是 case 0x31)处的
call    ebx
将进入你真正感兴趣的地方!

这里必须用条件断点Dword(ESP+0x0c) == 0x201, (注WM_LBUTTONDOWN == 0x201) 否则这个断点总会遇到.

找WM_COMMAND消息处理的地方

对于第二类,它的调用栈是:
CMyDoc::OnCmdXXX  <--最终目标
_AxfDispatchCmdMsg  <--找到这个函数就接近最终目标了
CCmdTarget::OnCmdMsg
CDocument::OnCmdMsg
CView::OnCmdMsg
CFrameWnd::OnCmdMsg
CWnd::OnCommand
CFrameWnd::OnCommand
CWnd::OnWndMsg
CWnd::WindowProc
AxfCallWndProc
AxfWndProc
AxfWndProcBase

ON_COMMAND定义如下
#define ON_COMMAND(id, memberFxn) /
  { WM_COMMAND, CN_COMMAND, (WORD)id, (WORD)id, AfxSig_vv, (AFX_PMSG)&memberFxn },
其中的AfxSig_vv = 12

搜索 71 74 5C 48  48 74 53 83 E8 0A 74 46,将找到_AfxDispatchCmdMsg函数,在case 12 的地方设断点并运行,当程序需要处理OnCmdXXX的时候,控制就会跑到这里,单步进入就可以了。

 

 

 

 
  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值