很多年前已经有人写出来了MFCSPY 我发现少个静态release支持 所以我重写了下
大致思路:
使用dll钩子获取被spy程序的MFC窗口类,然后获得消息映射表,遍历即可
有几个注意地方:
(1)dll需要用mfc dll来写,获取消息映射表MFC现成有GetMessageMap()虚函数,直接可以拿来用,
因为GetMessageMap()是保护函数,所以共有继承CWnd,类里调用GetMessageMap()即可
(静态release版本需要特殊处理下 CWnd虚表中GetMessageMap()的偏移不是0x30而是0x28)
(2)获取当前运行程序的编译方式,这点我没想到方法,知道的麻烦指教下,我只用了
if (GetModuleHandle("mfc42d.dll") != NULL)
{
return MFC42D;
}
if (GetModuleHandle("mfc42.dll") != NULL)
{
return MFC42;
}
return STATIC;
来获取编译方式,用此方法dll的编译方式不能为动态链接,因为我总感觉这种方式不好,所以MFC DLL窗口程序的特征码也没找,只处理了exe, 我使用的是VC6. 更高版本MFC因为没有安装,所以没有测试
具体实现:
测试发现,mfc动态debug方式下 直接在dll钩子函数使用CWnd::FromHandlePermanent便能获得对应的类信息,而其他编译方式都获得不了,所以我使用特征码来找被SPY的窗口CWnd::FromHandlePermanent函数的入口,因为CWnd::FromHandlePermanent在MFC框架的窗口消息处理函数中前几行就调用,所以可以找到4种不同编译方式下的窗口消息处理函数特征,
找到CWnd::FromHandlePermanent函数入口(我最后发现mfc dll中的特征和exe的并不一样,如果想处理dll,则必须再把mfc dll窗口消息处理函数的特征给弄全)
mfc static release:
00418787 55 push ebp
00418788 8B EC mov ebp,esp
0041878A 81 7D 0C 60 03 00 00 cmp dword ptr [ebp+0Ch],360h
00418791 56 push esi
00418792 75 05 jne 00418799
00418794 6A 01 push 1
00418796 58 pop eax
00418797 EB 34 jmp 004187CD
00418799 8B 75 08 mov esi,dword ptr [ebp+8]
0041879C 56 push esi
0041879D E8 5F FF FF FF call 00418701 ;CWnd::FromHandlePermanent
mfc static debug:
0047FFE8 55 push ebp
0047FFE9 8B EC mov ebp,esp
0047FFEB 51 push ecx
0047FFEC 53 push ebx
0047FFED 56 push esi
0047FFEE 57 push edi
0047FFEF 81 7D 0C 60 03 00 00 cmp dword ptr [nMsg],360h
0047FFF6 75 0A jne AfxWndProc+1Ah (00480002)
0047FFF8 B8 01 00 00 00 mov eax,1
0047FFFD E9 93 00 00 00 jmp AfxWndProc+0ADh (00480095)
00480002 8B 45 08 mov eax,dword ptr [hWnd]
00480005 50 push eax
00480006 E8 5D FE FF FF call CWnd::FromHandlePermanent (0047fe68)
mfc share Debug:
AfxWndProcBase:
5F492613 55 push ebp
5F492614 8B EC mov ebp,esp
5F492616 6A FF push 0FFh
5F492618 68 D1 97 4A 5F push offset $L89118 (5f4a97d1) ;171B8
5F49261D 64 A1 00 00 00 00 mov eax,fs:[00000000]
5F492623 50 push eax
5F492624 64 89 25 00 00 00 00 mov dword ptr fs:[0],esp
5F49262B 83 EC 0C sub esp,0Ch
5F49262E B9 10 48 4D 5F mov ecx,offset _afxBaseModuleState (5f4d4810)
5F492633 E8 28 03 00 00 call CProcessLocal<_AFX_BASE_MODULE_STATE>::GetData(5f492960)
5F492638 50 push eax
5F492639 8D 4D EC lea ecx,[_ctlState]
5F49263C E8 72 F8 FF FF call AFX_MAINTAIN_STATE2::AFX_MAINTAIN_STATE2 (5f491eb3)
5F492641 C7 45 FC 00 00 00 00 mov dword ptr [ebp-4],0
5F492648 8B 45 14 mov eax,dword ptr [lParam]
5F49264B 50 push eax
5F49264C 8B 4D 10 mov ecx,dword ptr [wParam]
5F49264F 51 push ecx
5F492650 8B 55 0C mov edx,dword ptr [nMsg]
5F492653 52 push edx
5F492654 8B 45 08 mov eax,dword ptr [hWnd]
5F492657 50 push eax
5F492658 E8 EB C9 F9 FF call AfxWndProc (5f42f048)
AfxWndProc:
5F42F048 55 push ebp
5F42F049 8B EC mov ebp,esp
5F42F04B 51 push ecx
5F42F04C 53 push ebx
5F42F04D 56 push esi
5F42F04E 57 push edi
5F42F04F 81 7D 0C 60 03 00 00 cmp dword ptr [nMsg],360h
5F42F056 75 0A jne AfxWndProc+1Ah (5f42f062)
5F42F058 B8 01 00 00 00 mov eax,1
5F42F05D E9 93 00 00 00 jmp AfxWndProc+0ADh (5f42f0f5)
5F42F062 8B 45 08 mov eax,dword ptr [hWnd]
5F42F065 50 push eax
5F42F066 E8 5D FE FF FF call CWnd::FromHandlePermanent (5f42eec8)
mfc share release:
AfxWndProcBase:
73DBE443 B8 EC 41 DC 73 mov eax,73DC41ECh ;0x5DA8
73DBE448 E8 A3 BB FF FF call 73DB9FF0
73DBE44D 51 push ecx
73DBE44E 51 push ecx
73DBE44F 68 89 FD DB 73 push 73DBFD89h ;0x1939
73DBE454 B9 50 26 E0 73 mov ecx,73E02650h ;0x441FB
73DBE459 E8 BF FE FF FF call 73DBE31D
73DBE45E 50 push eax
73DBE45F 8D 4D EC lea ecx,[ebp-14h]
73DBE462 E8 B5 FF FF FF call 73DBE41C
73DBE467 FF 75 14 push dword ptr [ebp+14h]
73DBE46A 83 65 FC 00 and dword ptr [ebp-4],0
73DBE46E FF 75 10 push dword ptr [ebp+10h]
73DBE471 FF 75 0C push dword ptr [ebp+0Ch]
73DBE474 FF 75 08 push dword ptr [ebp+8]
73DBE477 E8 20 35 F7 FF call 73D3199C ;AfxWndProc
AfxWndProc:
73D3199C 55 push ebp
73D3199D 8B EC mov ebp,esp
73D3199F 81 7D 0C 60 03 00 00 cmp dword ptr [ebp+0Ch],360h
73D319A6 75 05 jne 73D319AD
73D319A8 33 C0 xor eax,eax
73D319AA 40 inc eax
73D319AB EB 36 jmp 73D319E3
73D319AD 56 push esi
73D319AE 8B 75 08 mov esi,dword ptr [ebp+8]
73D319B1 56 push esi
73D319B2 E8 22 F8 FF FF call 73D311D9 ;CWnd::FromHandlePermanent
mfc share release dll
00BC1B70 55 PUSH EBP
00BC1B71 8BEC MOV EBP,ESP
00BC1B73 6A FF PUSH -1
00BC1B75 68 5935BC00 PUSH MfcDll1.00BC3559
00BC1B7A 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
00BC1B80 50 PUSH EAX
00BC1B81 64:8925 0000000>MOV DWORD PTR FS:[0],ESP
00BC1B88 83EC 0C SUB ESP,0C
00BC1B8B 68 9869BD00 PUSH MfcDll1.00BD6998
00BC1B90 8D4D EC LEA ECX,DWORD PTR SS:[EBP-14]
00BC1B93 E8 FEFDFFFF CALL <JMP.&MFC42D.#284>
00BC1B98 C745 FC 0000000>MOV DWORD PTR SS:[EBP-4],0
00BC1B9F 8B45 14 MOV EAX,DWORD PTR SS:[EBP+14]
00BC1BA2 50 PUSH EAX
00BC1BA3 8B4D 10 MOV ECX,DWORD PTR SS:[EBP+10]
00BC1BA6 51 PUSH ECX
00BC1BA7 8B55 0C MOV EDX,DWORD PTR SS:[EBP+C]
00BC1BAA 52 PUSH EDX
00BC1BAB 8B45 08 MOV EAX,DWORD PTR SS:[EBP+8]
00BC1BAE 50 PUSH EAX
00BC1BAF E8 7A060000 CALL <JMP.&MFC42D.#1192>
00BC1BB4 8945 E8 MOV DWORD PTR SS:[EBP-18],EAX
因为静态release的GetMessageMap()偏移为0x28 所以
我单独做了处理(这样就无关dll编译版本)
if (g_isStaticRelase == true)
{
__asm
{
mov eax,this
mov eax,[eax]
mov ecx,this
call [eax + 028h]
}
}
[培训]《安卓高级研修班(网课)》月薪三万计划,掌握调试、分析还原ollvm、vmp的方法,定制art虚拟机自动化脱壳的方法