分享
 
 
 

ASPROTECT 2.x 脱壳系列(一)

王朝asp·作者佚名  2006-01-10
窄屏简体版  字體: |||超大  

ASPROTECT 2.x 脱壳系列(一)

【目 标】:DVD Fab Gold 2.9.4.2

【工 具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F

【任 务】:简单的脱壳

【操作平台】:Windows XP sp2

【作 者】: LOVEBOOM[DFCG][FCG][US]

【相关链接】: 自己搜索下

【简要说明】: 时间在不断的减少,人越靠近死亡的边缘.人在死亡的边缘线上挣扎.寻求人间仅有的希望,骤觉得到了,又已失去了:-(.再虚幻的网络都要回到现实,但愿大家的现实比虚幻过的更充实.

ASPROTECT比起以前的版本可算是进步不少,脱壳难度大了不少,回头看看自己,感觉太失败了,别人进步了这么多,自己却还在原地踏步走:-(

【详细过程】:

想脱这个壳的话,建议对他的历史版本有所了解,那样对看起文章来不会那么吃力.asprotect 2.x惯用的伎俩:2.x版本anti-debug方面没有什么新变化,很多人说这是这个壳的失败之外,我倒觉得说其是失败之处,倒不如说是作者别有用心:-).代码混淆处理方面做了很大功夫,变形处理和1.23可以说基本不是一个层次了,新版不再是只抽程序入口代码,程序入口代码那一个段基本上都抽光了,其它地方也是抽的很利害.输入表也处理的很难修复.我这次挑的目标是没有抽入口代码的程序.所以相对简单些.

用OD载入目标,去除调试标志.打开内存异常项,通过N个异常后到程序的入口:

00ADAF43 64:8921 MOV DWORD PTR FS:[ECX], ESP

00ADAF46 C601 A6 MOV BYTE PTR DS:[ECX], 0A6 ; 最后一次异常

00ADAF49 5B POP EBX ; 00B4AC90

.......

00ADB09B E8 807AFEFF CALL 00AC2B20

00ADB0A0 E8 73CAFFFF CALL 00AD7B18 ; 直接在这里下断然后直接这里f2断点

00ADB0A5 83C4 2C ADD ESP, 2C

00ADB0A8 5D POP EBP ; 00B4AC90

最后一个异常发生时,在00adb0a0处下f2断点,然后shift+f9,断下后f7进去,进去之后CTRL+F9执行到RETURN

00D20000 68 1F1C0627 PUSH 27061C1F ; 进到这里

00D20005 66:81C0 96FC ADD AX, 0FC96

.......

00D2011C /0F85 0F000000 JNZ 00D20131

00D20122 |B0 6A MOV AL, 6A

00D20124 |E9 3E000000 JMP 00D20167 ; f4运行到这里

00D20129 |40 INC EAX

......

00D20192 2BC3 SUB EAX, EBX

00D20194 5C POP ESP ; DVDFabGo.00400000

00D20195 - FFE0 JMP EAX ; 这里跳去OEP

00D20197 40 INC EAX

当然如果你只是想直接到

oep的话,最后一个异常发生后直接在CODE段下f2断点,再shift+f9就可以了:

0047572E 55 PUSH EBP ; 程序OEP

0047572F 8BEC MOV EBP, ESP

00475731 6A FF PUSH -1

00475733 68 80F14700 PUSH 0047F180

.....

到了OEP后,我们先定位下IAT,观察后发现相关的API函数并没有什么加密处理,IAT:47A000 SIZE:BC4.

api没有什么特别处理,并不表示容易的,在程序里随便找一下就会看到call api到壳里去了。

00475832 E8 C9A78C00 CALL 00D40000

搜索一下发现很多地方都改成这样子了,一个一个去改??,我以前是试过一个一个去改。但那样效率太低了,且容易出错。跟过aspr 2.x的应该知道壳运行时会改地址的,因此在475832处下写入断点,运行中断:

00AE6265 8B45 F4 MOV EAX, DWORD PTR SS:[EBP-C]

00AE6268 8B40 3C MOV EAX, DWORD PTR DS:[EAX+3C]

00AE626B 8B55 FC MOV EDX, DWORD PTR SS:[EBP-4] ; 传递正确的API到EDX中

00AE626E E8 D1130000 CALL 00AE7644 ; 因是壳会检测相关代码,进去这里面后有地方不会被检测的

--------------------进入第一层----------------------------

00AE7644 55 PUSH EBP

00AE7645 8BEC MOV EBP, ESP

00AE7647 83C4 E4 ADD ESP, -1C

00AE764A 53 PUSH EBX

00AE764B 56 PUSH ESI

00AE764C 57 PUSH EDI

00AE764D 894D F4 MOV DWORD PTR SS:[EBP-C], ECX

00AE7650 8955 F8 MOV DWORD PTR SS:[EBP-8], EDX ; kernel32.GetModuleHandleA

00AE7653 8945 FC MOV DWORD PTR SS:[EBP-4], EAX

00AE7656 33C0 XOR EAX, EAX

00AE7658 8945 F0 MOV DWORD PTR SS:[EBP-10], EAX

00AE765B B8 00070000 MOV EAX, 700 ; 这里还有代码检测的,再次进入

00AE7660 E8 DFAEFDFF CALL 00AC2544

00AE7665 8945 E4 MOV DWORD PTR SS:[EBP-1C], EAX

----------------------------------进入第二层------------------------------------------

00AC2544 85C0 TEST EAX, EAX

00AC2546 74 0A JE SHORT 00AC2552 ; 经跟踪发现这里的条件判断在这个程序里是不会跳转的

00AC2548 FF15 18A0AE00 CALL DWORD PTR DS:[AEA018] ; 这里的代码也不会被检测到,因此我把这里做为我们的突破点

00AC254E 09C0 OR EAX, EAX

00AC2550 74 01 JE SHORT 00AC2553

00AC2552 C3 RETN

00AC2553 B0 01 MOV AL, 1

---------------------------------------------------------------------------------------

--------------------END----------------------------

00AE6273 8945 FC MOV DWORD PTR SS:[EBP-4], EAX

00AE6276 8B45 E0 MOV EAX, DWORD PTR SS:[EBP-20]

00AE6279 8B00 MOV EAX, DWORD PTR DS:[EAX]

00AE627B E8 D0E6FFFF CALL 00AE4950

00AE6280 8BD0 MOV EDX, EAX

00AE6282 0255 DF ADD DL, BYTE PTR SS:[EBP-21]

00AE6285 8B4D FC MOV ECX, DWORD PTR SS:[EBP-4]

00AE6288 8B45 F4 MOV EAX, DWORD PTR SS:[EBP-C]

00AE628B E8 80040000 CALL 00AE6710

00AE6290 8945 FC MOV DWORD PTR SS:[EBP-4], EAX

00AE6293 8B45 F4 MOV EAX, DWORD PTR SS:[EBP-C]

00AE6296 8B40 24 MOV EAX, DWORD PTR DS:[EAX+24]

00AE6299 8B55 F4 MOV EDX, DWORD PTR SS:[EBP-C]

00AE629C 0382 E0000000 ADD EAX, DWORD PTR DS:[EDX+E0]

00AE62A2 0145 1C ADD DWORD PTR SS:[EBP+1C], EAX

00AE62A5 8B45 FC MOV EAX, DWORD PTR SS:[EBP-4]

00AE62A8 2B45 1C SUB EAX, DWORD PTR SS:[EBP+1C] ; DVDFabGo.00475832

00AE62AB 83E8 05 SUB EAX, 5

00AE62AE 8B55 1C MOV EDX, DWORD PTR SS:[EBP+1C] ; DVDFabGo.00475832

00AE62B1 42 INC EDX ; DVDFabGo.00475833

00AE62B2 8902 MOV DWORD PTR DS:[EDX], EAX ; 这里断下,写入call的地址

00AE62B4 EB 01 JMP SHORT 00AE62B7

00AE62B6 E8 8B45F883 CALL 84A6A846

找到突破点后,再找这段代码的出口,tc command is:POPFD,条件符合后中断:

00D500B0 9D POPFD ; 条件中断在这里

00D500B1 5C POP ESP

00D500B2 F3: PREFIX REP: ; Superfluous prefix

00D500B3 EB 02 JMP SHORT 00D500B7

00D500B5 CD 20 INT 20

00D500B7 FF6424 FC JMP DWORD PTR SS:[ESP-4] ; 这里跳去执行原程序的call api,注意这里已经处理过了,不再是简单的call api了

00D500BB F3: PREFIX REP: ; Superfluous prefix

00D500BC EB 02 JMP SHORT 00D500C0

00D500BE CD 20 INT 20

再找一个空闲的地方写上修复代码,考虑到代码可能会长一点,选择代码后的空白地址479bc0修复代码起始地址。

总结一下大概为:

OEP: 47572E

IAT: 47A000

SIZE: BC4

Patch点一: 00AC2548

Patch点二: 00D500B7(这个地址每次运行都会改变的)

Patch起始地址: 479BC0

现在唯一没有解决的问题就是,都有哪些地方改成了CALL 00D40000,当然,可以通过比较死的方法,直接去搜索,我觉得那样可能没有那么准确,所以我选择了直接记录的方式。

重新加载,载入后,两次GetModuleHandleA中断后,让壳的代码完全解出来:

00AF25C2 /75 08 JNZ SHORT 00AF25CC

00AF25C4 |B8 01000000 MOV EAX, 1

00AF25C9 |C2 0C00 RETN 0C

00AF25CC \68 A08FAE00 PUSH 0AE8FA0 ; 壳的执行代码执行点

00AF25D1 C3 RETN

......

00AE8FA0 55 PUSH EBP ; 壳的代码

00AE8FA1 8BEC MOV EBP, ESP

00AE8FA3 83C4 B4 ADD ESP, -4C

壳的代码完全解出来后,搜索命令

MOV [EBP],EAX

PUSH 0A

找到相关位置后下硬件执行断点。执行后中断:

00AE653F 8945 00 MOV DWORD PTR SS:[EBP], EAX ; 找到这里,ebp-1就正好是call d40000的地址

00AE6542 6A 0A PUSH 0A

00AE6544 E8 63C4FEFF CALL 00AD29AC

00AE6549 8BC8 MOV ECX, EAX

现在要要找的就是存放这些地址的空间,ASPR加壳的程序,最后一个段是空的,我们可以利用下,我选择514100开始保存相关数据:

514100保存将要保存相关call地址的实际地址,514108保存call [address]中的address,514100开始保存相关call 00d40000的实际地址。好了,现在写上一段代码来保存相关数据:

00AE653F /EB 43 JMP SHORT 00AE6584 ; 跳去执行我们的代码

00AE6541 |90 NOP

00AE6542 |6A 0A PUSH 0A

00AE6544 |E8 63C4FEFF CALL 00AD29AC

00AE6549 |8BC8 MOV ECX, EAX

00AE654B |038B E4000000 ADD ECX, DWORD PTR DS:[EBX+E4]

00AE6551 |8BD6 MOV EDX, ESI

00AE6553 |8BC3 MOV EAX, EBX

00AE6555 |E8 9EE5FFFF CALL 00AE4AF8

00AE655A |FF0C24 DEC DWORD PTR SS:[ESP]

00AE655D |03B3 E4000000 ADD ESI, DWORD PTR DS:[EBX+E4]

00AE6563 |833C24 00 CMP DWORD PTR SS:[ESP], 0

00AE6567 ^|0F87 55FEFFFF JA 00AE63C2

00AE656D |53 PUSH EBX ; 写好代码后直接在这里F2断点

00AE656E |E8 5D000000 CALL 00AE65D0

00AE6573 |0183 EC000000 ADD DWORD PTR DS:[EBX+EC], EAX

00AE6579 |B0 01 MOV AL, 1

00AE657B |83C4 24 ADD ESP, 24

00AE657E |5D POP EBP ; DVDFabGo.004033AD

00AE657F |5F POP EDI

00AE6580 |5E POP ESI

00AE6581 |5B POP EBX

00AE6582 |C3 RETN

00AE6583 |90 NOP

00AE6584 \53 PUSH EBX ; 保存堆栈

00AE6585 51 PUSH ECX

00AE6586 B9 00415100 MOV ECX, 514100 ; 起始地址

00AE658B 8339 00 CMP DWORD PTR DS:[ECX], 0

00AE658E 75 06 JNZ SHORT 00AE6596

00AE6590 C701 10415100 MOV DWORD PTR DS:[ECX], 514110 ; 如果是第一次则写入相关数据

00AE6596 8B19 MOV EBX, DWORD PTR DS:[ECX]

00AE6598 4D DEC EBP ; DVDFabGo.004033AD

00AE6599 892B MOV DWORD PTR DS:[EBX], EBP ; 保存call的地址

00AE659B 83C3 04 ADD EBX, 4

00AE659E 8919 MOV DWORD PTR DS:[ECX], EBX ; 保存下次保存数据的地址

00AE65A0 45 INC EBP ; DVDFabGo.004033AD

00AE65A1 59 POP ECX

00AE65A2 5B POP EBX

00AE65A3 8945 00 MOV DWORD PTR SS:[EBP], EAX ; 执行壳原来的代码

00AE65A6 ^ EB 9A JMP SHORT 00AE6542

写完代码后直接在00AE656D下F2断点,断下后,还原patch代码,514100处的数据保存起来(主要是方便一次操作不成功,第二次不用再写代码获取相关数据,当然其实完全可以一次操作成功的)。

获取到了相关的数据后,运行到OEP处,然后就可以直接写上完整的修复代码了,在前面总结的479BC0处写上修复代码:

00479BC0 . 60 PUSHAD ; 保护堆栈,直接定位到这里

00479BC1 . B9 10415100 MOV ECX, 00514110 ; 把call 00d40000改成call ds:[addr]

00479BC6 > 8B19 MOV EBX, DWORD PTR DS:[ECX] ; 取出相关地址

00479BC8 . 83FB 00 CMP EBX, 0 ; 判断是否处理完了

00479BCB . 74 15 JE SHORT 00479BE2

00479BCD .- FFE3 JMP EBX ; 执行原call

00479BCF . 8B15 08415100 MOV EDX, DWORD PTR DS:[514108] ; [514108]就是保存call [address] 中的address

00479BD5 . 66:C703 FF15 MOV WORD PTR DS:[EBX], 15FF ; 修复成call ds:[address]

00479BDA . 8953 02 MOV DWORD PTR DS:[EBX+2], EDX ; 填上实际的address

00479BDD . 83C1 04 ADD ECX, 4

00479BE0 .^ EB E4 JMP SHORT 00479BC6

00479BE2 > 33C0 XOR EAX, EAX ; 这里开始修复call [addr]中实际上是jmp [addr]的部分

00479BE4 . B0 E8 MOV AL, 0E8

00479BE6 . BF 00104000 MOV EDI, <ModuleEntryPoint> ; 代码段的起始地址

00479BEB . B9 B89B0600 MOV ECX, 69BB8 ; 大小

00479BF0 > F2:AE REPNE SCAS BYTE PTR ES:[EDI]

00479BF2 . 83F9 00 CMP ECX, 0

00479BF5 . 74 3C JE SHORT 00479C33 ; 如果处理完则结束过程

00479BF7 . 8B1F MOV EBX, DWORD PTR DS:[EDI]

00479BF9 . 8D5C3B 04 LEA EBX, DWORD PTR DS:[EBX+EDI+4]

00479BFD . 81FB 00104000 CMP EBX, <ModuleEntryPoint>

00479C03 .^ 72 EB JB SHORT 00479BF0

00479C05 . 81FB BA9B4700 CMP EBX, 00479BBA

00479C0B .^ 77 E3 JA SHORT 00479BF0

00479C0D . 66:813B FF15 CMP WORD PTR DS:[EBX], 15FF

00479C12 .^ 75 DC JNZ SHORT 00479BF0

00479C14 . 817B 02 00A04>CMP DWORD PTR DS:[EBX+2], 0047A000 ; 再次准确的判断是否为真的要修改的代码

00479C1B .^ 72 D3 JB SHORT 00479BF0

00479C1D . 817B 02 C0AB4>CMP DWORD PTR DS:[EBX+2], 0047ABC0

00479C24 .^ 77 CA JA SHORT 00479BF0

00479C26 . 66:C703 FF25 MOV WORD PTR DS:[EBX], 25FF

00479C2B . 83C7 04 ADD EDI, 4

00479C2E . 83E9 04 SUB ECX, 4

00479C31 .^ EB BD JMP SHORT 00479BF0

00479C33 > 61 POPAD ; 还原现场

00479C34 . 00 DB 00

00479C35 . 00 DB 00 ; 因为我是操作边写的,这里留多点空间方便修改代码

00479C36 . 00 DB 00

00479C37 . 00 DB 00

00479C38 . 00 DB 00

00479C39 . 00 DB 00

00479C3A . 00 DB 00

00479C3B . 00 DB 00

00479C3C . 00 DB 00

00479C3D . 00 DB 00

00479C3E . 00 DB 00

00479C3F . 00 DB 00

00479C40 . 00 DB 00

00479C41 . 00 DB 00

00479C42 . 00 DB 00

00479C43 . 00 DB 00

00479C44 . 00 DB 00

00479C45 . 00 DB 00

00479C46 . 00 DB 00

00479C47 . 00 DB 00

00479C48 . 00 DB 00

00479C49 . 00 DB 00

00479C4A . 00 DB 00

00479C4B . 00 DB 00

00479C4C . 00 DB 00

00479C4D . 00 DB 00

00479C4E . 00 DB 00

00479C4F . 00 DB 00

00479C50 . 00 DB 00

00479C51 . 00 DB 00

00479C52 . 00 DB 00

00479C53 . 00 DB 00

00479C54 . 00 DB 00

00479C55 . 00 DB 00

00479C56 . 00 DB 00

00479C57 . 00 DB 00

00479C58 . 00 DB 00

00479C59 . 00 DB 00

00479C5A . 00 DB 00

00479C5B . 00 DB 00

00479C5C . 00 DB 00

00479C5D . 00 DB 00

00479C5E . 00 DB 00

00479C5F . 00 DB 00

00479C60 . 00 DB 00

00479C61 . 00 DB 00

00479C62 . 00 DB 00

00479C63 . 00 DB 00

00479C64 . 00 DB 00

00479C65 . 00 DB 00

00479C66 . 00 DB 00

00479C67 . 00 DB 00

00479C68 . 00 DB 00

00479C69 . 00 DB 00

00479C6A . 00 DB 00

00479C6B . 00 DB 00

00479C6C . 00 DB 00

00479C6D . 00 DB 00

00479C6E . 00 DB 00

00479C6F . 00 DB 00

00479C70 789C4700 DD DVDFabGo.00479C78

00479C74 00 DB 00

00479C75 90 NOP

00479C76 90 NOP

00479C77 90 NOP

00479C78 . 60 PUSHAD

00479C79 . 8BC2 MOV EAX, EDX

00479C7B . B9 C80B0000 MOV ECX, 0BC8 ; iat大小

00479C80 . BF 00A04700 MOV EDI, 0047A000 ; iat起始地址

00479C85 . F2:AF REPNE SCAS DWORD PTR ES:[EDI]

00479C87 . 83EF 04 SUB EDI, 4

00479C8A . 893D 08415100 MOV DWORD PTR DS:[514108], EDI ; 保存地址

00479C90 . 61 POPAD

00479C91 . FF15 18A0AE00 CALL DWORD PTR DS:[AEA018] ; 执行程序的原代码

00479C97 . C3 RETN

00479C98 90 NOP

再把这里的代码改一下:

00AC2548 FF15 709C4700 CALL DWORD PTR DS:[479C70] ; DVDFabGo.00479C78

写到这里,完了吗?当然没有了,认真看就会发前的的jmp ebx那里是个call,直接这样操作就回不来了,这也就是为什么前面还用一个patch2,

直接到00D500B7看看去,看看现在在哪里了。

00D500E1 9D POPFD

00D500E2 5C POP ESP ; 00A80000

00D500E3 - FF6424 FC JMP DWORD PTR SS:[ESP-4] ; 这次在这里了

00D500E7 CC INT3

直接在D500E3处下硬件断点,没错了,我想在这里的时候把返回地址改成跳去00479BCF,直接修改代码?当然不行了,壳会检测的,找到地方去除检测?我偷懒处理下,用脚本就很简单的搞定了:

//fixed aspr 2.x

var addr

start:

run

l1:

cmp eip,00D500E3

jne l2

mov addr,esp

sub addr,4

mov [addr],479bcf

jmp start

l2:

ret

写好后,记得在479c33处下个f2断,再运行,否则运行脚本后会"飞"的。

脚本运行完毕,赶快dump完,修复收工吧(做完后要记得把修复代码和保存的数据给清除掉哦,做事要有头有尾才行的).嗯,脱壳完毕,当然这里实际上还是有点小问题的,问题解决方法请参考我的第二篇ASPR文章

Greetz:

Fly.Jingulong,yock,tDasm.David.hexer,hmimys,ahao.UFO(brother).alan(sister).all of my

friends and you!

By loveboom[DFCG][FCG][US]

http://blog.csdn.net/bmd2chen

Email:loveboom#163.com

 
 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
2023年上半年GDP全球前十五强
 百态   2023-10-24
美众议院议长启动对拜登的弹劾调查
 百态   2023-09-13
上海、济南、武汉等多地出现不明坠落物
 探索   2023-09-06
印度或要将国名改为“巴拉特”
 百态   2023-09-06
男子为女友送行,买票不登机被捕
 百态   2023-08-20
手机地震预警功能怎么开?
 干货   2023-08-06
女子4年卖2套房花700多万做美容:不但没变美脸,面部还出现变形
 百态   2023-08-04
住户一楼被水淹 还冲来8头猪
 百态   2023-07-31
女子体内爬出大量瓜子状活虫
 百态   2023-07-25
地球连续35年收到神秘规律性信号,网友:不要回答!
 探索   2023-07-21
全球镓价格本周大涨27%
 探索   2023-07-09
钱都流向了那些不缺钱的人,苦都留给了能吃苦的人
 探索   2023-07-02
倩女手游刀客魅者强控制(强混乱强眩晕强睡眠)和对应控制抗性的关系
 百态   2020-08-20
美国5月9日最新疫情:美国确诊人数突破131万
 百态   2020-05-09
荷兰政府宣布将集体辞职
 干货   2020-04-30
倩女幽魂手游师徒任务情义春秋猜成语答案逍遥观:鹏程万里
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案神机营:射石饮羽
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案昆仑山:拔刀相助
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案天工阁:鬼斧神工
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案丝路古道:单枪匹马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:与虎谋皮
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:李代桃僵
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案镇郊荒野:指鹿为马
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:小鸟依人
 干货   2019-11-12
倩女幽魂手游师徒任务情义春秋猜成语答案金陵:千金买邻
 干货   2019-11-12
 
推荐阅读
 
 
 
>>返回首頁<<
 
靜靜地坐在廢墟上,四周的荒凉一望無際,忽然覺得,淒涼也很美
© 2005- 王朝網路 版權所有