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

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

1 如果想断下特定的消息的处理函数,则首先在函数CWnd::WindowProc函数中下条件断点,因为消息经过内核到相应的处理函数的过程中必须经过这个函数,此函数的定义如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
LRESULT CWnd::WindowProc(UINT message,WPARAM wParam,LPARAM lParam)
{
  LRESULT lResult
=0;
  
if(!OnWndMsg(message,wParam,lParam,&lResult))
    lResult
=DefWindowProc(message,wParam,lParam);
  
return lResult;
}

message即为消息,在这个函数中首先调用了函数OnWndMsg对消息进行处理,这个处理过程是找到消息对应的处理函数的过程,如果未能找到相应的处理函数则调用DefWindowProc,即默认的消息处理函数对消息进行处理,因此,如果我们需要对特定的消息下断点,只要在函数OnWndMsg处设置条件断点即可,WindowProc函数的反汇编代码如下

ContractedBlock.gif ExpandedBlockStart.gif Code
73D31B77    8BFF            mov     edi, edi                              ; CWnd::WindowProc
73D31B79    
55              push    ebp
73D31B7A    8BEC            mov     ebp, esp
73D31B7C    
51              push    ecx
73D31B7D    
8365 FC 00      and     dword ptr [ebp-4], 0
73D31B81    
56              push    esi
73D31B82    8BF1            mov     esi, ecx
73D31B84    8B06            mov     eax, dword ptr [esi]
73D31B86    8D4D FC         lea     ecx, dword ptr [ebp
-4]
73D31B89    
51              push    ecx
73D31B8A    FF75 
10         push    dword ptr [ebp+10]
73D31B8D    8BCE            mov     ecx, esi
73D31B8F    FF75 0C         push    dword ptr [ebp
+C]
73D31B92    FF75 
08         push    dword ptr [ebp+8]
73D31B95    FF90 A4000000   call    dword ptr [eax
+A4]                    ; OnWndMsg
73D31B9B    85C0            test    eax, eax
73D31B9D    
75 16           jnz     short 73D31BB5
73D31B9F    FF75 
10         push    dword ptr [ebp+10]
73D31BA2    8B06            mov     eax, dword ptr [esi]
73D31BA4    FF75 0C         push    dword ptr [ebp
+C]
73D31BA7    8BCE            mov     ecx, esi
73D31BA9    FF75 
08         push    dword ptr [ebp+8]
73D31BAC    FF90 A8000000   call    dword ptr [eax
+A8]                    ; DefWindowProc
73D31BB2    
8945 FC         mov     dword ptr [ebp-4], eax
73D31BB5    8B45 FC         mov     eax, dword ptr [ebp
-4]
73D31BB8    5E              pop     esi
73D31BB9    C9              leave
73D31BBA    C2 0C00         retn    0C

 

call    dword ptr [eax+A4]即为OnWndMsg函数的调用,函数的参数有四个,message,wParam,lParam,&lResult,分别对应73D31B92 73D31B8F 73D31B8A 73D31B89四行,因此,条件断点下在73D31B92处,例如下条件断点[ebp+8]==WM_TIMER即对定时器消息进行中断。

2 追踪用户自定义的消息处理函数

条件断点下好以后,此时已经断下了定时器消息,这个消息的处理过程是用户自定义的,如何找到它呢?

其实很简单,一路F8下去吧,如果遇到进入程序领空的call,就F7跟进,很快的。。示例如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
73D31BC2 >  B8 F1EFDC73     mov     eax, 73DCEFF1                         ; OnWndMsg
73D31BC7    E8 AC100900     call    73DC2C78
73D31BCC    83EC 
58         sub     esp, 58
73D31BCF    
8365 F0 00      and     dword ptr [ebp-10], 0
73D31BD3    
53              push    ebx
73D31BD4    8B5D 
08         mov     ebx, dword ptr [ebp+8]
73D31BD7    81FB 
11010000   cmp     ebx, 111                              ; WM_COMMAND
73D31BDD    
56              push    esi
73D31BDE    
57              push    edi
73D31BDF    8BF9            mov     edi, ecx
73D31BE1    
75 1B           jnz     short 73D31BFE

在第73D31BD7行,函数OnWndMsg比较当前消息是否为WM_COMMAND消息,如果是则执行73D31BE1以下的命令,如果不是则跳转到73D31BFE行,本例中拦截的是WM_TIMER,不是WM_COMMAND,所以会跳转。73D31BFE行代码如下:

73D31BFE    83FB 4E         cmp     ebx, 4E                               ; WM_NOTIFY
73D31C01    
75   23            jnz      short   < WM_ACTIVATE >

同样是一个比较,此处比较的是当前消息是否为WM_NOTIFY消息,此处会跳,跳的位置是73D31C26,此行代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
73D31C26 >  83FB 06         cmp     ebx, 6                                ; WM_ACTIVATE
73D31C29    8B75 
10         mov     esi, dword ptr [ebp+10]
73D31C2C    
75 10           jnz     short 73D31C3E

此处也是一个比较,比较当前消息是否喂WM_ACTIVATE消息,此处跳,跳到73D31C3E处,代码如下:

73D31C3E    83FB  20          cmp     ebx,  20                                ; WM_SETCURSOR
73D31C41    
75   18            jnz      short  73D31C5B

此处比较消息是否为WM_SETCURSOR,此处跳到73D31C5B处,代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
73D31C5B    8B07            mov     eax, dword ptr [edi]                  
73D31C5D    8BCF            mov     ecx, edi
73D31C5F    FF50 
30         call    dword ptr [eax+30]
73D31C62    8BD8            mov     ebx, eax
73D31C64    895D EC         mov     dword ptr [ebp
-14], ebx
73D31C67    335D 
08         xor     ebx, dword ptr [ebp+8]
73D31C6A    6A 
07           push    7
73D31C6C    81E3 FF010000   and     ebx, 1FF
73D31C72    E8 
07670900     call    #1196_AfxLockGlobals
73D31C77    8B4D 
08         mov     ecx, dword ptr [ebp+8]
73D31C7A    8B45 EC         mov     eax, dword ptr [ebp
-14]
73D31C7D    8D1C5B          lea     ebx, dword ptr [ebx
+ebx*2]
73D31C80    8D1C9D 58E6E073 lea     ebx, dword ptr [ebx
*4+73E0E658]
73D31C87    3B0B            cmp     ecx, dword ptr [ebx]
73D31C89    
75 24           jnz     short 73D31CAF

值得注意的是第73D31C5F处的call进入了程序领空,F7跟进以后代码如下:

00401240    .  B8 E8224000   mov     eax, 004022E8
00401245    .  C3            retn

这显然不是消息相应函数,继续跟踪,直到遇到进入程序领空的call,在第73D31FD1行找到了一个进入程序领空的call,F7跟进,代码如下:

ContractedBlock.gif ExpandedBlockStart.gif Code
00401480   .  56            push    esi
00401481   .  6A 00         push    0
00401483   .  68 28304000   push    00403028                              ;  ASCII "ok"
00401488   .  8BF1          mov     esi, ecx
0040148A   .  
68 20304000   push    00403020                              ;  ASCII "okok"
0040148F   .  E8 
44020000   call    <jmp.&MFC42.#4224_CWnd::MessageBoxA>
00401494   .  8BCE          mov     ecx, esi
00401496   .  E8 2B020000   call    <jmp.&MFC42.#2379_CWnd::Default>
0040149B   .  5E            pop     esi
0040149C   .  C2 
0400       retn    4

这就是WM_TIMER消息的相应函数,可以看到,调用了MessageBoxA函数,输出一个简单的对话框,消息的追踪流程到此结束,其他类型的消息可以同样追踪完成

博客很久没更新,汗颜。。。

 

转载于:https://www.cnblogs.com/feiyucq/archive/2009/07/12/1522156.html

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

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值