lenush 发表于 2008-11-29 11:28

lenushj老调重谈之Esp.定律

Esp.定律讲解
今天就来说说Esp.定律吧!主要是理论性的东西,录像就不做了吧!大家仔细看看文档就可以了!网上关于Esp.的资料可称得上泛滥了。在这里结合自己的一点经验,给大家做一个整理吧!
Esp.定律大家都知道它很有用,几乎全部的压缩壳都能用它来脱;少数的加密壳也用得上,
这么有用的一个东西,相信不会有人没兴趣吧!
那么,什么是Esp.定律?它的原理是什么?什么时候用得上它?又该怎样用它?这就是接下来要讲解的内容。(不是全文字说明,附有实例操作)
1.        Esp.定律的原理
“堆栈平衡”就是Esp.定律的原理,那么堆栈平衡又是什么了?看例子:
这个程序加的是AS Pack 2.11 -> Alexey Solodovnikov 的壳,
我们先OD载入程序,程序中断在这里:
0046A001 >60            pushad
0046A002    E9 3D040000   jmp   0046A444
0046A007    45            inc   ebp
0046A008    3D 58815D03   cmp   eax, 35D8158
0046A00D    55            push    ebp
0046A00E    3C 8D         cmp   al, 8D
0046A010    51            push    ecx
其他的先不看,重点看看ESP中的内容:
EAX 00000000
ECX 0012FFB0
EDX 7C92EB94 ntdll.KiFastSystemCallRet
EBX 7FFD8000
ESP 0012FFC4
EBP 0012FFF0
ESI 7C937304 ntdll.7C937304
EDI FFFFFFFF
EIP 0046A001 CRACKME1.<模块入口点>
记下这里的内容,我们先跟踪程序先(单步跟踪法),一首歌时间后,我们跟踪到了程序的OEP,再来看看ESP中的内容吧!
EAX 00000000
ECX 0012FFB0
EDX 7C92EB94 ntdll.KiFastSystemCallRet
EBX 7FFDE000
ESP 0012FFC4
EBP 0012FFF0
ESI 7C937304 ntdll.7C937304
EDI FFFFFFFF
EIP 004584F0 CRACKME1.004584F0
聪明的你已经发现了,除EIP不同外其他的全是一样的,为什么会是这样的了?
再次来到程序入口点去看看:注意壳的开始两行


0046A001 >60            pushed
0046A002    E9 3D040000   jmp   0046A444
一开始就把全部的寄存器压栈。看完这里,再去程序OEP看看:也注意开始两行
0046A3AA    61            popad
0046A3AB    75 08         jnz   short 0046A3B5
Popad这里是出栈所有的寄存器。
当我们执行Pushed后,ESP将寄存器压入了0012FFC0--0012FFA4的堆栈中!
这点可以看出:在上面跟踪过程中,只要我们对ESP的0012FFA4下一个硬件访问断点。意思就是说当程序要访问这些堆栈,从而恢复原来寄存器的值,准备跳向苦苦寻觅的OEP的时候,OD帮助我们中断下来,并且停在0040EE10这一行。这样一来,我们就不必苦苦跟踪程序了!
我们知道壳是保护程序的代码,当壳把代码解压前和解压后,他必须要做的是保持程序堆栈平衡,让ESP执行到OEP的时候,使ESP=0012FFC4。
2.        玩转ESP定律
根据上面ESP的原理,我们知道绝大多数的壳在OEP处都是ESP=0012FFC4。那么意思就是说载入的程序第一句是对0012FFC0进行写入的操作!试想一下,是不是我们只要在0012FFC0下硬件写入断点,我们就能到达程序的OEP了?(说干就干,唉,说打就打),OD重新载入程序。单步走,注意看OD右上角的寄存器中ESP处有没有变成红色(准确的说,我们是选择的ESP值是关键句之后的第一个ESP值),到JMP处这里,我们在右边寄存器里面的ESP处右击,然后选择在 数据窗口跟随 ,接着在数据窗口中右击0012FFA4,找到断点,选择硬件访问,再选择Word,然后我们再运行程序,(另一种方法:在命令行下:dd XXXXXXXX“指在当前代码中的ESP地址,或者是hr XXXXXXXX”,按回车!)
来到这里:
0046A3AB   /75 08         jnz   short 0046A3B5
0046A3AD   |B8 01000000   mov   eax, 1
0046A3B2   |C2 0C00         retn    0C
0046A3B5   \68 F0844500   push    004584F0                         ; ASCII "U",8B,"?,83,"聂",B8,"",A0,"",83,"E"
0046A3BA    C3            retn
向上拉一点看看:
0046A3A2    0BC9            or      ecx, ecx
0046A3A4    8985 E63C4400   mov   dword ptr , eax
0046A3AA    61            popad
看到Popad了吧!到底这是不是OEP的前兆了?还得要我们继续跟踪下去看看。
果然,我们在一个大的跳转后来到这里:
004584F0    55            push    ebp
004584F1    8BEC            mov   ebp, esp
004584F3    83C4 F4         add   esp, -0C
004584F6    B8 A0834500   mov   eax, 004583A0
如果你对程序语言了解的话,一看就知道这应该是Delphi 的了!是不是了?我们还是脱壳来检验吧!完毕后,PEID 检测是Borland Delphi 4.0 - 5.0,完全没错,你答对了!
3.        ESP适用对像
那么是不是说ESP定律就是0012FFA4了?错,完全不是这样。我们具体情况要具体对待,对于拿在手里的程序,要先拿来分析,不要没有看到0012FFA4,就认为这个壳不能用ESP定律了。当然这只是ESP定律的一个体现罢了。不要忘了上面已经说过:几乎全部的压缩壳都能用它来脱;少数的加密壳也用得上。到于什么时候下断点避开校验,什么时候下断OD才能断下来,这还需要你不断的分析和总结。(有新新发现时不要忘了告诉我哦!)
4.后续
到这里我能写的关于ESP的也就这些了,完全是个人见解,错误和不清楚的地方还请大家海涵,方法靠自己分析,经验靠自己总结!
希望破解这条路一直走下去!
                                                                Lenushj
                                                             08-11-8 凌晨两点半

鬼手 发表于 2008-11-29 11:30

做个记号,现在还看不懂,学会了再来看.谢谢楼主发贴

evilangel 发表于 2008-11-30 21:25

:handshake            还得学习学习谢谢分享啊

ppsyswww 发表于 2008-12-1 05:26

:lol :lol   忽忽不错

小风吹吹 发表于 2008-12-1 13:33

楼主分析的很到位,
学习了,。
:handshake

wycx 发表于 2008-12-2 14:55

Esp.定律 经典!!:P

wenbo998 发表于 2013-12-3 10:31

学习学习!!

阿顺 发表于 2013-12-16 22:30

页: [1]
查看完整版本: lenushj老调重谈之Esp.定律