对于软件破解的同学应该都知道ESP定律,ESP定律是在脱壳中运用最广泛的一种方法,适用于大部分程序脱壳。
至于什么是ESP定律?我们不用太过于钻研这个,就当作是一个名字吧,我们要知道的就是:ESP定律用来脱壳的。
为了学习更方便,易捷博客网简单制作了一款软件,并加上了 UPX 的壳,来看下PEID的查壳截图
我们今天要做的就是把这个UPX壳脱掉,下面介绍的就是去壳教程。主要掌握其原理就可以了。
所需软件:
OD https://www.vxia.net/post-378.html
PEID https://www.vxia.net/post-219.html
所测试的程序,下载地址会放在文章底部。
注:脱壳时,如果是 64 位操作系统,建议使用虚拟机安装 32位 系统进行脱壳。否则脱壳后可能会导致打开提示错误。
易捷博客网在 WIN8.1的环境下,安装了一个虚拟机,里面用的是XP系统。
下面正式开始我们的教程:
1、使用OD 载入程序,会有下面的提示框,我们 点“否” 就可以了。
2、点否之后,我们会停留在这个位置,在右侧有个寄存器窗口,我们按下 F8 ,注意看右侧寄存器窗口的变化。
按下F8之后,可以看到右侧寄存器发生了变化,只有 ESP 和 EIP 为红色
3、然后我们在寄存器窗口里的ESP这里右键,选择“数据窗口中跟随”
也可以在最下面的Command窗口中输入dd 0012FFA4,跟踪到这个位置。
4、然后,我们需要在左下角的位置,(注意:是左下角,不是左边。)
右键--断点--硬件访问--Word
也可以在最下面的Command窗口中输入HR 0012FFA4,直接进行断点。
5、我们设置断点后,按 F9 运行程序,程序会在我们设置断点的位置停下,如下图所示
6、然后我们按 F8 单步走下去,但是注意这里是一个向上的跳转。
凡是向上的跳转,我们就用鼠标选中他的下一行,按下F4,让程序直接到跳转的下面。
7、我们继续单步走1次之后,发现又是一个跳转,但这个跳转没有箭头的指向,是一个无条件跳转。JMP!
这是一个大的跳转,这次我们继续按 F8 让程序走下去,因为这有可能就是跳到了程序的OEP(OEP就是程序入口)
所以,我们继续 按F8键。
现在我们就已经跳转到了程序的入口,如下图所示,下图是易语言程序的入口。
至于是怎么知道是程序的入口的,每个编程语言的程序入口都是不同的。易语言的入口跟C语言的类似。
(脱壳方法都是一样的,只是程序入口的样子不同而已)
其它语言的程序入口,我们发表在文章底部。
8、把刚才我们设置的断点删掉。
9、断点删除掉以后,我们在入口处右键--用OllyDump脱壳调试进程
然后会弹出一个窗口,我们直接 点 脱壳 就可以了
最后,我们使用PEID查看下脱壳保存的文件,并看看是否能正常打开。
附:
常见程序入口点(OEP)特征
delphi: 55 PUSH EBP 8BEC MOV EBP,ESP 83C4 F0 ADD ESP,-10 B8 A86F4B00 MOV EAX,PE.004B6FA8 vc++ 55 PUSH EBP 8BEC MOV EBP,ESP 83EC 44 SUB ESP,44 56 PUSH ESI vc6.0 55 push ebp 8BEC mov ebp,esp 6A FF push -1 vc7.0 6A 70 push 70 68 50110001 push hh.01001150 E8 1D020000 call hh.010017B0 33DB xor ebx,ebx vb: 00401166 - FF25 6C104000 JMP DWORD PTR DS:[<&MSVBVM60.#100>] ; MSVBVM60.ThunRTMain 0040116C > 68 147C4000 PUSH PACKME.00407C14 00401171 E8 F0FFFFFF CALL <JMP.&MSVBVM60.#100> 00401176 0000 ADD BYTE PTR DS:[EAX],AL 00401178 0000 ADD BYTE PTR DS:[EAX],AL 0040117A 0000 ADD BYTE PTR DS:[EAX],AL 0040117C 3000 XOR BYTE PTR DS:[EAX],AL bc++ 0040163C > $ /EB 10 JMP SHORT BCLOCK.0040164E 0040163E |66 DB 66 ; CHAR 'f' 0040163F |62 DB 62 ; CHAR 'b' 00401640 |3A DB 3A ; CHAR ':' 00401641 |43 DB 43 ; CHAR 'C' 00401642 |2B DB 2B ; CHAR '+' 00401643 |2B DB 2B ; CHAR '+' 00401644 |48 DB 48 ; CHAR 'H' 00401645 |4F DB 4F ; CHAR 'O' 00401646 |4F DB 4F ; CHAR 'O' 00401647 |4B DB 4B ; CHAR 'K' 00401648 |90 NOP 00401649 |E9 DB E9 0040164A . |98E04E00 DD OFFSET BCLOCK.___CPPdebugHook 0040164E > \A1 8BE04E00 MOV EAX,DWORD PTR DS:[4EE08B] 00401653 . C1E0 02 SHL EAX,2 00401656 . A3 8FE04E00 MOV DWORD PTR DS:[4EE08F],EAX 0040165B . 52 PUSH EDX 0040165C . 6A 00 PUSH 0 ; /pModule = NULL 0040165E . E8 DFBC0E00 CALL <JMP.&KERNEL32.GetModuleHandleA> ; \GetModuleHandleA 00401663 . 8BD0 MOV EDX,EAX dasm: 00401000 >/$ 6A 00 PUSH 0 ; /pModule = NULL 00401002 |. E8 C50A0000 CALL <JMP.&KERNEL32.GetModuleHandleA> ; \GetModuleHandleA 00401007 |. A3 0C354000 MOV DWORD PTR DS:[40350C],EAX 0040100C |. E8 B50A0000 CALL <JMP.&KERNEL32.GetCommandLineA> ; [GetCommandLineA 00401011 |. A3 10354000 MOV DWORD PTR DS:[403510],EAX 00401016 |. 6A 0A PUSH 0A ; /Arg4 = 0000000A 00401018 |. FF35 10354000 PUSH DWORD PTR DS:[403510] ; |Arg3 = 00000000 0040101E |. 6A 00 PUSH 0 ; |Arg2 = 00000000 00401020 |. FF35 0C354000 PUSH DWORD PTR DS:[40350C] ; |Arg1 = 00000000