好友
阅读权限255
听众
最后登录1970-1-1
|
Peace
发表于 2009-8-27 08:38
本帖最后由 peace2008 于 2009-8-27 08:44 编辑
作者: Fly
脱壳最佳时机——甲壳试用版.V1.0主程序完美脱壳
http://www.unpack.cn/viewthread.php?tid=39660
甲壳加密引擎完全自主开发,采用了大量自主研发的新型技术,加密强度达到了前所未有的水平,基本上一个月一次大更新,因为开发者拥用超强的开发能力,用户不用为升级担心。这个壳因为花了很多时间和精力。 代码:[甲壳试用版.V1.0 -> 无名氏 * Sign.By.fly * 20090823]
signature = E9 15 AC 00 00 00 00 E9 ED 3A 01 00 00 00 E9 A1 9A 01 00 00 00 E9 CD 76 02 00 00 00 E9 8D FA 01 00 00 00 E9 CB 04 00 00 00 00 E9 A4 9F 00 00 00 00 66 B8 00 02 66 85 C0 0F 85 F0 5E 04 00 00 00 00 00 00 00 00 00 66 B8 00 00 E9 73 8F 02 00 00 00 00 00 00 E9 1A 57 03 00 00 00 E9 35 4E 04 00 00 00 E9 74 9D 00 00 00 00 E9 44 4D 02 00 00 00 E9 9B F2 03 00 00 00 E9 8B 63 03 00 00 00 E9 06 95 01 00 00 00 E9 77 7D 03 00 00 00 B0 02 E9 74 BB 02 00 00 00 00 00 00 00 00 E9 3C E5 03 00 00 00 E9 F4 83 02 00 00 00 E9 9D 9F 00 00 00 00 E9 72 CB 00 00 00 00 E9 88 C2 00 00 00 00 E9 42 3B 04 00 00 00 E9 F4 4C 00 00 00 00 E9 B8 28 04 00 00 00 E9 0F 4F 00 00 00 00 66 83 E8 00 E9 02 F4 00 00 00 00 00 00 00 84 C0 E9 B9 90 01 00 00 00 00 00 00 00 00 E9 78 C5 02 00
ep_only = true
_____________________________________________________________
〇.序言
UpK软件安全社区对于壳等软件保护系统一向是支持的,大家玩调试玩分析从逆向的另个角度来说何尝不是在做免费的安全测试?希望作者可以从教程中看到有待改进的地方然后予以加强,这样就是个互相促进发展的游戏。和甲壳的作者也简单聊过,大家写程序都不容易,玩调试也不容易,摆正心态学习别人的分析过程从而找到短板然后增强,这样的游戏才有意思。
另外手动脱壳这两年有衰落的趋势,一个重要的因素是新手的青黄不接,学习是自己的事,为了兴趣学习更是如此。通过阅读学习别人的教程,自己跟随练习,熟练后自己摸索属于自己的脱壳方法,把复杂的流程简单化,找到自己的最优流程,也就出道了。
_____________________________________________________________
一.脱壳最佳时机 引用:
问题:何谓脱壳最佳时机?
解答:手动脱壳理想的最佳dump时机是指壳已经把程序代码包括资源等数据全部解密、输入表等数据还原但还未填充系统函数地址、DLL则还未重定位,此时dump出来的文件只需修正OEP、ImportTableRVA等信息即可正常运行完成脱壳。
答者:fly
日期:2008.01.23
甲壳的Anti用StrongOD或者PhantOm都可以搞定,就不细看了。StrongOD设置如下:
设置OllyDbg暂停在系统断点,载入甲壳试用版.exe,去除之前有可能的所有断点
Alt+M打开内存查看窗口,在其第3区段004E6000上设置内存写入断点。为何要在第3区段?因为LordPE看其RVA=00001000的Vsize是0
Shift+F9,中断后取消断点 代码:007CC6E6 8801 mov byte ptr ds:[ecx],al
//内存写入断点中断在这里,中断后取消断点
007CC6E8 EB 03 jmp short 007CC6ED
下面F7吧 这个版本的壳只要你会F7就能脱壳了
也可以搜索特定码: 代码:cmp ecx,dword ptr ss:[ebp-34]
cmp ecx,dword ptr ss:[ebp-14]
找到后自下面的判断跳转处过去,然后F4到达那里走出解码循环 代码:007CC6ED EB 01 jmp short 007CC6F0
007CC6F0 8B4D E4 mov ecx,dword ptr ss:[ebp-1C]
007CC6F3 8A55 E3 mov dl,byte ptr ss:[ebp-1D]
007CC6F6 8811 mov byte ptr ds:[ecx],dl
007CC6F8 EB 03 jmp short 007CC6FD
007CC6FD EB 01 jmp short 007CC700
007CC700 8B45 E4 mov eax,dword ptr ss:[ebp-1C]
007CC703 83E8 01 sub eax,1
007CC706 8945 E4 mov dword ptr ss:[ebp-1C],eax
007CC709 EB 02 jmp short 007CC70D
007CC70D EB 02 jmp short 007CC711
007CC711 EB 02 jmp short 007CC715
007CC715 EB 02 jmp short 007CC719
007CC719 EB 94 jmp short 007CC6AF
//循环解码
007CC6AF 8B45 C4 mov eax,dword ptr ss:[ebp-3C]
007CC6B2 83C0 01 add eax,1
007CC6B5 8945 C4 mov dword ptr ss:[ebp-3C],eax
007CC6B8 8B4D C4 mov ecx,dword ptr ss:[ebp-3C]
007CC6BB 3B4D CC cmp ecx,dword ptr ss:[ebp-34]
007CC6BE 73 5B jnb short 007CC71B
//解码完毕则跳转
007CC6C0 EB 03 jmp short 007CC6C5
007CC71B EB 02 jmp short 007CC71F
//F4到这里
007CC71F EB 02 jmp short 007CC723
007CC723 E9 73FEFFFF jmp 007CC59B
007CC59B 8B45 C8 mov eax,dword ptr ss:[ebp-38]
007CC59E 83C0 01 add eax,1
007CC5A1 8945 C8 mov dword ptr ss:[ebp-38],eax
007CC5A4 8B4D C8 mov ecx,dword ptr ss:[ebp-38]
007CC5A7 3B4D EC cmp ecx,dword ptr ss:[ebp-14]
007CC5AA 0F83 78010000 jnb 007CC728
//继续循环解码
007CC5B0 EB 03 jmp short 007CC5B5
007CC728 EB 2F jmp short 007CC759
//F4到这里
007CC759 5E pop esi
007CC75A 8BE5 mov esp,ebp
007CC75C 5D pop ebp
007CC75D C3 retn
注意:到这里后解码完毕了,是最佳脱壳时机
为何知道到这里解码完毕了?很简单,加壳98记事本或者自己熟悉的程序作为试炼品调试一下,观察一下数据就知道了,所以拿到新壳先用98记事本作为记事本可以事半功倍的。
还等什么?运行LordPE来dump进程吧
其实目前甲壳的壳代码没有加密,整个脱壳过程都可以通过特定码来搞定,F7是让大家了解更多。
_____________________________________________________________
二.输入表
由于代码和输入表等数据都还原成原始数据,因此我们可以通过输入表函数名搜索IID表来定位ImportTable RVA
也可以继续F7下去 代码:007CB990 EB 02 jmp short 007CB994
007CB994 EB 02 jmp short 007CB998
007CB998 E8 D1040000 call 007CBE6E
007CB99D EB 03 jmp short 007CB9A2
007CB9A2 EB 01 jmp short 007CB9A5
007CB9A5 EB 03 jmp short 007CB9AA
007CB9AA EB 01 jmp short 007CB9AD
007CB9AD 50 push eax
007CB9AE EB 02 jmp short 007CB9B2
007CB9AD 50 push eax
007CB9AE EB 02 jmp short 007CB9B2
中间一段东西,你可以继续F7
但有更快的方法:特定码
Ctl+B在整个段块搜索甲壳试用版.V1.0的输入表处理特定码:8B 04 8A 05
找到2处都设断,Shift+F9,中断后取消断点 代码:007CB0E4 8B048A mov eax,dword ptr ds:[edx+ecx*4]
//中断在这里
//[edx+ecx*4]=[007C3AAA]=0032B6D8
007CB0E7 05 00004000 add eax,400000
//EAX=0032B6D8+00400000=0072B6D8
007CB0EC 8985 78FFFFFF mov dword ptr ss:[ebp-88],eax
007CB0F2 8B8D 74FFFFFF mov ecx,dword ptr ss:[ebp-8C]
007CB0F8 83C1 01 add ecx,1
007CB0FB 898D 74FFFFFF mov dword ptr ss:[ebp-8C],ecx
007CB101 EB 02 jmp short 007CB105
在数据窗口里面跟随:007C3AAA 代码:007C3AAA D8 B6 32 00 FC BB 32 00 E0 B2 32 00 AC B2 32 00
007C3ABA D8 C0 32 00 00 B2 32 00 6C BB 32 00 7C B2 32 00
007C3ACA B4 BB 32 00 B0 C2 32 00 14 C1 32 00 68 BA 32 00
007C3ADA 00 00 00 00 00 00 D6 00 00 00 E8 00 00 00 80 7C
我们看这些数据,每个Dword+基址后是什么?看看吧
数据窗口里面Ctrl+G Dword+基址:0032B6D8+00400000=0072B6D8 代码:0072B6D8 FC C2 32 00 C0 F5 32 00 DA F5 32 00 EC F5 32 00
0072B6E8 FC F5 32 00 12 F6 32 00 10 CF 32 00 02 CF 32 00
数据窗口里面Ctrl+G Dword+基址:0032C2FC+00400000=0072C2FC 代码:0072C2FC DF 03 53 65 74 46 69 6C 65 50 6F 69 6E 74 65 72 ?SetFilePointer
0072C30C 00 00 68 03 52 65 61 64 46 69 6C 65 00 00 8D 04 ..hReadFile..?
0072C31C 57 72 69 74 65 46 69 6C 65 00 43 00 43 6C 6F 73 WriteFile.C.Clos
0072C32C 65 48 61 6E 64 6C 65 00 29 03 4F 70 65 6E 46 69 eHandle.)OpenFi
0072C33C 6C 65 00 00 C0 00 44 65 6C 65 74 65 46 69 6C 65 le..?DeleteFile
我们看到输入表函数名了
原来007C3AAA处保存的是输入表各DLL的FirstThunk
在数据窗口里面定位到0072B6D8,Ctrl+B在整个段块搜索第一个DLL的FirstThunk:D8 B6 32 00,找到在0072A010处 代码:0072A000 DC A5 32 00 00 00 00 00 00 00 00 00 2A CF 32 00
0072A010 D8 B6 32 00 00 AB 32 00 00 00 00 00 00 00 00 00
0072A020 6E DF 32 00 FC BB 32 00 E4 A1 32 00 00 00 00 00
0072A030 00 00 00 00 82 EC 32 00 E0 B2 32 00 B0 A1 32 00
0072A040 00 00 00 00 00 00 00 00 B0 EC 32 00 AC B2 32 00
0072A050 DC AF 32 00 00 00 00 00 00 00 00 00 FE EC 32 00
0072A060 D8 C0 32 00 04 A1 32 00 00 00 00 00 00 00 00 00
0072A070 FA ED 32 00 00 B2 32 00 70 AA 32 00 00 00 00 00
0072A080 00 00 00 00 6C EE 32 00 6C BB 32 00 80 A1 32 00
0072A090 00 00 00 00 00 00 00 00 90 EE 32 00 7C B2 32 00
0072A0A0 B8 AA 32 00 00 00 00 00 00 00 00 00 18 EF 32 00
0072A0B0 B4 BB 32 00 B4 B1 32 00 00 00 00 00 00 00 00 00
0072A0C0 A8 EF 32 00 B0 C2 32 00 18 B0 32 00 00 00 00 00
0072A0D0 00 00 00 00 9A F5 32 00 14 C1 32 00 6C A9 32 00
0072A0E0 00 00 00 00 00 00 00 00 A4 F5 32 00 68 BA 32 00
0072A0F0 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00
如果你看过IID表的话,你们应该很清晰的知道0072A000就是IID开始的地方,也就是输入表的VA
ImportTable RVA=0072A000-ImageBase00400000=0032A000
好了,不必管其怎么加密处理输入表了,直接Ctrl+F9到此段代码末尾吧 代码:007CB28D C3 retn
//返回到 007CBA15
_____________________________________________________________
三.OEP 代码:007CBA15 EB 03 jmp short 007CBA1A
//007CB28D返回到这里,我们继续F7
007CBA1A EB 01 jmp short 007CBA1D
007CBA1D E9 1FDDD1FF jmp 004E9741
//飞向光明之巅
[code]
[code]004E9741 E9 7A1A1500 jmp 0063B1C0
//OEP
004E9746 E9 37621B00 jmp 0069F982
004E974B E9 40BF0D00 jmp 005C5690
004E9750 E9 6BB20500 jmp 005449C0
004E9755 E9 261E1C00 jmp 006AB580
OEP RVA=004E9741-ImageBase00400000=000E9741
这样的OEP代码是否奇怪?是奇怪,但VC++ 8.0 [Debug]方式编译的文件入口就这样,所以不必奇怪,这里就是OEP
_____________________________________________________________
四.修整
01.修改dump.exe的OEP RVA=000E9741,修改dump.exe的ImportTable RVA=0032A000
02.因为程序是VC8编译,因此去掉TlsTable的RVA和Size数据
03.清除壳数据,壳数据在最后一个区段,保留最后一个区段中的重定位表数据,ReloctionTable RVA 0035D000 + Size 000167E8=003737E8,保留200对齐度00373800,用LordPE转化RVA的Offset地址,把后面的数据都删除
04.VC++ 8.0 [Debug]方式编译的文件看区段表各区段属性,拿过来修dump.exe
05.保留LordPE的ValIDAte PE选项,Rebuild修整过的脱壳文件,可以运行了
06.Game Over
_____________________________________________________________
, _/
/| _.-~/ \_ , 青春都一晌
( /~ / \~-._ |\
`\\ _/ \ ~\ ) 忍把浮名
_-~~~-.) )__/;;,. \_ //'
/'_,\ --~ \ ~~~- ,;;\___( (.-~~~-. 换了脱壳轻狂
`~ _( ,_..--\ ( ,;'' / ~-- /._`\
/~~//' /' `~\ ) /--.._, )_ `~
" `~" " `" /~'`\ `\\~~\
" " "~' ""
fly[CUG]
http://www.unpack.cn
UpK软件安全社区
2008.08.23 00:00 |
|
发帖前要善用【论坛搜索】功能,那里可能会有你要找的答案或者已经有人发布过相同内容了,请勿重复发帖。 |
|
|
|
|