Terrorblade 发表于 2015-2-19 18:47

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 12:08

本帖最后由 Terrorblade 于 2015-2-20 19:43 编辑

莫言丶 发表于 2015-2-19 19:08
真的是大神啊
我不是大神{:301_998:}
这篇文章,开头就说自己庸人自扰,在结尾的时候已经留下重要线索,看得懂之人,肯定会会心一笑,毕竟这是个牛叉外挂还加着vmprotect,谁去碰它都要谨慎……还没弄清楚的同学,就看视频吧,彩蛋在视频里,其实就改动一个地方,程序就正常运行了{:301_997:}

莫言丶 发表于 2015-2-19 19:08

真的是大神啊{:301_1009:}

凌云9 发表于 2015-2-19 19:06

学习了,谢谢分享

一夜九次郎 发表于 2015-2-26 20:50

{:17_1065:}真的是大神啊

SeiSyun20 发表于 2015-2-19 19:01

好东西啊,就是不知道怎么破。

a5680497 发表于 2015-2-19 19:09

力顶!!不错

Terrorblade 发表于 2015-2-19 19:20

本帖最后由 Terrorblade 于 2015-2-19 20:32 编辑

SeiSyun20 发表于 2015-2-19 19:01
好东西啊,就是不知道怎么破。
请在论坛搜索“天道酬勤 DNF”
写外挂个人感觉不是很难,基本就是注入线程-QueueUserAPC() || CreateRemoteTread(),关键是你怎么破DNF的保护

小裕 发表于 2015-2-19 19:30

值得借鉴、

qscb001 发表于 2015-2-19 20:23

不错,看看啊

a111dao 发表于 2015-2-20 12:16

大神学习了。。。
页: [1] 2
查看完整版本: DNF羊羊0218A脱壳修复