- UID
- 8764
注册时间2006-3-1
阅读权限10
最后登录1970-1-1
周游历练
TA的每日心情 | 开心 2018-1-9 11:05 |
---|
签到天数: 2 天 [LV.1]初来乍到
|
标 题: ASPROTECT 2.x 脱壳系列(一)
发帖人:loveboom
时 间: 2005-10-05 20:36
原文链接:http://bbs.pediy.com/showthread.php?threadid=17373
详细信息:
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文章
标 题: 答复
发帖人:wenglingok
时 间: 2005-10-08 11:01
详细信息:
引用:
--------------------------------------------------------------------------------
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中
--------------------------------------------------------------------------------
我用Aspr2.11加壳的记事本
第一个Call api 应该是调用 GetCommandLineA
被改为Call 00D60000
跟进来到你说的传递正确API到EDX的地方时,竟然变成了GetSartupInfo
怎么也想不通会这样,正在郁闷中啊!
(已解决)
原来修改代码前传递正确的API,随后会传递下一个Api准备调用,下一个Api就是GetSartupInfo,我跟到那里去了。
ASPROTECT 2.x 脱壳系列(二)
Submitted by heartnn on 2006, March 14, 6:18 AM. 技术
【目 标】:DVD Fab Gold 2.9.3.5
【工 具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
【任 务】:简单的脱壳
【操作平台】:Windows XP sp2
【作 者】:LOVEBOOM[DFCG][FCG][US]
【相关链接】:自己搜索下
【简要说明】:其实这个版本的还是更先脱的,只是整理的时候更后整理出来。看这篇文章之前建议先看我的第一篇文章,否则有些过程可能不好理解。
【详细过程】:
话也不多说,直接入主题, 载入目标程序,去除调试标志,下断bp GetModuleHandleA,运行中断两次,然后执行到完全解压出壳的代码:
00AF24AC 85C0 TEST EAX, EAX ; 第二次返回到这里
00AF24AE 75 07 JNZ SHORT 00AF24B7
00AF24B0 53 PUSH EBX
00AF24B1 FF95 F0314400 CALL DWORD PTR SS:[EBP+4431F0] ; kernel32.LoadLibraryA
......
00AF25BB 8985 112F4400 MOV DWORD PTR SS:[EBP+442F11], EAX
00AF25C1 61 POPAD ; 直接f4执行到这里
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
00AF25D2 8B85 DC304400 MOV EAX, DWORD PTR SS:[EBP+4430DC] ; kernel32.7C800000
......
00AE8FA0 55 PUSH EBP ; 壳代码入口点
00AE8FA1 8BEC MOV EBP, ESP
00AE8FA3 83C4 B4 ADD ESP, -4C
00AE8FA6 B8 988DAE00 MOV EAX, 0AE8D98
到了壳的入口点后直接搜索以下命令:
MOV DWORD PTR SS:[EBP], EAX
PUSH 0A
找到一处:
00AE653F 8945 00 MOV DWORD PTR SS:[EBP], EAX ; 找到这里
00AE6542 6A 0A PUSH 0A
00AE6544 E8 63C4FEFF CALL 00AD29AC
00AE6549 8BC8 MOV ECX, EAX
找到地址后,在上面的地址处下硬件断点,执行发生中断后取消硬件断点。
再找一下存放相关数据的地址,我选择的是513100.找到后,写段保存数据代码:
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 ; 00ADBDC8
00AE657F |5F POP EDI ; 00ADBDC8
00AE6580 |5E POP ESI ; 00ADBDC8
00AE6581 |5B POP EBX ; 00ADBDC8
00AE6582 |C3 RETN
00AE6583 |90 NOP
00AE6584 \53 PUSH EBX ; 保护堆栈
00AE6585 51 PUSH ECX
00AE6586 B9 00315100 MOV ECX, 513100 ; 保存相关数据的起始地址
00AE658B 8339 00 CMP DWORD PTR DS:[ECX], 0
00AE658E 75 06 JNZ SHORT 00AE6596
00AE6590 C701 10315100 MOV DWORD PTR DS:[ECX], 513110 ; 如果是第次则初始化,从513110处开始保存相关数据
00AE6596 8B19 MOV EBX, DWORD PTR DS:[ECX] ; wsock32.#1139
00AE6598 4D DEC EBP ; DVDFabGo.004EE4A6
00AE6599 892B MOV DWORD PTR DS:[EBX], EBP ; 保存相关地址
00AE659B 83C3 04 ADD EBX, 4
00AE659E 8919 MOV DWORD PTR DS:[ECX], EBX
00AE65A0 45 INC EBP ; DVDFabGo.004EE4A6
00AE65A1 59 POP ECX ; 00ADBDC8
00AE65A2 5B POP EBX ; 00ADBDC8
00AE65A3 8945 00 MOV DWORD PTR SS:[EBP], EAX ; 执行原壳的代码
00AE65A6 ^ EB 9A JMP SHORT 00AE6542
00AE65A8 C1E3 18 SHL EBX, 18
00AE65AB 31D8 XOR EAX, EBX
写好代码后在00AE656D处下F2断点,再F9运行,运行中断后,把修复代码还原回去,第三次出现机器码时写上注册信息:
--------------------第一次----------------------
0012FF1C 0012FF28 Pointer to next SEH record
0012FF20 00ADC92E SE handler
0012FF24 00000002
0012FF28 0012FF80 Pointer to next SEH record
0012FF2C 00ADD739 SE handler
0012FF30 0012FF78
0012FF34 00AC0000
0012FF38 00A80000
0012FF3C 00ADBDC8
0012FF40 00000000
0012FF44 00B59E34 ASCII "6uCokAAAJmg="
0012FF48 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF4C C5FC9640
0012FF50 41B05FF0
0012FF54 F81D0E0A
......
--------------------第二次----------------------
0012FF1C 0012FF28 Pointer to next SEH record
0012FF20 00ADCAD5 SE handler
0012FF24 00B3045C
0012FF28 0012FF80 Pointer to next SEH record
0012FF2C 00ADD739 SE handler
0012FF30 0012FF78
0012FF34 00AC0000
0012FF38 00A80000
0012FF3C 00ADBDC8
0012FF40 00000000
0012FF44 00B59E34 ASCII "6uCokAAAJmg="
0012FF48 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF4C C5FC9640
0012FF18 0012FF28 Pointer to next SEH record
0012FF1C 00ADCEE7 SE handler
0012FF20 00B3045C
0012FF24 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF28 0012FF80 Pointer to next SEH record
0012FF2C 00ADD739 SE handler
0012FF30 0012FF78
0012FF34 00AC0000
0012FF38 00A80000
0012FF3C 00ADBDC8
0012FF40 00000000
0012FF44 00B59E34 ASCII "6uCokAAAJmg="
0012FF48 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF4C C5FC9640
......
--------------------第三次----------------------
0012FF18 0012FF28 Pointer to next SEH record
0012FF1C 00ADCEE7 SE handler
0012FF20 00B3045C
0012FF24 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF28 0012FF80 Pointer to next SEH record
0012FF2C 00ADD739 SE handler
0012FF30 0012FF78
0012FF34 00AC0000
0012FF38 00A80000
0012FF3C 00ADBDC8
0012FF40 00000000
0012FF44 00B59E34 ASCII "6uCokAAAJmg="
0012FF48 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF4C C5FC9640
第三次出现机器码后,在code段访问断点,shift+f9后中断在这里:
00424CD7 8B4424 04 MOV EAX, DWORD PTR SS:[ESP+4] ; 中断在这里,[esp+4]保存注册名地址
00424CDB 81EC 08020000 SUB ESP, 208
......
0012FF1C 00ADD190 RETURN to 00ADD190
0012FF20 00AC3A29
0012FF24 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF28 0012FF80 Pointer to next SEH record
修改为:
0012FF1C 00ADD190 RETURN to 00ADD190
0012FF20 00479F70 ASCII "loveboom[DFCG][FCG][US]"
0012FF24 00B59E00 ASCII "2A0FFBAB-CB5A"
0012FF28 0012FF80 Pointer to next SEH record
这样注册块就处理好了,再过几个异常后直接F2断到程序OEP:
0047550E 55 PUSH EBP ; OEP
0047550F 8BEC MOV EBP, ESP
00475511 6A FF PUSH -1
......
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
......
00D500EB 5C POP ESP
00D500EC - FF6424 FC JMP DWORD PTR SS:[ESP-4] ;patch
00D500F0 EB 01 JMP SHORT 00D500F3
再找一下找到输入表信息:
IAT位置:47A000 SIZE:bb0
PATCH 1: 00ac2548
PATCH 2: 00D500EC
PATCH 3: 4799b0(保存修复代码的起始地址)
修改跳转地址为: 004799BF
写上全部的修复代码:
004799B0 . 60 PUSHAD ; 保存堆栈
004799B1 . B9 10315100 MOV ECX, 00513110 ; 取出相关的地址
004799B6 > 8B19 MOV EBX, DWORD PTR DS:[ECX]
004799B8 . 83FB 00 CMP EBX, 0
004799BB . 74 15 JE SHORT 004799D2 ; 如果取完了则跳去修复jmp [addr]
004799BD . FFE3 JMP EBX ; 执行原CALL
004799BF . 8B15 08315100 MOV EDX, DWORD PTR DS:[513108] ; 取出call [addr]中的addr
004799C5 . 66:C703 FF15 MOV WORD PTR DS:[EBX], 15FF ; 修改成call [addr]
004799CA . 8953 02 MOV DWORD PTR DS:[EBX+2], EDX ; <&winmm.PlaySound>
004799CD . 83C1 04 ADD ECX, 4
004799D0 .^ EB E4 JMP SHORT 004799B6
004799D2 > 33C0 XOR EAX, EAX
004799D4 . B0 E8 MOV AL, 0E8 ; 修复jmp [addr]
004799D6 . BF 00104000 MOV EDI, 00401000 ; code段的起始地址
004799DB . B9 A0990600 MOV ECX, 699A0 ; 大小
004799E0 > F2:AE REPNE SCAS BYTE PTR ES:[EDI]
004799E2 . 83F9 00 CMP ECX, 0
004799E5 . 74 3C JE SHORT 00479A23 ; 处理完则跳
004799E7 . 8B1F MOV EBX, DWORD PTR DS:[EDI]
004799E9 . 8D5C3B 04 LEA EBX, DWORD PTR DS:[EBX+EDI+4]
004799ED . 81FB 00104000 CMP EBX, 00401000 ; Entry address
004799F3 .^ 72 EB JB SHORT 004799E0
004799F5 . 81FB 94994700 CMP EBX, 00479994
004799FB .^ 77 E3 JA SHORT 004799E0
004799FD . 66:813B FF15 CMP WORD PTR DS:[EBX], 15FF
00479A02 .^ 75 DC JNZ SHORT 004799E0
00479A04 . 817B 02 00A04>CMP DWORD PTR DS:[EBX+2], <&advapi32>
00479A0B .^ 72 D3 JB SHORT 004799E0
00479A0D . 817B 02 C0AB4>CMP DWORD PTR DS:[EBX+2], 0047ABC0
00479A14 .^ 77 CA JA SHORT 004799E0 ; 让代码更精确些
00479A16 . 66:C703 FF25 MOV WORD PTR DS:[EBX], 25FF
00479A1B . 83C7 04 ADD EDI, 4
00479A1E . 83E9 04 SUB ECX, 4
00479A21 .^ EB BD JMP SHORT 004799E0
00479A23 > B9 10315100 MOV ECX, 00513110 ; 再次精确些处理jmp [addr] **********这里是上篇中没有注意到的
00479A28 > 8B19 MOV EBX, DWORD PTR DS:[ECX]
00479A2A . 83FB 00 CMP EBX, 0
00479A2D . 74 2E JE SHORT 00479A5D ; 操作完则跳
00479A2F . 66:8B03 MOV AX, WORD PTR DS:[EBX]
00479A32 . 66:3D FF15 CMP AX, 15FF ; 判断是否为call [addr]
00479A36 . 75 20 JNZ SHORT 00479A58
00479A38 . 66:8B43 FA MOV AX, WORD PTR DS:[EBX-6] ; 如果是的话,判断前一句代码是否为jmp [addr]
00479A3C . 66:3D FF25 CMP AX, 25FF
00479A40 . 75 16 JNZ SHORT 00479A58
00479A42 . 8B53 FC MOV EDX, DWORD PTR DS:[EBX-4]
00479A45 . 81FA 00A04700 CMP EDX, <&advapi32.AdjustTokenPrivi>
00479A4B . 72 0B JB SHORT 00479A58
00479A4D . 81FA C0AB4700 CMP EDX, 0047ABC0
00479A53 . 77 03 JA SHORT 00479A58
00479A55 . 66:8903 MOV WORD PTR DS:[EBX], AX ; 如果是的话则认为这当前句也是jmp [addr]
00479A58 > 83C1 04 ADD ECX, 4
00479A5B .^ EB CB JMP SHORT 00479A28
00479A5D > 61 POPAD
00479A5E . 00 DB 00
00479A5F . 00 DB 00
00479A60 689A4700 DD dumped_.00479A68
00479A64 . 00 DB 00
00479A65 90 NOP
00479A66 90 NOP
00479A67 90 NOP
00479A68 . 60 PUSHAD
00479A69 . 8BC2 MOV EAX, EDX ; 保存call [addr]中的addr到 513108处
00479A6B . B9 C80B0000 MOV ECX, 0BC8
00479A70 . BF 00A04700 MOV EDI, <&advapi32.AdjustTokenPrivi>
00479A75 . F2:AF REPNE SCAS DWORD PTR ES:[EDI]
00479A77 . 83EF 04 SUB EDI, 4
00479A7A . 893D 08315100 MOV DWORD PTR DS:[513108], EDI ; ntdll.7C930738
00479A80 . 61 POPAD
00479A81 FF15 18A0AE00 CALL DWORD PTR DS:[AEA018]
00479A87 . C3 RETN
00479A88 90 NOP
再写上修复脚本:
//fixed aspr 2.x
var addr
start:
run
l1:
cmp eip,00D500EC
jne l2
mov addr,esp
sub addr,4
mov [addr],004799BF
jmp start
l2:
ret
写好后在00D500EC下硬件执行断点,在00479A5D下普通F2断点,再执行脚本。脱壳完毕!
破解就像恋爱,这过程没有什么人能帮到你,什么都得靠自己一步一步的走。愿自己的恋爱能和脱壳一样风雨无阻:-).
http://www.my.usmanbiz.com/blog/trackback.php?id=321
标 题】:ASPROTECT 2.x 脱壳系列(三)
【关键字】:ASPROTECT,2.x
【来 源】:BLOG.CSDN.NET
ASPROTECT 2.x 脱壳系列(三)
ASPROTECT 2.x 脱壳系列(三)
【目 标】:BeeIcons 4.02.1
【工 具】:Olydbg1.1(diy版)、LORDPE、ImportREC1.6F
【任 务】:简单的脱壳
【操作平台】:Windows XP sp2
【作 者】:LOVEBOOM[DFCG][FCG][US]
【相关链接】:自己搜索下
【简要说明】:继上一篇,这次的目标前两篇的又有所不同了.难度稍微大了点。这次来个一气呵成:-)
【详细过程】:
OD设置:忽略除int3之外的其它异常,载入目标:
00401000 > 68 01706100 PUSH 00617001 ; 壳EP
00401005 E8 01000000 CALL 0040100B
F9运行后中断下来:
0103700B 90 NOP ; 异常中断
0103700C EB 01 JMP SHORT 0103700F
0103700E 6966 81 FE47467>IMUL ESP, DWORD PTR DS:[ESI-7F], 7446>
异常中断在code段下F2断点,然后shift+f9,中断:
0102267D F3:A5 REP MOVS DWORD PTR ES:[EDI], DWORD P>; 中断这里
0102267F 89C1 MOV ECX, EAX
01022681 83E1 03 AND ECX, 3
01022684 83C6 03 ADD ESI, 3
01022687 83C7 03 ADD EDI, 3
0102268A F3:A4 REP MOVS BYTE PTR ES:[EDI], BYTE PTR>
断下后,查找相关命令:
mov [ebp],eax
push 0a
找到一处,在找到的位置下硬件执行断点:
01045F7B 8945 00 MOV DWORD PTR SS:[EBP], EAX ; 找到这里,直接在这里下硬件执行断点
01045F7E 6A 0A PUSH 0A
01045F80 E8 8FCEFEFF CALL 01032E14
01045F85 8BC8 MOV ECX, EAX
和上两篇一样,找到相关地址,然后写上相关代码:
___________________________获取CALL 01270000全部地址的修复代码_______________________________
01045F7B /EB 43 JMP SHORT 01045FC0 ; 找到这里,直接在这里下硬件执行断点
01045F7D |90 NOP
01045F7E |6A 0A PUSH 0A
01045F80 |E8 8FCEFEFF CALL 01032E14
01045F85 |8BC8 MOV ECX, EAX
01045F87 |038B E4000000 ADD ECX, DWORD PTR DS:[EBX+E4]
01045F8D |8BD6 MOV EDX, ESI
01045F8F |8BC3 MOV EAX, EBX
01045F91 |E8 9EE5FFFF CALL 01044534
01045F96 |FF0C24 DEC DWORD PTR SS:[ESP]
01045F99 |03B3 E4000000 ADD ESI, DWORD PTR DS:[EBX+E4]
01045F9F |833C24 00 CMP DWORD PTR SS:[ESP], 0
01045FA3 ^|0F87 55FEFFFF JA 01045DFE
01045FA9 |53 PUSH EBX ; 这里F2断点
01045FAA |E8 5D000000 CALL 0104600C
01045FAF |0183 EC000000 ADD DWORD PTR DS:[EBX+EC], EAX
01045FB5 |B0 01 MOV AL, 1
01045FB7 |83C4 24 ADD ESP, 24
01045FBA |5D POP EBP ; BeeIcons.0040129D
01045FBB |5F POP EDI
01045FBC |5E POP ESI
01045FBD |5B POP EBX
01045FBE |C3 RETN
01045FBF |90 NOP
01045FC0 \53 PUSH EBX
01045FC1 51 PUSH ECX
01045FC2 B9 00916400 MOV ECX, 649100
01045FC7 8339 00 CMP DWORD PTR DS:[ECX], 0
01045FCA 75 06 JNZ SHORT 01045FD2
01045FCC C701 10916400 MOV DWORD PTR DS:[ECX], 649110 ; 保存相关地址数据的起始地址
01045FD2 8B19 MOV EBX, DWORD PTR DS:[ECX]
01045FD4 4D DEC EBP ; BeeIcons.0040129D
01045FD5 892B MOV DWORD PTR DS:[EBX], EBP ; BeeIcons.0040129D
01045FD7 83C3 04 ADD EBX, 4
01045FDA 8919 MOV DWORD PTR DS:[ECX], EBX
01045FDC 45 INC EBP ; BeeIcons.0040129D
01045FDD 59 POP ECX
01045FDE 5B POP EBX
01045FDF 8945 00 MOV DWORD PTR SS:[EBP], EAX
01045FE2 ^ EB 9A JMP SHORT 01045F7E
_______________________________END___________________________________________
保存好全部数据后,F9再次发生INT3异常中断:
0103700B 90 NOP ; INT 3异常中断
0103700C EB 01 JMP SHORT 0103700F
0103700E 6966 81 FE47467>IMUL ESP, DWORD PTR DS:[ESI-7F], 7446>
01037015 05 31C040EB ADD EAX, EB40C031
0103701A 0231 ADD DH, BYTE PTR DS:[ECX]
0103701C C031 DB SAL BYTE PTR DS:[ECX], 0DB ; Shift constant out of range 1..31
0103701F 64:8F03 POP DWORD PTR FS:[EBX] ; 0012FF20
01037022 83C4 04 ADD ESP, 4
01037025 EB 01 JMP SHORT 01037028
01037027 E8 5F5E5BC3 CALL C45ECE8B
0103702C 51 PUSH ECX
0103702D 52 PUSH EDX
0103702E 53 PUSH EBX
0103702F 56 PUSH ESI
01037030 57 PUSH EDI
01037031 E8 01000000 CALL 01037037
01037036 - E9 5831C031 JMP 32C3A193
0103703B D2B9 03000000 SAR BYTE PTR DS:[ECX+3], CL
01037041 BE 8F700301 MOV ESI, 103708F ; ASCII " \\.\SICE"
01037046 EB 01 JMP SHORT 01037049
01037048 69AC50 516A0068>IMUL EBP, DWORD PTR DS:[EAX+EDX*2+680>
01037053 6A 03 PUSH 3
01037055 6A 00 PUSH 0
01037057 6A 01 PUSH 1
01037059 EB 01 JMP SHORT 0103705C
0103705B E8 68000000 CALL 010370C8
01037060 8056 E8 A5 ADC BYTE PTR DS:[ESI-18], 0A5
01037064 E6 FE OUT 0FE, AL ; I/O command
01037066 FF59 5A CALL FAR FWORD PTR DS:[ECX+5A] ; Far call
01037069 40 INC EAX
0103706A 75 0C JNZ SHORT 01037078
0103706C 01D6 ADD ESI, EDX
0103706E EB 02 JMP SHORT 01037072
01037070 CD 20 INT 20
01037072 ^ E2 D2 LOOPD SHORT 01037046
01037074 31C0 XOR EAX, EAX
01037076 EB 0D JMP SHORT 01037085
01037078 48 DEC EAX
01037079 50 PUSH EAX
0103707A E8 85E6FEFF CALL 01025704 ; JMP to kernel32.CloseHandle
0103707F EB 01 JMP SHORT 01037082
01037081 0F31 RDTSC
01037083 C040 5F 5E ROL BYTE PTR DS:[EAX+5F], 5E ; Shift constant out of range 1..31
01037087 EB 01 JMP SHORT 0103708A
01037089 C7 ??? ; Unknown command
0103708A 5B POP EBX ; 0012FF20
0103708B 5A POP EDX ; 0012FF20
0103708C 59 POP ECX ; 直接在这里下F2断点
0103708D C3 RETN
0103708E 9A 095C5C2E 5C5>CALL FAR 535C:2E5C5C09 ; Far call
01037095 49 DEC ECX
01037096 43 INC EBX
01037097 45 INC EBP
在0103708C处下断,shift+f9一次中断,断下后在code段下断,断下后可以看到OEP了:
00569594 55 PUSH EBP ; OEP
00569595 8BEC MOV EBP, ESP
00569597 83C4 F0 ADD ESP, -10
到了OEP处后,像前面的文章一样,找到保存相关地方:
01022544 85C0 TEST EAX, EAX
01022546 > 74 0A JE SHORT 01022552
01022548 FF15 18900401 CALL DWORD PTR DS:[1049018] ;这里改成我们自己的代码
0102254E 09C0 OR EAX, EAX
01022550 74 01 JE SHORT 01022553
......
012800A0 9D POPFD
012800A1 5C POP ESP
012800A2 FF6424 FC JMP DWORD PTR SS:[ESP-4] ;这里设置硬件断点用于写上我们自己的代码
012800A6 54 PUSH ESP
因为这个程序里的IAT是部分加密处理过的,所以相对来说处理会麻烦一点,这个要靠自己去想怎么去解决,我的处理方法比较麻烦。可能有更好的方法,我现在还没有想到:-(.再写上一段代码和一段脚本,然后运行脚本就可以了:
________________________-相关代码_________________________________
005695D0 . 60 PUSHAD
005695D1 . B9 10916400 MOV ECX, 00649110 ; 调用call address的位置
005695D6 > 8339 00 CMP DWORD PTR DS:[ECX], 0
005695D9 . 74 17 JE SHORT 005695F2
005695DB . 8B19 MOV EBX, DWORD PTR DS:[ECX] ; ntdll.7C92E64E
005695DD .- FFE3 JMP EBX ; 跳去执行原call
005695DF . 66:C703 FF15 MOV WORD PTR DS:[EBX], 15FF ; 改写成call [addr]
005695E4 . 8B15 08916400 MOV EDX, DWORD PTR DS:[649108] ; <&comdlg32.ChooseColorA>
005695EA . 8953 02 MOV DWORD PTR DS:[EBX+2], EDX ; ntdll.KiFastSystemCallRet
005695ED . 83C1 04 ADD ECX, 4
005695F0 .^ EB E4 JMP SHORT 005695D6
005695F2 > 33C0 XOR EAX, EAX ; 修复为jmp [addr]的部分
005695F4 . B9 CC951600 MOV ECX, 1695CC
005695F9 . BF 00104000 MOV EDI, 00401000
005695FE > B0 E8 MOV AL, 0E8
00569600 > F2:AE REPNE SCAS BYTE PTR ES:[EDI]
00569602 . 83F9 00 CMP ECX, 0
00569605 . 74 2C JE SHORT 00569633
00569607 . 8B1F MOV EBX, DWORD PTR DS:[EDI]
00569609 . 8D5C3B 04 LEA EBX, DWORD PTR DS:[EBX+EDI+4]
0056960D . 81FB 00104000 CMP EBX, 00401000
00569613 .^ 72 EB JB SHORT 00569600
00569615 . 81FB C7955600 CMP EBX, 005695C7 ; 判断是否符合修复条件
0056961B .^ 77 E3 JA SHORT 00569600
0056961D . 66:8B03 MOV AX, WORD PTR DS:[EBX]
00569620 . 66:3D FF15 CMP AX, 15FF
00569624 . 75 0B JNZ SHORT 00569631
00569626 . 66:C703 FF25 MOV WORD PTR DS:[EBX], 25FF
0056962B . 83C7 04 ADD EDI, 4
0056962E . 83E9 04 SUB ECX, 4
00569631 >^ EB CB JMP SHORT 005695FE
00569633 > 61 POPAD
00569634 . 90 NOP
00569635 . 90 NOP
00569636 . 90 NOP
00569637 . 90 NOP
00569638 . 90 NOP
00569639 . 90 NOP
0056963A . 90 NOP
0056963B . 90 NOP
0056963C . 90 NOP
0056963D . 90 NOP
0056963E . 90 NOP
0056963F . 90 NOP
00569640 . 48965600 DD dumped_.00569648
00569644 00 DB 00
00569645 00 DB 00
00569646 00 DB 00
00569647 00 DB 00
00569648 90 NOP
00569649 . 60 PUSHAD
0056964A . BD 00916400 MOV EBP, 00649100
0056964F . 90 NOP
00569650 . 8B4D 04 MOV ECX, DWORD PTR SS:[EBP+4]
00569653 . 0BC9 OR ECX, ECX
00569655 . 75 18 JNZ SHORT 0056966F ; 这里修复和上两篇有所不同,这篇里的iat是加密处理过的
00569657 . B9 C4E05700 MOV ECX, <&kernel32.GetFileType> ; 对于修复加密的输入表,我采用脚本+代码的方式
0056965C . 8911 MOV DWORD PTR DS:[ECX], EDX ; 来修复输入表
0056965E . 894D 08 MOV DWORD PTR SS:[EBP+8], ECX
00569661 . 83C1 04 ADD ECX, 4
00569664 . 894D 04 MOV DWORD PTR SS:[EBP+4], ECX
00569667 . 90 NOP
00569668 . 90 NOP
00569669 . 90 NOP
0056966A . 90 NOP
0056966B . 90 NOP
0056966C . 90 NOP
0056966D . EB 45 JMP SHORT 005696B4
0056966F > 8BF1 MOV ESI, ECX
00569671 . 81E9 C4E05700 SUB ECX, <&kernel32.GetFileType>
00569677 . C1E9 02 SHR ECX, 2
0056967A . 8BC2 MOV EAX, EDX ; ntdll.KiFastSystemCallRet
0056967C . BF C4E05700 MOV EDI, <&kernel32.GetFileType>
00569681 . F2:AF REPNE SCAS DWORD PTR ES:[EDI]
00569683 . 0BC9 OR ECX, ECX
00569685 . 74 08 JE SHORT 0056968F
00569687 . 83EF 04 SUB EDI, 4
0056968A . 897D 08 MOV DWORD PTR SS:[EBP+8], EDI ; ntdll.7C930738
0056968D . EB 25 JMP SHORT 005696B4
0056968F > 90 NOP
00569690 90 NOP ; 写好脚本和这里的代码后,先在这里下f2断
00569691 . 90 NOP ; 用于脚本判断是否为相同的DLL
00569692 . 90 NOP
00569693 . 90 NOP
00569694 . 90 NOP
00569695 . 0BD2 OR EDX, EDX ; 通过脚本判断是否为相同的DLL,如果相同edx=0不同edx=1
00569697 . 75 0D JNZ SHORT 005696A6
00569699 . 8906 MOV DWORD PTR DS:[ESI], EAX
0056969B . 8975 08 MOV DWORD PTR SS:[EBP+8], ESI
0056969E . 83C6 04 ADD ESI, 4
005696A1 . 8975 04 MOV DWORD PTR SS:[EBP+4], ESI
005696A4 . EB 0E JMP SHORT 005696B4
005696A6 > 83C6 04 ADD ESI, 4
005696A9 . 8906 MOV DWORD PTR DS:[ESI], EAX
005696AB . 8975 08 MOV DWORD PTR SS:[EBP+8], ESI
005696AE . 83C6 04 ADD ESI, 4
005696B1 . 8975 04 MOV DWORD PTR SS:[EBP+4], ESI
005696B4 > 61 POPAD
005696B5 . FF15 18900401 CALL DWORD PTR DS:[1049018] ; 执行原壳的代码
005696BB . C3 RETN
_____________________END_____________________________________
____________________相关脚本_________________________________
//fix1
var dll1
var dllnow
var addr
start:
run
l1:
cmp eip,569690 //跳去处理是否为同一DLL
je l2
cmp eip,0012800c5 //判断是否为jmp [esp-4]处
je l6
ret
l2:
gn edx
mov dllnow,$RESULT_1
cmp dll1,0
jne l3
mov dll1,dllnow
l3:
cmp dll1,dllnow
jne l4
mov edx,0
jmp l5
l4:
mov dll1,dllnow
mov edx,1
l5:
sto
jmp start
l6:
mov addr,esp
sub addr,4
mov [addr],5695df //修改eip
jmp start
_____________________END_____________________________________
写好了上面的东西,运行脚本,用importrec修复输入表时,有一个是GetProcAddress:
00407784 - FF25 28B45700 JMP DWORD PTR DS:[57B428]
把这个API修复好,其它无效的直接cut掉,分两次就可以把iat获取并修复好。
修复好程序并不能够运行的。通过运行发现下面的地方,就是检测是否被壳的相关地址:
0055B03B . E8 7498FDFF CALL 005348B4 ; CreateFileA
0055B040 3D A66D0D00 CMP EAX, 0D6DA6 ; 判断文件大小?
0055B045 0F8E 8B000000 JLE 0055B0D6 ; 如果小于或等于则跳,正常这里是跳的
因为考虑到处理反脱壳检测可能会比较麻烦,所以我直接改CreateFileA为原来没有脱壳的文件名,这样就可以通过检测,操作好后,还有一个段被抽在程序里,直接用lordpe添加段进去。这样子程序就可以运行了,不过可惜的,按菜单功能的时间还是会异常退出:-(,唉不脱了,再脱真的是脱皮而不是脱壳了。
ASProtect SKE 2.X +代码变形 (實例)
【破解作者】 SYSCOM
【使用工具】 Ollydbg1.10, LordPE,ImportREC1.65,PEid 0.93
【破解平台】 Windows XP SP1
【软件名称】 BetterJPEG 1, 4, 4, 0
【下载地址】 http://www.betterjpeg.com/
【软件简介】 Edit JPEG photos
【加壳方式】 ASProtect SKE 2.X
【破解声明】 我是一只小菜鸟,偶得一点心得,愿与大家分享:)
--------------------------------------------------------------------------------
(1) 用ollydbg 载入BetterJPEG.exe ,设置忽略所有异常。
在命令栏输入
BP GetVersion ,按 F9,看 STACK 返回 431EE4 ,在按 ALT+F9
返回,主程式 ,往上看.....不远地方
431EB8-PUSH EBP <======= OEP 进入点
431EB9-MOV EBP,ESP
431EBB-PUSH -1
.....
.....
(2)修正 Import Table and .CODE 写入补丁 PATCH(1)
先修正 9F4387-PUSH 9F43A4==>PUSH PATCH(1)+0x29 Offset Address
//********************** Start of Code in Object BinaryCode **************
:00000000 mov edx, 00401000 ;主程式 Start address
:00000005 cmp byte ptr [edx], E8 ;判断是否为 call 指令
:00000008 jne 0000001E
:0000000A mov eax, dword ptr [edx+01]
:0000000D add eax, edx
:0000000F add eax, 00000005
:00000014 cmp eax, 00CD0000 ;判断是否为 call API 加密,进入点
:00000019 jne 0000001E
:0000001B pushad ;保存所有暂存器
:0000001C jmp edx
:0000001E inc edx
:0000001F cmp edx, 00461000 ;主程式 end address
:00000025 jbe 00000005
:00000027 jmp 00000027 ;PATCH END
:00000029 mov ecx, 00461000 ;IAT start address (解码返回进入点)
:0000002E mov edx, dword ptr [ebp-0C]
:00000031 cmp dword ptr [ecx], edx
:00000033 jne 00000052
:00000035 mov dword ptr [00460800], ecx ;暂存 Import Address
:0000003B add esp, 0000023C
:00000041 popad ;取回所有暂存器
:00000042 mov ebx, dword ptr [00460800] ;取出 Import Address
:00000048 mov dword ptr [edx+02], ebx ;修正 Import Address
:0000004B mov word ptr [edx], 15FF ;修正 CALL
:00000050 jmp 0000001E
:00000052 add ecx, 00000004
:00000055 cmp ecx, 004616AC ;IAT End address
:0000005B jl 00000031
:0000005D jmp 0000005D
(3)写入补丁 PATCH(2)
//********************** Start of Code in Object BinaryCode **************
:00000000 mov edx, 00401000 ;主程式 Start address
:00000005 cmp byte ptr [edx], E8 ;判断是否为 call 指令
:00000008 jne 00000030
:0000000A mov eax, dword ptr [edx+01]
:0000000D add eax, edx
:0000000F add eax, 00000005
:00000014 cmp eax, 00401000 ;判断是否为 > 401000
:00000019 jb 00000030
:0000001B cmp eax, 00461000 ;判断是否为 < 461000
:00000020 ja 00000030
:00000022 mov bx, word ptr [eax]
:00000025 cmp bx, 15FF ;判断是否为 call 指令
:0000002A jne 00000030
:0000002C mov [eax+01], 25 ;修正 CALL =>JMP
:00000030 inc edx
:00000031 cmp edx, 00461000 ;主程式 End address
:00000037 jne 00000005
:00000039 jmp 00000039
(4) PATCH 完后,Dump BetterJPEG_dump.exe
(5)run BetterJPEG.exe 在用 ImportREC 抓出 Import
并修复 kernel32,中一个无效指针,改为 GetProcAddress
再修正,RestoreLastError ==>SetLastError (98/XP/NT4/2003 相容)
(6)使用 lordPE DUMP 变形程式,MEMORY 区块
并附加在 BetterJPEG_dump.exe,的后面
ADDRESS: SIZE SET
-----------------------------------
9D0000 32000 RWE
A64000 10000 RWE
C80000 1000 RWE
D10000 1000 RWE
D30000 2000 RWE
D40000 2000 RWE
D50000 1000 RWE
D60000 1000 RWE
-----------------------------------
(7)修正 Route CHECK
9F70CE-MOV EAX,[EAX+34] => 9F70CE-NOP
9F70D1-CALL EAX => 9F70CF-NOP
9FD0D3-SUB [EBP+C],EAX => 9F70D0-MOV EAX,[ESP+58]
9FD0D6-MOV EAX,[ENP+C] => 9F70D4-SUB EAX,5
(9)OK->TEST->RUN BetterJPEG_dump.exe
总结:
找oep很简单的,直接到最后一个异常后找到离返回处最近的那个call进去-->执行一次到返回(ctrl+f9),
如果没有抽代码,进去后jmp eax就是跳去oep,如果抽代码ctrl+f9后就是stolen code的开始处
剛剛試了一個軟件結果出現一個ERROR視窗內容如下:
OS: Windows XP Professional, SP2
CPU: AuthenticAMD, AMD AMD Athlon(tm) , MMX @ 2480 MHz
Application data:
VmVyc2lvbjogVWtSdWJXUmtZWFlwSlZCamRYUmhaMmNFQURnbE95eHV
lR1JpYWk4L0lUNGdJakpBZG45eGRXWndPQT09DQpJbWFnZUJhc2U6ID
AwNDAwMDAwDQpFaXA6IDE2N0U5MDYNCkVheDogRTg1MUQ4QkYNCkVje
DogMA0KRWR4OiAxM0ZGODANCkVieDogRTg1MUQ4QkYNCkVzaTogMTZC
MDc0Qw0KRWRpOiAxNjUwMDAwDQpFYnA6IDEzRkY5OA0KRXNwOiAxM0Z
GMzgNCkVycm9yQ29kZTogDQo4MyxDNCw0LDhELEMsNyw1OSxBMSw0OC
w0OCw2OCwxLDhCLDAsOEIsNjgsMUMsQTEsNDgsNDgsNjgsMSw4QiwwL
DhCLDAsODksNDQsMjQsNCxBMSw0OCw0OCw2OCwxLDhCLDAsOEQsNzgs
MTgsQTEsQjgsNDcsNjgsMSw4OCw1OCw4LDgzLDNGLDAsMC4uLg0KQ29
kZSA9IFsyMzddDQotIDIwDQotIDIwOA0KLSAwDQotIDANCi0gW10NCj
4gRDpcVzgwMElcYWFhXGNsaWVudFxjbGllbnQxNC5leGUNCj4gQzpcV
會出現這個訊息,就是你被 aspr 偵測發現,使用 debug
不可亂下 BP ,會被發現的...............
我沒有下bp呀~~
只是照著loveboom大大說的方法到了最後一次異常處,找到离返回处最近的那个call进去
,從異常那個位置要到call的地方就過不去了,在od左下角提示shift+f7 f8 f9
按了shift+f7就會跑到地址7c92eaf0去,這是正常的嗎?
以上問題已解決!
只要再离返回处最近的那个call先下F2斷點,在SHIFT+F9,就會停在那了,然後再F7進去! |
本帖子中包含更多资源
您需要 登录 才可以下载或查看,没有账号?加入我们
x
|