【破文作者】小伟
【作者邮箱】xie.qing.13.46.7@126.com
【使用工具】 od PeiD
【破解平台】 Win9x/NT/2000/XP
【脱壳目标】 PECompact 1.68 - 1.84 -> Jeremy Collake一个加壳的记事本
【破解声明】 我是一个菜鸟 第一次写这样的文章 失误之处还请大虾们多多批评多多指教 你们就多多批评多多指教 呵呵 这样可以激发我以后写出更好的文章来
好了 进入正题!~~~~~~~~~~~~~~~~~~~~~~
现在很多壳用单步跟踪是很麻烦的 而且说不定到那程序就运行了 给我们脱壳带来了很大的捆饶 其实有很多的壳用ESP定律来脱是很快的 今天我就那一个简单的不能在简单的壳来给大家说说
在文章开始之前我先给大家说说什么是ESP?它的使用范围?
首先ESP定律不仅用于压缩壳他也可以用于加密壳!!!
ESP定律的原理就是“堆栈平衡”原理。
让我们来到UPX的程序的入口处看看吧!
这个是加了UPX壳的入口时各个寄存器的值!
EAX 00000000
ECX 0012FFB0
EDX 7FFE0304
EBX 7FFDF000
ESP 0012FFC4
EBP 0012FFF0
ESI 77F51778 ntdll.77F51778
EDI 77F517E6 ntdll.77F517E6
EIP 0040EC90 note-upx.<ModuleEntryPoint>
C 0 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 0 DS 0023 32bit 0(FFFFFFFF)
S 1 FS 0038 32bit 7FFDE000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E)
这个是UPX壳JMP到OEP后的寄存器的值!
EAX 00000000
ECX 0012FFB0
EDX 7FFE0304
EBX 7FFDF000
ESP 0012FFC4
EBP 0012FFF0
ESI 77F51778 ntdll.77F51778
EDI 77F517E6 ntdll.77F517E6
EIP 004010CC note-upx.004010CC
C 0 ES 0023 32bit 0(FFFFFFFF)
P 1 CS 001B 32bit 0(FFFFFFFF)
A 0 SS 0023 32bit 0(FFFFFFFF)
Z 1 DS 0023 32bit 0(FFFFFFFF)
S 0 FS 0038 32bit 7FFDE000(FFF)
T 0 GS 0000 NULL
D 0
O 0 LastErr ERROR_MOD_NOT_FOUND (0000007E)
是不是除了EIP不同以外,其他都一模一样啊!
为什么会这样呢?
我们来看看UPX的壳的第一行:
0040EC90 n> 60 pushad //****注意这里*****
0040EC91 BE 15B04000 mov esi,note-upx.0040B015
PUSHAD就是把所有寄存器压栈!我们在到壳的最后看看:
0040EE0F 61 popad //****注意这里*****
0040EE10 - E9 B722FFFF jmp note-upx.004010CC //JMP到OEP
POP就是将所有寄存器出栈!
而当我们PUSHAD的时候,ESP将寄存器压入了0012FFC0--0012FFA4的堆栈中!如下:
0012FFA4 77F517E6 返回到 ntdll.77F517E6 来自 ntdll.77F78C4E //EDI
0012FFA8 77F51778 返回到 ntdll.77F51778 来自 ntdll.77F517B5 //ESI
0012FFAC 0012FFF0 //EBP
0012FFB0 0012FFC4 //ESP
0012FFB4 7FFDF000 //EBX
0012FFB8 7FFE0304 //EDX
0012FFBC 0012FFB0 //ECX
0012FFC0 00000000 //EAX
所以这个时候,在教程上面就告诉我们对ESP的0012FFA4下硬件访问断点。也就是说当程序要访问这些堆栈,从而恢复原来寄存器的值,准备跳向苦苦寻觅的OEP的时候,OD帮助我们中断下来。
于是我们停在0040EE10这一行!
总结:我们可以把壳假设为一个子程序,当壳把代码解压前和解压后,他必须要做的是遵循堆栈平衡的原理,让ESP执行到OEP的时候,使ESP=0012FFC4。
这是狭义ESP定律 大家先记住
首先,告诉你一条经验也是事实---当PE文件运行开始的时候,也就是进入壳的第一行代码的时候。寄存器的值总是上面的那些值,不信你自己去试试!而当到达OEP后,绝大多的程序都第一句都是压栈!(除了BC编写的程序,BC一般是在下面几句压栈)
现在,根据上面的ESP原理,我们知道多数壳在运行到OEP的时候ESP=0012FFC4。这就是说程序的第一句是对0012FFC0进行写入操作!
最后我们得到了广义的ESP定律,对只要在0012FFC0下,硬件写入断点,我们就能停在OEP的第二句处!!
这是广义的ESP定律 新手们看了是不是很头疼啊!~~~~~ 呵呵~~不要仅现在让我们来用ESP定律来脱一个非常简单的壳 就上我上面说的PECompact 1.68 - 1.84 -> Jeremy Collake 进入正题 呵呵~~~~~ 废话那么多~~~~~
用OD载入(忽略所有异常)
0040C000 P> /EB 06 jmp short PECompac.0040C008 //停在这,继续F8
0040C002 |68 CC100000 push 10CC
0040C007 |C3 retn
0040C008 \9C pushfd
0040C009 60 pushad //ESP,突现,0012ffc0 到时候了 ^_^
0040C00A E8 02000000 call PECompac.0040C011
下命令行 hr 0012ffc0 回车,F9运行
0040D550 50 push eax //到这里了,继续F8(记得取消硬件断点哦^_^)
0040D551 68 CC104000 push PECompac.004010CC
0040D556 C2 0400 retn 4 //返回来到OEP
。。。。。。。。。。。。。。。
004010CC 55 push ebp 在这里dump就可以了
004010CD 8BEC mov ebp,esp
004010CF 83EC 44 sub esp,44
很容易就到了OEP了~~
是不是很简单啊!~~~~~
我一开始也感觉ESP定律有多难呢 其实只要你肯努力 就没有学不会的东西
我只是一个菜鸟 学了点知识上来买弄买弄 让大家见笑了 ^_^
有兴趣的可以家我的QQ:345185273
也可以加我的群群号是:1833066都是新见的群 有兴趣的可以进来交流一下 也教教小弟我不明白的地方 ^_^
还有哦!CS玩的厉害的找我 有机会打几盘啊!!!~~~ 我会一枪暴你头的 嘿嘿~~~~
时间不早了 我去睡觉了 明天还要上学 88
个人主业:www.66h6.com
有兴趣进来看看 呵呵
[招生]系统0day安全班,企业级设备固件漏洞挖掘,Linux平台漏洞挖掘!