【文章标题】DotFix NiceProtect 2.x-3.x (Max Protection) 脱壳分析
【文章作者】KuNgBiM/[CCG]
【作者邮箱】kungbim@163.com
【脱壳目标】MetaTrader 4 Client Terminal 主程序
【下载地址】http://www.metaquotes.net/files/mt4setup.exe
【程序简介】国外的一款外汇交易软件
【加壳方式】DotFix NiceProtect 2.x - 3.x
【保护选项】Max Protection
【使用工具】OllyICE,LordPE,ImportREC
【脱壳平台】三元钱一张的非正版WinXPsp2
【作者声明】只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教!
--------------------------------------------------------------------------------
【脱壳内容】
OllyICE载入目标程序,忽略所有异常。
00BD20CC > /E9 FF000000 jmp terminal.00BD21D0 ; EP
00BD20D1 |60 pushad
00BD20D2 |8B7424 24 mov esi,dword ptr ss:[esp+24]
00BD20D6 |8B7C24 28 mov edi,dword ptr ss:[esp+28]
00BD20DA |FC cld
00BD20DB |B2 80 mov dl,80
00BD20DD |33DB xor ebx,ebx
00BD20DF |A4 movsb
00BD20E0 |B3 02 mov bl,2
00BD20E2 |E8 6D000000 call terminal.00BD2154
00BD20E7 ^|73 F6 jnb short terminal.00BD20DF
00BD20E9 |33C9 xor ecx,ecx
00BD20EB |E8 64000000 call terminal.00BD2154
00BD20F0 |73 1C jnb short terminal.00BD210E
00BD20F2 |33C0 xor eax,eax
00BD20F4 |E8 5B000000 call terminal.00BD2154
00BD20F9 |73 23 jnb short terminal.00BD211E
00BD20FB |B3 02 mov bl,2
00BD20FD |41 inc ecx
00BD20FE |B0 10 mov al,10
【避开调试器检测及代码解压缩】(虽然现在很多修改版的OD都能跑,不过既然是脱壳,那么就一定要避开它检测!)
命令窗:bp FindWindowA
Shift+F9 运行:
——————————— 过时的调试器检测办法 ——————————————
0012FBB8 00BACA18 /CALL 到 FindWindowA 来自 terminal.00BACA16
0012FBBC 00BAC9CA |Class = "OLLYDBG"
0012FBC0 00BAC986 指向下一个 SEH 记录的指针
0012FBC4 00BAC02E SE处理程序
0012FBC8 00BAB317 返回到 terminal.00BAB317 来自 terminal.00BABCDC
0012FBCC 00BAAC9B 返回到 terminal.00BAAC9B 来自 terminal.00BAB30B
0012FBD0 00BAA2FF 返回到 terminal.00BAA2FF 来自 terminal.00BAA96F
0012FBD4 7C9237BF 返回到 ntdll.7C9237BF
————————————————————————————————————
77D2E591 > 8BFF mov edi,edi ; 中断后取消函数断点
77D2E593 55 push ebp
77D2E594 8BEC mov ebp,esp
77D2E596 33C0 xor eax,eax
77D2E598 50 push eax
77D2E599 FF75 0C push dword ptr ss:[ebp+C]
77D2E59C FF75 08 push dword ptr ss:[ebp+8]
77D2E59F 50 push eax
77D2E5A0 50 push eax
77D2E5A1 E8 4CFFFFFF call USER32.77D2E4F2
77D2E5A6 5D pop ebp
77D2E5A7 C2 0800 retn 8 ; 在此F2下断
命令窗:bc FindWindowA
Shift+F9 继续运行,中断后取消断点:
00BACA18 85C0 test eax,eax ; 返回到这里,继续F7
00BACA1A 75 05 jnz short terminal.00BACA21
00BACA1C E8 70060000 call terminal.00BAD091
00BACA21 E8 0B000000 call terminal.00BACA31
00BACA26 3036 xor byte ptr ds:[esi],dh
00BACA28 2037 and byte ptr ds:[edi],dh
00BACA2A 76 77 jbe short terminal.00BACAA3
00BACA2C 6B21 29 imul esp,dword ptr ds:[ecx],29
00BACA2F 2900 sub dword ptr ds:[eax],eax
00BACA31 EB 01 jmp short terminal.00BACA34
00BACA33 - E9 5AEB01EA jmp EABCB592
00BACA38 52 push edx
00BACA39 4A dec edx
00BACA3A EB 01 jmp short terminal.00BACA3D
5次F7:
00BAD0A1 /EB 01 jmp short terminal.00BAD0A4 ; 注意观察ESP变化,使用ESP定律中断2次即可
00BAD0A3 |EB 5A jmp short terminal.00BAD0FF
00BAD0A5 EB 01 jmp short terminal.00BAD0A8
00BAD0A7 EA 524AEB06 72DD jmp far DD72:06EB4A52
00BAD0AE ^ 73 E5 jnb short terminal.00BAD095
00BAD0B0 1F pop ds
00BAD0B1 A8 EB test al,0EB
00BAD0B3 01EA add edx,ebp
00BAD0B5 B9 0A000000 mov ecx,0A
00BAD0BA EB 03 jmp short terminal.00BAD0BF
00BAD0BC 1838 sbb byte ptr ds:[eax],bh
00BAD0BE DEEB fsubp st(3),st
00BAD0C0 01EA add edx,ebp
命令窗:hr esp
Shift+F9中断后:
00BAD0A5 /EB 01 jmp short terminal.00BAD0A8 ; 第1次中断,继续
00BAD0A7 |EA 524AEB06 72DD jmp far DD72:06EB4A52
00BAD0AE ^ 73 E5 jnb short terminal.00BAD095
00BAD0B0 1F pop ds
00BAD0B1 A8 EB test al,0EB
00BAD0B3 01EA add edx,ebp
00BAD0B5 B9 0A000000 mov ecx,0A
00BAD0BA EB 03 jmp short terminal.00BAD0BF
00BAD0A9 4A dec edx ; 第2次中断后来到这里
00BAD0AA EB 06 jmp short terminal.00BAD0B2
00BAD0AC ^ 72 DD jb short terminal.00BAD08B
00BAD0AE ^ 73 E5 jnb short terminal.00BAD095
00BAD0B0 1F pop ds
00BAD0B1 A8 EB test al,0EB
00BAD0B3 01EA add edx,ebp
00BAD0B5 B9 0A000000 mov ecx,0A
00BAD0BA EB 03 jmp short terminal.00BAD0BF
00BAD0BC 1838 sbb byte ptr ds:[eax],bh
00BAD0BE DEEB fsubp st(3),st
00BAD0C0 01EA add edx,ebp
取消所有断点,Alt+M打开内存镜像,在PE header段设置访问断点,Shift+F9运行中断后,再次在CODE区段设置访问断点,Shift+F9运行后即可到达程序内部,当然这时的IAT也是没加密的了。
00541DBF 33DB xor ebx,ebx ; 程序内部
00541DC1 3BC3 cmp eax,ebx
00541DC3 8906 mov dword ptr ds:[esi],eax
00541DC5 74 62 je short terminal.00541E29
00541DC7 57 push edi
00541DC8 8B3D 08C25500 mov edi,dword ptr ds:[55C208] ; kernel32.GetProcAddress
00541DCE 68 88985800 push terminal.00589888 ; ASCII "OpenThemeData"
00541DD3 50 push eax
00541DD4 FFD7 call edi
00541DD6 8946 04 mov dword ptr ds:[esi+4],eax
00541DD9 8B06 mov eax,dword ptr ds:[esi]
00541DDB 68 78985800 push terminal.00589878 ; ASCII "CloseThemeData"
00541DE0 50 push eax
00541DE1 FFD7 call edi
00541DE3 8B0E mov ecx,dword ptr ds:[esi]
00541DE5 68 64985800 push terminal.00589864 ; ASCII "DrawThemeBackground"
00541DEA 51 push ecx
00541DEB 8946 08 mov dword ptr ds:[esi+8],eax
00541DEE FFD7 call edi
00541DF0 8B16 mov edx,dword ptr ds:[esi]
00541DF2 68 48985800 push terminal.00589848 ; ASCII "DrawThemeParentBackground"
00541DF7 52 push edx
【以上步骤我们完全可以用脚本来完成】
/*
Script written by KuNgBiM
Script: DotFix NiceProtect 辅助脚本
Debugging options: Tick all items in OllyDbg's Debugging Options-Exceptions
Test Environment : OllyDbg 1.10, ODBGScript 1.65, WinXP
*/
#log
var tmp
// 相当于“bp FindWindowA”不过插件不能直接支持这样的下断命令
gpa "FindWindowA","user32.dll"
cmp $RESULT,0
je error
// 寻找“retn 8”特征准备返回
find $RESULT,#C20800#
cmp $RESULT,0
je error
bp $RESULT
esto
bc eip
// 按5次F7
sti
sti
sti
sti
sti
// ESP定律(两次)
mov tmp,esp
bphws tmp,"r"
esto
esto
bphwc tmp
msg "请用Alt+M打开内存镜像,在PE header段设置访问断点,Shift+F9运行中断后,再次在CODE区段设置访问断点,Shift+F9运行后即可到达程序内部,当然这时的IAT也是没加密的了。"
msg "提示: 修补StolenCode及VM code由你自己去完成! ^_^"
ret
error:
msg "脚本错误!"
ret
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)
上传的附件: