[分享]ASPr 2.0.06.23 Alpha另一种法子脱壳(Import Recovery&补区段&Script)
发表于:
2007-4-13 09:29
12804
[分享]ASPr 2.0.06.23 Alpha另一种法子脱壳(Import Recovery&补区段&Script)
【文章标题】: ASPr 2.0.06.23
Alpha 另一种法子脱壳(Import Recovery&补区段&Script)
【文章作者】: wynney
【下载地址】: 附件下载
【操作平台】: XP SP2 64位双核
【作者声明】: ASPr
2.0Alpha 两个分支的处理
--------------------------------------------------------------------------------
【详细过程】
一、前言
前几天似乎在论坛上看到一个程序就是
2.0Alpha 的,volx大侠的脚本不支持,遂连同1.31一并看了下,发现1.31和2.0Alpha
基本上差不多,稍有不同。
二、“探听军情”
忽略除了内存访问异常和指定异常之外的所有异常
到达最后一次异常后在Code段下断,Shift+F9,中断在Code段后
易发现输入表是Call类型的,而且有Stolen OEP,这就是我们要探听的军情了
三、输入表处理
请忽略所有异常
bp VirtualAlloc,Shift+F9,中断两次,取消断点
Alt+F9一次
接着
Ctrl+F9一次
00AA8000 90 nop ; 返回到这 00AA8001 60 pushad ; 看到这,突想到某大侠说过ASProtect=ASPcak+dll 00AA8002 E8 40060000 call 00AA8647 ; F8到这,hr esp 00AA8007 EB 44 jmp short 00AA804D 00AA8009 0000 add byte ptr [eax], al 00AA800B 0000 add byte ptr [eax], al
Shift+F9
00AA85C2 /75 08 jnz short 00AA85CC ; Shift+F9 中断在这,删除断点 00AA85C4 |B8 01000000 mov eax, 1 00AA85C9 |C2 0C00 retn 0C 00AA85CC \68 788FA900 push 0A98F78 00AA85D1 C3 retn
1、
Ctrl+B:8A 00 FF 43 08
00A8CC8A /75 1A jnz short 00A8CCA6 ; IAT处理完就跳 00A8CC8C |EB 01 jmp short 00A8CC8F 00A8CC8E |698B C7E8CE58 F>imul ecx, dword ptr [ebx+58CEE> 00A8CC98 |E9 1B040000 jmp 00A8D0B8 00A8CC9D -|E9 E9150400 jmp 00ACE28B 00A8CCA2 |00EB add bl, ch 00A8CCA4 |01E8 add eax, ebp 00A8CCA6 \337424 28 xor esi, dword ptr [esp+28] 00A8CCAA 0373 40 add esi, dword ptr [ebx+40] 00A8CCAD 8B43 08 mov eax, dword ptr [ebx+8] 00A8CCB0 8A00 mov al, byte ptr [eax] ; 找到这,F2,Shift+F9 中断下来,删除断点 00A8CCB2 FF43 08 inc dword ptr [ebx+8] 00A8CCB5 33D2 xor edx, edx 00A8CCB7 8AD0 mov dl, al 00A8CCB9 8BC7 mov eax, edi
2、
Ctrl+B:8B 54 24 0C 89 02 8B 44 24 0C 89 06 0F B7 44 24 04 01 43 08
00A8CEAD 8B5424 0C mov edx, dword ptr [esp+C] ; 找到这 00A8CEB1 8902 mov dword ptr [edx], eax ; ①ebp里才是IAT,把eax改成ebp 00A8CEB3 8B4424 0C mov eax, dword ptr [esp+C] 00A8CEB7 8906 mov dword ptr [esi], eax 00A8CEB9 0FB74424 04 movzx eax, word ptr [esp+4] 00A8CEBE 0143 08 add dword ptr [ebx+8], eax
3、
Ctrl+B:53 8B D8 8B C3 E8 ?? ?? ?? ?? C6 03 E8 43 89 03 5B C3
00A83780 53 push ebx ; ②找到这,Patch这里 00A83781 8BD8 mov ebx, eax 00A83783 8BC3 mov eax, ebx 00A83785 E8 56FFFFFF call 00A836E0 00A8378A C603 E8 mov byte ptr [ebx], 0E8 ; 这里是IAT加密,给改成E8了 00A8378D 43 inc ebx 00A8378E 8903 mov dword ptr [ebx], eax 00A83790 5B pop ebx 00A83791 C3 retn 3
以下是Patch代码
00A83780 66:C700 FF15 mov word ptr [eax], 15FF ; Call类型的,第二步探听到的,呵呵,如果是jmp类型的把15FF改成25FF即可 00A83785 83C0 02 add eax, 2 00A83788 8910 mov dword ptr [eax], edx 00A8378A 892A mov dword ptr [edx], ebp ; ebp是正确的IAT 00A8378C 90 nop 00A8378D 90 nop 00A8378E 90 nop 00A8378F 90 nop 00A83790 90 nop 00A83791 C3 retn 66 C7 00 FF 15 83 C0 02 89 10 89 2A 90 90 90 90 90 C3
另外判断是Jmp还是Call类型的方法
Ctrl+B:8B 54 24 0C 89 02 8D 4C 24 0C 8A 54 24 07 8B C3
00A8CDD1 8B5424 0C mov edx, dword ptr [esp+C] ; 找到这 00A8CDD5 8902 mov dword ptr [edx], eax 00A8CDD7 8D4C24 0C lea ecx, dword ptr [esp+C] 00A8CDDB 8A5424 07 mov dl, byte ptr [esp+7] ; [esp+7]为1则jmp[xxxxxxxx]类型,为2则Call[xxxxxxxx]类型 00A8CDDF 8BC3 mov eax, ebx 00A8CDE1 E8 FAF7FFFF call 00A8C5E0 00A8CDE6 8BC6 mov eax, esi 00A8CDE8 83E8 02 sub eax, 2
4、
Ctrl+B:C6 03 E9 8D 53 01 89 02 8B 45 08 89 10 B8 05 00 00 00 5B 5D C2 04 00
00A83767 C603 E9 mov byte ptr [ebx], 0E9 ; 找到这,F2打个埋伏,为了找方便伪OEP 00A8376A 8D53 01 lea edx, dword ptr [ebx+1] 00A8376D 8902 mov dword ptr [edx], eax 00A8376F 8B45 08 mov eax, dword ptr [ebp+8] 00A83772 8910 mov dword ptr [eax], edx 00A83774 B8 05000000 mov eax, 5 00A83779 5B pop ebx 00A8377A 5D pop ebp 00A8377B C2 0400 retn 4
四、到达伪OEP&补区段
做了上述2处Patch后,Shift+F9,中断在00A83767,删除断点,注意看ECX=00CE0178
这个地址就是Stolen Code的起始地址
Ctrl+G:00CE0178
00CE0178 55 push ebp ; 伪OEP,F2,Shift+F9,中断后删除断点 00CE0179 89E5 mov ebp, esp 00CE017B 6A FF push -1 00CE017D F3: prefix rep: 00CE017E EB 02 jmp short 00CE0182 00CE0180 CD20 FF74241C vxdcall 1C2474FF 00CE0186 66:9C pushfw 00CE0188 51 push ecx 00CE0189 81C1 CED3EF23 add ecx, 23EFD3CE
补上这么几个区段
Region00920000-00928000.DMP
Region00AB0000-00AC8000.DMP
Region00BB0000-00C00000.DMP
Region00CE0000-00CE1000.DMP
修改虚拟地址后,最后只选上“验证PE”重建PE!
想完美恢复Stolen OEP的话,就根据程序语言特征从这里慢慢分析吧:)
五、ImportREC上阵
按照如图所示操作
如若想顺便解决下跨平台的问题的话,就纠正几个ntdll.dll函数为kernel32.dll函数
ntdll.dll kernel32.dll
*********************************************************
RtlUnwind RtlUnwind
RtlFreeHeap HeapFree
RtlAllocateHeap HeapAlloc
RtlGetLastWin32Error GetLastError
纠正OEP为8E0178,修复!
最后优化下文件吧
附上简单的修复脚本吧
请忽略所有异常,否则用不了,没测试其他平台如何
/* Script written by wynney Date: 2007-04-12 Script:ASProtect 2.0 Alpha Simple Fixer Environment : OllyDbg 1.1, ODBGScript 1.52,Winxp Sp2 Debugging options: Tick all items in OllyDbg's Debugging Options-Exceptions Thanks : kanxue - author of HideOD hnhuqiong - author of ODbgScript 1.52 */ var API var PatchAddr var ImagBase var ImagSize var CBase var CSize var Dll var DllBase var Addr var 1st var 2nd var end var Start var temp var SC var fix //获取基址 GetBase: dbh BPHWCALL GMI eip, ModuleBase cmp $RESULT,0 je error mov ImagBase,$RESULT GMI eip,ModuleSize cmp $RESULT,0 je error mov ImagSize,$RESULT GMI eip,CodeBase cmp $RESULT,0 je error mov CBase,$RESULT GMI eip, CodeSize cmp $RESULT,0 je error mov CSize,$RESULT //进入Dll Getloader: GPA "GetModuleHandleA","kernel32.Dll" cmp $RESULT,0 je error mov API,$RESULT bphws API,"x" esto esto bphwc API RTU mov DllBase,eax find eip,#617508B801000000C20C0068????????C3# cmp $RESULT,0 je error mov temp,$RESULT bp temp esto bc temp mov PatchAddr,[esp] mov fix,[esp] mov temp,esp bphws temp,"r" esto bphwc temp FindAddr: find eip,#C603E98D530189028B45088910B8050000005B5DC20400# cmp $RESULT,0 je error mov SC,$RESULT find eip,#8BC0538BD88BC3E8????????C603E84389035BC3# cmp $RESULT,0 je error mov 2nd,$RESULT add 2nd,0C find eip,#8A00FF430833D28AD08BC7# cmp $RESULT,0 je error mov temp,$RESULT bp temp esto bc temp sub temp,03D mov Start,temp find eip,#83C4??5D5F5E5BC3# cmp $RESULT,0 je error mov end,$RESULT add end,7 SetData: mov Dll,PatchAddr mov [Dll],DllBase mov Addr,PatchAddr add Addr,08 mov temp,CBase add temp,CSize mov [Addr],temp Patch1st: find eip,#8B44240C89060FB7442404014308# cmp $RESULT,0 je error mov 1st,$RESULT add PatchAddr,11 mov [PatchAddr],#51528B54241C3B150000A700740D89150000A70083050800A700048B0D0800A7008929890E83050800A700045A596890909090C390# eval "jmp {PatchAddr}" asm 1st,$RESULT add 1st,5 fill 1st,1,90 add 1st,1 add PatchAddr,2F mov [PatchAddr],1st Patch2nd: add PatchAddr,6 mov [PatchAddr],#51528B5424243B150000A700740D89150000A70083050800A700048B0D0800A7008929890E83050800A7000466C703FF15807C241702740566C703FF255A596890909090C390# eval "jmp {PatchAddr}" asm 2nd,$RESULT add 2nd,5 fill 2nd,1,90 add 2nd,1 add PatchAddr,40 mov [PatchAddr],2nd FixData: add fix,19 mov [fix],Dll add fix,8 mov [fix],Dll add fix,6 mov [fix],Addr add fix,7 mov [fix],Addr add fix,0A mov [fix],Addr add fix,16 mov [fix],Dll add fix,8 mov [fix],Dll add fix,6 mov [fix],Addr add fix,7 mov [fix],Addr add fix,0A mov [fix],Addr Final: bphws end,"x" esto BPHWCALL BPRM CBase,CSize esto BPMC bphws SC,"x" jmp Done HavSC: BPHWCALL mov temp,ecx bp temp esto bc temp jmp OK Done: cmp eip,SC je HavSC MSGYN "请检查是否是OEP?" cmp $RESULT,1 je OK esto jmp HavSC OK: BPHWCALL cmt eip,"OEP" msg "脚本完成,请使用ImportREC的高级指令修复输入表^_^" ret error: msg "错误退出:(" ret
--------------------------------------------------------------------------------
【经验总结】
1、思路在于人想出来的:)
2、本想写一个支持1.31和2.0 Alpha的脚本的,写起来才发现,要做到通用还是蛮要点时间的,对Volx大侠的敬佩之情由然
而生啊
--------------------------------------------------------------------------------
【版权声明】: 本文原创于看雪技术论坛, 转载请注明作者并保持文章的完整, 谢谢!
2007年04月12日 wynney
[课程]Android-CTF解题方法汇总!
上传的附件: