论坛: 编程破解 标题: [转帖]2008年第二个Unpack:三种方法手脱ASPack变形壳 复制本贴地址    
作者: yongmin [yongmin]    论坛用户   登录
转贴自:一蓑烟雨
【文章作者】: cnkq
【软件名称】: 某游戏登录器
【保护方式】: PECrc32 0.88 -> ZhouJinYu * sign by fly *
【使用工具】: PEiD0.94,OD汉化第三版,ImportREC,LordPE
【使用平台】: WINXP SP2
【脱壳说明】: 菜鸟学习心得,无技术含量,有纪念意义

脱壳步骤:

首先PEiD查壳:PECrc32 0.88 -> ZhouJinYu * sign by fly *

第一种方法:ESP定律法

设置OD:忽略所有异常,然后OD载入程序:
00717082 >  60              PUSHAD        //入口关键提示,F8单步
00717083    E8 00000000    CALL 登陆器.00717088  //到这里,注意寄存器提示ESP=0012FFA4突显红色
00717088    5D              POP EBP
00717089    81ED B6A44500  SUB EBP,登陆器.0045A4B6
0071708F    8DBD B0A44500  LEA EDI,DWORD PTR SS:[EBP+45A4B0]
00717095    81EF 82000000  SUB EDI,82
0071709B    89BD 18A84500  MOV DWORD PTR SS:[EBP+45A818],EDI
007170A1    8B4F 18        MOV ECX,DWORD PTR DS:[EDI+18]
007170A4    89FE            MOV ESI,EDI
007170A6    0377 14        ADD ESI,DWORD PTR DS:[EDI+14]
007170A9    8B47 10        MOV EAX,DWORD PTR DS:[EDI+10]
007170AC    E8 2A060000    CALL 登陆器.007176DB
007170B1    8B4F 24        MOV ECX,DWORD PTR DS:[EDI+24]
007170B4    89FE            MOV ESI,EDI
007170B6    0377 20        ADD ESI,DWORD PTR DS:[EDI+20]
007170B9    8B47 1C        MOV EAX,DWORD PTR DS:[EDI+1C]
007170BC    E8 1A060000    CALL 登陆器.007176DB
007170C1    6A 00          PUSH 0

直接在ESP=0012FFA4处右键选择“数据窗口中跟随”,到数据窗口下断(断点-硬件访问-字),F9运行,删除断点

(调试-硬件断点-删除):
00717374  - FFE0            JMP EAX                                  ; 登陆器.00714001
00717376    42              INC EDX
00717377    4B              DEC EBX
00717378    2E:44          INC ESP                                  ; 多余的前缀
0071737A    41              INC ECX
0071737B    54              PUSH ESP
0071737C    0052 65        ADD BYTE PTR DS:[EDX+65],DL
0071737F    73 74          JNB SHORT 登陆器.007173F5
00717381    54              PUSH ESP
00717382    6F              OUTS DX,DWORD PTR ES:[EDI]              ; I/O 命令
00717383    6F              OUTS DX,DWORD PTR ES:[EDI]              ; I/O 命令
00717384    6C              INS BYTE PTR ES:[EDI],DX                ; I/O 命令
00717385    2E:45          INC EBP                                  ; 多余的前缀
00717387    58              POP EAX
00717388    45              INC EBP
00717389    0000            ADD BYTE PTR DS:[EAX],AL
0071738B    0040 00        ADD BYTE PTR DS:[EAX],AL
0071738E    0000            ADD BYTE PTR DS:[EAX],AL
00717390    59              POP ECX
00717391    7D 58          JGE SHORT 登陆器.007173EB

继续F8单步,跳到这里:
00714001    60              PUSHAD
00714002    E8 03000000    CALL 登陆器.0071400A
00714007  - E9 EB045D45    JMP 45CE44F7
0071400C    55              PUSH EBP
0071400D    C3              RETN
0071400E    E8 01000000    CALL 登陆器.00714014
00714013    EB 5D          JMP SHORT 登陆器.00714072
00714015    BB EDFFFFFF    MOV EBX,-13
0071401A    03DD            ADD EBX,EBP
0071401C    81EB 00403100  SUB EBX,314000
00714022    83BD 22040000 0>CMP DWORD PTR SS:[EBP+422],0
00714029    899D 22040000  MOV DWORD PTR SS:[EBP+422],EBX
0071402F    0F85 65030000  JNZ 登陆器.0071439A
00714035    8D85 2E040000  LEA EAX,DWORD PTR SS:[EBP+42E]
0071403B    50              PUSH EAX
0071403C    FF95 4D0F0000  CALL DWORD PTR SS:[EBP+F4D]
00714042    8985 26040000  MOV DWORD PTR SS:[EBP+426],EAX
00714048    8BF8            MOV EDI,EAX

貌似到了OEP了,试着用OD的插件“脱一下壳”,命名为1.exe,测试一下也可以正常运行,竟然不用修复吗?呵呵

,打开ImportREC,OEP输入:314001,提示:在此OEP入口点没找到任何有用的信息!显然,刚才那并不是程序真正

的OEP,难道脱了半天壳都白忙活了?

再用PEiD查一下1.exe的壳:ASPack 2.12 -> Alexey Solodovnikov,哈哈,看来也并非“白脱”,起码我们把变形

壳打回原形了!对ASPack,我们的方法就多了,就用内存镜像法吧

OD载入1.exe:
00714001 >  60              PUSHAD
00714002    E8 03000000    CALL 1.0071400A
00714007  - E9 EB045D45    JMP 45CE44F7
0071400C    55              PUSH EBP
0071400D    C3              RETN
0071400E    E8 01000000    CALL 1.00714014
00714013    EB 5D          JMP SHORT 1.00714072
00714015    BB EDFFFFFF    MOV EBX,-13
0071401A    03DD            ADD EBX,EBP
0071401C    81EB 00403100  SUB EBX,314000
00714022    83BD 22040000 0>CMP DWORD PTR SS:[EBP+422],0
00714029    899D 22040000  MOV DWORD PTR SS:[EBP+422],EBX
0071402F    0F85 65030000  JNZ 1.0071439A
00714035    8D85 2E040000  LEA EAX,DWORD PTR SS:[EBP+42E]
0071403B    50              PUSH EAX
0071403C    FF95 4D0F0000  CALL DWORD PTR SS:[EBP+F4D]
00714042    8985 26040000  MOV DWORD PTR SS:[EBP+426],EAX
00714048    8BF8            MOV EDI,EAX

按ALT+M,打开内存镜象,找到程序的第一个.rsrc:
内存映射, 条目 23
地址=004D3000
大小=00241000 (2363392.)
属主=1        00400000
区段=.rsrc
包含=资源
类型=Imag 01001002
访问=R
初始访问=RWE

F2下断点,然后F9运行到断点,

接着再ALT+M打开内存镜象,找到程序的第一个.rsrc.上面的.CODE:
内存映射, 条目 17
地址=00401000
大小=000BB000 (765952.)
属主=1        00400000
区段=CODE
包含=代码
类型=Imag 01001002
访问=R
初始访问=RWE

F2下断点,然后SHIFT+F9(或者是在没异常情况下按F9),直接到达程序OEP:
004BBDD8    55              PUSH EBP
004BBDD9    8BEC            MOV EBP,ESP
004BBDDB    83C4 F0        ADD ESP,-10
004BBDDE    B8 98B94B00    MOV EAX,1.004BB998
004BBDE3    E8 BCA5F4FF    CALL 1.004063A4
004BBDE8    A1 7CE84B00    MOV EAX,DWORD PTR DS:[4BE87C]
004BBDED    8B00            MOV EAX,DWORD PTR DS:[EAX]
004BBDEF    E8 1073FAFF    CALL 1.00463104
004BBDF4    8B0D 84E44B00  MOV ECX,DWORD PTR DS:[4BE484]            ; 1.004C007C
004BBDFA    A1 7CE84B00    MOV EAX,DWORD PTR DS:[4BE87C]
004BBDFF    8B00            MOV EAX,DWORD PTR DS:[EAX]
004BBE01    8B15 A87D4B00  MOV EDX,DWORD PTR DS:[4B7DA8]            ; 1.004B7DF4
004BBE07    E8 1073FAFF    CALL 1.0046311C
004BBE0C    8B0D 6CE94B00  MOV ECX,DWORD PTR DS:[4BE96C]            ; 1.004C0000
004BBE12    A1 7CE84B00    MOV EAX,DWORD PTR DS:[4BE87C]
004BBE17    8B00            MOV EAX,DWORD PTR DS:[EAX]
004BBE19    8B15 04BC4900  MOV EDX,DWORD PTR DS:[49BC04]            ; 1.0049BC50

就用OD插件直接脱吧,这个肯定是要修复的,打开ImportREC,OEP输入:BBDD8,点自动搜索IAT,再获得输入信息

,呵呵,全部有效,修复抓取文件,试着运行一下,提示应用程序错误,无法运行!
看来只有请处LordPE啦,打开LP,点重建PE,选择修复后的程序后确定,呵呵,现在可以正常运行了,再用PEiD查

一下:Borland Delphi 6.0 - 7.0,没问题了,大功告成!

第二种方法:内存镜像法

刚才脱ASPack的时候用的是内存镜像法,很快很轻松,那么对变形壳直接使用内存镜像法会如何呢?呵呵,再练一

下手吧

OD载入,仍然来到这里:
00717082 >  60              PUSHAD
00717083    E8 00000000    CALL 登陆器.00717088
00717088    5D              POP EBP
00717089    81ED B6A44500  SUB EBP,登陆器.0045A4B6
0071708F    8DBD B0A44500  LEA EDI,DWORD PTR SS:[EBP+45A4B0]
00717095    81EF 82000000  SUB EDI,82
0071709B    89BD 18A84500  MOV DWORD PTR SS:[EBP+45A818],EDI
007170A1    8B4F 18        MOV ECX,DWORD PTR DS:[EDI+18]
007170A4    89FE            MOV ESI,EDI
007170A6    0377 14        ADD ESI,DWORD PTR DS:[EDI+14]
007170A9    8B47 10        MOV EAX,DWORD PTR DS:[EDI+10]
007170AC    E8 2A060000    CALL 登陆器.007176DB
007170B1    8B4F 24        MOV ECX,DWORD PTR DS:[EDI+24]
007170B4    89FE            MOV ESI,EDI
007170B6    0377 20        ADD ESI,DWORD PTR DS:[EDI+20]
007170B9    8B47 1C        MOV EAX,DWORD PTR DS:[EDI+1C]
007170BC    E8 1A060000    CALL 登陆器.007176DB

按Alt+M打开内存镜像,找到.rsrc区段:
内存映射, 条目 30
地址=004D3000
大小=00241000 (2363392.)
属主=登陆器  00400000
区段=.rsrc
包含=资源
类型=Imag 01001002
访问=R
初始访问=RWE

按F2下断,按F9运行;

再按Alt+M打开内存镜像,找到.code区段:
内存映射, 条目 23
地址=00401000
大小=000BB000 (765952.)
属主=登陆器  00400000
区段=CODE
包含=代码
类型=Imag 01001002
访问=R
初始访问=RWE

F2下断,(Shift+)F9运行,哈哈,直接到达OEP耶!

看来,“万变不离其宗”的道理在这里亦然也(在这里膜拜前人一下,呵呵)!
后面的步骤就一样了,ImportREC修复,测试运行,用PEID查看是Borland Delphi 6.0 - 7.0写的,完成!

第三种方法:二次使用ESP定律法(本人命名,呵呵)

对本例来说,用内存镜像法要比ESP定律法快很多,可是总感觉第一种方法什么地方有点问题,再来回顾一下,看能

不能找到问题:

在使用了一次ESP定律以后,程序直接跳到了这里:
00714001    60              PUSHAD
00714002    E8 03000000    CALL 登陆器.0071400A
00714007  - E9 EB045D45    JMP 45CE44F7
0071400C    55              PUSH EBP
0071400D    C3              RETN
0071400E    E8 01000000    CALL 登陆器.00714014
00714013    EB 5D          JMP SHORT 登陆器.00714072
00714015    BB EDFFFFFF    MOV EBX,-13
0071401A    03DD            ADD EBX,EBP
0071401C    81EB 00403100  SUB EBX,314000
00714022    83BD 22040000 0>CMP DWORD PTR SS:[EBP+422],0
00714029    899D 22040000  MOV DWORD PTR SS:[EBP+422],EBX
0071402F    0F85 65030000  JNZ 登陆器.0071439A
00714035    8D85 2E040000  LEA EAX,DWORD PTR SS:[EBP+42E]
0071403B    50              PUSH EAX
0071403C    FF95 4D0F0000  CALL DWORD PTR SS:[EBP+F4D]
00714042    8985 26040000  MOV DWORD PTR SS:[EBP+426],EAX
00714048    8BF8            MOV EDI,EAX

当时我是把这里当作OEP直接就使用插件“脱壳”了,但是显然这里并非程序的OEP,所以我的做法应该是有问题的

,至于可以继续完成脱壳,不排除歪打正着的可能。继续仔细观察关键句可以发现,这里不就是另外一个“入口”

吗?既然是入口,我们何不二次使用ESP定律呢?试试吧。

00714001    60              PUSHAD            //关键句,F8单步
00714002    E8 03000000    CALL 登陆器.0071400A    //注意ESP 0012FFA4突显红色
00714007  - E9 EB045D45    JMP 45CE44F7
0071400C    55              PUSH EBP
0071400D    C3              RETN
0071400E    E8 01000000    CALL 登陆器.00714014
00714013    EB 5D          JMP SHORT 登陆器.00714072
00714015    BB EDFFFFFF    MOV EBX,-13
0071401A    03DD            ADD EBX,EBP
0071401C    81EB 00403100  SUB EBX,314000

直接命令行下断:hr 0012FFA4,F9运行,删除断点来到:
007143B0  /75 08          JNZ SHORT 登陆器.007143BA      //F8单步
007143B2  |B8 01000000    MOV EAX,1
007143B7  |C2 0C00        RETN 0C
007143BA  \68 D8BD4B00    PUSH 登陆器.004BBDD8
007143BF    C3              RETN
007143C0    8B85 26040000  MOV EAX,DWORD PTR SS:[EBP+426]
007143C6    8D8D 3B040000  LEA ECX,DWORD PTR SS:[EBP+43B]
007143CC    51              PUSH ECX
007143CD    50              PUSH EAX
007143CE    FF95 490F0000  CALL DWORD PTR SS:[EBP+F49]
007143D4    8985 55050000  MOV DWORD PTR SS:[EBP+555],EAX
007143DA    8D85 47040000  LEA EAX,DWORD PTR SS:[EBP+447]
007143E0    50              PUSH EAX
007143E1    FF95 510F0000  CALL DWORD PTR SS:[EBP+F51]
007143E7    8985 2A040000  MOV DWORD PTR SS:[EBP+42A],EAX
007143ED    8D8D 52040000  LEA ECX,DWORD PTR SS:[EBP+452]
007143F3    51              PUSH ECX
007143F4    50              PUSH EAX

直接到达OEP:
004BBDD8    55              PUSH EBP
004BBDD9    8BEC            MOV EBP,ESP
004BBDDB    83C4 F0        ADD ESP,-10
004BBDDE    B8 98B94B00    MOV EAX,登陆器.004BB998
004BBDE3    E8 BCA5F4FF    CALL 登陆器.004063A4
004BBDE8    A1 7CE84B00    MOV EAX,DWORD PTR DS:[4BE87C]
004BBDED    8B00            MOV EAX,DWORD PTR DS:[EAX]
004BBDEF    E8 1073FAFF    CALL 登陆器.00463104
004BBDF4    8B0D 84E44B00  MOV ECX,DWORD PTR DS:[4BE484]            ; 登陆器.004C007C
004BBDFA    A1 7CE84B00    MOV EAX,DWORD PTR DS:[4BE87C]
004BBDFF    8B00            MOV EAX,DWORD PTR DS:[EAX]
004BBE01    8B15 A87D4B00  MOV EDX,DWORD PTR DS:[4B7DA8]            ; 登陆器.004B7DF4
004BBE07    E8 1073FAFF    CALL 登陆器.0046311C
004BBE0C    8B0D 6CE94B00  MOV ECX,DWORD PTR DS:[4BE96C]            ; 登陆器.004C0000
004BBE12    A1 7CE84B00    MOV EAX,DWORD PTR DS:[4BE87C]
004BBE17    8B00            MOV EAX,DWORD PTR DS:[EAX]
004BBE19    8B15 04BC4900  MOV EDX,DWORD PTR DS:[49BC04]            ; 登陆器.0049BC50
004BBE1F    E8 F872FAFF    CALL 登陆器.0046311C

接下来的工作就简单了,OD插件脱壳,ImportREC修复,测试运行正常,再用PEiD查看:Borland Delphi 6.0 - 7.0

,完工!

学习心得:

写完这篇文章,感慨颇多,最大的收获就是明白了一个道理:基础知识一定要打扎实,基本方法一定要熟练掌握!

教程是死的,方法是活的,看教程应该领会其中的方法,殊途而同归,不必强求和教程的步骤完全吻合。就我个人

而言,很多时候即便是跟着教程一步一步操作,也会发现很多不一样的地方(郁闷),这时候往往需要反复尝试多

次才能达到目的,虽然走了很多弯路,但是在这个过程中,对基本方法的操作更熟练了,对基本方法的理解也更深

了,这样,我想,学习的目的应该也达到了吧,呵呵。

地主 发表时间: 08-02-17 10:08

论坛: 编程破解

20CN网络安全小组版权所有
Copyright © 2000-2010 20CN Security Group. All Rights Reserved.
论坛程序编写:NetDemon

粤ICP备05087286号