• 标 题:HTMLZip脱壳后的Import Table的修复 (750字)
  • 作 者:henryw
  • 时 间:2001-2-10 23:36:15
  • 链 接:http://bbs.pediy.com

HTMLZip脱壳后的Import Table的修复

启动HTMLZip, 然后启动imp_list.exe。

找到HTMLzip.exe,去掉autodetect前的框。RVA输入57000,长度3000。

Rebuilder后有三个文件,Import0.bin, Import1.bin, Import2.bin。


一、适用trw2000的pedump脱壳后的文件
(1)打开Import0.bin,全选,选中2C00个字节,复制
Hex Workshop打开脱壳后文件,Go to 57000,选中2C00个字节,
粘贴。存盘。
(2)用PE-editor打开修改后的文件,按directory按钮,将IMPORT Table RVA改为57000, 长度为3000就可以了。

二、适用与ProcDump脱壳后的文件
(1)用pe-editor看section,发现有57000的section的Raw Offset为54A00。
    改Entry Point为542E4。存盘退出。
(2)打开Import1.bin,全选,共924个字节,copy。
(3)打开脱壳后的文件,goto 54A00,选924个字节,paste。存盘就可以了。不用其他改动。

  • 标 题:手动脱HTMLZip的壳(asprotect)[通用方法] (5千字)
  • 作 者:henryw
  • 时 间:2001-2-10 23:35:22

手动脱HTMLZip的壳(asprotect)

有幸认识了hying兄,结果hying兄教了我如下方法进行Asprotect1.1版本以上的脱壳。
hying兄要我成功后贴个贴子,我的文笔不好,只好迎着头皮上了。

软件:    HTMLZip  1.0  Beta  (下载地址为:)
工具:    TRW2000

TRW2000装入程序,一直到下面的连续五个Call应该如何跟,还是等Hying兄的文章吧。
告诉大家一个偷懒的办法,如果前面跟了很久也没看到这5个call的典型地方,就按F12,
一次一次地按,直到按下F12后要等将近10秒甚至更多时间才回到trw时,就按F8,
这就到了。:)

(我的系统是WinMe,其他系统会有不同的xxxx:xxxxxxxx)
016F:01110684  PUSH    EBP
016F:01110685  MOV      EBP,ESP
016F:01110687  ADD      ESP,BYTE -0C
016F:0111068A  CALL    01102F7C
016F:0111068F  JNZ      NEAR 01103C58
016F:01110695  CALL    01104114
016F:0111069A  CALL    01108894
016F:0111069F  CALL    01109224
016F:011106A4  CALL    0110B584
016F:011106A9  CALL    01103C58    <-------- 这个Call进去。
016F:011106AE  MOV      ESP,EBP
016F:011106B0  POP      EBP
进去后按F10跟,期间能够遇到2个Call,都用F10带过,当走过第二个RET后,
(懒人可按F12, F8, F12, F8)
代码会变成:
016F:0110F4CA  MOV      EAX,[ESP+0C]
016F:0110F4CE  JMP      SHORT 0110F4D1
016F:0110F4D1  ADD      DWORD [EAX+B8],BYTE +02
016F:0110F4D8  JMP      SHORT 0110F4F4
下面两行动态生成:
016F:0110F4F4  XOR      EAX,EAX
016F:0110F4F6  RET      <--------停,看stack窗口,会看到xxxxxxxx:BFFxxxxxx
016F:0110FC4F  CALL    0110D304
016F:0110FC54  CMP      DWORD [01112578],BYTE +00
然后下u命令翻页,在最近的地方设断点。
此时能看到如下代码:(110F4F4,110F4F6为动态生成,翻页后就不见了。)
016F:0110F51F  PUSH    DWORD 0110F600
016F:0110F524  PUSH    DWORD 0110EF20
016F:0110F529  PUSH    DWORD 0110EBC8
016F:0110F52E  PUSH    DWORD 0110E58C
016F:0110F533  PUSH    DWORD 0110E118
016F:0110F538  PUSH    DWORD 0110F27C
016F:0110F53D  RET    <------- 在这里下断点,然后G可到这里。
bd这个断点,再F8。以下用F10走,看见类似于
016F:0110F4CA  MOV      EAX,[ESP+0C]
016F:0110F4CE  JMP      SHORT 0110F4D1
016F:0110F4D1  ADD      DWORD [EAX+B8],BYTE +02
016F:0110F4D8  JMP      SHORT 0110F4F4
016F:0110F4F4  XOR      EAX,EAX
016F:0110F4F6  RET      <---------------停,看stack窗口,会看到xxxxxxxx:BFFxxxxxx
就翻页找最近的RET,重复下断点,F5, bd断点,F8继续。
如此大约我进行了7次。

======================以上就是hying兄教我的方法=============================


再接着往下说之前先讲个跟踪原则:
*************************************************
*    xxxx:AAAAAAAA  CALL BBBBBBBB        *
*    当跟踪时看到一个Call的时候,要看看    *
*    BBBBBBBB是不是比AAAAAAAA大,如果是,    *
*    用F8;如果不是,用F10带过。        *
*************************************************
(当然,原则会有例外,下面会讲到什么情况下原则不适用。)

现在开始,利用上面说的原则,用F8或者F10追吧。
到了这里需要注意了,下面这段代码细看和我们前面遇上的有些不同。
016F:0110F263  RET   
016F:0110F264  MOV      EAX,0111290C
016F:0110F269  MOV      EDX,0A
016F:0110F26E  CALL    0110B8D4  <------- 离110F26E很远
016F:0110F273  CALL    0110F0E4  <------- 离110F273很近,这个Call一定用F8进去,否则GameOver。
016F:0110F278  RET   
*********************************************************
*    这就是原则例外(1). 当看见两个Call并在一起,    *
*    BBBBBBBB都<AAAAAAAA,但是第二个CALL的        *
*    BBBBBBBB和AAAAAAAA相差不如第一个悬殊,用F8。    *
*********************************************************
很快会走到这里,看到USER32!MessageBoxA,标志着离终点不远了。
016F:0110F1EE  PUSH    BYTE +00
016F:0110F1F0  CALL    `USER32!MessageBoxA`  <--------  注意!!!!!!!!!!!!!!!!
016F:0110F1F5  CALL    01102CDC
016F:0110F1FA  XOR      EAX,EAX
016F:0110F1FC  POP      EDX
016F:0110F1FD  POP      ECX
016F:0110F1FE  POP      ECX
016F:0110F1FF  MOV      [FS:EAX],EDX
016F:0110F202  JMP      SHORT 0110F20E
016F:0110F204  JMP      01102B70

往下慢慢走,继续遵循我们的原则,来到这里,这是1126C1执行以前的代码:
016F:01126C61  CALL    01126C7E  <----  观察下面代码,是不是很“乱”?
                     这里一定用F10带,F8就GameOver了。
016F:01126C66  NOP
016F:01126C67  MOV      BH,86
016F:01126C69  MOV      EDI,GS
016F:01126C6B  CALL    1A22A1A4 
016F:01126C70  DB      FF
016F:01126C71  JNG      01126C3D
016F:01126C73  ROR      DWORD [ECX+EDX],E2
016F:01126C77  HLT   
016F:01126C78  MOV      BH,1A
016F:01126C7A  REPNE POP  EDI
016F:01126C7C  IDIV    DWORD [EBX]
016F:01126C7E  AND      EAX,BYTE -68
*************************************************
*    这里是原则例外(2),            *    
*    走过USER32!MessageBoxA以后,        *
*    看到类似上面这个Call,下面代码很“乱”    *
*    一定用F10带过。                *
*************************************************
这就是F10执行1126C1以后的代码:
016F:01126C61  CALL    01126C7E
016F:01126C66  POP      EBX
016F:01126C67  POP      EAX
016F:01126C68  ADD      EAX,33371CB8
016F:01126C6D  POP      ESP
016F:01126C6E  OR      ECX,ECX
016F:01126C70  JZ      01126C55
016F:01126C72  MOV      [ECX],EAX
016F:01126C74  ADD      EAX,EBX
016F:01126C76  MOV      [ESP+1C],EAX
016F:01126C7A  POPA   
016F:01126C7B  JMP      EAX  <------- 终于到家了,注意Eax的值,这就是入口值。

以上这个原则其实是hying兄方法的复杂操作,但是有时遇上
xor eax, eax
ret
最近的ret只能断一次时,就有用了。比如PictureToExe这个东东的asprotect脱壳。
用上述原则,就能成功脱掉Asprotect。

想作练习的话,可以找Advanced System Agent,前面有人在论坛上要求脱壳的,虽然
可以用冲击波,不过练习一下纯手动脱壳也不失为一个好教材。