DNF羊羊0218A脱壳修复
本帖最后由 Terrorblade 于 2015-2-20 00:03 编辑首先我要声明,这篇文章不是外挂破解,只是练手过程中的一些经验分享!
前些天看到论坛里有一哥们说想破解DNF羊羊,说是一运行就出错,我在脱了壳之后发现如他所说,确实没法运行双击之后没反应,也没有进程的产生,见下图,一开始就怀疑是在CreateFile()附近做了校验,也正是因为这条经验导致我过度自信,为庸人自扰埋下伏笔……
这里还是先脱壳吧,我就不用什么bp VirtualProtect了,这些东西前人已经栽树,我们就坐享其成吧,脱壳不算难,难在于之后的修复,还好,对于这些难题大牛们都分享了他们的方法和工具,当然,我还是想多说一句,对于想学vmp的同学,还是搜索ximo大神的关于vmp的帖子,会受益匪浅的!
这里我直接跑lCF的脚本,就不用ximo大的zues了,因为我想看看到底是否有stolenoep(ximo在zues演示的时候,好像说vmp是把oep也vm了,说法不同,不必纠结这些),因为oep被偷了之后,双击是无法运行的,下面代码显示并没有stolen oep: 004AF596 55 push ebp ; Seems to be the real OEP - not stolen!Very good!
004AF597 8BEC mov ebp,esp
004AF599 6A FF push -0x1
004AF59B 68 E8475100 push YY_vmp.005147E8
004AF5A0 68 6C184B00 push YY_vmp.004B186C
004AF5A5 64:A1 00000000mov eax,dword ptr fs:
004AF5AB 50 push eax
004AF5AC 64:8925 0000000>mov dword ptr fs:,esp
004AF5B3 83EC 58 sub esp,0x58
004AF5B6 53 push ebx
004AF5B7 56 push esi
004AF5B8 57 push edi
004AF5B9 8965 E8 mov dword ptr ss:,esp
004AF5BC FF15 60034D00 call dword ptr ds: ; <jmp.&KERNEL32.GetVersion>
继续跑脚本,就生成了两个补区段的.men文件:
第一个应该就是修复iat跨平台的,第二个应该就是antidump了,进入ESP Logdata of YY.vmp.exe –看看: Use this logged data for a possible stolen OEP follow back!
-----------------------------------------------------------
12FF88 | 76E71162
12FF88 | 246
12FF88 | 246
12FF88 | FFFFFDB9
12FF88 | 200
12FF88 | 55C2470
12FF88 | 55C2470
12FF88 | FAA3DB8F
12FF88 | 5140060
12FF88 | 6A771C
12FF88 | 0
12FF88 | 4AF596
Ximo在http://www.52pojie.cn/thread-59641-1-1.html中写过这段是找到oep时,堆栈中停留的数据,找一篇空白区填补成完整的oep就可以dump了,但是这里千真万确没有stolen oep,看来我的猜测是对的!
脚本跑完,各种Antidump也修复了:
但是却并没有修复cpuid和rdtsc ,所以之后的程序没法运行,我怀疑是rdtsc校验了createfile这个过程,导致无法运行文件(我疑心太重了,但是绝对是有根据的)……
好,载入dump,直接F9,然后文件就终止了:
下面来看看这个文件CPUID and RDTSC of YY.vmp.exe -: // CPUID and RDTSC BP script
//----------------------------------
pause
bp 40F766 // 1 Possible CPUID VA
bp 42652C // 2 Possible CPUID VA
bp 4D9E29 // 3 Possible CPUID VA
bp 58A8EB // 4 Possible CPUID VA
bp 5B38CA // 5 Possible CPUID VA
bp 5DF416 // 6 Possible CPUID VA
bp 61A703 // 7 Possible CPUID VA
bp 670A49 // 8 Possible CPUID VA
bp 684AFB // 9 Possible CPUID VA
bp 69901A // A Possible CPUID VA
bp 69B7A0 // B Possible CPUID VA
bp 6B597C // C Possible CPUID VA
bp 6BAC66 // D Possible CPUID VA
bp 424957 // 1 Possible RDTSC VA
bp 4409B8 // 2 Possible RDTSC VA
bp 4E993D // 3 Possible RDTSC VA
bp 524404 // 4 Possible RDTSC VA
bp 524406 // 5 Possible RDTSC VA
bp 524408 // 6 Possible RDTSC VA
bp 52440A // 7 Possible RDTSC VA
bp 52440C // 8 Possible RDTSC VA
bp 52440E // 9 Possible RDTSC VA
bp 524410 // A Possible RDTSC VA
bp 524412 // B Possible RDTSC VA
bp 524414 // C Possible RDTSC VA
bp 524416 // D Possible RDTSC VA
bp 524418 // E Possible RDTSC VA
bp 52441A // F Possible RDTSC VA
bp 52441C // 10 Possible RDTSC VA
bp 52441E // 11 Possible RDTSC VA
bp 524420 // 12 Possible RDTSC VA
bp 524422 // 13 Possible RDTSC VA
bp 524424 // 14 Possible RDTSC VA
bp 524426 // 15 Possible RDTSC VA
bp 524428 // 16 Possible RDTSC VA
bp 525938 // 17 Possible RDTSC VA
bp 525AF0 // 18 Possible RDTSC VA
bp 526188 // 19 Possible RDTSC VA
bp 52640A // 1A Possible RDTSC VA
bp 5264F8 // 1B Possible RDTSC VA
bp 526512 // 1C Possible RDTSC VA
bp 5269E6 // 1D Possible RDTSC VA
bp 5277FC // 1E Possible RDTSC VA
bp 566507 // 1F Possible RDTSC VA
bp 5CDB04 // 20 Possible RDTSC VA
bp 5F96A8 // 21 Possible RDTSC VA
bp 610E88 // 22 Possible RDTSC VA
bp 62B980 // 23 Possible RDTSC VA
bp 62C987 // 24 Possible RDTSC VA
bp 696A8D // 25 Possible RDTSC VA
bp 6A6A78 // 26 Possible RDTSC VA
bp 6BA2A5 // 27 Possible RDTSC VA
ret // Finished
////////////////////
CPUID Exsample:
----------------------------------
CPUID ; Command of VMP code!Access first and read and note the return values!
VMP COMMAND xy ; Original VMP command before hooking!
cmp R32, 01 ; In some cases VMP access the command with conditions!Mostly eax 1!
je short @Patch ; If eax 01 then jump to our patch!
CPUID ; Fill CPUID if you hooked VMP before that command!
jmp Back to VMP ; Jump to VMP code again after Hook!>>>> A1 <<<<
@PATCH: ; Your Patch code label!
mov eax, xxxxxxxx ; Enter value of "eax" after the step over the VMP CPUID!
mov ecx, xxxxxxxx ; Enter value of "ecx" after the step over the VMP CPUID!
mov edx, xxxxxxxx ; Enter value of "edx" after the step over the VMP CPUID!
mov ebx, xxxxxxxx ; Enter value of "ebx" after the step over the VMP CPUID!
jmp Back to VMP ; Jump to VMP code again after Hook!You can also make a short jump to >>>> A1! <<<<
////////////////////
RDTSC Exsample:
----------------------------------
RDTSC ; Command of VMP code!Access first and read and note the return values!
VMP COMMAND xy ; Original VMP command before hooking!
RDTSC" ; Insert command if needed!
mov eax, xxxxxxxx ; Enter value of "eax" after the step over the VMP RDTSC!
mov edx, xxxxxxxx ; Enter value of "edx" after the step over the VMP RDTSC!
jmp Back to VMP ; Jump to VMP code again after Hook!
Just test your dumped file under VM with a other OS and check whether it's needed to patch CPUID & RDTSC!
Note that you will have problems with that if VMP used also CRC checks on that VMP addresses!
Just play a little with that till you got some success or till you failed!
So I hope that you have understand the exsamples above!
----------------------------------
LCF-AT
有13个cpuid和27个rdtsc,根据所停的位置:
0040D0E8 .8B45 08 mov eax,dword ptr ss:
0040D0EB .8B55 00 mov edx,dword ptr ss:
0040D0EE .8D52 08 lea edx,dword ptr ds:
使用eax和edx两个寄存器,这个正是rdtsc所要patch的寄存器,所以才导致我怀疑rdtsc校验这一部分代码,导致文件不能createfile。哎,其实我也是看了ximo的zues演示之后才产生这种YY的,在ximo的zues演示中,ximo通过按钮事件定位到cpuid和rdtsc的,所以,我就认为,rdtsc会不会就刚好校验了createfile() ?!
接着就我就用api下断,bp CreateFile,试图跟着handle的地址,然后无论怎么下断,F9后程序马上就终止了,后来在0040D0E8下了硬件断点,才走过了:0040D0F1 .CD2E int 0x2E
然后我继续bp CreateFile,觉得这下应该可以下断了吧,很遗憾,F9后再次跑飞了(糊涂呀,后来才知道这里就是createfile的中断)……
萌萌的我,并未就此放弃,我来到了段首,从上往下,看看能不能得到其他线索:
.text:0040D003 ; =============== S U B R O U T I N E =======================================
.text:0040D003
.text:0040D003 ; Attributes: bp-based frame
.text:0040D003
.text:0040D003 sub_40D003 proc near ; CODE XREF: sub_407E0E+64p
.text:0040D003 ; sub_40D1AE+64p ...
.text:0040D003
.text:0040D003 var_C = dword ptr -0Ch
.text:0040D003 var_4 = dword ptr -4
.text:0040D003 var_s0 = dword ptr0
.text:0040D003 arg_0 = dword ptr8
.text:0040D003
.text:0040D003 000 push ebp
.text:0040D004 004 mov ebp, esp
.text:0040D006 004 sub esp, 14h ; Integer Subtraction
.text:0040D00C 018 cmp , 0; Compare Two Operands
.text:0040D010 018 jge loc_40D025 ; Jump if Greater or Equal (SF=OF)
.text:0040D016 018 mov eax, 0FFFFFFFDh
.text:0040D01B 018 jmp loc_40D102 ; Jump
.text:0040D020 ; ---------------------------------------------------------------------------
.text:0040D020 018 jmp loc_40D0F8 ; Jump
.text:0040D025 ; ---------------------------------------------------------------------------
.text:0040D025
.text:0040D025 loc_40D025: ; CODE XREF: sub_40D003+Dj
.text:0040D025 018 mov ebx, dword_5303A4
.text:0040D02B 018 add ebx, 1Ch ; Add
.text:0040D02E 018 mov , ebx
.text:0040D031 018 mov ebx,
.text:0040D034 018 cmp dword ptr , 0 ; Compare Two Operands
.text:0040D037 018 jz loc_40D0D0 ; Jump if Zero (ZF=1)
.text:0040D03D 018 mov ebx, dword_5303A4
.text:0040D043 018 add ebx, 4 ; Add
.text:0040D046 018 mov , ebx
.text:0040D049 018 mov ebx,
.text:0040D04C 018 cmp dword ptr , 6 ; Compare Two Operands
.text:0040D04F 018 jnz loc_40D074 ; Jump if Not Zero (ZF=0)
.text:0040D055 018 mov ebx, dword_5303A4
.text:0040D05B 018 add ebx, 8 ; Add
.text:0040D05E 018 mov , ebx
.text:0040D061 018 mov ebx,
.text:0040D064 018 cmp dword ptr , 2 ; Compare Two Operands
.text:0040D067 018 jnz loc_40D074 ; Jump if Not Zero (ZF=0)
.text:0040D06D 018 mov eax, 1
.text:0040D072 018 jmp short loc_40D076 ; Jump
.text:0040D074 ; ---------------------------------------------------------------------------
.text:0040D074
.text:0040D074 loc_40D074: ; CODE XREF: sub_40D003+4Cj
.text:0040D074 ; sub_40D003+64j
.text:0040D074 018 xor eax, eax ; Logical Exclusive OR
.text:0040D076
.text:0040D076 loc_40D076: ; CODE XREF: sub_40D003+6Fj
.text:0040D076 018 test eax, eax ; Logical Compare
.text:0040D078 018 jz loc_40D0A2 ; Jump if Zero (ZF=1)
.text:0040D07E 018 mov eax,
.text:0040D081 018 add eax, 80h ; Add
.text:0040D086 018 mov ecx, 20h
.text:0040D08B
.text:0040D08B loc_40D08B: ; CODE XREF: sub_40D003+8Dj
.text:0040D08B 018 push dword ptr
.text:0040D08D 01C sub eax, 4 ; Integer Subtraction
.text:0040D090 01C loop loc_40D08B ; Loop while CX != 0
.text:0040D092 01C mov eax,
.text:0040D095 01C call large dword ptr fs:0C0h ; Indirect Call Near Procedure
.text:0040D09C 01C nop ; No Operation
.text:0040D09D 01C nop ; No Operation
.text:0040D09E 01C leave ; High Level Procedure Exit
.text:0040D09F 004 retn 4 ; Return Near from Procedure
很遗憾,并没有找到有价值的东西,然后打开ida,停在程序终止的地方:
看到这里,我笑了,学了那么多,基础都忘了(大过年的,脑子被鞭炮炸乱了)……此时我脑子浮现出int 3 断点,也就是cc,然后,马上百度:
; DOS 2+ internal - EXECUTE COMMAND
; DS:SI -> counted CR-terminated command
在这里:http://www.cnblogs.com/jack204/archive/2011/12/06/2278392.html,我找到了答案:
关于 int 2E 见http://www.pediy.com/kssd/pediy08/pediy8-682.htm,我就不在赘述{:301_995:}
写到这里,就不往下写了,剩下的都在视频里,看来,还是脱离不了ida这个工具的注释呀!过年这几天奔波劳累,又被鞭炮狂轰滥炸(我特别讨厌鞭炮-噪音污染&空气污染),脑子实在太乱……还有就是那位要破解DNF羊羊的哥们,你的截图跟我终止的地方不一样,是不是脱壳出了什么问题吧?我只写我想写的东西,我不玩DNF,所以这个外挂也不跟下去。最后,大家新年快乐!
视频:http://pan.baidu.com/s/1sjkFrh7解压密码:yang
本帖最后由 Terrorblade 于 2015-2-20 19:43 编辑
莫言丶 发表于 2015-2-19 19:08
真的是大神啊
我不是大神{:301_998:}
这篇文章,开头就说自己庸人自扰,在结尾的时候已经留下重要线索,看得懂之人,肯定会会心一笑,毕竟这是个牛叉外挂还加着vmprotect,谁去碰它都要谨慎……还没弄清楚的同学,就看视频吧,彩蛋在视频里,其实就改动一个地方,程序就正常运行了{:301_997:} 真的是大神啊{:301_1009:} 学习了,谢谢分享 {:17_1065:}真的是大神啊 好东西啊,就是不知道怎么破。 力顶!!不错 本帖最后由 Terrorblade 于 2015-2-19 20:32 编辑
SeiSyun20 发表于 2015-2-19 19:01
好东西啊,就是不知道怎么破。
请在论坛搜索“天道酬勤 DNF”
写外挂个人感觉不是很难,基本就是注入线程-QueueUserAPC() || CreateRemoteTread(),关键是你怎么破DNF的保护 值得借鉴、 不错,看看啊 大神学习了。。。
页:
[1]
2