上篇讲的是对程序的定时器消息下断点,如果要拦截用户消息,比如点击按钮等,则需要对消息WM_COMMAND下条件断点,下断点的位置与定时器消息相同,步骤如下:
1 首先找到CWnd::WindowProc函数,进入这个函数以后在函数OnWndMsg前下条件断点,条件为[ebp+8]==WM_COMMAND,代码如下

















点击程序按钮,断下command消息,F7跟进73D31B95


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
73D31BE3 FF75 10 push dword ptr [ebp+10]
73D31BE6 8B07 mov eax, dword ptr [edi]
73D31BE8 FF75 0C push dword ptr [ebp+C]
73D31BEB FF90 80000000 call dword ptr [eax+80] ; <jmp.&MFC42.#4441_CWnd::OnCommand>
与WM_TIMER消息不通,此时在73D31BE1处不会发生跳转,继续F8到call处,跟进,进入OnCommand函数中,继续F8,直到call函数_CDialog::OnCmdMsg处


73D33234 895D 08 mov dword ptr [ebp+8>
73D33237 8B06 mov eax, dword ptr [>
73D33239 53 push ebx
73D3323A 53 push ebx
73D3323B FF75 08 push dword ptr [ebp+8>
73D3323E 8BCE mov ecx, esi
73D33240 57 push edi
73D33241 FF50 14 call dword ptr [eax+1>; <jmp.&MFC42.#4425_CDialog::OnCmdMsg>
跟进这个call


73D9DE90 > 8BFF mov edi, edi ; OnCmdMsg
73D9DE92 55 push ebp
73D9DE93 8BEC mov ebp, esp
73D9DE95 53 push ebx
73D9DE96 8B5D 08 mov ebx, dword ptr [ebp+8]
73D9DE99 56 push esi
73D9DE9A 57 push edi
73D9DE9B FF75 14 push dword ptr [ebp+14]
73D9DE9E 8B7D 0C mov edi, dword ptr [ebp+C]
73D9DEA1 FF75 10 push dword ptr [ebp+10]
73D9DEA4 8BF1 mov esi, ecx
73D9DEA6 57 push edi
73D9DEA7 53 push ebx
73D9DEA8 E8 0844F9FF call #4424_CCmdTarget::OnCmdMsg
很快发现了对_CCmdTarget::OnCmdMsg的call,继续跟进,在这个函数中会调用_AfxDispatchCmdMsg对消息进行分发,只要跟进这个函数很快就能找到消息处理函数了,继续F8寻找_AfxDispatchCmdMsg函数


73D323A7 FF75 14 push dword ptr [ebp+14]
73D323AA FF70 10 push dword ptr [eax+10]
73D323AD FF75 10 push dword ptr [ebp+10]
73D323B0 FF70 14 push dword ptr [eax+14] ; 消息函数地址
73D323B3 FF75 0C push dword ptr [ebp+C]
73D323B6 FF75 08 push dword ptr [ebp+8]
73D323B9 57 push edi
73D323BA E8 7F000000 call 73D3243E
终于找到了,跟进这个call,来到函数_AfxDispatchCmdMsg内部,跟进遇见的第一个call
73D324BD FF55 14 call dword ptr [ebp + 14 ] ; MFC42.73D4AAB0
这是一个MFC42领空的调用,进入以后代码如下
73D4AAB2 - FFA0 CC000000 jmp dword ptr [eax + CC] ; 拦截按钮.004014A0
出现了程序领空了,这里不是用的call,是直接jmp过去的,跟进,消息处理函数终于出来了!哈


004014A0 . 8B41 20 mov eax, dword ptr [ecx+20] ; 按钮的消息相应函数
004014A3 . 6A 00 push 0 ; /Timerproc = NULL
004014A5 . 68 D0070000 push 7D0 ; |Timeout = 2000. ms
004014AA . 6A 02 push 2 ; |TimerID = 2
004014AC . 50 push eax ; |hWnd
004014AD . FF15 D0214000 call dword ptr [<&USER32.SetTimer>] ; \SetTimer
004014B3 . C3 retn
消息处理函数很简单,就是调用下定时器,再结合上篇寻找定时器消息相应函数的方法,这个程序的秘密已经完全被消除了,oh yeah!