unpack.cn 上发了一次,这里再发一次,混个脸熟,也混点积分
手推themida 1.8.0.0
学脱壳一个月了,帖子看了n多个,经常看到脱友们抱怨老大们的帖子和脚本难懂,说好像老大们事先知道在哪里下断一样等等,我也是这个感觉,可那叫境界,得慢慢学,道理是这样的,我还远没到那个境界,看了不少老大们的帖子,总感觉云里雾里的,网上不少脱themida的帖子,可大部分都是用okdodo的脚本脱的,我也用了,一跑,真爽,可还是不明白之前壳干什么了。实在没办法,干脆甩开帖子们,老老实实的自己慢慢跟跟看吧,当然用的知识都是老大们教过的,写下这篇文,与和我一样菜的脱友们一起学习吧
只是随便选了个1800的版本,想想后来的版本也差不多,因为老大们已经把olly给改了,19xx以上的版本调起来应该也没有问题了
写文章前,我已经脱了这个壳了,不过我会尽量装作是第一次脱,一个下午脱完的,很多细节我自己都觉得没有仔细研究,不过大概步骤是这样的,有兴趣的接着研究吧,另外这是我自己脱的第一个壳,以前都是看别人的帖子,希望能给同学们一点帮助,高手们给点指点,在下受用不尽
好了,废话少说,先向老大们致敬,然后开始。。。
我是用xp的notepad加的壳,选了一大堆选项,65k的notepad加了壳后一看1.35M,真吓一跳。。。
OD载入,入口代码如下:
01014014 > B8 00000000 mov eax,0
01014019 60 pushad
0101401A 0BC0 or eax,eax
0101401C 74 58 je short notepad-.01014076
0101401E E8 00000000 call notepad-.01014023
01014023 58 pop eax
01014024 05 43000000 add eax,43
01014029 8038 E9 cmp byte ptr ds:[eax],0E9
0101402C 75 03 jnz short notepad-.01014031
0101402E 61 popad
0101402F EB 35 jmp short notepad-.01014066
01014031 E8 00000000 call notepad-.01014036
01014036 58 pop eax
我在之前调试的时候做了些注释,现在打开看看,
用户自定义注释
地址 反汇编 注释
01014029 cmp byte ptr ds:[eax],0E9 (初始 CPU 选择)
01014087 call notepad-.0101408C init some area to 00000000000
010141CB rep movs byte ptr es:[edi],byte ptr ds:[esi] init to 000000000
01014220 rep movs byte ptr es:[edi],byte ptr ds:[esi] init to 00000000
01147C34 das to check if PE file
01147C3F wait go to PE header
0114C2F4 add byte ptr ds:[eax],al kernel32.VirtualAlloc
012058ED add byte ptr ds:[eax],al kernel32.VirtualAlloc
0120590D add byte ptr ds:[eax],al kernel32.VirtualAllc
0120592D add byte ptr ds:[eax],al kernel32.VirtualAllc
01205951 add byte ptr ds:[eax],al kernel32.VirtualAllc
01205A1E add byte ptr ds:[eax],al kernel32.VirtualAllc 990000
01205A5D add byte ptr ds:[eax],al copy code to 990000 from packer
01205A70 add byte ptr ds:[eax],al operation on the section new alloced
01205B53 add byte ptr ds:[eax],al decryption
012246AE add byte ptr ds:[eax],al PE file?
012246BD add byte ptr ds:[eax],al go PE header
012246E4 add byte ptr ds:[eax],al section number
012246ED add byte ptr ds:[eax],al size of image
012246F8 add byte ptr ds:[eax],al code section
0125BCA1 add byte ptr ds:[eax],al decoding
0126395D add byte ptr ds:[eax],al get IAT input
012642A4 add byte ptr ds:[eax],al IAT recover from packer?
01264A98 add byte ptr ds:[eax],al decode the next part
从地址01147C34开始,可以看到代码应该都是无效的,这是因为在这些地址的代码还没有解密,脱的过程中我们还会来看这个注释表的,就可以看到有些代码已经变成了有效的了,这样就可以找到这部分代码在什么地方解密的。。。
往下F7走,有不少解码的地方
01014080 50 push eax
01014081 51 push ecx
01014082 E8 84000000 call notepad-.0101410B ;执行到这里可以看到注释里内容的变化,不过还没有最终解密完
01014087 E8 00000000 call notepad-.0101408C ; init some area to 00000000000
0101408C 58 pop eax
0101408D 2D 26000000 sub eax,26
来到
01147C2F 5B pop ebx
01147C30 8BCA mov ecx,edx
01147C32 33FF xor edi,edi ; notepad-.0114EBCF
01147C34 66:8138 4D5A cmp word ptr ds:[eax],5A4D ; to check if PE file
01147C39 75 0E jnz short notepad-.01147C49
01147C3B 0FB750 3C movzx edx,word ptr ds:[eax+3C]
01147C3F 03D0 add edx,eax ; go to PE header
01147C41 813A 50450000 cmp dword ptr ds:[edx],4550
01147C47 74 08 je short notepad-.01147C51
下面有个CreateFileA,我没管,接着走,有空好好看看。。。
01147C86 /76 03 jbe short notepad-.01147C8B
01147C88 |8B70 1C mov esi,dword ptr ds:[eax+1C]
01147C8B \33C0 xor eax,eax ; <&KERNEL32.CreateFileA>
01147C8D 83F8 32 cmp eax,32
01147C90 74 1F je short notepad-.01147CB1
越过多个解码程序后,分配了几个section:830000,850000, 860000,870000,990000等,并往其中的一些段内解压代码
0114C2F2 FFD0 call eax
0114C2F4 8985 8D29E805 mov dword ptr ss:[ebp+5E8298D],eax ; kernel32.VirtualAlloc
0114C2FA 6A 40 push 40
0114C2FC 68 00100000 push 1000
0114C301 68 00200000 push 2000
0114C306 6A 00 push 0
0114C308 FF95 8D29E805 call dword ptr ss:[ebp+5E8298D] ; kernel32.VirtualAlloc
0114C30E 8985 9E7BE805 mov dword ptr ss:[ebp+5E87B9E],eax
0114C314 FF95 9130E805 call dword ptr ss:[ebp+5E83091]
012058ED FF95 8D29E805 call dword ptr ss:[ebp+5E8298D] ; kernel32.VirtualAlloc
012058F3 8985 0E7DE805 mov dword ptr ss:[ebp+5E87D0E],eax
012058F9 FF95 9130E805 call dword ptr ss:[ebp+5E83091] ; notepad-.01148841
012058FF 6A 40 push 40
01205901 68 00100000 push 1000
01205906 68 F4020000 push 2F4
0120590B 6A 00 push 0
0120590D FF95 8D29E805 call dword ptr ss:[ebp+5E8298D] ; kernel32.VirtualAllc
01205913 8985 127DE805 mov dword ptr ss:[ebp+5E87D12],eax
01205919 FF95 9130E805 call dword ptr ss:[ebp+5E83091]
解压代码
01205B49 B8 35AB2698 mov eax,9826AB35
01205B4E 2BCF sub ecx,edi
01205B50 C1E9 02 shr ecx,2
01205B53 3107 xor dword ptr ds:[edi],eax ; decryption
01205B55 D0C8 ror al,1
01205B57 83C7 04 add edi,4
01205B5A 49 dec ecx
01205B5B ^ 0F85 F2FFFFFF jnz notepad-.01205B53
接着走,
01206F61 ^\E9 83ECFFFF jmp notepad-.01205BE9
01206F66 68 E5602440 push 402460E5
01206F6B ^ E9 79ECFFFF jmp notepad-.01205BE9
01206F70 68 A66EB579 push 79B56EA6
01206F75 ^ E9 6FECFFFF jmp notepad-.01205BE9
01206F7A 68 E58E4413 push 13448EE5
01206F7F ^ E9 65ECFFFF jmp notepad-.01205BE9
01206F84 68 F0382B01 push 12B38F0
01206F89 ^ E9 5BECFFFF jmp notepad-.01205BE9
01206F8E 68 5C55B018 push 18B0555C
01206F93 ^ E9 51ECFFFF jmp notepad-.01205BE9
01206F98 68 F73A5B27 push 275B3AF7
01206F9D ^ E9 47ECFFFF jmp notepad-.01205BE9
01206FA2 68 813F4956 push 56493F81
哈哈,softworm说的VM,出来了,在最后一个jmp处F2打断点,把这段程序跑完,一下子就跑尽VM,半天没出来,看堆栈段830000,VM的代码段8xxxx ~90xxxx, 我们刚才VirtualAlloc分配的段,VM的代码还是看softworm的吧,我也说不明白,VM代码后,跟的时候小心,别进VM里了,要不想出来可就麻烦了
代码解码了这么半天,总该往code段里写点东西了吧?试试看,code段打内存存取断点,跑。。。来到:
012246AE 66:8138 4D5A cmp word ptr ds:[eax],5A4D ; PE file?
012246B3 0F85 12000000 jnz notepad-.012246CB
012246B9 0FB750 3C movzx edx,word ptr ds:[eax+3C]
012246BD 03D0 add edx,eax ; go PE header
012246BF 813A 50450000 cmp dword ptr ds:[edx],4550
012246C5 0F84 0A000000 je notepad-.012246D5
012246CB 2D 00100000 sub eax,1000
012246D0 ^ E9 D9FFFFFF jmp notepad-.012246AE
012246D5 8BC8 mov ecx,eax
012246D7 8985 050CE805 mov dword ptr ss:[ebp+5E80C05],eax
012246DD 0340 3C add eax,dword ptr ds:[eax+3C]
012246E0 0FB750 06 movzx edx,word ptr ds:[eax+6]
012246E4 8995 9D23E805 mov dword ptr ss:[ebp+5E8239D],edx ; section number
012246EA 8B50 50 mov edx,dword ptr ds:[eax+50]
012246ED 8995 F130E805 mov dword ptr ss:[ebp+5E830F1],edx ; size of image
012246F3 05 F8000000 add eax,0F8
012246F8 8B50 0C mov edx,dword ptr ds:[eax+C] ; code section
012246FB 03D1 add edx,ecx
shift-f9,继续走
0125BC9F 8BC8 mov ecx,eax
0125BCA1 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi] ; decoding
0125BCA3 C685 190BE805 56 mov byte ptr ss:[ebp+5E80B19],56
0125BCAA 68 396D1FD4 push D41F6D39
此时,ecx是6000,esi是 15a4000,edi是1005000,霍霍,这么长的代码从壳里写到代码段里了
shift-f9,继续走
0126437A 8B85 7931E805 mov eax,dword ptr ss:[ebp+5E83179] ; comdlg32.PageSetupDlgW
01264380 2BC7 sub eax,edi
01264382 83E8 04 sub eax,4
01264385 AB stos dword ptr es:[edi]
01264386 AD lods dword ptr ds:[esi]
01264387 C746 FC 00000000 mov dword ptr ds:[esi-4],0
0126438E ^ E9 11FFFFFF jmp notepad-.012642A4
01264393 89B5 990AE805 mov dword ptr ss:[ebp+5E80A99],esi
01264399 52 push edx
0126439A 68 00800000 push 8000
0126439F 6A 00 push 0
012643A1 FFB5 0130E805 push dword ptr ss:[ebp+5E83001]
012643A7 FF95 6909E805 call dword ptr ss:[ebp+5E80969]
内存断点取消,终于来到了恢复IAT的地方,不容易啊。。。
接着F7慢慢走。。。过了几段解码的片断后
01264A7E 8D8D 5F93F905 lea ecx,dword ptr ss:[ebp+5F9935F]
01264A84 B8 158249F5 mov eax,F5498215
01264A89 2BCF sub ecx,edi
01264A8B 83BD 8BE8F905 00 cmp dword ptr ss:[ebp+5F9E88B],0
01264A92 0F84 A3000000 je notepad-.01264B3B
01264A98 3007 xor byte ptr ds:[edi],al ; decode the next part
01264A9A D0C8 ror al,1
01264A9C 47 inc edi
01264A9D 49 dec ecx
01264A9E ^ 0F85 F4FFFFFF jnz notepad-.01264A98
实在忍不住了,再取把巧,code段设内存访问断点,shift-f9走
01007568 68 BA750001 push notepad-.010075BA
0100756D 64:A1 00000000 mov eax,dword ptr fs:[0]
01007573 50 push eax
01007574 8B4424 10 mov eax,dword ptr ss:[esp+10]
01007578 896C24 10 mov dword ptr ss:[esp+10],ebp
0100757C 8D6C24 10 lea ebp,dword ptr ss:[esp+10]
01007580 2BE0 sub esp,eax
01007582 53 push ebx
01007583 56 push esi
01007584 57 push edi
01007585 8B45 F8 mov eax,dword ptr ss:[ebp-8]
呵呵,终于来到了poep。。。okdodo的脚本就是跑到这里的,被偷了,想办法自己补吧,很多人发过了这之后的文章,肯定比我讲的好
前几天在啊cr他们那个群里夸口说,未来一个月内学会脱流行的这几个壳,总得有点行动,兄弟我比较笨,只能用最土的办法跟,本想从头跟到尾的,后来晕了,取了点巧,很多内容没有详细看,有空的吧
[课程]FART 脱壳王!加量不加价!FART作者讲授!