首页
论坛
课程
招聘
[原创]MFC消息拦截分析(+示例程序分析)
2014-12-16 21:54 7490

[原创]MFC消息拦截分析(+示例程序分析)

2014-12-16 21:54
7490
写这篇文章的目的只是为了精确简洁的拦截MfC的消息.(搞清楚原理,以后都好办了)
我还是以VC6.0的mfc进行分析(当然是静态链接的).只是提供分析的思路,其他版本类似.
思路是找到派发用户事件的地方.
...话说好久没发贴了.
示例软件:Galaxy3D.exe 一个3D屏保设置程序.
主要工具:IDA,OllyDbg.
我自己做了一个vc6.0 mfc的sig签名,用于IDA识别.
简单源代码调试,发现派发command事件实在这个函数:
// CCmdTarget windows message dispatching
AFX_STATIC BOOL AFXAPI _AfxDispatchCmdMsg(CCmdTarget* pTarget, UINT nID, int nCode,
    AFX_PMSG pfn, void* pExtra, UINT nSig, AFX_CMDHANDLERINFO* pHandlerInfo)
        // return TRUE to stop routing
{
    ASSERT_VALID(pTarget);
    UNUSED(nCode);   // unused in release builds

    union MessageMapFunctions mmf;
    mmf.pfn = pfn;
    BOOL bResult = TRUE; // default is ok

    if (pHandlerInfo != NULL)
    {
        // just fill in the information, don't do it
        pHandlerInfo->pTarget = pTarget;
        pHandlerInfo->pmf = mmf.pfn;
        return 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)();
        break;
    ..........
好了,IDA分析Galaxy3D.exe,然后生成map文件给OD用,直接来到_AfxDispatchCmdMsg函数里面下断点.
输入注册信息,点击注册按钮完美断下.

按照上面的源代码,我们最后时候间接跳向事件处理地址
因此直接单步到跳转的地方,马上来到按钮事件处理的函数:
CPU Disasm
Address    Hex dump      Command                                        Comments
00406940 r /.  64:A1 000 mov eax, dword ptr fs:[0]
00406946   |.  6A FF     push -1
00406948   |.  68 436044 push unknown_libname_605
0040694D   |.  50        push eax
0040694E   |.  64:8925 0 mov dword ptr fs:[0], esp                      ; Installs SE handler unknown_libname_605
00406955   |.  81EC B400 sub esp, 0B4
0040695B   |.  53        push ebx
0040695C   |.  55        push ebp
0040695D   |.  56        push esi
0040695E   |.  57        push edi
0040695F   |.  8BF1      mov esi, ecx
00406961   |.  6A 01     push 1                                         ; /Arg1 = 1
00406963   |.  E8 665A03 call CWnd::UpdateData(int)                     ; \Galaxy3D.CWnd::UpdateData(int)
00406968   |.  68 2C0100 push 12C                                       ; /Time = 300. ms
0040696D   |.  FF15 7092 call dword ptr ds:[<&KERNEL32.Sleep>]          ; \KERNEL32.Sleep
00406973   |.  8DBE A000 lea edi, [esi+0A0]
00406979   |.  8DAE 9C00 lea ebp, [esi+9C]
0040697F   |.  8D9E 9800 lea ebx, [esi+98]
00406985   |.  57        push edi
00406986   |.  55        push ebp
00406987   |.  53        push ebx
00406988   |.  FF15 9882 call dword ptr ds:[458298]  ;看下面的出错对话框,这里就是算法了
0040698E   |.  83C4 0C   add esp, 0C
00406991   |.  85C0      test eax, eax
00406993   |.  0F84 9700 jz 00406A30
00406999   |.  8D4C24 10 lea ecx, [arg.4]
0040699D   |.  E8 BE7400 call 0040DE60                                  ; [Galaxy3D.0040DE60
004069A2   |.  6A 00     push 0                                         ; /Arg1 = 0
004069A4   |.  8D4C24 14 lea ecx, [arg.5]                               ; |
004069A8   |.  C78424 D0 mov dword ptr ss:[arg.52], 0                   ; |
004069B3   |.  E8 187A00 call 0040E3D0                                  ; \Galaxy3D.0040E3D0
004069B8   |.  53        push ebx                                       ; /Arg1
004069B9   |.  8D4C24 50 lea ecx, [arg.20]                              ; |
004069BD   |.  E8 292403 call CString::operator=(CString const &)       ; \Galaxy3D.CString::operator=
004069C2   |.  55        push ebp                                       ; /Arg1
004069C3   |.  8D4C24 54 lea ecx, [arg.21]                              ; |
004069C7   |.  E8 1F2403 call CString::operator=(CString const &)       ; \Galaxy3D.CString::operator=
004069CC   |.  57        push edi                                       ; /Arg1
004069CD   |.  8D4C24 4C lea ecx, [arg.19]                              ; |
004069D1   |.  E8 152403 call CString::operator=(CString const &)       ; \Galaxy3D.CString::operator=
004069D6   |.  6A 00     push 0                                         ; /Arg1 = 0
004069D8   |.  8D4C24 14 lea ecx, [arg.5]                               ; |
004069DC   |.  E8 9F7700 call 0040E180                                  ; \Galaxy3D.0040E180
004069E1   |.  6A 00     push 0                                         ; /Arg2 = 0
004069E3   |.  68 970000 push 97                                        ; |Arg1 = 97
004069E8   |.  8D4C24 70 lea ecx, [arg.28]                              ; |
004069EC   |.  E8 C43203 call CDialog::CDialog(uint,CWnd *)             ; \Galaxy3D.CDialog::CDialog
004069F1   |.  8D4C24 68 lea ecx, [arg.26]
004069F5   |.  C68424 CC mov byte ptr ss:[arg.51], 1
004069FD   |.  E8 683303 call CDialog::DoModal(void)                    ; [Galaxy3D.CDialog::DoModal(void)
00406A02   |.  8BCE      mov ecx, esi
00406A04   |.  E8 4C3603 call CDialog::OnOK(void)                       ; [Galaxy3D.CDialog::OnOK(void)
00406A09   |.  8D4C24 68 lea ecx, [arg.26]
00406A0D   |.  C68424 CC mov byte ptr ss:[arg.51], 0
00406A15   |.  E8 862F03 call CDialog::~CDialog                         ; [Galaxy3D.CDialog::~CDialog
00406A1A   |.  8D4C24 10 lea ecx, [arg.4]
00406A1E   |.  C78424 CC mov dword ptr ss:[arg.51], -1
00406A29   |.  E8 427600 call 0040E070                                  ; [Galaxy3D.0040E070
00406A2E   |.  EB 16     jmp short 00406A46
00406A30   |>  68 C80000 push 0C8                                       ; /Time = 200. ms
00406A35   |.  FF15 7092 call dword ptr ds:[<&KERNEL32.Sleep>]          ; \KERNEL32.Sleep
00406A3B   |.  6A FF     push -1                                        ; /Arg3 = -1
00406A3D   |.  6A 00     push 0                                         ; |Arg2 = 0
00406A3F   |.  6A 0E     push 0E                                        ; |Arg1 = 0E
00406A41   |.  E8 5E9903 call AfxMessageBox(uint,uint,uint)             ; \Galaxy3D.AfxMessageBox ;出错对话框!
00406A46   |>  8B8C24 C4 mov ecx, dword ptr ss:[arg.49]
00406A4D   |.  5F        pop edi
00406A4E   |.  5E        pop esi
00406A4F   |.  5D        pop ebp
00406A50   |.  5B        pop ebx
00406A51   |.  64:890D 0 mov dword ptr fs:[0], ecx
00406A58   |.  81C4 C000 add esp, 0C0
00406A5E   \.  C3        retn

算法call:
CPU Disasm
Address    Hex dump      Command                                        Comments
00402CC0   /$  55        push ebp
00402CC1   |.  8BEC      mov ebp, esp
00402CC3   |.  6A FF     push -1
00402CC5   |.  68 705D44 push unknown_libname_285
00402CCA   |.  64:A1 000 mov eax, dword ptr fs:[0]
00402CD0   |.  50        push eax
00402CD1   |.  64:8925 0 mov dword ptr fs:[0], esp                      ; Installs SE handler unknown_libname_285
00402CD8   |.  83EC 20   sub esp, 20
00402CDB   |.  8B45 08   mov eax, dword ptr ss:[arg.1]
00402CDE   |.  53        push ebx
00402CDF   |.  56        push esi
00402CE0   |.  57        push edi
00402CE1   |.  8965 F0   mov dword ptr ss:[local.4], esp
00402CE4   |.  50        push eax                                       ; /Arg1 => [ARG.1]
00402CE5   |.  8D4D 08   lea ecx, [arg.1]                               ; |
00402CE8   |.  E8 336003 call CString::CString(char const *)            ; \Galaxy3D.CString::CString(char const *)
00402CED   |.  8B0D 88BD mov ecx, dword ptr ds:[_afxPchNil]
00402CF3   |.  33F6      xor esi, esi
00402CF5   |.  8975 FC   mov dword ptr ss:[local.1], esi
00402CF8   |.  894D EC   mov dword ptr ss:[local.5], ecx
00402CFB   |.  8D4D 08   lea ecx, [arg.1]
00402CFE   |.  C645 FC 0 mov byte ptr ss:[local.1], 1
00402D02   |.  E8 824D03 call CString::TrimLeft(void)                   ; [Galaxy3D.CString::TrimLeft(void)
00402D07   |.  8D4D 08   lea ecx, [arg.1]
00402D0A   |.  E8 2E4D03 call CString::TrimRight(void)                  ; [Galaxy3D.CString::TrimRight(void)
00402D0F   |.  8975 E8   mov dword ptr ss:[local.6], esi
00402D12   |>  8B4D 08   /mov ecx, dword ptr ss:[ebp+8]
00402D15   |>  3B71 F8   |/cmp esi, dword ptr ds:[ecx-8]
00402D18   |.  7D 6F     ||jge short 00402D89
00402D1A   |.  8A040E    ||mov al, byte ptr ds:[ecx+esi]
00402D1D   |.  3C 2D     ||cmp al, 2D
00402D1F   |.  74 26     ||je short 00402D47
00402D21   |.  3C 41     ||cmp al, 41
00402D23   |.  7C 04     ||jl short 00402D29
00402D25   |.  3C 46     ||cmp al, 46
00402D27   |.  7E 18     ||jle short 00402D41
00402D29   |>  3C 61     ||cmp al, 61
00402D2B   |.  7C 04     ||jl short 00402D31
00402D2D   |.  3C 66     ||cmp al, 66
00402D2F   |.  7E 10     ||jle short 00402D41
00402D31   |>  3C 30     ||cmp al, 30
00402D33   |.  0F8C FC00 ||jl 00402E35
00402D39   |.  3C 39     ||cmp al, 39
00402D3B   |.  0F8F F400 ||jg 00402E35
00402D41   |>  46        ||inc esi
00402D42   |.  8975 E8   ||mov dword ptr ss:[ebp-18], esi
00402D45   |.^ EB CE     |\jmp short 00402D15
只列出了一部分,改一下算法call的跳转,可以得到注册正确的对话框.

看来我们判断是对的.
因此,对mfc消息拦截,就变得简单明了了.
对很多MFC消息处理的拦截,直接找_AfxDispatchCmdMsg就行.
写的不好,请多多包含.

看雪招聘平台创建简历并且简历完整度达到90%及以上可获得500看雪币~

收藏
点赞0
打赏
分享
最新回复 (4)
雪    币: 692
活跃值: 活跃值 (309)
能力值: ( LV8,RANK:120 )
在线值:
发帖
回帖
粉丝
落笔飞花 活跃值 1 2014-12-16 22:22
2
0
学习留名
雪    币: 2632
活跃值: 活跃值 (915)
能力值: ( LV6,RANK:93 )
在线值:
发帖
回帖
粉丝
lynnux 活跃值 2014-12-17 08:46
3
0
打个广告--直接用xspy就可以看了
雪    币: 188
活跃值: 活跃值 (10)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
JackJoker 活跃值 2014-12-17 15:59
4
0
厉害,学习啦。
雪    币: 331
活跃值: 活跃值 (45)
能力值: ( LV2,RANK:10 )
在线值:
发帖
回帖
粉丝
bgptlmzyh 活跃值 2014-12-17 22:40
5
0
厉害,学习了
游客
登录 | 注册 方可回帖
返回