• 标 题:关于用ASProtect v1.3加壳软件的脱壳方法体会 (5千字)
  • 作 者:leo_cyl1
  • 时 间:2001-11-21 16:38:29
  • 链 接:http://bbs.pediy.com

目标软件:CloneCD 3.1.1.0
目标文件:CloneCD.exe
加壳方式:ASProtect v1.3?
使用工具:trw2000
      Procdump
          peditor
      Imprec 1.3
      SuperBPM

CloneCD加壳有点特别,它将一部分注册函数放在外壳里,当你将它dump出来后没法运行产生非法操作。(另外冲击波2000也找不到oep)。
论坛精华3里有很多有关ASProtect 脱壳的文章,我就不详细介绍每一个步骤了,重点放在重建IAT和脱壳后没法运行的解决方法上。

一、查找oep

运行SuperBPM和trw2000加载CloneCD.exe。按照论坛精华3里的方法:凡有 xor eax,eax;ret;的地方将断点设在往下不远的ret处。
但也有例外,这时应在xor eax,eax处停下,查看eax+b8的内容"dd eax+b8",可得到一个地址,将断点设在那里。(其实eax是个_CONTEXT 指针,eax+b8是程序的eip)。
很幸运,oep在401000h处。

二、dump出脱壳后的主程序
在401000h处下指令"suspend"将进程挂起,回到window,执行Procdump,将主程序dump为dump.exe备用。

三、重建IAT
执行Imprec 1.3,选CloneCD.exe,"IAT AutoSearch" 它会提示你如果Search失败就把rav改为105000,size改为4000加大Search范围。就按它提示的做吧。"Get Import"后,再按"Auto Trace",还有大概70个指针没解决。只好手工修改了:(
最后还有6个ptr没解决:
        RAV                            PTR
    00105628    ?    0000    0213C914
    001055A4    ?    0000    0213C944
    001055A0    ?    0000    0213C93C
    00105598    ?    0000    0213C94C
    0010568C    ?    0000    0213C954
    0010558C    ?    0000    0213C960


前四个都和0213C93C处的代码类似:

017F:0213C93C A148361402      MOV      EAX,[02143648]
017F:0213C941 C3              RET   
017F:0213C942 8BC0            MOV      EAX,EAX
017F:0213C944 A150361402      MOV      EAX,[02143650]
017F:0213C949 C3              RET   
017F:0213C94A 8BC0            MOV      EAX,EAX
017F:0213C94C A140361402      MOV      EAX,[02143640]
017F:0213C951 C3              RET   

下命令"bpm 2143648 w" 重新运行CloneCD.exe,数次中断后来到这里:

017F:0213C7B9 C3              RET   
017F:0213C7BA 8BC0            MOV      EAX,EAX
017F:0213C7BC 6A00            PUSH    BYTE +00
017F:0213C7BE E8897CFFFF      CALL    `KERNEL32!GetModuleHandleA`
017F:0213C7C3 A34C361402      MOV      [0214364C],EAX
017F:0213C7C8 E8977CFFFF      CALL    `KERNEL32!GetVersion`
017F:0213C7CD A344361402      MOV      [02143644],EAX
017F:0213C7D2 68AC351402      PUSH    DWORD 021435AC
017F:0213C7D7 E8907CFFFF      CALL    `KERNEL32!GetVersionExA`
017F:0213C7DC E83B7CFFFF      CALL    `KERNEL32!GetCurrentProcess`
017F:0213C7E1 A348361402      MOV      [02143648],EAX
017F:0213C7E6 E8397CFFFF      CALL    `KERNEL32!GetCurrentProcessId`
017F:0213C7EB A350361402      MOV      [02143650],EAX
017F:0213C7F0 E81F7CFFFF      CALL    `KERNEL32!GetCommandLineA`
017F:0213C7F5 A340361402      MOV      [02143640],EAX
呵呵……知道是什么了吧?所以:

00105628是GetVersion
001055A0是GetCurrentProcess
001055A4是GetCurrentProcessId
00105598是GetCommandLineA


再看0213C954的代码:

017F:0213C954 55              PUSH    EBP
017F:0213C955 8BEC            MOV      EBP,ESP
017F:0213C957 8B4508          MOV      EAX,[EBP+08]
017F:0213C95A 5D              POP      EBP
017F:0213C95B C20400          RET      04
017F:0213C95E 8BC0            MOV      EAX,EAX

017F:0213C960 55              PUSH    EBP
017F:0213C961 8BEC            MOV      EBP,ESP
017F:0213C963 5D              POP      EBP
017F:0213C964 C20400          RET      04

两个空函数,暂时不用理它,将0010568C和0010558C改为KERNEL32中的任意一个函数,(我用GetTickCount).
"Fix Dumped"后,将生成dump_.exe文件.
现在修改0010568C和0010558C的调用。对比运行CloneCD.exe,可知道调用在4A6929和4A6957处:
017F:004A6925 8B4314          MOV      EAX,[EBX+14]
017F:004A6928 50              PUSH    EAX
017F:004A6929 E8584B0200      CALL    004CB486 <==此call是调用0213C954
017F:004A692E 8BD0            MOV      EDX,EAX
017F:004A6930 8BC3            MOV      EAX,EBX

017F:004A6953 8B4614          MOV      EAX,[ESI+14]
017F:004A6956 50              PUSH    EAX
017F:004A6957 E8AA490200      CALL    004CB306 <==此call是调用0213C960
017F:004A695C 8BD3            MOV      EDX,EBX

将017F:004A6929改为pop eax;nop;nop;nop;nop;将017F:004A6957也改为pop eax;nop;nop;nop;nop;(注意不要搞乱堆栈)。
到这里重建IAT完成。

四、修正dump_.exe

运行dump_.exe,还会有非法操作,地址都是213xxxx和215xxxx,而这些地址是程序的外壳部分。看来解决办法只有把残留的外壳部分加到dump_.exe中了。
再次载入CloneCD.exe,在oep(401000h)处中断,然后下命令:"w 2131000,2148000 c:\213.bin" 和 "w 2150000,215a000 c:\215.bin"。将2131000到2148000,2150000到215a000两处内存保存下来。为什么不直接把2130000到215a000的内容保存下来呢?因为在2148000到215000的地方是没有映射的“空洞”,直接dump会让window崩溃!

用peditor装入dump_.exe,可看到Image Base是4000000;点"Scetion",在Scetion列表中点右键,选"add a Section"添加一个新section,取名"213";然后修改它,参数如下:
Virtual Size = 1F000;(2148000-2131000)
Virtual Offset = 01D31000;(2130000-400000)
Raw Size = 1F000;(2148000-2131000)

用十六进制编辑器修改dump_.exe,在文件最后的地方添加213.bin的全部内容。存盘退出。用peditor继续添加一个section,取名"215";参数如下:
Virtual Size = A000;(215A000-2150000)
Virtual Offset = 01D50000;(2150000-400000)
Raw Size = A000;(215A000-2150000)

在文件最后的地方添加215.bin的全部内容
用peditor装入改好的dump_.exe,点击"rebiulder" 选中"Make PE Header win nt/2k compitable"复选框。(注意其他的选项不要选,否则会改变内存的映射)。
到这里dump_.exe已经可以完美运行了!至于爆破为注册版我就不多说了,注册算法很复杂,(据说是椭圆曲线公开密匙算法)。爆破却很容易,415aff处是关键比较。

总结

对于这类加壳软件的脱壳方法,关键是加壳程序与脱壳后的程序要注意相互比较,脱壳后的程序如果缺少某些残留的外壳,可以用以上方法添加。