脱壳方法

  1. 1、下载文档前请自行甄别文档内容的完整性,平台不提供额外的编辑、内容补充、找答案等附加服务。
  2. 2、"仅部分预览"的文档,不可在线预览部分如存在完整性等问题,可反馈申请退款(可完整预览的文档不适用该条件!)。
  3. 3、如文档侵犯您的权益,请联系客服反馈,我们会尽快为您处理(人工客服工作时间:9:00-18:30)。

/*****************脱壳手记************/

/***********由于本人才疏学浅,有什么不足之处,望大家指点********************/
/*
先给自己找些借口:
虽然接触脱壳有很长一段时间了,但是对壳的分析还是处于新手阶段.
详细的脱壳过程也没有必要一再重复,论坛里基本上都有的了.
本文是给一些像我一样在脱壳门口徘徊的新人们看的,其实脱壳很简单.
要是大牛们能留下宝贵的意见当然是求之不得的.
当然 有很多加密壳 像ASProtect , 穿山甲, ACProtect 等. 这些壳,已经有很多前辈给我们这些后人都做好了铺垫,有好多脱该类壳的脚本.
记得VolX写的一个脚本Aspr2.XX_unpacker_v1.0SC.osc
/*
Script written by VolX
Script : Aspr2.XX_unpacker
版本 : v1.0SC
日期 : 15-Jan-2007
调试环境 : OllyDbg 1.1, ODBGScript 1.47, WINXP, WIN2000
调试选项 : 设置 OllyDbg 忽略所有异常选项
工具 : OllyDbg, ODBGScript 1.47, Import Reconstructor.
感谢 : Oleh Yuschuk - author of OllyDbg
SHaG - author of OllyScript
Epsylon3 - author of ODbgScript
特别感谢 : fly, linex, machenglin 等兄弟的帮忙测试.
//support Asprotect 1.32, 1.33, ,1.35, 1.4, 2.0, 2.1, 2.11, 2.2beta, 2.2, 2.3
*/

这个脚本脱Asprotect很给力 似乎更高级一些的 例如 2.4 的版本也适用.

对于牛壳,比如壳safeguard1.03,我可是费了不少心思,可是总是没有什么结果,在论坛里好像只有一篇文章是有关该壳的
标 题: safeguard1.03 主程序之“游晕惊萝”之浅游(未脱)
发帖人:askformore
时 间: 2005-07-01 16:45
原文链接:/showthread.php?threadid=14854

唉~都不知道要等到何年何月啊 ~

*/
///////////////////////////////////////////////////////////////////////////
下面是小弟我最近的手记,因为最近才想起来要做手记,所以内容很少很少,希望大家能帮忙补充
2011/4/8 13:40
手脱PECompact 2.x -> Jeremy Collake 壳是我自己加的,加壳的工具是PECompact2 Graphical User Interface Application
软件名:虚拟光驱绿色版
使用内存二次断点再单步跟踪就能到OEP
下内存函数断点脱 bpx VirtualFree
单步跟踪也可以 不过要注意凡跑飞的call重新加载后F7进去然后继续单步跟踪即可慢慢到达OEP
有经验的知道该壳加壳后的程序和原程序的入口点是一样的 所以可以在壳的ep下硬件执行断点一样可以到达oep
软件语言:Microsoft Visual C++ 7.0
////////////////////////////////////////////////////////////
2011/4/8 17:50
手脱ASPack 2.12 -> Alexey Solodovnikov
软件名:电子日记EDiary2.53
ESP定律解决
后来想了想,为了方便一些新手学习,就写多一些能脱该累壳的办法,该壳可以使用单步跟踪(其实压缩壳都可以单步跟踪来到OEP的),内存断点,SFX,ESP定律,二进制搜索C2 0C 00 68 00 00 00 00 C3(由于本人才疏学浅,目

前发现这段二进制代码对ASPack壳起作用,对于其他壳,还没有留意,也还没有尝试)
软件语言:Borland Delphi 6.0 - 7.0
注:说点题外话,和大学的密码学老师和网络安全老师讨论了一下有关该壳的加密算法和验证密码的方式的时候(当然是在仅有的一些资料的情况下得到的一些些小结论,也不知道是对还是错):该验证算法是建立在SHS杂凑算法(SHA算法的小变形)和Blowfish加密算法的综合利用上的.我听得一头雾水,呵呵.
//////////////////////////////////////////////////////////////////////////////////////
2011/4/11 12:36
手脱ASPack 2.x (without poly) -> Alexey Solodovnikov
软件名:锐速简历通
开始以为一次ESP定律就可以解决了,一看,OD断下来的时候和刚加载的一样,我马上想到是不是自己操作失误了?本来还想自嘲一下说老马失蹄,但是查看断点,这个软件唯一有点意思的地方是作者使用了两次一样的壳(不知道为什么,老觉得软件作者很会开玩笑),所以再使用一次ESP定律直接到达OEP dump 之后直接能使用 不用import修复
软件语言:Borland Delphi 6.0 - 7.0
//////////////////////////////////////////////////////////////////////////////
2011/04/11 21:30
手脱nSpack V2.3 -> LiuXingPing *
软件名 sms.exe 是自己手动加壳的脱ASPack的壳是一样的
由于是加密壳所以和
软件语言:Borland Delphi 6.0 - 7.0

刚刚帮 dlnh 脱了个 eXPressor.Protection.V1.7.0.1 -> CGSoftLabs 的壳
本以为是加密壳 可费劲一切脑力寻思着用什么断点才能断下来,查看了fly 的一篇文章:
///////////////////////////////////////////////////////////////////////////////////////////////
标 题: eXPressor V1.0脱壳+破解——eXPressor主程序
发帖人:fly
时 间: 2005-02-01 12:20
原文链接:/showthread.php?threadid=10640

才知道eXPressor属于压缩壳 不过补知道高级的版本是否改了.
抱着一试的心态采用了内存断点办法 结果 嘻嘻~ 成功了 呵呵

//想了想 还是说说aspr壳的一些脱壳办法 我是站在巨人的肩膀上说话的,说的话的分量可能不是很重,呵呵

脱aspr的壳 对于一些第一点版本的 可以使用 int3 和内存访问异常来使得调试的时候能断下来.但是对于现在的aspr的壳来说,我们已经遇到很多很多 没有int3 和内存访问异常的了 .因为aspr壳会用到库函数中的 GetModuleHandleA函数 所以可以下bpx GetModuleHandleA 或者是GetSystemTime 也是可以的

具体可以参考

标 题:ASPR学习笔记上篇:修复IAT
作 者:lelfei
时 间:2009-01-13 17:47:14

链 接:/showthread.php?t=80422


这样就可以很轻松的来到OEP 剩下的就是需要修复IAT了

///////////////////////////////////////////////////////////////////////////////////////
手脱AHpack 0.1 -> FEUERRADER
建议不

要单步跟踪 使用ESP定律能更快到达OEP SFX方法也可以 不过效率就 呵呵~

////////////////////////////////////////////////////////////////////////////////////////////
这个壳 好像没有脱壳机可以脱的 linhanshi的一个贴
"2009-07-31, 22:15:58 【转帖】RL!dePacker v1.5 release vs TitanEngine"
/showthread.php?t=94764
那个脱壳机虽然有说可以脱 !EP (ExE Pack) 1.x 可是经本人测试,脱不了!EP(EXE Pack)1.4

用peidv0.95 查壳 yoda's Protector v1.02 (.dll,.ocx) -> Ashkbiz Danehkar (h) *

看EP区段 显示 .!ep

突然发现peid 查壳很一般了 越来越不能相信它了

下面是我的脱壳手记:

用OD载入:
程序入口: 看壳的入口,好像是!EP(EXE Pack)1.4的,就暂且相信它吧
004B3000 > F8 clc
004B3001 57 push edi
004B3002 A9 426688BC test eax, BC886642
004B3007 5F pop edi
004B3008 51 push ecx
004B3009 66:B9 A7AB mov cx, 0ABA7
004B300D 59 pop ecx
004B300E 81EE 00000000 sub esi, 0
004B3014 C0C5 60 rol ch, 60
004B3017 F6C6 74 test dh, 74
004B301A 0BDB or ebx, ebx
004B301C 40 inc eax
004B301D 48 dec eax
004B301E 84D2 test dl, dl
004B3020 50 push eax
004B3021 E8 56000000 call UnPackMe.004B307C 在此call F7 否则程序运行了
004B3026 73 22 jnb short UnPackMe.004B304A
004B3028 F2: prefix repne:
004B3029 D20C7E ror byte ptr ds:[esi+edi*2], cl
004B302C DED8 ficomp eax ; 非法使用寄存器
004B302E - 71 B4 jno short UnPackMe.004B2FE4

F7之后来到

004B307C 58 pop eax ; UnPackMe.004B3026
004B307D 58 pop eax
004B307E 53 push ebx
004B307F 53 push ebx
004B3080 66:83FB E7 cmp bx, 0FFE7
004B3084 5B pop ebx
004B3085 5B pop ebx
004B3086 66:83F5 00 xor bp, 0
004B308A 52 push edx
004B308B 52 push edx
004B308C 53 push ebx
004B308D 66:A9 1435 test ax, 3514
004B3091 5B pop ebx
004B3092 5A pop edx
004B3093 5A pop edx
004B3094 F9 stc
004B3095 2D 00000000 sub eax, 0
004B309A 57 push edi
004B309B E8 42000000 call UnPackMe.004B30E2 在此call F7 否则程序运行了
004B30A0 4A dec edx
004B30A1 EE out dx, al

之后来到

004B30E2 5F pop edi ; UnPackMe.004B30A0
004B3

0E3 5F pop edi
004B30E4 57 push edi
004B30E5 52 push edx
004B30E6 53 push ebx
004B30E7 51 push ecx
004B30E8 83C4 04 add esp, 4
004B30EB 5B pop ebx
004B30EC 5A pop edx
004B30ED 5F pop edi
004B30EE 66:C1C6 B0 rol si, 0B0
004B30F2 74 05 je short UnPackMe.004B30F9
004B30F4 74 03 je short UnPackMe.004B30F9
004B30F6 C1FF 40 sar edi, 40
004B30F9 F8 clc
004B30FA F8 clc
004B30FB 53 push ebx
004B30FC E8 FB020000 call UnPackMe.004B33FC 在此call F7 否则程序运行了
004B3101 45 inc ebp
004B3102 9B wait
004B3103 BF B0A79629 mov edi, 2996A7B0

之后一直单步跟踪.......直到


004B3573 5D pop ebp
004B3574 83ED 05 sub ebp, 5
004B3577 8B3424 mov esi, dword ptr ss:[esp]
004B357A 89F7 mov edi, esi
004B357C 81E7 00000070 and edi, 70000000
004B3582 85FF test edi, edi
004B3584 0F84 F8020000 je UnPackMe.004B3882 //注意这行 凡是这个都是不跳的.下面还有几个和这行一样的代码.随便一个跳了我们就跳出了1.4版本的防调试.所以我们就让它跳吧,呵呵 这就是1.4版本和1.0版本的最大区别
004B358A E8 67010000 call UnPackMe.004B36F6
004B358F 89C7 mov edi, eax
004B3591 89C3 mov ebx, eax
004B3593 8D85 36020000 lea eax, dword ptr ss:[ebp+236]
004B3599 E8 82010000 call UnPackMe.004B3720
004B359E 85C0 test eax, eax
004B35A0 0F84 DC020000 je UnPackMe.004B3882 //注意这行
004B35A6 89C6 mov esi, eax
004B35A8 8D9D FE020000 lea ebx, dword ptr ss:[ebp+2FE]
004B35AE 53 push ebx
004B35AF 8D9D 45020000 lea ebx, dword ptr ss:[ebp+245]
004B35B5 53 push ebx
004B35B6 57 push edi
004B35B7 FFD6 call esi
004B35B9 85C0 test eax, eax
004B35BB 0F84 C1020000 je UnPackMe.004B3882 //注意这行
004B35C1 FFD0 call eax
004B35C3 66:85C0 test ax, ax
004B35C6 0F85 BA010000 jnz UnPackMe.004B3786
004B35CC E8 01010000 call UnPackMe.004B36D2
004B35D1 83F8 05 cmp eax, 5
004B35D4 0F84 A8020000 je UnPackMe.004B3882 //注意这行
004B35DA 8D9D FE020000 lea ebx, dword ptr ss:[ebp+2FE]
004B35E0 53 push ebx
004B35E1 8D9D 55020000 lea ebx, dword ptr ss:[ebp+255]
004B35E7 53 push ebx
004B35E8 57 push edi
004B35E9

FFD6 call esi
004B35EB 85C0 test eax, eax
004B35ED 0F84 8F020000 je UnPackMe.004B3882 //注意这行
004B35F3 FFD0 call eax
004B35F5 66:85C0 test ax, ax
004B35F8 0F84 C1000000 je UnPackMe.004B36BF
004B35FE C785 AA020000 4>mov dword ptr ss:[ebp+2AA], 44
004B3608 C785 AE020000 0>mov dword ptr ss:[ebp+2AE], 0
004B3612 C785 B2020000 0>mov dword ptr ss:[ebp+2B2], 0
004B361C C785 B6020000 0>mov dword ptr ss:[ebp+2B6], 0
004B3626 C785 D6020000 0>mov dword ptr ss:[ebp+2D6], 0
004B3630 C785 DC020000 0>mov dword ptr ss:[ebp+2DC], 0
004B363A C785 DE020000 0>mov dword ptr ss:[ebp+2DE], 0
004B3644 8D9D EE020000 lea ebx, dword ptr ss:[ebp+2EE]
004B364A 53 push ebx
004B364B 8D9D AA020000 lea ebx, dword ptr ss:[ebp+2AA]
004B3651 53 push ebx
004B3652 6A 00 push 0
004B3654 6A 00 push 0
004B3656 6A 00 push 0
004B3658 6A 00 push 0
004B365A 6A 00 push 0
004B365C 6A 00 push 0
004B365E 8D9D 84020000 lea ebx, dword ptr ss:[ebp+284]
004B3664 53 push ebx
004B3665 57 push edi
004B3666 FFD6 call esi
004B3668 85C0 test eax, eax
004B366A 0F84 12020000 je UnPackMe.004B3882 //注意这行
004B3670 FFD0 call eax
004B3672 50 push eax
004B3673 6A 00 push 0
004B3675 8D9D 75020000 lea ebx, dword ptr ss:[ebp+275]
004B367B 53 push ebx
004B367C 57 push edi
004B367D FFD6 call esi
004B367F 85C0 test eax, eax
004B3681 0F84 FB010000 je UnPackMe.004B3882 //注意这行 之前的都不跳,这行再不跳的话 下面的那个程序就运行了
004B3687 FFD0 call eax
004B3689 8B9D EE020000 mov ebx, dword ptr ss:[ebp+2EE]
004B368F 53 push ebx
004B3690 8D9D 94020000 lea ebx, dword ptr ss:[ebp+294]
004B3696 53 push ebx
004B3697 57 push edi
004B3698 FFD6 call esi
004B369A 85C0 test eax, eax
004B369C 0F84 E0010000 je UnPackMe.004B3882 //注意这行
004B36A2 FFD0 call eax
004B36A4 8B9D F2020000 mov ebx, dword ptr ss:[ebp+2F2]
004B36AA 53 push ebx
004B36AB 8D9D 94020000 lea ebx, dword ptr ss:[ebp+294]
004B36B1 53 push ebx
004B36B2 57 push edi
004B36B3 FFD6 call esi
004B36B5 85C0 test eax, eax
004B36B7 0F84 C5010000 je UnPackMe.004B3882 //注意这行
004B36BD

FFD0 call eax
004B36BF 6A 00 push 0
004B36C1 8D9D A0020000 lea ebx, dword ptr ss:[ebp+2A0]
004B36C7 53 push ebx
004B36C8 57 push edi
004B36C9 FFD6 call esi
004B36CB 85C0 test eax, eax
004B36CD 74 02 je short UnPackMe.004B36D1
004B36CF FFD0 call eax
004B36D1 C3 retn
004B36D2 64:A1 18000000 mov eax, dword ptr fs:[18]
004B36D8 8B40 34 mov eax, dword ptr ds:[eax+34]
004B36DB C3 retn

004B3584 0F84 F8020000 je UnPackMe.004B3882
跳了之后来到

004B3882 90 nop
004B3883 E2 4E loopd short UnPackMe.004B38D3
004B3885 E3 4C jecxz short UnPackMe.004B38D3
004B3887 6A EE push -12
004B3889 92 xchg eax, edx

单步跟踪一下下来到
004B38D3 41 inc ecx
004B38D4 C1FA 60 sar edx, 60
004B38D7 57 push edi
004B38D8 E8 45000000 call UnPackMe.004B3922 //在这F7进去 否则又飞了 呵呵 这个壳也太贼啊
004B38DD 57 push edi
004B38DE 0F4A0F cmovpe ecx, dword ptr ds:[edi]
004B38E1 A8 03 test al, 3
004B38E3 B2 CC mov dl, 0CC
004B38E5 5C pop esp
004B38E6 8976 C2 mov dword ptr ds:[esi-3E], esi
004B38E9 AB stos dword ptr es:[edi]

之后来到

004B3983 41 inc ecx
004B3984 51 push ecx
004B3985 81E4 FFFFFFFF and esp, FFFFFFFF
004B398B 59 pop ecx
004B398C 51 push ecx
004B398D E8 F6000000 call UnPackMe.004B3A88 //在这F7进去 否则又飞了 我突然变得有点不耐烦了
004B3992 53 push ebx
004B3993 D27F 1B sar byte ptr ds:[edi+1B], cl
004B3996 3F aas
004B3997 A8 50 test al, 50

之后来到
004B3A88 83C4 04 add esp, 4
004B3A8B 59 pop ecx
004B3A8C 31C0 xor eax, eax
004B3A8E 55 push ebp
004B3A8F E8 00000000 call UnPackMe.004B3A94
004B3A94 830424 34 add dword ptr ss:[esp], 34
004B3A98 64:FF30 push dword ptr fs:[eax]
004B3A9B 64:8920 mov dword ptr fs:[eax], esp
004B3A9E 9C pushfd
004B3A9F 58 pop eax
004B3AA0 0D 00010000 or eax, 100
004B3AA5 6A 00 push 0
004B3AA7 6A FF push -1
004B3AA9 6A 00 push 0
004B3AAB 6A 00 push 0
004B3AAD 50 push eax
004B3AAE B8 01010000 mov eax, 101
004B3AB3 89E2 mov edx, esp
004B3AB5 83C2 04 add edx, 4
004B3AB8 C74424 FC 0

F340>mov dword ptr ss:[esp-4], 340F
004B3AC0 89E1 mov ecx, esp
004B3AC2 83E9 04 sub ecx, 4
004B3AC5 9D popfd
004B3AC6 - FFE1 jmp ecx //F7 或者 F8 都提示错误
004B3AC8 58 pop eax // 所以在这个下断 F9
004B3AC9 58 pop eax
004B3ACA 58 pop eax
004B3ACB 58 pop eax
004B3ACC 31C0 xor eax, eax
004B3ACE 5A pop edx
004B3ACF 59 pop ecx
然后又是单步跟踪.........

004B3D15 68 FF242400 push 2424FF
004B3D1A E8 00000000 call UnPackMe.004B3D1F
004B3D1F 830424 0B add dword ptr ss:[esp], 0B
004B3D23 89E3 mov ebx, esp
004B3D25 83C3 04 add ebx, 4
004B3D28 FFE3 jmp ebx
004B3D2A 5B pop ebx
004B3D2B 5B pop ebx
004B3D2C B8 FF204B00 mov eax, UnPackMe.004B20FF ; ASCII "`hT K"
004B3D31 FFE0 jmp eax //跳到原程序代码开始解压的地方去了 呵呵 所以让他跳吧
004B3D33 51 push ecx
004B3D34 E8 C3020000 call UnPackMe.004B3FFC
004B3D39 B6 B7 mov dh, 0B7
004B3D3B AB stos dword ptr es:[edi]
004B3D3C 74 69 je short UnPackMe.004B3DA7
004B3D3E 54 push esp

来到这里
004B20FF 60 pushad //让人觉得很熟悉啊 这就是1.0版本的壳的开始啊 呵呵
004B2100 68 54204B00 push UnPackMe.004B2054 //单步来到这行 使用ESP定律
004B2105 B8 48204B00 mov eax, <&KERNEL32.GetModuleHandleA>
004B210A FF10 call dword ptr ds:[eax]
004B210C 68 B3204B00 push UnPackMe.004B20B3 ; ASCII "GlobalAlloc"
004B2111 50 push eax
004B2112 B8 44204B00 mov eax, <&KERNEL32.GetProcAddress>
004B2117 FF10 call dword ptr ds:[eax]
004B2119 68 004A0900 push 94A00

断下来时候 来到
004B229A BA EC584900 mov edx, UnPackMe.004958EC
004B229F FFE2 jmp edx //跳向OEP
004B22A1 90 nop
004B22A2 C3 retn
004B22A3 44 inc esp
004B22A4 0000 add byte ptr ds:[eax], al
004B22A6 0000 add byte ptr ds:[eax], al

再单步一下下 就来到OEP了
004958EC 55 push ebp
004958ED 8BEC mov ebp, esp
004958EF 83C4 F0 add esp, -10
004958F2 53 push ebx
004958F3 B8 84564900 mov eax, UnPackMe.00495684
004958F8 E8 C712F7FF call UnPackMe.00406BC4
004958FD 8B1D D8744900 mov ebx, dword ptr ds:[4974D8] ; UnPackMe

.00498C34
00495903 8B03 mov eax, dword ptr ds:[ebx]
00495905 E8 8E19FDFF call UnPackMe.00467298
0049590A 8B0D D0744900 mov ecx, dword ptr ds:[4974D0] ; UnPackMe.00498D38
00495910 8B03 mov eax, dword ptr ds:[ebx]
00495912 8B15 D8064900 mov edx, dword ptr ds:[4906D8] ; UnPackMe.00490724
00495918 E8 9319FDFF call UnPackMe.004672B0
0049591D 8B0D B4724900 mov ecx, dword ptr ds:[4972B4] ; UnPackMe.00498D18
00495923 8B03 mov eax, dword ptr ds:[ebx]
00495925 8B15 74FD4800 mov edx, dword ptr ds:[48FD74] ; UnPackMe.0048FDC0

直接dump 不用修复IAT 真开心 呵呵
!EP(EXE Pack)1.0版本的壳非常容易脱 但是对于1.4版本的时候就有点耐人寻味了.

原程序是用Borland Delphi 6.0 - 7.0

///////////////////////////////////////////////////////////////////////////////////////
20121029
查壳:C.I Crypt V0.1 -> FearlesS * Sign.By.fly
/showthread.php?t=157885


思路很简单的拉,单步就可以先过花指令(遇到飞了的CALL就F7),然后是对付压缩壳,ESP定律就能解决了。
或者一开始使用内存断点法,然后单步就来到压缩壳开始处,再ESP定律也可到达OEP
////////////////////////////////////////////////////////////////////////////////////////s

相关文档
最新文档