1,call eax ,进去是 oep, 根据你的图,oep == 00401000
2,处理下 iat , molebox iat 加密很简单,magic jump 就可以了
3,如果有文件捆绑,需要解绑文件。
4,补丁程序通常有自校验
如果只是脱壳,找脚本,找工具吧。
如果学习脱壳,molebox 难点在第3点,解绑文件,但是目测你前2步都没明白
想要脱VMP的壳,首要工作当然是要找一个强OD。至于是什么版本的OD自己多试验几个,网上有很多,一般来说只要加载了你想脱的VMP加壳程序不关闭都可以。
其次,就是StrongODdll这个插件了,现在用的比较多的就是海风月影。下载回来后复制到你的OD程序所在的文件夹里面的plugin里。StrongOD的设置选项搞不懂就全部打钩。
接下来要做的工作就是搞清楚我们要脱壳的程序编程的语言了,可以用PEID或者fastscanner查看,如果在这里看不到也可以在OD载入以后通过里面的字符串判断了。例如VB的程序会出现MSVB----/VC的会出现MSVC---等等。这些都是程序运行所需要的windows链接文件。
做完这些预备工作接下来当然是用OD载入文件。文件载入后在反汇编窗口CTRL+G搜索VirtualProtect(注意V跟P要大写,至于为什么要搜索这个别问我)。一般来说搜索的结果会出现以下的类似:
7C801AE3 E8 75FFFFFF call kernel32VirtualProtectEx
我们在这里下F2断点。然后F9运行到我们下的这个断点。接下来我们就要注意观察堆栈窗口了。一般来说当我们F9运行到我们上面下的断点的时候在堆栈窗口会出现以下类似:
0012F66C 00401000 |Address = TradeCen00401000
0012F670 000280D1 |Size = 280D1 (164049)
0012F674 00000004 |NewProtect = PAGE_READWRITE
0012F678 0012FF98 \pOldProtect = 0012FF98
我们要注意观察的就是在接下来我们F9运行的时候,ADDRESS和NEWPROTECT这两行的变化。按F9-速度别太快,直到NewProtect项变为PAGE_READONLY,这时候程序就释放完毕了。
0012F66C 0042A000 |Address = TradeCen0042A000
0012F670 000069DE |Size = 69DE (27102)
0012F674 00000002 |NewProtect = PAGE_READONLY
0012F678 0012FF98 \pOldProtect = 0012FF98
现在可以取消刚才我们下的断点了。接下来就是找OEP了。找OEP的时候我个人的一个经验就是OEP一般就在接近上面的ADDRESS地址的附近。例如上面的地址是0042A000,我一般就在这个基础上减到420000搜索程序的特征段,当然我们也可以直接跳到401000开始搜索。虽然我们搜索的范围比较大,但是因为我们搜索的是命令序列,所以工作量还不是很大。
CTRL+G--上面的地址,然后CTRL+S 查找命令序列。命令序列的内容就是我们用查到的编程语言的特征段。我们可以在特征段里面选择两三句固定不变的命令查找。例如VC++60的特征段是:
0046C07B U> 55 push ebp
0046C07C 8BEC mov ebp,esp
0046C07E 6A FF push -1
0046C080 68 18064C00 push UltraSna004C0618
0046C085 68 F8364700 push UltraSna004736F8
0046C08A 64:A1 00000000 mov eax,dword ptr fs:[0]
0046C090 50 push eax
0046C091 64:8925 00000000 mov dword ptr fs:[0],esp
0046C098 83EC 58 sub esp,58
0046C09B 53 push ebx
0046C09C 56 push esi
0046C09D 57 push edi
我们可以只搜索前三条命令。找到符合前三条命令的,我们在对照接下来的命令。只要命令相符那这个地址八九不离十就是OEP了。如果在ADDRESS地址附近找不到OEP,那就只好用笨办法,从401000开始找吧。
找到OEP地址后,我们在OEP处点鼠标右键《此处为新EIP》。接下来就可以dump啦。通常选择OD的dump插件脱壳要好点,用loadpe脱壳后要么程序不运行要么干脆没脱。用OD的dump插件脱壳的时候,脱壳窗口下面的(重建输入表)项前面的勾一定要去掉。
如果有反编译出来显示是“数组索引超出界限”的话,脱壳基本上是不太可能的。因为它是使用了Net Reactor这款软件进行加壳的。如果有反编译出来显示是“数组索引超出界限”的话,脱壳基本上是不太可能的。因为它是使用了Net Reactor这款软件进行加壳的。
目标软件WINME下的记事本
加壳方式Armadillo360 CopyMem-ll Debug-Blocker
调试环境:WinXP、Ollydbg、PEiD、LordPE、ImportREC 16F
1前言
为了练习脱壳,前一段时间从网上下了一个Armadillo360,然后给记事本加壳,当然本人初学破解,参考了很多大虾们的文章,然后自己模仿脱壳,可是当我修改了Magic Jump后,用401000段“内存断点”大法想到达那个盼望已久的OEP的时候,意外出现了:程序终止,退出!是我做法错误,然后我又实验了N遍,依然如此,为什么?随后又在论坛不停的搜索着,想找一些有关的知识,终于找到了(抱歉,忘记了作者是谁),而且解决了这个问题,为了使象我一样初学者不要重蹈覆辙,我决定详细的写一写,也许你认为很简单,那么请略过。
2脱壳过程(分以下几步进行)
设置Ollydbg忽略所有的异常选项,用IsDebug 14插件去掉Ollydbg的调试器标志。
(1)查找OEP
用OD中载入程序,下bp WaitForDebugEvent,F9运行,中断如下:
77E93A07 k> 55 push ebp <====中断在此处,清除断点
77E93A08 8BEC mov ebp,esp
77E93A0A 83EC 68 sub esp,68
77E93A0D 56 push esi
77E93A0E FF75 0C push dword ptr ss:[ebp C]
查看堆栈窗口:
0012DAC0 00423D67 /CALL 到 WaitForDebugEvent 来自 NOTEPAD00423D61
0012DAC4 0012EB84 |pDebugEvent = 0012EB84 <====注意这里
0012DAC8 000003E8 \Timeout = 1000 ms
在0012EB84所在的行上点击右键选“转存中跟随”。
然后再下bp WriteProcessMemory,F9运行
77E41A90 k> 55 push ebp <====中断在此处
77E41A91 8BEC mov ebp,esp
77E41A93 51 push ecx
77E41A94 51 push ecx
77E41A95 8B45 0C mov eax,dword ptr ss:[ebp C]
看数据转存窗口:
0012EB84 01 00 00 00 40 07 00 00 @
0012EB8C 5C 01 00 00 01 00 00 80 \
0012EB94 00 00 00 00 00 00 00 00
0012EB9C CC 10 40 00 02 00 00 00 @
0012EBA4 00 00 00 00 CC 10 40 00 @
0012EBAC CC 10 40 00 00 00 00 00 @
红色字体的4010CC就是OEP,这样我们接着来第2步
(2)dump文件
现在我们重新用OD中载入程序,下硬件断点,he WaitForDebugEvent,F9运行,中断如下:
77E93A07 k> 55 push ebp <====中断在此处,删除断点
77E93A08 8BEC mov ebp,esp
77E93A0A 83EC 68 sub esp,68
77E93A0D 56 push esi
77E93A0E FF75 0C push dword ptr ss:[ebp C]
Alt F9返回,搜索常数FFFFFFF8,来到(004243D6处):
0042438A > \83BD D0F5FFFF>cmp dword ptr ss:[ebp-A30],0<====参考文章里提到的关键代码
00424391 0F8C A9020000 jl NOTEPAD00424640<====跳转到00424640处,因此在00424640处下断点
00424397 8B8D D0F5FFFF mov ecx,dword ptr ss:[ebp-A30]
0042439D 3B0D E4454500 cmp ecx,dword ptr ds:[4545E4]
004243A3 0F8D 97020000 jge NOTEPAD00424640
004243A9 8B95 44F6FFFF mov edx,dword ptr ss:[ebp-9BC]
004243AF 81E2 FF000000 and edx,0FF
004243B5 85D2 test edx,edx
004243B7 0F84 AD000000 je NOTEPAD0042446A
004243BD 6A 00 push 0
004243BF 8BB5 D0F5FFFF mov esi,dword ptr ss:[ebp-A30]
004243C5 C1E6 04 shl esi,4
004243C8 8B85 D0F5FFFF mov eax,dword ptr ss:[ebp-A30]
004243CE 25 07000080 and eax,80000007
004243D3 79 05 jns short NOTEPAD004243DA
004243D5 48 dec eax
004243D6 83C8 F8 or eax,FFFFFFF8<=====搜索来到这里,向上看
004243D9 40 inc eax
004243DA > 33C9 xor ecx,ecx
004243DC 8A88 802A4500 mov cl,byte ptr ds:[eax 452A80]
004243E2 8B95 D0F5FFFF mov edx,dword ptr ss:[ebp-A30]
004243E8 81E2 07000080 and edx,80000007
004243EE 79 05 jns short NOTEPAD004243F5
004243F0 4A dec edx
004243F1 83CA F8 or edx,FFFFFFF8
004243F4 42 inc edx
004243F5 > 33C0 xor eax,eax
004243F7 8A82 812A4500 mov al,byte ptr ds:[edx 452A81]
004243FD 8B3C8D 60E244>mov edi,dword ptr ds:[ecx4 44E260]
00424404 333C85 60E244>xor edi,dword ptr ds:[eax4 44E260]
0042440B 8B8D D0F5FFFF mov ecx,dword ptr ss:[ebp-A30]
00424411 81E1 07000080 and ecx,80000007
00424417 79 05 jns short NOTEPAD0042441E
00424419 49 dec ecx
0042441A 83C9 F8 or ecx,FFFFFFF8
0042441D 41 inc ecx
0042441E > 33D2 xor edx,edx
00424420 8A91 822A4500 mov dl,byte ptr ds:[ecx 452A82]
00424426 333C95 60E244>xor edi,dword ptr ds:[edx4 44E260]
0042442D 8B85 D0F5FFFF mov eax,dword ptr ss:[ebp-A30]
00424433 99 cdq
00424434 B9 1C000000 mov ecx,1C
00424439 F7F9 idiv ecx
0042443B 8BCA mov ecx,edx
0042443D D3EF shr edi,cl
0042443F 83E7 0F and edi,0F
00424442 03F7 add esi,edi
00424444 8B15 D4454500 mov edx,dword ptr ds:[4545D4]
0042444A 8D04B2 lea eax,dword ptr ds:[edx esi4]
0042444D 50 push eax
0042444E 8B8D D0F5FFFF mov ecx,dword ptr ss:[ebp-A30]
00424454 51 push ecx
00424455 E8 FF1F0000 call NOTEPAD00426459
0042445A 83C4 0C add esp,0C
0042445D 25 FF000000 and eax,0FF<====从这里开始修改
00424462 85C0 test eax,eax
00424464 0F84 D6010000 je NOTEPAD00424640
在0042438A处下 硬件执行 断点,F9运行到0042438A处,得到ebp-A30=12EB70,这样上述的修改地方修改为:
0042445D FF05 70EB1200 inc dword ptr ds:[12EB70]
00424463 90 nop
00424464 ^ E9 21FFFFFF jmp NOTEPAD0042438A
把12EB70处置0,去掉所有断点,并在00424640处下断,F9运行,断住。好了,所有代码都强制解压完成。
运行LordPE,有2个关于NOTEPAD的进程,选择第2个,即可完全dump出来了。
(3)修复IAT表
因为Armadillo的壳使得ImportREC的"IAT AutoSearch"失效,所以必须确定IAT的RAV以及大小,为此我们用OD载入刚刚DUMP出来的文件,来确定IAT的RAV以及大小,载入之前先修改入口点为10CC,然后载入:
004010CC d> 55 push ebp
004010CD 8BEC mov ebp,esp
004010CF 83EC 44 sub esp,44
004010D2 56 push esi
004010D3 FF15 F4734000 call dword ptr ds:[4073F4]<====注意这里
004010D9 8BF0 mov esi,eax
我们可以随便找一个CALL入手确定IAT的RAV以及大小(不妨找看到的第一个CALL)。光标定位到数据转存窗口中,然后 Ctrl G,4073F4,可以看到:
004072E4 BE 7D 00 00 00 00 00 00 缄
004072EC D7 23 DA 77 46 BA 3C 00 赵F
004072F4 F0 59 DA 77 CC 5E DA 77 餣赵蘜赵
(省略若干)
004073DC 7D 15 F5 77 90 9B 3C 00 } 鮳悰<
004073E4 03 38 E5 77 67 31 E5 77 8鍂g1鍂
004073EC 3C 51 E5 77 97 2D E5 77 <Q鍂鍂
004073F4 C7 C3 3C 00 45 9A E5 77 敲<E氩w<====到达这里,由此处向上和向下看
004073FC 91 B2 3C 00 8D B8 3C 00 懖<嵏<
00407404 50 88 3C 00 CE 8A 47 77 P螉Gw
(省略若干)
00407504 EC 72 D1 77 11 9A D1 77 靣褀 氀w
0040750C 06 81 D1 77 D3 3D D1 77 布w褀
00407514 37 89 3C 00 B3 22 32 76 72v
0040751C 39 DC 33 76 3B C2 32 76 9v;v
00407524 10 1D 34 76 D6 8B 32 76 4v謰2v
0040752C B7 44 33 76 70 1B 32 76 稤3vp 2v
00407534 8B 88 3C 00 00 00 00 00 媹<
这样IAT的大小是终点-始点=00407530-004072EC=244,RVA=72EC。为什么是这样呢,我们看到很多77XXXXXX之类的,而到了00407534处是8B 88 3C 00,为了确定其是否在IAT内,我们可以在OD的CPU窗口内定位光标到401000处,然后Ctrl B,填入 34 75 40,结果搜索不到,而30 75 40能够搜索到,是JMP [407530],因此确定IAT的终点点是407530,用同样的方法可以确定起点点是4072EC。
好了,IAT的RAV以及大小确定了,现在就要修复IAT了,用OD再一次载入未脱壳的程序,bp DebugActiveProcess,F9断下。看堆栈窗口:
0012DAC4 00423BDB /CALL 到 DebugActiveProcess 来自 NOTEPAD00423BD5
0012DAC8 00000324 \ProcessId = 324<=====子进程句柄
0012DACC 0012FF2C
打开另一个OD附加324这个子进程。然后ALT+F9返回程序:
00433999 N> - EB FE jmp short NOTEPAD<ModuleEntryPoint><====中断在此处,还原代码
0043399B EC in al,dx
0043399C | 6A FF push -1
0043399E | 68 503C4500 push NOTEPAD00453C50
还原00433999处代码代码,EB FE改为55 8B,接下来就要按照FLY等大虾们的方法了。在接下来的步骤中前一部分可以参考Fly的《壹次脱壳法——Armadillo 双进程标准壳 快速脱壳》,我们从Magic Jump,避开IAT加密开始,取消以前断点,下断:BP GetModuleHandleA 5,
77E59F98 /0F84 23060000 je kernel3277E5A5C1<====中断在此处,注意看堆栈
77E59F9E |FF7424 04 push dword ptr ss:[esp 4]
77E59FA2 |E8 55080000 call kernel3277E5A7FC
77E59FA7 |85C0 test eax,eax
在这里中断若干次,注意堆栈窗口的变化,当出现:
0012BF20 00AAC807 返回到 00AAC807 来自 kernel32GetModuleHandleA
0012BF24 00ABD6C8 ASCII "kernel32dll"
0012BF28 00ABE67C ASCII "VirtualAlloc"
0012BF20 00AAC824 返回到 00AAC824 来自 kernel32GetModuleHandleA
0012BF24 00ABD6C8 ASCII "kernel32dll"
0012BF28 00ABE670 ASCII "VirtualFree"
0012BC98 00A9799B 返回到 00A9799B 来自 kernel32GetModuleHandleA
0012BC9C 0012BDD4 ASCII "kernel32dll"
然后Alt F9返回,
00A97995 FF15 C480AB00 call dword ptr ds:[AB80C4] ; kernel32GetModuleHandleA
00A9799B 8B0D E011AC00 mov ecx,dword ptr ds:[AC11E0]<====返回到这里
00A979A1 89040E mov dword ptr ds:[esi ecx],eax
00A979A4 A1 E011AC00 mov eax,dword ptr ds:[AC11E0]
00A979A9 393C06 cmp dword ptr ds:[esi eax],edi
00A979AC 75 16 jnz short 00A979C4
00A979AE 8D85 B4FEFFFF lea eax,dword ptr ss:[ebp-14C]
00A979B4 50 push eax
00A979B5 FF15 CC80AB00 call dword ptr ds:[AB80CC] ; kernel32LoadLibraryA
00A979BB 8B0D E011AC00 mov ecx,dword ptr ds:[AC11E0]
00A979C1 89040E mov dword ptr ds:[esi ecx],eax
00A979C4 A1 E011AC00 mov eax,dword ptr ds:[AC11E0]
00A979C9 393C06 cmp dword ptr ds:[esi eax],edi
00A979CC 0F84 AD000000 je 00A97A7F<====Magic Jump,修改为JMP
00A979D2 33C9 xor ecx,ecx
00A979D4 8B03 mov eax,dword ptr ds:[ebx]
修改了上面的Magic Jump后,清除所有断点,Alt M ,在401000上下 内存访问断点,F9运行,这次中断到了OEP,然后运行ImportREC,选择324这个进程,OEP填:10CC,RVA:72EC,SIZE:244,然后“Get Imports”,再按“Show Invalid”地址,剪掉修复抓取文件,程序能够正常运行,至此脱壳完毕 !第一次用OD脱壳,感觉就是爽,和Softice比起来,感觉OD脱壳很方便
软件编写以后有些人为了防止被破解或者其他目的就给软件加上壳所谓壳其实也就是一种压缩算法,可以将程序压缩当然这个压缩不同于 WinRAR 的那个压缩例如假设一个程序是100KB用UPX压缩后大概是 40-60KB 压缩好后你再用WinRAR 压缩可能就只有10+KB了他的原理很简单,先将本身的程序压缩,然后当对方运行时,先将本身程序放入内存,在内存中释放出来,当然这个解压速度非常快,基本感觉不出来但是程序未运行的时候是经过压缩的所以就可以避免被破解等下面是关键了:一些人还有中比较通用的方法,就是先将程序执行,这样程序在内存中被解压,然后将内存中的数据抓出来,保存到硬盘,这个方法基本所有壳通杀已经回答了2个了至于脱壳程序和没脱的(条件是软件有壳的情况下)一般有壳程序运行速度会略微比较慢,程序大的比较明显加了壳的程序一般比较小另外就是加了壳的不容易被破解,大致区别就这些了
以上就是关于这个程序怎么去脱壳全部的内容,包括:这个程序怎么去脱壳、怎么脱E语言程序的VMP壳、关于.net程序 MaxtoCode 脱壳求助等相关内容解答,如果想了解更多相关内容,可以关注我们,你们的支持是我们更新的动力!
欢迎分享,转载请注明来源:内存溢出
评论列表(0条)