特定码——用OllyDBG手脱Enigma Protector V1.12加壳的试炼品
破解下载: http://www.unpack.cn/viewthread.php?tid=3806
软件大小: 1.21 M
软件简介: Enigma Protector serves for software protection of applications. It defending your work from program crackers with state-of-the-art encryption, data compression, and other security features. Enigma Protector provides creation trial and registered applications, with possibility of the checking mode parameters with help internal Enigma API functions. It allows you to design and add a complete software protection and registration-key system to your existing programs. It works with any language which produce Windows PE files. Enigma works with Win PE 32 executables (*.exe), screen savers (*.scr), dynamic libraryes (*.dll, *.ocx).
【作者声明】:只是感兴趣,没有其他目的。失误之处敬请诸位大侠赐教
【调试环境】:WinXP、OllyDBD、PEiD、LordPE、ImportREC
—————————————————————————————————
【脱壳过程】:
ENIGMA Protector是俄罗斯新出的一款保护壳,有发展为猛壳的潜质。
使用ENIGMA Protector V1.12.CracKed.eXe对Win98的记事本加壳。
选项如下:
—————————————————————————————————
一、特定码
特定码 ?
先简单说个例子吧,UPX的手动脱壳大家想必都清楚了。
一般我们会Ctrl+F搜索popad,或者Ctrl+B搜索61E9
0040EA1E 61 popad
//会搜索到这里
0040EA1F E9 A826FFFF jmp 004010CC
//飞向光明之巅
我们都知道,对于UPX来说,popad就是其跳转OEP前的特定命令。
如果写OllyScript脚本的话可以这样:
findop eip,#61#
推而广之:对于其它壳来说,我们在其处理输入表、跳OEP等过程中有的也可以找到这样特定的命令,而这些命令对于某壳某些版本来说是固定的,可以被反复验证使用,借助这些特定代码,可以大大简化对此壳的脱壳步骤、节省脱壳时间。
此类代码姑且我名之曰:特定码。
当然,你可以用其它的名称。下面就使用ENIGMA Protector的特定码来演示对其试炼品脱壳。
shoooo写过《Enigma protector V1.02.build.4.00 主程序脱壳》,建议先参看。
—————————————————————————————————
二、代码段解码+首次处理输入表加密
设置OllyDBD忽略所有异常选项。
清除以前的所有断点,用IsDebug插件去掉OllyDBD的调试器标志。
00421B93 60 pushad
//进入OllyDBG后暂停在这
00421B94 E8 00000000 call 00421B99
00421B99 5D pop ebp
00421B9A 83C5 FA add ebp,-6
Alt+M,在代码段401000段设置内存写入断点,Shift+F9
Wait ……
00D4267F F3:A5 rep movs dword ptr es:[edi],dword ptr ds:[esi]
//中断在这里
00D42681 89C1 mov ecx,eax
00D42683 83E1 03 and ecx,3
00D42686 F3:A4 rep movs byte ptr es:[edi],byte ptr ds:[esi]
00D42688 5F pop edi
00D42689 5E pop esi
00D4268A C3 retn
Enigma Protector对程序输入表加密的样式如下:
0040343A FF15 F0634000 call dword ptr ds:[4063F0] ; SHELL32.ShellExecuteA
//原始的
0040343A FF15 396ED900 call dword ptr ds:[D96E39] ; 00D97318
//加密后
[D96E39]处原先保存的是API系统函数地址,Enigma Protector在下面要改成加密地址。
或许不容易理解,多做几遍认真分析就明白了。
Ctrl+S 搜索命令序列:
inc esi
dec ebp
00D509D9 8B07 mov eax,dword ptr ds:[edi]
00D509DB 33D2 xor edx,edx
00D509DD E8 DA050000 call 00D50FBC
00D509E2 8BD8 mov ebx,eax
00D509E4 84DB test bl,bl
00D509E6 74 24 je short 00D50A0C
00D509E8 33C9 xor ecx,ecx
00D509EA 8ACB mov cl,bl
00D509EC 8BD7 mov edx,edi
00D509EE 8B4424 08 mov eax,dword ptr ss:[esp+8]
00D509F2 E8 C145FFFF call 00D44FB8
00D509F7 33C0 xor eax,eax
00D509F9 8AC3 mov al,bl
00D509FB 03F8 add edi,eax
00D509FD 33C0 xor eax,eax
00D509FF 8AC3 mov al,bl
00D50A01 014424 08 add dword ptr ss:[esp+8],eax
00D50A05 33DB xor ebx,ebx
00D50A07 E9 82F8FFFF jmp 00D5028E
00D50A0C 803C24 00 cmp byte ptr ss:[esp],0
00D50A10 75 21 jnz short 00D50A33
00D50A12 8B4424 08 mov eax,dword ptr ss:[esp+8]
00D50A16 C600 68 mov byte ptr ds:[eax],68
00D50A19 FF4424 08 inc dword ptr ss:[esp+8]
00D50A1D 8B4424 08 mov eax,dword ptr ss:[esp+8]
00D50A21 8938 mov dword ptr ds:[eax],edi
00D50A23 834424 08 04 add dword ptr ss:[esp+8],4
00D50A28 8B4424 08 mov eax,dword ptr ss:[esp+8]
00D50A2C C600 C3 mov byte ptr ds:[eax],0C3
00D50A2F FF4424 08 inc dword ptr ss:[esp+8]
00D50A33 8D04F6 lea eax,dword ptr ds:[esi+esi*8]
00D50A36 8B15 1000D700 mov edx,dword ptr ds:[D70010]
00D50A3C 8B4C24 04 mov ecx,dword ptr ss:[esp+4]
00D50A40 894C02 01 mov dword ptr ds:[edx+eax+1],ecx
//改写加密的API地址,需要修改。
00D50A44 46 inc esi
//找到这里
00D50A45 4D dec ebp
00D50A46 0F85 D3F7FFFF jnz 00D5021F
00D50A4C 83C4 14 add esp,14
00D50A4F 5D pop ebp
00D50A50 5F pop edi
00D50A51 5E pop esi
00D50A52 5B pop ebx
00D50A53 C3 retn
但是现在还不能修改00D50A40,因为有检验。继续看
—————————————————————————————————
三、去除壳检验
注意,此时我们不能使用硬件断点也不能使用普通断点以及修改壳代码。
硬件断点的Anti没有分析,猜测是采用类似tELock清除DRx的方法,而壳代码内的普通断点则是由壳检验来“包含”检测。
现在选择00D50A40处的几个字节,右键->断点->内存访问
Shit+F9,中断在00D525E8处,这里就是计算检验值了。
00D525E3 33F6 xor esi,esi
00D525E5 8D143E lea edx,dword ptr ds:[esi+edi]
00D525E8 8A12 mov dl,byte ptr ds:[edx]
00D525EA 92 xchg eax,edx
00D525EB E8 BCFFFFFF call 00D525AC
00D525F0 46 inc esi
00D525F1 4B dec ebx
00D525F2 75 F1 jnz short 00D525E5
//循环计算壳代码检验值
00D525F4 83F0 FF xor eax,FFFFFFFF
00D525F7 EB 02 jmp short 00D525FB
00D525F9 33C0 xor eax,eax
00D525FB 5F pop edi
00D525FC 5E pop esi
00D525FD 5B pop ebx
00D525FE 5D pop ebp
00D525FF C2 0800 retn 8
清除内存断点,F4至00D525F7处,EAX=6386B0E0,这个就是此程序壳代码的检验值。
因为我们避开代码段、输入表加密时要修改壳代码,所以这里需要把检验值固定下来,否则壳就挂了。
0D525F4处固定检验值修改如下:
00D525F4 B8 E0B08663 mov eax,6386B0E0 ★
00D525F9 90 nop
00D525FA 90 nop
00D525FB 5F pop edi
00D525FC 5E pop esi
00D525FD 5B pop ebx
00D525FE 5D pop ebp
00D525FF C2 0800 retn 8
现在可以修改00D50A40处避开加密了:
00D50A40 894C02 01 mov dword ptr ds:[edx+eax+1],ecx
//改写加密的API地址,修改为NOP ★
00D50A44 46 inc esi
————————————————————————
附:ENIGMA Protector对API普通断点的检测
00D50BAA 8B1E mov ebx,dword ptr ds:[esi]
00D50BAC 80FB CC cmp bl,0CC
00D50BAF 75 18 jnz short 00D50BC9
00D50BB1 8D45 F8 lea eax,dword ptr ss:[ebp-8]
00D50BB4 8B15 E0D4D500 mov edx,dword ptr ds:[D5D4E0]
00D50BBA 8B12 mov edx,dword ptr ds:[edx]
00D50BBC E8 872DFFFF call 00D43948
00D50BC1 8B45 F8 mov eax,dword ptr ss:[ebp-8]
00D50BC4 E8 4F000000 call 00D50C18
00D50BC9 B2 01 mov dl,1
00D50BCB 8BC3 mov eax,ebx
00D50BCD E8 EA030000 call 00D50FBC
00D50BD2 25 FF000000 and eax,0FF
00D50BD7 03F0 add esi,eax
00D50BD9 80C3 3E add bl,3E
00D50BDC 80EB 02 sub bl,2
00D50BDF 72 09 jb short 00D50BEA
00D50BE1 80EB 25 sub bl,25
00D50BE4 74 04 je short 00D50BEA
00D50BE6 85C0 test eax,eax
00D50BE8 75 C0 jnz short 00D50BAA
00D50BEA 83C7 04 add edi,4
00D50BED FF4D FC dec dword ptr ss:[ebp-4]
00D50BF0 75 AB jnz short 00D50B9D
—————————————————————————————————
四、搞定普通加密的输入表
Ctrl+S 在“整个段块”搜索命令序列:
inc ebx
dec dword ptr ss:[esp]
找到在00D4FB00处,在其上的00D4FAFA处下断,Shift+F9,确定弹出的演示提示,中断下来
00D4FAA8 E8 3B47FFFF call 00D441E8
00D4FAAD 48 dec eax
00D4FAAE 85C0 test eax,eax
00D4FAB0 72 54 jb short 00D4FB06
00D4FAB2 40 inc eax
00D4FAB3 890424 mov dword ptr ss:[esp],eax
00D4FAB6 33DB xor ebx,ebx
00D4FAB8 8D04DB lea eax,dword ptr ds:[ebx+ebx*8]
00D4FABB 8B16 mov edx,dword ptr ds:[esi]
00D4FABD 8B4402 05 mov eax,dword ptr ds:[edx+eax+5]
00D4FAC1 E8 2247FFFF call 00D441E8
00D4FAC6 8BD0 mov edx,eax
00D4FAC8 4A dec edx
00D4FAC9 85D2 test edx,edx
00D4FACB 72 33 jb short 00D4FB00
00D4FACD 42 inc edx
00D4FACE 33C0 xor eax,eax
00D4FAD0 8D0CDB lea ecx,dword ptr ds:[ebx+ebx*8]
00D4FAD3 8B3E mov edi,dword ptr ds:[esi]
00D4FAD5 8B7C0F 05 mov edi,dword ptr ds:[edi+ecx+5]
00D4FAD9 833C87 00 cmp dword ptr ds:[edi+eax*4],0
00D4FADD 74 1D je short 00D4FAFC
00D4FADF 8B3E mov edi,dword ptr ds:[esi]
00D4FAE1 8D4C0F 01 lea ecx,dword ptr ds:[edi+ecx+1]
00D4FAE5 8D3CDB lea edi,dword ptr ds:[ebx+ebx*8]
00D4FAE8 8B2E mov ebp,dword ptr ds:[esi]
00D4FAEA 8B7C3D 05 mov edi,dword ptr ss:[ebp+edi+5]
00D4FAEE 8B3C87 mov edi,dword ptr ds:[edi+eax*4]
00D4FAF1 8B2D C4D5D500 mov ebp,dword ptr ds:[D5D5C4]
00D4FAF7 037D 00 add edi,dword ptr ss:[ebp]
00D4FAFA 890F mov dword ptr ds:[edi],ecx
//修改IAT地址为加密地址,这里下断。
//修改为:JMP 00D4FB0C ★
00D4FAFC 40 inc eax
00D4FAFD 4A dec edx
00D4FAFE 75 D0 jnz short 00D4FAD0
00D4FB00 43 inc ebx
//找到这里
00D4FB01 FF0C24 dec dword ptr ss:[esp]
00D4FB04 75 B2 jnz short 00D4FAB8
00D4FB06 5A pop edx
00D4FB07 5D pop ebp
00D4FB08 5F pop edi
00D4FB09 5E pop esi
00D4FB0A 5B pop ebx
00D4FB0B C3 retn
//再次下断
Patch 代码如下:
00D4FB0C 56 push esi
00D4FB0D 53 push ebx
00D4FB0E 8B31 mov esi,dword ptr ds:[ecx] ; shell32.ShellExecuteA
//[ecx]是正确的API函数系统地址
00D4FB10 8B1F mov ebx,dword ptr ds:[edi]
//[edi]是IAT地址
00D4FB12 8933 mov dword ptr ds:[ebx],esi
//放入正确的API函数系统地址
00D4FB14 5B pop ebx
00D4FB15 5E pop esi
00D4FB16 EB E4 jmp short 00D4FAFC
//循环
从OllyDBG中二进制复制:
56 53 8B 31 8B 1F 89 33 5B 5E EB E4
写好Patch代码后在00D4FB0B处下断,Shift+F9,中断后输入表处理完毕
可以运行LordPE完全Dump此进程了,否则下面要进行某些重定位处理了 ★
在数据窗口察看输入表函数:
004062DC 00000000
004062E0 77DAEBE7 advapi32.RegSetValueExA
//开始
004062E4 77DA7883 advapi32.RegQueryValueExA
…… ……
00406514 763300CE comdlg32.CommDlgExtendedError
00406518 76322533 comdlg32.GetFileTitleA
0040651C 00000000
//结束
运行ImportREC,填入IAT RVA=000062E0,Size=0000023C
获取输入表,发现几个无效的特殊函数,等到OEP后再分析看看。
—————————————————————————————————
五、避开数据段地址重定位
Enigma Protector还会对数据段地址重定位,如:
00401159 A1 B8574000 mov eax,dword ptr ds:[4057B8]
//原始的
00401159 A1 B8F7D800 mov eax,dword ptr ds:[D8F7B8]
//重定位后
Ctrl+F 搜索命令:
and eax,7FFFFFFF
找到在00D5AC35处,在其上的00D5ABE0处下断,Shift+F9,中断后取消断点
00D5ABE0 A9 00000080 test eax,80000000
//这里下断
00D5ABE5 75 28 jnz short 00D5AC0F
00D5ABE7 8B15 84D4D500 mov edx,dword ptr ds:[D5D484]
00D5ABED 8B12 mov edx,dword ptr ds:[edx]
//[edx]=[00D5C304]=00D8F000 ★
00D5ABEF 8B0D C4D5D500 mov ecx,dword ptr ds:[D5D5C4]
00D5ABF5 2B11 sub edx,dword ptr ds:[ecx]
00D5ABF7 8B0D C8D5D500 mov ecx,dword ptr ds:[D5D5C8]
00D5ABFD 2B91 ED000000 sub edx,dword ptr ds:[ecx+ED]
00D5AC03 8B0D C4D5D500 mov ecx,dword ptr ds:[D5D5C4]
00D5AC09 0301 add eax,dword ptr ds:[ecx]
00D5AC0B 0110 add dword ptr ds:[eax],edx
00D5AC0D EB 36 jmp short 00D5AC45
00D5AC0F 8B0D 84D4D500 mov ecx,dword ptr ds:[D5D484]
00D5AC15 8B09 mov ecx,dword ptr ds:[ecx]
00D5AC17 8B35 C4D5D500 mov esi,dword ptr ds:[D5D5C4]
00D5AC1D 2B0E sub ecx,dword ptr ds:[esi]
00D5AC1F 8B15 C8D5D500 mov edx,dword ptr ds:[D5D5C8]
00D5AC25 8B92 ED000000 mov edx,dword ptr ds:[edx+ED]
00D5AC2B 2BCA sub ecx,edx
00D5AC2D 8B35 84D4D500 mov esi,dword ptr ds:[D5D484]
00D5AC33 8B36 mov esi,dword ptr ds:[esi]
00D5AC35 25 FFFFFF7F and eax,7FFFFFFF
//找到这里
00D5AC3A 03F0 add esi,eax
00D5AC3C A1 C8D5D500 mov eax,dword ptr ds:[D5D5C8]
00D5AC41 2BF2 sub esi,edx
00D5AC43 010E add dword ptr ds:[esi],ecx
00D5AC45 8305 D002D700 04 add dword ptr ds:[D702D0],4
00D5AC4C A1 D002D700 mov eax,dword ptr ds:[D702D0]
00D5AC51 8B00 mov eax,dword ptr ds:[eax]
00D5AC53 85C0 test eax,eax
00D5AC55 75 89 jnz short 00D5ABE0
00D5AC57 A1 C8D5D500 mov eax,dword ptr ds:[D5D5C8]
//数据段地址重定位处理完毕
00D5AC5C 8378 34 00 cmp dword ptr ds:[eax+34],0
00D5AC60 0F84 9E000000 je 00D5AD04
当我们走至00D5ABED时,在数据窗口中跟随[edx],00D8F000处保存的就是还未重定位的数据段!
看看Test.ENIGMA.Protector.eXe的数据段VirtualSize=00001000,00D8F000+00001000=00D90000
在OllyDBG中把00D8F000-00D90000处数据二进制复制,然后用WinHex保存为data.bin
F4至00D5AC57处,数据段地址重定位处理完毕
—————————————————————————————————
六、OEP + Stolen OEP Code
准备找OEP吧,你也可以根据目标程序的语言特征或者其它方法来走至OEP
Ctrl+S 在“整个段块”搜索命令序列:
popad
retn
找到在00D4B4DB处,选择00D4B4DB处一些字节,设置内存访问断点
00D4B4C4 68 544F4550 push 50454F54
00D4B4C9 60 pushad
00D4B4CA 31C0 xor eax,eax
00D4B4CC B9 5453495A mov ecx,5A495354
00D4B4D1 BF 54414452 mov edi,52444154
00D4B4D6 F2:AA repne stos byte ptr es:[edi]
00D4B4D8 47 inc edi
00D4B4D9 AB stos dword ptr es:[edi]
00D4B4DA AB stos dword ptr es:[edi]
00D4B4DB 61 popad
//找到这里,设置内存访问断点
00D4B4DC C3 retn
Shift+F9,中断后取消内存断点
00D525E8 8A12 mov dl,byte ptr ds:[edx]
//中断在这里
00D525EA 92 xchg eax,edx
00D525EB E8 BCFFFFFF call 00D525AC
00D525F0 46 inc esi
00D525F1 4B dec ebx
00D525F2 75 F1 jnz short 00D525E5
00D525F4 B8 E0B08663 mov eax,6386B0E0
00D525F9 90 nop
00D525FA 90 nop
00D525FB 5F pop edi
00D525FC 5E pop esi
00D525FD 5B pop ebx
00D525FE 5D pop ebp
00D525FF C2 0800 retn 8
原来这里还要校验,取消内存断点,00D525FF处下断,Shift+F9,中断后取消断点。
再次在00D4B4DB处设置内存访问断点,Shift+F9,中断后取消断点。
00D4B52C 8B16 mov edx,dword ptr ds:[esi]
//中断在这里
00D4B52E 81FA 54414452 cmp edx,52444154
00D4B534 74 18 je short 00D4B54E
00D4B536 81FA 544F4550 cmp edx,50454F54
00D4B53C 74 10 je short 00D4B54E
00D4B53E 81FA 5453495A cmp edx,5A495354
00D4B544 74 08 je short 00D4B54E
00D4B546 81FA 43524354 cmp edx,54435243
00D4B54C 75 40 jnz short 00D4B58E
00D4B54E 8BDA mov ebx,edx
00D4B550 81EB 544F4550 sub ebx,50454F54
00D4B556 74 1F je short 00D4B577
00D4B558 81EB 00F2FE01 sub ebx,1FEF200
00D4B55E 74 12 je short 00D4B572
00D4B560 81EB EF10FF01 sub ebx,1FF10EF
00D4B566 74 19 je short 00D4B581
00D4B568 81EB 11010606 sub ebx,6060111
00D4B56E 74 0C je short 00D4B57C
00D4B570 EB 12 jmp short 00D4B584
00D4B572 8B55 0C mov edx,dword ptr ss:[ebp+C]
00D4B575 EB 0D jmp short 00D4B584
00D4B577 8B55 FC mov edx,dword ptr ss:[ebp-4]
00D4B57A EB 08 jmp short 00D4B584
00D4B57C 8B55 10 mov edx,dword ptr ss:[ebp+10]
00D4B57F EB 03 jmp short 00D4B584
00D4B581 8B55 08 mov edx,dword ptr ss:[ebp+8]
00D4B584 8910 mov dword ptr ds:[eax],edx
00D4B586 83C0 04 add eax,4
00D4B589 83C6 04 add esi,4
00D4B58C EB 9E jmp short 00D4B52C
00D4B58E 81FA 54454E44 cmp edx,444E4554
00D4B594 74 06 je short 00D4B59C
00D4B596 8810 mov byte ptr ds:[eax],dl
//注意这里,EAX=00D92CD8,壳把00D4B4DB处数据又挪移了 ★
00D4B598 40 inc eax
00D4B599 46 inc esi
00D4B59A EB 90 jmp short 00D4B52C
00D4B59C 2BF1 sub esi,ecx
00D4B59E 8BCE mov ecx,esi
00D4B5A0 8BC1 mov eax,ecx
00D4B5A2 5E pop esi
00D4B5A3 5B pop ebx
00D4B5A4 59 pop ecx
00D4B5A5 5D pop ebp
00D4B5A6 C2 0C00 retn 0C
//这里下断,,Shift+F9,中断后取消断点。
Enigma Protector 当完搬运工后我们去00D92CD8处看看
在00D92CDB的popad处下断,Shift+F9,中断后取消断点。
00D92CD7 AA stos byte ptr es:[edi]
//清理战场
00D92CD8 47 inc edi
00D92CD9 AB stos dword ptr es:[edi]
00D92CDA AB stos dword ptr es:[edi]
00D92CDB 61 popad
//这里下断
00D92CDC C3 retn
//返回到 004010D3 --> 飞向光明之巅 ★
004010D3 FF15 E0634000 call dword ptr ds:[4063E0]
//Stolen OEP
004010D9 8BF0 mov esi,eax
004010DB 8A00 mov al,byte ptr ds:[eax]
004010DD 3C 22 cmp al,22
004010DF 75 13 jnz short 004010F4
很明显,OEP被Stolen了几行代码。
由于Enigma Protector这部分处理比较长,没有跟踪了,直接看堆栈和寄存器情况恢复吧。
EAX FFFFFF02
ECX 00D92C9A
EDX 29ACE3D8
EBX 07A25951
ESP 0012FF78
EBP 0012FFC0
ESI 6B7BFD9F
EDI 29ACE452
EIP 004010D3
0012FF78 6B7BFD9F
0012FF7C 00000000
0012FF80 00000000
0012FF84 00000000
ESP=0012FF78
EBP=0012FFC0
ESI=6B7BFD9F
Stolen OEP Code 修复代码为:
push ebp
mov ebp,esp
sub esp,44
push esi
当然,Stolen OEP Code 这样修复需要你分析好调试器当时情况以及了解各编译语言的特征。
—————————————————————————————————
七、修复输入表的特殊函数+完成脱壳
ImportREC里面显示的无效函数如下:
0 00006394 ? 0000 00D4E50C
0 00006398 ? 0000 00D4E4FC
0 000063E0 ? 0000 00D4E74C
Ctrl+G:00D4E50C
00D4E50C 55 push ebp
00D4E50D 8BEC mov ebp,esp
00D4E50F 8B45 08 mov eax,dword ptr ss:[ebp+8]
00D4E512 85C0 test eax,eax
00D4E514 74 08 je short 00D4E51E
00D4E516 50 push eax
00D4E517 E8 4C69FFFF call 00D44E68 ; jmp to kernel32.GetModuleHandleA
00D4E51C EB 05 jmp short 00D4E523
00D4E51E A1 D0FFD600 mov eax,dword ptr ds:[D6FFD0]
00D4E523 5D pop ebp
00D4E524 C2 0400 retn 4
可以判定00006394是GetModuleHandleA
Ctrl+G:00D4E4FC
00D4E4FC 55 push ebp
00D4E4FD 8BEC mov ebp,esp
00D4E4FF 8B45 08 mov eax,dword ptr ss:[ebp+8]
00D4E502 50 push eax
00D4E503 E8 0869FFFF call 00D44E10 ; jmp to kernel32.ExitProcess
00D4E508 5D pop ebp
00D4E509 C2 0400 retn 4
可以判定00006398是ExitProcess
000063E0的需要跟踪看看了,正好在Stolen OEP处,跟踪看看
004010D3 FF15 E0634000 call dword ptr ds:[4063E0]
00D4E74C E8 02000000 call 00D4E753
00D4E753 83C4 04 add esp,4
00D4E756 68 7EE7D400 push 0D4E77E
00D4E75B 64:FF35 00000000 push dword ptr fs:[0]
00D4E762 EB 05 jmp short 00D4E769
00D4E769 64:8925 00000000 mov dword ptr fs:[0],esp
00D4E770 31C0 xor eax,eax
00D4E772 E8 02000000 call 00D4E779
00D4E779 83C4 04 add esp,4
00D4E77C 3100 xor dword ptr ds:[eax],eax
//异常
00D4E77E E8 05000000 call 00D4E788
//SE 句柄 下断,Shift+F9后中断
00D4E788 83C4 04 add esp,4
00D4E78B 8B4424 0C mov eax,dword ptr ss:[esp+C]
00D4E78F C780 B8000000 B5E7>mov dword ptr ds:[eax+B8],0D4E7B5
//00D4E7B5处下断
00D4E799 8B0D E4FFD600 mov ecx,dword ptr ds:[D6FFE4]
//注意[D6FFE4]处的值
//"D:\UnPacK\ENIGMA Protector\Enigma Protector V1.12\Test\Test.ENIGMA.Protector.eXe""
00D4E79F 8988 B0000000 mov dword ptr ds:[eax+B0],ecx
00D4E7A5 E8 05000000 call 00D4E7AF
00D4E7AF 83C4 04 add esp,4
00D4E7B2 31C0 xor eax,eax
00D4E7B4 C3 retn
//Shift+F9
00D4E7B5 EB 05 jmp short 00D4E7BC
//00D4E7B5处中断,EAX=[D6FFE4]处的值
注意,[D6FFE4]处的值是壳执行GetCommandLineA后获得的结果
Enigma Protector准备了不少特殊函数,类似ASProtect V1.2X的特殊函数。
在ImportREC里面修正这几个函数,填入OEP RVA=10CC后FixDump
修正dumped_.exe的OEP处Stolen OEP Code
用WinHex把第五步获得的data.bin数据写入到dumped_.exe的数据段0X00005000处,保存。
终于完成这个试炼品的脱壳了。
当然,Enigma Protector主程序的脱壳比试炼品要复杂,有几个SDK需要修复。
—————————————————————————————————
八、特定码
痛并快乐着 ……
用心地写脱壳教程,越来越像是自虐
如何知道哪些是可用的特定码?
多次的调试和分析从而总结出来的。
特定码:
特定壳在运行的特定流程中可以被利用的特定代码。
—————————————————————————————————
, _/
/| _.-~/ \_ , 青春都一晌
( /~ / \~-._ |\
`\\ _/ \ ~\ ) 忍把浮名
_-~~~-.) )__/;;,. \_ //'
/'_,\ --~ \ ~~~- ,;;\___( (.-~~~-. 换了脱壳轻狂
`~ _( ,_..--\ ( ,;'' / ~-- /._`\
/~~//' /' `~\ ) /--.._, )_ `~
" `~" " `" /~'`\ `\\~~\
" " "~' ""
UnPacKed By : fly
2006-04-14 19:00