DFCGASPROTECT 2.x 脱壳系列(二)

【目    标】:DVD Fab Gold 2.9.3.5
【工    具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
【任    务】:简单的脱壳
【操作平台】:Windows XP sp2
【作    者】:LOVEBOOM[DFCG][FCG][US]
【相关链接】:自己搜索下
【简要说明】:其实这个版本的还是更先脱的,只是整理的时候更后整理出来。看这篇文章之前建议先看我的第一篇文章,否则有些过程可能不好理解。

【详细过程】:
  话也不多说,直接入主题, 载入目标程序,去除调试标志,下断bp GetModuleHandleA,运行中断两次,然后执行到完全解压出壳的代码:
00AF24AC    85C0            TEST    EAXEAX                         ; 第二次返回到这里
00AF24AE    75 07           JNZ     SHORT 00AF24B7
00AF24B0    53              PUSH    EBX
00AF24B1    FF95 F0314400   CALL    DWORD PTR SS:[EBP+4431F0]        ; kernel32.LoadLibraryA
......
00AF25BB    8985 112F4400   MOV     DWORD PTR SS:[EBP+442F11], EAX
00AF25C1    61              POPAD                                    ; 直接f4执行到这里
00AF25C2    75 08           JNZ     SHORT 00AF25CC
00AF25C4    B8 01000000     MOV     EAX, 1
00AF25C9    C2 0C00         RETN    0C
00AF25CC    68 A08FAE00     PUSH    0AE8FA0                          ; 解压完跳去壳的代码入口点
00AF25D1    C3              RETN
00AF25D2    8B85 DC304400   MOV     EAXDWORD PTR SS:[EBP+4430DC]   ; kernel32.7C800000
......
00AE8FA0    55               PUSH    EBP                              ; 壳代码入口点
00AE8FA1    8BEC             MOV     EBPESP
00AE8FA3    83C4 B4          ADD     ESP, -4C
00AE8FA6    B8 988DAE00      MOV     EAX, 0AE8D98

到了壳的入口点后直接搜索以下命令:
  MOV     DWORD PTR SS:[EBP], EAX
  PUSH    0A
找到一处:
00AE653F    8945 00          MOV     DWORD PTR SS:[EBP], EAX          ; 找到这里
00AE6542    6A 0A            PUSH    0A
00AE6544    E8 63C4FEFF      CALL    00AD29AC
00AE6549    8BC8             MOV     ECXEAX

找到地址后,在上面的地址处下硬件断点,执行发生中断后取消硬件断点。

再找一下存放相关数据的地址,我选择的是513100.找到后,写段保存数据代码:
00AE653F   /EB 43            JMP     SHORT 00AE6584                   ; 找到这里
00AE6541   |90               NOP
00AE6542   |6A 0A            PUSH    0A
00AE6544   |E8 63C4FEFF      CALL    00AD29AC
00AE6549   |8BC8             MOV     ECXEAX
00AE654B   |038B E4000000    ADD     ECXDWORD PTR DS:[EBX+E4]
00AE6551   |8BD6             MOV     EDXESI
00AE6553   |8BC3             MOV     EAXEBX
00AE6555   |E8 9EE5FFFF      CALL    00AE4AF8
00AE655A   |FF0C24           DEC     DWORD PTR SS:[ESP]
00AE655D   |03B3 E4000000    ADD     ESIDWORD PTR DS:[EBX+E4]
00AE6563   |833C24 00        CMP     DWORD PTR SS:[ESP], 0
00AE6567  ^|0F87 55FEFFFF    JA      00AE63C2
00AE656D   |53               PUSH    EBX                              ; 写好保存相关数据代码后,在这里下F2断点
00AE656E   |E8 5D000000      CALL    00AE65D0
00AE6573   |0183 EC000000    ADD     DWORD PTR DS:[EBX+EC], EAX
00AE6579   |B0 01            MOV     AL, 1
00AE657B   |83C4 24          ADD     ESP, 24
00AE657E   |5D               POP     EBP                              ; 00ADBDC8
00AE657F   |5F               POP     EDI                              ; 00ADBDC8
00AE6580   |5E               POP     ESI                              ; 00ADBDC8
00AE6581   |5B               POP     EBX                              ; 00ADBDC8
00AE6582   |C3               RETN
00AE6583   |90               NOP
00AE6584   \53               PUSH    EBX                              ; 保护堆栈
00AE6585    51               PUSH    ECX
00AE6586    B9 00315100      MOV     ECX, 513100                      ; 保存相关数据的起始地址
00AE658B    8339 00          CMP     DWORD PTR DS:[ECX], 0
00AE658E    75 06            JNZ     SHORT 00AE6596
00AE6590    C701 10315100    MOV     DWORD PTR DS:[ECX], 513110       ; 如果是第次则初始化,从513110处开始保存相关数据
00AE6596    8B19             MOV     EBXDWORD PTR DS:[ECX]          ; wsock32.#1139
00AE6598    4D               DEC     EBP                              ; DVDFabGo.004EE4A6
00AE6599    892B             MOV     DWORD PTR DS:[EBX], EBP          ; 保存相关地址
00AE659B    83C3 04          ADD     EBX, 4
00AE659E    8919             MOV     DWORD PTR DS:[ECX], EBX
00AE65A0    45               INC     EBP                              ; DVDFabGo.004EE4A6
00AE65A1    59               POP     ECX                              ; 00ADBDC8
00AE65A2    5B               POP     EBX                              ; 00ADBDC8
00AE65A3    8945 00          MOV     DWORD PTR SS:[EBP], EAX          ; 执行原壳的代码
00AE65A6  ^ EB 9A            JMP     SHORT 00AE6542
00AE65A8    C1E3 18          SHL     EBX, 18
00AE65AB    31D8             XOR     EAXEBX

写好代码后在00AE656D处下F2断点,再F9运行,运行中断后,把修复代码还原回去,第三次出现机器码时写上注册信息:

--------------------第一次----------------------
0012FF1C   0012FF28  Pointer to next SEH record
0012FF20   00ADC92E  SE handler
0012FF24   00000002
0012FF28   0012FF80  Pointer to next SEH record
0012FF2C   00ADD739  SE handler
0012FF30   0012FF78
0012FF34   00AC0000
0012FF38   00A80000
0012FF3C   00ADBDC8
0012FF40   00000000
0012FF44   00B59E34  ASCII "6uCokAAAJmg="
0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF4C   C5FC9640
0012FF50   41B05FF0
0012FF54   F81D0E0A
......
--------------------第二次----------------------
0012FF1C   0012FF28  Pointer to next SEH record
0012FF20   00ADCAD5  SE handler
0012FF24   00B3045C
0012FF28   0012FF80  Pointer to next SEH record
0012FF2C   00ADD739  SE handler
0012FF30   0012FF78
0012FF34   00AC0000
0012FF38   00A80000
0012FF3C   00ADBDC8
0012FF40   00000000
0012FF44   00B59E34  ASCII "6uCokAAAJmg="
0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF4C   C5FC9640
0012FF18   0012FF28  Pointer to next SEH record
0012FF1C   00ADCEE7  SE handler
0012FF20   00B3045C
0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF28   0012FF80  Pointer to next SEH record
0012FF2C   00ADD739  SE handler
0012FF30   0012FF78
0012FF34   00AC0000
0012FF38   00A80000
0012FF3C   00ADBDC8
0012FF40   00000000
0012FF44   00B59E34  ASCII "6uCokAAAJmg="
0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF4C   C5FC9640
......
--------------------第三次----------------------
0012FF18   0012FF28  Pointer to next SEH record
0012FF1C   00ADCEE7  SE handler
0012FF20   00B3045C
0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF28   0012FF80  Pointer to next SEH record
0012FF2C   00ADD739  SE handler
0012FF30   0012FF78
0012FF34   00AC0000
0012FF38   00A80000
0012FF3C   00ADBDC8
0012FF40   00000000
0012FF44   00B59E34  ASCII "6uCokAAAJmg="
0012FF48   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF4C   C5FC9640

第三次出现机器码后,在code段访问断点,shift+f9后中断在这里:
00424CD7    8B4424 04        MOV     EAXDWORD PTR SS:[ESP+4]        ; 中断在这里,[esp+4]保存注册名地址
00424CDB    81EC 08020000    SUB     ESP, 208
......
0012FF1C   00ADD190  RETURN to 00ADD190
0012FF20   00AC3A29
0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF28   0012FF80  Pointer to next SEH record
修改为:
0012FF1C   00ADD190  RETURN to 00ADD190
0012FF20   00479F70  ASCII "loveboom[DFCG][FCG][US]"
0012FF24   00B59E00  ASCII "2A0FFBAB-CB5A"
0012FF28   0012FF80  Pointer to next SEH record

这样注册块就处理好了,再过几个异常后直接F2断到程序OEP:

0047550E    55               PUSH    EBP                              ; OEP
0047550F    8BEC             MOV     EBPESP
00475511    6A FF            PUSH    -1
......
00AC2544    85C0             TEST    EAXEAX
00AC2546    74 0A            JE      SHORT 00AC2552
00AC2548    FF15 18A0AE00    CALL    DWORD PTR DS:[AEA018]
00AC254E    09C0             OR      EAXEAX
00AC2550    74 01            JE      SHORT 00AC2553
......
00D500EB    5C               POP     ESP
00D500EC  - FF6424 FC        JMP     DWORD PTR SS:[ESP-4]    ;patch 
00D500F0    EB 01            JMP     SHORT 00D500F3



再找一下找到输入表信息:
IAT位置:47A000 SIZE:bb0


PATCH 1:       00ac2548
PATCH 2:      00D500EC
PATCH 3:      4799b0(保存修复代码的起始地址)
修改跳转地址为:      004799BF


写上全部的修复代码:

004799B0   .  60            PUSHAD                                   ;  保存堆栈
004799B1   .  B9 10315100   MOV     ECX, 00513110                    ;  取出相关的地址
004799B6   >  8B19          MOV     EBXDWORD PTR DS:[ECX]
004799B8   .  83FB 00       CMP     EBX, 0
004799BB   .  74 15         JE      SHORT 004799D2                   ;  如果取完了则跳去修复jmp [addr]
004799BD   .  FFE3          JMP     EBX                              ;  执行原CALL
004799BF   .  8B15 08315100 MOV     EDXDWORD PTR DS:[513108]       ;  取出call [addr]中的addr
004799C5   .  66:C703 FF15  MOV     WORD PTR DS:[EBX], 15FF          ;  修改成call [addr]
004799CA   .  8953 02       MOV     DWORD PTR DS:[EBX+2], EDX        ;  <&winmm.PlaySound>
004799CD   .  83C1 04       ADD     ECX, 4
004799D0   .^ EB E4         JMP     SHORT 004799B6
004799D2   >  33C0          XOR     EAXEAX
004799D4   .  B0 E8         MOV     AL, 0E8                          ;  修复jmp [addr]
004799D6   .  BF 00104000   MOV     EDI, 00401000                    ;  code段的起始地址
004799DB   .  B9 A0990600   MOV     ECX, 699A0                       ;  大小
004799E0   >  F2:AE         REPNE   SCAS BYTE PTR ES:[EDI]
004799E2   .  83F9 00       CMP     ECX, 0
004799E5   .  74 3C         JE      SHORT 00479A23                   ;  处理完则跳
004799E7   .  8B1F          MOV     EBXDWORD PTR DS:[EDI]
004799E9   .  8D5C3B 04     LEA     EBXDWORD PTR DS:[EBX+EDI+4]
004799ED   .  81FB 00104000 CMP     EBX, 00401000                    ;  Entry address
004799F3   .^ 72 EB         JB      SHORT 004799E0
004799F5   .  81FB 94994700 CMP     EBX, 00479994
004799FB   .^ 77 E3         JA      SHORT 004799E0
004799FD   .  66:813B FF15  CMP     WORD PTR DS:[EBX], 15FF
00479A02   .^ 75 DC         JNZ     SHORT 004799E0
00479A04   .  817B 02 00A04>CMP     DWORD PTR DS:[EBX+2], <&advapi32>
00479A0B   .^ 72 D3         JB      SHORT 004799E0
00479A0D   .  817B 02 C0AB4>CMP     DWORD PTR DS:[EBX+2], 0047ABC0
00479A14   .^ 77 CA         JA      SHORT 004799E0                   ;  让代码更精确些
00479A16   .  66:C703 FF25  MOV     WORD PTR DS:[EBX], 25FF
00479A1B   .  83C7 04       ADD     EDI, 4
00479A1E   .  83E9 04       SUB     ECX, 4
00479A21   .^ EB BD         JMP     SHORT 004799E0
00479A23   >  B9 10315100   MOV     ECX, 00513110                    ;  再次精确些处理jmp [addr] **********这里是上篇中没有注意到的
00479A28   >  8B19          MOV     EBXDWORD PTR DS:[ECX]
00479A2A   .  83FB 00       CMP     EBX, 0
00479A2D   .  74 2E         JE      SHORT 00479A5D                   ;  操作完则跳
00479A2F   .  66:8B03       MOV     AXWORD PTR DS:[EBX]
00479A32   .  66:3D FF15    CMP     AX, 15FF                         ;  判断是否为call [addr]
00479A36   .  75 20         JNZ     SHORT 00479A58
00479A38   .  66:8B43 FA    MOV     AXWORD PTR DS:[EBX-6]          ;  如果是的话,判断前一句代码是否为jmp [addr]
00479A3C   .  66:3D FF25    CMP     AX, 25FF
00479A40   .  75 16         JNZ     SHORT 00479A58
00479A42   .  8B53 FC       MOV     EDXDWORD PTR DS:[EBX-4]
00479A45   .  81FA 00A04700 CMP     EDX, <&advapi32.AdjustTokenPrivi>
00479A4B   .  72 0B         JB      SHORT 00479A58
00479A4D   .  81FA C0AB4700 CMP     EDX, 0047ABC0
00479A53   .  77 03         JA      SHORT 00479A58
00479A55   .  66:8903       MOV     WORD PTR DS:[EBX], AX            ;  如果是的话则认为这当前句也是jmp [addr]
00479A58   >  83C1 04       ADD     ECX, 4
00479A5B   .^ EB CB         JMP     SHORT 00479A28
00479A5D   >  61            POPAD
00479A5E   .  00            DB      00
00479A5F   .  00            DB      00
00479A60      689A4700      DD      dumped_.00479A68
00479A64   .  00            DB      00
00479A65      90            NOP
00479A66      90            NOP
00479A67      90            NOP
00479A68   .  60            PUSHAD
00479A69   .  8BC2          MOV     EAXEDX                         ;  保存call [addr]中的addr到 513108处
00479A6B   .  B9 C80B0000   MOV     ECX, 0BC8
00479A70   .  BF 00A04700   MOV     EDI, <&advapi32.AdjustTokenPrivi>
00479A75   .  F2:AF         REPNE   SCAS DWORD PTR ES:[EDI]
00479A77   .  83EF 04       SUB     EDI, 4
00479A7A   .  893D 08315100 MOV     DWORD PTR DS:[513108], EDI       ;  ntdll.7C930738
00479A80   .  61            POPAD
00479A81      FF15 18A0AE00 CALL    DWORD PTR DS:[AEA018]
00479A87   .  C3            RETN
00479A88      90            NOP

再写上修复脚本:
//fixed aspr 2.x
var addr


start:
  run

l1:
  cmp eip,00D500EC
  jne l2
  mov addr,esp
  sub addr,4
  mov [addr],004799BF
  jmp start

l2:
  ret


写好后在00D500EC下硬件执行断点,在00479A5D下普通F2断点,再执行脚本。脱壳完毕!
破解就像恋爱,这过程没有什么人能帮到你,什么都得靠自己一步一步的走。愿自己的恋爱能和脱壳一样风雨无阻:-).






Greetz:
 Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my 

friends and you!

          By loveboom[DFCG][FCG][US]
                      http://blog.csdn.net/bmd2chen
                

                                        Email:loveboom#163.com