发信人: cca (^ok^), 信区: Crack
标 题: (原创) 用OLLYDBG脱ASPR压缩过的程序 激励人气!
发信站: BBS 水木清华站 (Sat Feb 7 21:17:42 2004), 转信
--------------------------------------------------------------------------------
用OLLYDBG脱ASPR压缩过的程序
目标程序:奇迹游戏的的客户端 Main.exe Ver 0.97.0.0
作者:cca
--------------------------------------------------------------------------------
1。脱壳前的准备工作
使用的工具
Ollydbg V1.09d (我的是汉化版),插件最好有Ollydump
ImportREC v1.6,插件(需要ASProtect1.22的插件)
LordPe
工具不全的兄弟到请用Google搜索一下,网上都很容易找到的。
要脱壳的程序请到奇迹网站下载,
fb9K9s2c8@1M7q4)9K6b7g2)9J5c8W2)9J5c8Y4N6%4N6#2)9J5k6h3#2#2j5$3S2A6L8X3q4Q4x3X3g2U0L8$3@1`.
2。第一步 寻找程序的入口点OEP
紧记住ASProtect保护的程序是动态地址分配,每次的地址都不同的,所以不要关心代码地址,地址不同,代码基本是相同的。
用OD装载Main.exe后,忽略压缩提示,选不继续分析。运行程序,程序会出异常出错,停在
0B2041A4 3100 XOR DWORD PTR DS:[EAX],EAX
0B2041A6 EB 01 JMP SHORT 0B2041A9
连续按25次Shift+F9,一直到代码显示为:
0B2039EC 3100 XOR DWORD PTR DS:[EAX],EAX
0B2039EE 64:8F05 00000000 POP DWORD PTR FS:[0]
0B2039F5 58 POP EAX
0B2039F6 833D B07E200B 00 CMP DWORD PTR DS:[B207EB0],0
0B2039FD 74 14 JE SHORT 0B203A13
0B2039FF 6A 0C PUSH 0C
0B203A01 B9 B07E200B MOV ECX,0B207EB0
0B203A06 8D45 F8 LEA EAX,DWORD PTR SS:[EBP-8]
0B203A09 BA 04000000 MOV EDX,4
0B203A0E E8 2DD1FFFF CALL 0B200B40
0B203A13 FF75 FC PUSH DWORD PTR SS:[EBP-4]
0B203A16 FF75 F8 PUSH DWORD PTR SS:[EBP-8]
0B203A19 8B45 F4 MOV EAX,DWORD PTR SS:[EBP-C]
0B203A1C 8338 00 CMP DWORD PTR DS:[EAX],0
0B203A1F 74 02 JE SHORT 0B203A23
0B203A21 FF30 PUSH DWORD PTR DS:[EAX]
0B203A23 FF75 F0 PUSH DWORD PTR SS:[EBP-10]
0B203A26 FF75 EC PUSH DWORD PTR SS:[EBP-14]
0B203A29 C3 RETN
0B203A2A 5F POP EDI
0B203A2B 5E POP ESI
0B203A2C 5B POP EBX
0B203A2D 8BE5 MOV ESP,EBP
0B203A2F 5D POP EBP
0B203A30 C3 RETN
在 0B203A29 处按F2设置断点,然后按Shift+F9运行到断点处。
记得一定要在0B203A29 RETN返回前按F2清除断点,然后单步跟踪F7,后代码为:
0B214B58 66:BB 56CA MOV BX,0CA56
0B214B5C 0F8F 1C000000 JG 0B214B7E
0B214B62 81F6 2ECE3D5D XOR ESI,5D3DCE2E
0B214B68 E9 11000000 JMP 0B214B7E
0B214B6D 65:3AEB CMP CH,BL ; 多余的前缀
0B214B70 48 DEC EAX
0B214B71 E1 06 LOOPDE SHORT 0B214B79
0B214B73 C7 ??? ; 未知命令
0B214B74 F4 HLT ; 特权级命令
0B214B75 1D 92636019 SBB EAX,19606392
0B214B7A DEBF 8CD5E80F FIDIVR WORD PTR DS:[EDI+FE8D58C]
0B214B80 0000 ADD BYTE PTR DS:[EAX],AL
0B214B82 00DB ADD BL,BL
0B214B84 78 51 JS SHORT 0B214BD7
0B214B86 B6 B7 MOV DH,0B7
0B214B88 24 8D AND AL,8D
0B214B8A 42 INC EDX
0B214B8B 53 PUSH EBX
说明,下面的代码是Asprotect的解码部分,多按F7几次,(不要在Call指令处按F8,否则会跑飞)。
当看到如下代码段后:
0B214D3C 5E POP ESI
0B214D3D 66:81C0 706D ADD AX,6D70
0B214D42 80E0 9C AND AL,9C
0B214D45 58 POP EAX
0B214D46 81FF 54EBFFFF CMP EDI,-14AC
0B214D4C 0F85 2F000000 JNZ 0B214D81 ;此处是判断解码是否完成
0B214D52 0FB7C2 MOVZX EAX,DX
0B214D55 E8 07000000 CALL 0B214D61
0B214D5A A3 A0591EFF MOV DWORD PTR DS:[FF1E59A0],EAX
0B214D5F CC INT3
在0B214D52下断点,F9运行至断点处,清除断点后,按F7单步跟踪,记住不要F8,否则会跑飞。一直按F7,记住要有些耐心,运行到
0B21488E 55 PUSH EBP
0B21488F 8BEC MOV EBP,ESP
0B214891 6A FF PUSH -1
0B214893 68 48E95400 PUSH 54E948
0B214898 68 542B5400 PUSH 542B54
0B21489D 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0B2148A3 F2: PREFIX REPNE: ; 多余的前缀
0B2148A4 EB 01 JMP SHORT 0B2148A7
这里的代码涉及到 Aspr抽掉的代码(stolen),但与寻找OEP没关系。先把它拷贝下来复制到一个文本文件。0B2148A4 后跳转到:
0B2148A7 50 PUSH EAX
0B2148A8 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0B2148AF 83EC 58 SUB ESP,58
0B2148B2 F2: PREFIX REPNE: ; 多余的前缀
0B2148B3 EB 01 JMP SHORT 0B2148B6
0B2148B6 53 PUSH EBX
0B2148B7 F2: PREFIX REPNE: ; 多余的前缀
0B2148B8 EB 01 JMP SHORT 0B2148BB
0B2148BB 56 PUSH ESI
0B2148BC F2: PREFIX REPNE: ; 多余的前缀
0B2148BD EB 01 JMP SHORT 0B2148C0
0B2148C0 57 PUSH EDI
0B2148C1 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
0B2148C4 3E:EB 01 JMP SHORT 0B2148C8 ; 多余的前缀
这些代码都涉及到 Aspr抽掉的代码(stolen),都要拷贝下来复制到文本文件。
单步继续跟踪到
0B2148CC 68 3BF05300 PUSH 53F03B
0B2148D1 68 7247210B PUSH 0B214772
0B2148D6 C3 RETN
这里 53F03B 就是原来程序被Aspr修改过的入口点,这不是真正的入口点。
0B2148D6 处RETN后,到
0B214775 51 PUSH ECX
0B214776 57 PUSH EDI
0B214777 9C PUSHFD
0B214778 FC CLD
0B214779 BF B647210B MOV EDI,0B2147B6
0B21477E B9 5E140000 MOV ECX,145E
0B214783 F3:AA REP STOS BYTE PTR ES:[EDI]
0B214785 9D POPFD
0B214786 5F POP EDI
0B214787 59 POP ECX
0B214788 C3 RETN
这段代码是用来把 Aspr的自解压代码清除的(不留痕迹!)。
F7执行到0B214788 处返回到0053F03B,(在0B214783处可F8)
0053F03B FF15 DCD15400 CALL DWORD PTR DS:[54D1DC]
0053F041 33D2 XOR EDX,EDX
0053F043 8AD4 MOV DL,AH
0053F045 8915 10AF8B08 MOV DWORD PTR DS:[88BAF10],EDX
这里0053F03B可不是程序真正的入口点,:)
在Ollydbg里CPU窗口向上滚动,
0053F00B 8B62 10 MOV ESP,DWORD PTR DS:[EDX+10]
0053F00E 83C4 04 ADD ESP,4
0053F011 FF62 14 JMP DWORD PTR DS:[EDX+14]
0053F014 C3 RETN
0053F015 0000 ADD BYTE PTR DS:[EAX],AL
0053F017 0000 ADD BYTE PTR DS:[EAX],AL
0053F019 0000 ADD BYTE PTR DS:[EAX],AL
0053F01B 0000 ADD BYTE PTR DS:[EAX],AL
0053F01D 0000 ADD BYTE PTR DS:[EAX],AL
0053F01F 0000 ADD BYTE PTR DS:[EAX],AL
0053F021 0000 ADD BYTE PTR DS:[EAX],AL
0053F023 0000 ADD BYTE PTR DS:[EAX],AL
0053F025 0000 ADD BYTE PTR DS:[EAX],AL
0053F027 0000 ADD BYTE PTR DS:[EAX],AL
0053F029 0000 ADD BYTE PTR DS:[EAX],AL
0053F02B 0000 ADD BYTE PTR DS:[EAX],AL
0053F02D 0000 ADD BYTE PTR DS:[EAX],AL
0053F02F 0000 ADD BYTE PTR DS:[EAX],AL
0053F031 0000 ADD BYTE PTR DS:[EAX],AL
0053F033 0000 ADD BYTE PTR DS:[EAX],AL
0053F035 0000 ADD BYTE PTR DS:[EAX],AL
0053F037 0000 ADD BYTE PTR DS:[EAX],AL
0053F039 0000 ADD BYTE PTR DS:[EAX],AL
0053F03B FF15 DCD15400 CALL DWORD PTR DS:[54D1DC]
0053F041 33D2 XOR EDX,EDX
0053F043 8AD4 MOV DL,AH
0053F045 8915 10AF8B08 MOV DWORD PTR DS:[88BAF10],EDX
大家看到了吧,从0053F015 到 0053F03B 的代码段为空!大家一定都很聪明,猜到
0053F015 才是真正的 OEP !
3。第二步,恢复被Aspr 偷走的代码
看一下我们刚才拷贝到文本框里的代码段
0B21488E 55 PUSH EBP
0B21488F 8BEC MOV EBP,ESP
0B214891 6A FF PUSH -1
0B214893 68 48E95400 PUSH 54E948
0B214898 68 542B5400 PUSH 542B54
0B21489D 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0B2148A3 F2: PREFIX REPNE: ; 多余的前缀
0B2148A4 EB 01 JMP SHORT 0B2148A7
0B2148A7 50 PUSH EAX
0B2148A8 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0B2148AF 83EC 58 SUB ESP,58
0B2148B2 F2: PREFIX REPNE: ; 多余的前缀
0B2148B3 EB 01 JMP SHORT 0B2148B6
0B2148B6 53 PUSH EBX
0B2148B7 F2: PREFIX REPNE: ; 多余的前缀
0B2148B8 EB 01 JMP SHORT 0B2148BB
0B2148BB 56 PUSH ESI
0B2148BC F2: PREFIX REPNE: ; 多余的前缀
0B2148BD EB 01 JMP SHORT 0B2148C0
0B2148C0 57 PUSH EDI
0B2148C1 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
0B2148C4 3E:EB 01 JMP SHORT 0B2148C8
把跳转指令和前缀去掉后就是
0B21488E 55 PUSH EBP
0B21488F 8BEC MOV EBP,ESP
0B214891 6A FF PUSH -1
0B214893 68 48E95400 PUSH 54E948
0B214898 68 542B5400 PUSH 542B54
0B21489D 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0B2148A7 50 PUSH EAX
0B2148A8 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0B2148AF 83EC 58 SUB ESP,58
0B2148B6 53 PUSH EBX
0B2148BB 56 PUSH ESI
0B2148C0 57 PUSH EDI
0B2148C1 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
被偷走的字节序列为
558bec6aff6848E9540068542B540064A100000000506489250000000083EC585356578965e8
共38个字节,而 0x0053F03B-0x0053F015 = 0x26, 0x26 = 38,呵呵,正好是被Apsr偷走的字节长度。
先把558bec6aff6848E9540068542B540064A100000000506489250000000083EC585356578965e8拷贝到剪贴版,在Ollydbg里选择从0053F015到0053F03B的代码段,然后点右键选择二进制里的二进制粘贴,就把被偷走的代码恢复了。
恢复后的代码段为
0053F014 C3 RETN
0053F015 55 PUSH EBP
0053F016 8BEC MOV EBP,ESP
0053F018 6A FF PUSH -1
0053F01A 68 48E95400 PUSH 54E948
0053F01F 68 542B5400 PUSH 542B54
0053F024 64:A1 00000000 MOV EAX,DWORD PTR FS:[0]
0053F02A 50 PUSH EAX
0053F02B 64:8925 00000000 MOV DWORD PTR FS:[0],ESP
0053F032 83EC 58 SUB ESP,58
0053F035 53 PUSH EBX
0053F036 56 PUSH ESI
0053F037 57 PUSH EDI
0053F038 8965 E8 MOV DWORD PTR SS:[EBP-18],ESP
0053F03B FF15 DCD15400 CALL DWORD PTR DS:[54D1DC]
0053F041 33D2 XOR EDX,EDX
0053F043 8AD4 MOV DL,AH
0053F045 8915 10AF8B08 MOV DWORD PTR DS:[88BAF10],EDX
0053F04B 8BC8 MOV ECX,EAX
0053F04D 81E1 FF000000 AND ECX,0FF
0053F053 890D 0CAF8B08 MOV DWORD PTR DS:[88BAF0C],ECX
0053F059 C1E1 08 SHL ECX,8
0053F05C 03CA ADD ECX,EDX
入口点和被偷走的代码恢复后,就是的工作就是Dump程序和恢复引入表的工作了。
4。将恢复后的程序从内存Dump下来
如果装了Ollydump插件,可以直接在插件菜单里选OllyDump,在弹出的对话框里
去掉Rebuild Import选项,我们不要使用它的恢复引入表的功能,低版本的Ollydump插件没有这项选项。
在Modify框里 输入正确的OEP,13F015(这里是偏移,53F015-40000=13f014),接着我们要修改几个段的属性
段表里的项为
Section | VirtualSize | Virtual Offset | Raw Size | Raw Offset | Charactaristics
0014c000 00001000 0014c000 00001000 C0000040
00006000 0014D000 00006000 0014d000 C0000040
0836A000 00153000 0836A000 00153000 C0000040
.rsrc 00003000 084bd000 00003000 084bd000 C0000040
.data 00012000 084C0000 00012000 084C0000 C0000040
.adata 00001000 084D2000 00001000 084D2000 C0000040
修改后段表为
Section | VirtualSize | Virtual Offset | Raw Size | Raw Offset | Charactaristics
.code 0014c000 00001000 0014c000 00001000 E0000060
.rdata 00006000 0014D000 00006000 0014d000 40000040
.data 0836A000 00153000 0836A000 00153000 C00000C0
.rsrc 00003000 084bd000 00003000 084bd000 C0000040
.data 00012000 084C0000 00012000 084C0000 C0000040
.adata 00001000 084D2000 00001000 084D2000 C0000040
主要是修改前三个段的属性,取个名字,并修正段的属性,否则程序运行会出问题。
完成这些后,按Dump取文件名Main2.exe保存,由于这个程序分配的虚拟空间较大,所以初始保存下来的文件静像也会很大。
如果没有Ollydump插件,也可以用LordPe等工具Dump,注意的是也要修正OEP和段的属性。
5。恢复引入表
这是最重要的一步了。记住,保持Ollydbg的状态,不要继续运行,也不要退出。
运行ImPortRec1.6,怎么使用它请大家参考其使用说明,我只描述具体步骤。
1) 选择要获取的激活的进程Main.exe
2) 在IAT需要的信息处的OEP里填13F015,然后按自动搜索IAT, ImportRec会自动找到可能的IAT,并在RAV框里显示出其偏移地址
3) 按获取输入表后,在上面的输入函数列表框里会显示出找到的输入函数,
4) 选择 显示非法函数,ImportRec会选中无效的RAV项,先在这些选中的无效项里点右键选择跟踪层次1, ImportRec会恢复大部分Rav项,
5) 再次选择 显示非法函数,在剩下的无效RAV项上点右键,在谈出的菜单里选插件跟踪的子菜单里的ASProtect1.22,ImportRec 会恢复所有剩下的无效的RAV项。
6) 在新的输入信息组里 去掉增加新块的选项,在RAV里填入左边RAV里的值0014D000,这是为了覆盖原来的IAT表。
7)选择修复抓取文件选中Main2.exe进行修复!
恭喜恭喜,Main2.exe的Import表修复了!
但是这时的Main2.exe还太臃肿,这是因为
它的有个段
.data 0836A000 00153000 0836A000 00153000 C00000C0
太大,但其中大部分为空值。
6。减肥!
运行LordPe,用它里面的Rebuilder功能对Main2.exe进行减肥!
呵呵减肥后的程序为1462K, 大功告成!