比起用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的時候,控制就會跑到這裏,單步進入就可以了。
|
||
|
如何在IDA中找到MFC程序的消息處理函數
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.