• 标 题:手工脱壳 Advanced Administrative Tools 4.0a (8千字)
  • 作 者:cloudnumber9
  • 时 间:2000-6-6 16:38:39
  • 链 接:http://bbs.pediy.com/

版权声明:本文可自由转载和引用,但请勿用于商业目的。转载时请保持完整。
写作目的:我已很久没有破解软件,在偶然的机会里看到了一些看学学苑的脱壳教程,
      随即顺手找了这个软件练习一下。没想到竟碰上一个大难题,足足用了我
      一个星期的时间。我先用 ProcDump 的 script 脱掉了壳,后来发现不能
      运行,随后又看了很多文章,敖了好多夜,才最后解决这个问题。
      我想,cracker 的精神就是共享软件、共享知识、共享快乐和骄傲。
      这也就是我写作本文的唯一目的。
写作日期:新世纪的第一个端午节,6th June, 2000.

脱壳软件:AATools 4.0a build 4.0.0.596
文件大小: 752,128 bytes
软件功能:我没太注意,只为练习脱壳。
发行公司:G-lock software, http://www.glocksoft.com
脱壳日期:June 3rd, 2000

破解环境:Windows Me (English Version), MMX 200, 64M.
使用工具:Trw2000 V1.21, ProcDump 1.6.2, topo, UltraEdit 7.0, W32dsm89.
---------------------------------------------------------------------------

首先用 ProcDump 看一下 AATools.exe 的 PE 头。
Entry Point    : 00222001
Size of Image    : 00239000
Image Base     : 00400000

现在运行 trw2k, 起始代码如下:
---------    AATOOLS!.data        -----------------------
:00622001 60        PUSHA
:00622002 E801000000    CALL 00622008
:00622007 90        NOP

按 F8 跟踪,只见这程序费劲了心思、不断的在内存中动态生成代码,
从.data 转换到一段段无名的空间,最后终于变换到 .CODE, 出现下列代码:
---------    AATOOLS!.CODE+1754C0    -----------------------
:005764C0 55                      push ebp
:005764C1 8BEC                    mov ebp, esp
:005764C3 83C4F4                  add esp, FFFFFFF4
:005764C6 53                      push ebx
:005764C7 B8705E5700              mov eax, 00575E70
:005764CC E8CF0EE9FF              call 004073A0
:005764D1 8B1D84A85700            mov ebx, dword ptr [0057A884]

经过不断试验,确定此时程序已完全脱壳。cs:5764c0 就是程序的新入口点。
由于我没有注册的 trw2k, 所以手工脱壳,
E CS:EIP EB FE 90
G
然后运行 ProcDump 脱壳。文件大小应为 2135K.
(如果将 ProcDump 中的 rebuild new import table 选项选中的话,脱壳后的文件
大小为 2138K, 同用 script 脱壳的大小一样)

这时 PE 头变为:
Name    Virtual Size    Virtual Offset    Raw Size    Raw Offset
CODE    00176000    00001000    001755B8    00000600
DATA    00004000    00177000    00003B30    00175C00
BSS    00002000    0017B000    00000000    0017B000
.idata    00004000    0017D000    00000B04    00179800
.tls    00001000    00181000    00000000    00181000
.rdata    00001000    00182000    00000010    0017A400
.reloc    00019000    00183000    00000000    0017A600
.rsrc    00086000    0019C000    00085BD0    0017A600
.data    00016000    00222000    000158AC    00200200
.data    00001000    00238000    00000000    00215C00

将脱壳后文件中的 EB FE 90 改回 55 8B EC,然后将 Entry Point 改为 1764C0.
但此时文件还是不能运行。

再通过 trw2k 跟踪,
:004073A0 50                      push eax
:004073A1 6A00                    push 00000000
:004073A3 E8F8FEFFFF              call 004072A0
:004073A8 BA00715700              mov edx, 00577100
:004073AD 52                      push edx
:004073AE 8905DCB45700            mov dword ptr [0057B4DC], eax
:004073B4 894204                  mov dword ptr [edx+04], eax
:004073B7 C7420800000000          mov [edx+08], 00000000
:004073BE C7420C00000000          mov [edx+0C], 00000000
:004073C5 E88AFFFFFF              call 00407354
:004073CA 5A                      pop edx
:004073CB 58                      pop eax
:004073CC E827C8FFFF              call 00403BF8
:004073D1 C3                      ret

其中:
:0057D1C0 00 00 00 00 00 00 00 00 00 00 00 00 8C 54 3B 01
:0057D1D0 98 54 3B 01 A4 54 3B 01 B0 54 3B 01 BC 54 3B 01

:004072A0 FF25E4D25700            jmp dword ptr [0057D2E4]

在 cs:0057d2e4 数据为:
:0057D2E0 14 57 3B 01 20 57 3B 01

cs:013b5720 处代码为:
:013B5720 E9C91FBBBE          JMP KERNEL32!GetModuleHandleA
:013B5725 1000

:013B572C E99E1FBBBE          JMP KERNEL32!GetModuleFileNameA
:013B5731 1000

继续跟踪会发现一段特别的代码:
:004013D0 FF258CD25700          jmp dword ptr [0057D28C]

在 cs:0057d28c 数据为:
:0057D28C C4 56 3B 01

:013B56C4 68CE563B01          PUSH DWORD 013B56CE
:013B56C9 E8720F2CFF          CALL 00676640
:013B56CE EB2F

从 PE 头可知,cs:57d000 - cs:57d000 + b04 为 idata 的数据,
可见从 cs:57d1cc 开始为 first_thunk 库, 而 cs:013bxxxx 为跳转表。
(我不知道专门的术语,请指正)
再跟踪 CALL 00676640, 发现这是一段解码程序,在很多地方都被调用。
而且其内部用了很多硬码,如:
mov dword ptr [0067xxxx], eax
call 0066xxxx
push 0066xxxx

通过 PE 头可知:
Size of Image : 00239000
Image Base    : 00400000
所以程序所占地址空间为 00400000 - 00639000。
可见 00676640, 013bxxxx 都是申请的空间,超出了程序的地址空间,
脱壳后都不会被保存。

这种加壳方法非常难以恢复,以至我已几乎失去信心。

经过几天的实验和摸索,终于找到解决方法。
简单讲,就是扩展脱壳后的程序地址空间,然后将上述地址中的数据移回。
我将保存 0066 和 0067 段,将 013b 段保存到 0069 段。
(一开始我将 013b 改到 0064 或 0065, 后来发现不行,浪费了很多时间)

具体步骤如下:
---------------------------------------------------------------------------
1、重新脱壳:(必须手动,因为 script 无法存下 )
bpx 5764c0
1.1 Start AATools
1.2 Interrupted by Trw2k
1.3 Quit AATools

重复运行 1.1 - 1.3,直到 cs: 013b56c9 为 call 0067xxxx.
(0068 或 0069 占用空间太多,运气好的话有可能为 0066)

下面以 call 00676640 为例,
键入下列命令:
W cs:00664000 L1e000 0066.bin
W cs:013b0000 L8000 013b.bin
W cs:00640000 L200 0064.bin
E cs:eip EB FE 90
G
然后再用 ProcDump 脱壳,假设存为 aa.exe。
将 aa.exe 中的 EB FE 90 改回 55 8B EC. Entry Point 改为 1764c0.
经过观察,动态申请的006X 内存段大小为固定的 1E000 大,013b 为 8000。
00676640 和 00664000 的偏移好像是固定的(请自试之)。
0064 段是后来跟踪时发现的。

---------------------------------------------------------------------------
2、用 topo, 在aa.exe 中加入大小为 458822 的段,这时 PE 头变为:
Name    Virtual Size    Virtual Offset    Raw Size    Raw Offset
CODE    00176000    00001000    001755B8    00000600
DATA    00004000    00177000    00003B30    00175C00
BSS    00002000    0017B000    00000000    0017B000
.idata    00004000    0017D000    00000B04    00179800
.tls    00001000    00181000    00000000    00181000
.rdata    00001000    00182000    00000010    0017A400
.reloc    00019000    00183000    00000000    0017A600
.rsrc    00086000    0019C000    00085BD0    0017A600
.data    00016000    00222000    000158AC    00200200
.data    00001000    00238000    00000000    00215C00
.topo0    00070046    00238000    00070200    00215C00

Size of Image : 2c,b000

这时,.topo0 中就有了 00660000 - 006A0000 的空间。

---------------------------------------------------------------------------
3、使用 UltraEdit 7.0 改换地址。

3.1 将 .idata 段的所有 013b 改为 0069。
(最好先从aa.exe 中抽出存入 idata.bin 中)

3.2 将 013b.bin 中的地址改换。

:013B5720 E9C91FBBBE    (3.2.1)      JMP KERNEL32!GetModuleHandleA
:013B5725 1000
如果 013B 移为 0069 的话,应为
:00695720 E9C91F8DBF
:00695725 1000

:013B56C4 68CE563B01    (3.2.2)      PUSH DWORD 013B56CE
:013B56C9 E8720F2CFF    (3.2.3)      CALL 00676640
:013B56CE EB2F
改为
:006956C4 68CE566900          PUSH DWORD 006956CE
:006956C9 E8720FFEFF          CALL 00676640
:006956CE EB2F

具体实施如下:
3.2.1 从 be ac 开始,一直到 be bf, ( be ad, be ae, ..., be bb, ... be bf )
    将 ac be 10 改为 7e bf 10
    将 bf be 10 改为 91 bf 10
013b        0069    ( 0069 + 00d2 == 013b )
be ac    ->    bf 7e    (2 places)
...
be bb    ->    bf 8d
...
be bf    ->    bf 91    (1 place)
(由于我漏改了一处 be ac, 程序总是抛出个Exception, 说 Imagelist1.Bitmap
调用出错,以至于我调试了很久、很久...很久)

3.2.2 将所有的 013b 改为 0069

3.2.3 将 2c ff, 2b ff 改为 fe ff, fd ff
013b        0069    ( 0069 + 00d2 == 013b )
ff 2c    ->    ff fe
ff 2b    ->    ff fd

3.3 改动 0066.bin,将0067:d800 后所有 013b 改为 0069。
经过跟踪发现,程序在 0067:d800 - 0067:d9a0 处还有一段 import table 数据。
好在数据已保存在 0066.bin 中了。
(如果地址不同的话,我估计偏移量应该相同,00664000 - 0067d800 )

---------------------------------------------------------------------------
4、用 UltraEdit 恢复 aa.exe。
Raw Offset    Virtual Offset    Copy Size
0021,5c00    0063,8000
0021,dc00    0064,0000    200
0023,dc00    0066,0000    1,e000
0026,dc00    0069,0000    8000

按照相应的位置和大小,将 0064.bin, 0066.bin, 013b.bin 拷贝到 aa.exe 中。

---------------------------------------------------------------------------
5、至此程序已完全脱壳,运行无误。
但我发现只能在 Windows Me 下运行,不能在 Win2k Pro 运行。(同机不同硬盘)
另外,在 PWin98, 16M 机器上也不能运行。
我只能接触到这两种机器,其他的请自试验。
估计是要改正 PE 头,使之能够在 NT 下运行。

---------------------------------------------------------------------------
6、总结:
据网友说AATools 用的是一种新的 Asprotect , 此种保护实在是非常难于脱壳。
经过我的实践,相信我的方法基本上已经可以解掉此类加壳方式。
Cracking 其实没有什么神秘之处,只要知道了基本方法,剩下的只是耐心和毅力。

另:一开始我用的是 trw2k v1.21,后来刚好碰上新出的 v1.22。
新版本稳定多了,非常好用。只可惜还是要提示,注册费也太贵。不爽而破之。:-p

-全文完-