好友
阅读权限30
听众
最后登录1970-1-1
|
红绡枫叶
发表于 2014-12-16 21:48
本帖最后由 红绡枫叶 于 2014-12-16 21:50 编辑
写这篇文章的目的只是为了精确简洁的拦截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就行.
写的不好,请多多包含.
|
免费评分
-
查看全部评分
|