[版本]1.0版
[脱壳工具]PEID,Ollydbg
[脱壳平台]windows xp
[软件简介]免疫007 是一款优秀的加壳软件。具体介绍我就不说了,自己上网搜吧.前一阵用它加壳可以过众多的杀毒软件,包括卡巴.江民.金山.诺顿.瑞星等.也因此一度成为众多朋友的加壳首选.
【脱壳声明】 本人菜鸟一只,还请高手不要见笑.我的一点心得,愿与大家分享:)
首先用免疫007加壳windows的记事本,这里我选择自己曾经写的一个往PE文件里填加字节从而跳出对话框的程序加过的记事本.以便测试007的壳上加壳功能.东西见附件.朋友们也可以随便选个EXE文件.好工作开始:
PEID查壳显示什么也没有.
[注]手动脱壳时,用Olldbg载入程序,脱壳程序里面会有有好多循环。对付循环时,只能让程序往前运行,绝大部分情况下不要让它往回跳,要想法用F4之类跳出循环圈。007为保护壳,里面有SEH暗桩,所以请在用OD跟踪之前把你的OD设下下.把Od中的选项-调试选项-异常选项卡中除了忽略在KERNEL32 中的内存访问异常打勾,其余一个勾都不打,请检查自己的Od设置。
用OD载入程序后。
确定一个入口警告,Od提示程序有自解压之类的功能,点击确定。
01025042 > 52 push edx ; ntdll.KiFastSystemCallRet
01025043 03D3 add edx,ebx
01025045 030C24 add ecx,dword ptr ss:[esp]
01025048 5A pop edx
01025049 C1CA 45 ror edx,45
0102504C C1C2 45 rol edx,45
0102504F 2BCA sub ecx,edx
01025051 60 pushad
01025052 53 push ebx
01025053 893424 mov dword ptr ss:[esp],esi
01025056 2BF2 sub esi,edx
01025058 03F2 add esi,edx
0102505A 46 inc esi
0102505B 83C4 04 add esp,4
0102505E 8B7424 FC mov esi,dword ptr ss:[esp-4]
01025062 E8 00000000 call _New.01025067
01025067 E8 00000000 call _New.0102506C
0102506C 83C4 04 add esp,4
0102506F 8B3C24 mov edi,dword ptr ss:[esp]
从上面可以看到加了花指令,一开始就加,这作者可真够恶心的.先按F9试运行下,目的是为了检测是否有暗桩.按下F9后断在这里.
01024F70 FE02 inc byte ptr ds:[edx]
显示发生程序异常,可见有暗桩,我们的第一个目标跳过暗桩,用最后一次异常法对之.OK,说干就干,CTRL+F2重新载入程序,按Shift+F9,发现按了三次后程序运行,所以我们CTRL+F2重新载入程序,按Shift+F9两次,看OD的堆栈区:
0006FF78 0006FFE0 指针到下一个 SEH 记录
0006FF7C 0101B27C SE 句柄
0006FF80 7C930738 ntdll.7C930738
0006FF84 0101AE48 _New.0101AE48
0006FF88 0101B1F9 返回到 _New.0101B1F9 来自 _New.01024F59
我们在数据代码区按CTRL+G进行跟随,输入地址0101B27C(这段原理我想大家应该懂)
来到0101B27C后按F2 下断,此时再按Shift+F9,切记此是是按Shift+F9而不是按F9,要不然又会出现程序异常.好了相信你已经做到了,我们现在停在了0101B27C,现在我们按F2取消0101B27C的断点:
0101B27C 53 push ebx
0101B27D E8 00000000 call _New.0101B282
0101B282 5B pop ebx
0101B283 B8 859F0150 mov eax,50019F85
0101B288 2D 729F0150 sub eax,50019F72
0101B28D 2BD8 sub ebx,eax
0101B28F 8B45 10 mov eax,dword ptr ss:[ebp+10]
0101B292 8998 B8000000 mov dword ptr ds:[eax+B8],ebx
0101B298 33DB xor ebx,ebx
0101B29A 8958 04 mov dword ptr ds:[eax+4],ebx
我们F8单步运行,到达0101B27D,发现这里是近CALL,我们用F7跟进,否则程序就会跑飞.然后一路F8单步到达:0101B2B3
0101B2A0 8958 0C mov dword ptr ds:[eax+C],ebx
0101B2A3 8958 10 mov dword ptr ds:[eax+10],ebx
0101B2A6 C740 18 5501000>mov dword ptr ds:[eax+18],155
0101B2AD B8 00000000 mov eax,0
0101B2B2 5B pop ebx
0101B2B3 C2 0A00 retn 0A
0101B2B6 8BD5 mov edx,ebp
0101B2B8 8B85 0FFCFFFF mov eax,dword ptr ss:[ebp-3F1]
0101B2BE 2BD0 sub edx,eax
此时如果继续F8则会进入系统领空,不久程序运行,如果你选择在
0101B2B3 C2 0A00 retn 0A
的下一句按F4 程序也会跑飞.这里我就在
0101B2BE 2BD0 sub edx,eax
这一句上F2下断,按F9程序运行到了0101B2BE,OK我们跳过了刚才的那个CALL,现在继续F8单步运行.
0101B2EF 85C0 test eax,eax
0101B2F1 0F84 89040000 je _New.0101B780 ;大跳转没有实现,这里记下,以防呆会下面有不能跳过的回跳时用它来步过
0101B2F7 8985 23FCFFFF mov dword ptr ss:[ebp-3DD],eax
接着一跳F8到达这里
0101B377 58 pop eax
0101B378 59 pop ecx
0101B379 5E pop esi
0101B37A 83C6 04 add esi,4
0101B37D ^ EB DF jmp short _New.0101B35E ;往回跳
0101B37F 61 popad ;F4运行到这里
0101B380 8BDF mov ebx,edi
继续F8
0101B3F5 8A07 mov al,byte ptr ds:[edi]
0101B3F7 47 inc edi
0101B3F8 2C E8 sub al,0E8
0101B3FA 3C 01 cmp al,1
0101B3FC ^ 77 F7 ja short _New.0101B3F5 ;往回跳
0101B3FE 8B07 mov eax,dword ptr ds:[edi]动;F4到达这里
............
0101B408 381F cmp byte ptr ds:[edi],bl
0101B40A ^ 75 E9 jnz short _New.0101B3F5面;又是往回跳
0101B40C 8A5F 04 mov bl,byte ptr ds:[edi+4];F4
.........
0101B42A 83C7 05 add edi,5
0101B42D 80EB E8 sub bl,0E8
0101B430 8BC3 mov eax,ebx
0101B432 ^ E2 C6 loopd short _New.0101B3FA ;大的循环回跳
0101B434 E8 D8000000 call _New.0101B511
0101B439 8D8D 4FFCFFFF lea ecx,dword ptr ss:[ebp-3B1];在这里按F4运行到这里
一路F8
0101B4FC 5A pop edx
0101B4FD 5B pop ebx
0101B4FE 59 pop ecx
0101B4FF 5E pop esi
0101B500 83C3 0C add ebx,0C
0101B503 ^ E2 E1 loopd short _New.0101B4E6 ;又是往回跳
0101B505 E8 7E020000 call _New.0101B788
0101B50A 61 popad ;F4到这里,寄存器出栈
0101B50B 9D popfd;标志寄存器出栈,OEP应该就在附近了
0101B50C - E9 EF7AFFFF jmp _New.01013000 ;大的跨段跳转,应该快到OEP,F8跟进.
01013000 60 pushad ; 真实入口点
01013001 6A 00 push 0
01013003 6A 01 push 1
01013005 6A 02 push 2
01013007 6A 00 push 0
01013009 E8 FC32D576 call USER32.MessageBoxW
0101300E 61 popad
0101300F ^ E9 8943FFFF jmp _New.0100739D
[注]以上这段代码便是我自己写的一段给PE文件加壳的程序给记事本加的一段代码,只是跳出一个空对话框,所以如果你不是用我在附件里提供的记事本的话就应该是直接跳转到了记事本的入口点0100739D,这里解释下,免得误会.
呵呵好了到达我们的入口点,我们在
01013000 60 pushad
上用Od的Dump插件直接脱壳。程序能直接运行不用修复.脱壳完毕.
[脱壳总结]程序在起初加了大量花指令,有三个SEH暗桩.另外其实这个加壳的程序还可以用其它方法脱壳,只要是已经跳过了最后一次异常,同时也跳过了那个返回系统领空的回调
retn 0A就可以用多种方法来脱掉它,比如ESP定律,下条件断点也行,还可以用下内存访问断点的方法来脱壳,总之是只要大家跳过了前面的困难期了,后面就一片光明了.
最后再给大家说个最简单的方法.用SFX跟踪来对付这个壳可以让OD给你自动找到OEP,不过个人不推荐用这种方法,毕竟还是要提高水平为妙.
[招生]科锐逆向工程师培训(2024年11月15日实地,远程教学同时开班, 第51期)