频道栏目
首页 > 资讯 > 加密解密 > 正文

esp的原理

06-05-09        来源:[db:作者]  
收藏   我要投稿

1.前言

 

  在论坛上看到很多朋友,不知道什么是ESP定律,ESP的适用范围是什么,ESP定律的原理是什么,如何使用ESP定律?看到了我在“”调查结果发现,大家对ESP定律很感兴趣,当然因为实在是太好用了,现在我就来告诉大家什么是ESP定律,它的原理是什么!

 

BTW:在看完了手动脱壳入门十八篇了以后,再看这篇文章也许会对你更有帮助!

 

在下面地址下载:

 

http://www.jetdown.com/down/down.asp?id=37350&no=1

 

2.准备知识

 

  在我们开始讨论ESP定律之前,我先给你讲解一下一些简单的汇编知识。

 

  1.call

 

  这个命令是访问子程序的一个汇编基本指令。也许你说,这个我早就知道了!别急请继续看完。

 

  call真正的意义是什么呢?我们可以这样来理解:1.向堆栈中压入下一行程序的地址;2.JMP到call的子程序地址处。例如:

 

00401029    .  E8 DA240A00    call 004A3508

 

0040102E    .  5A             pop edx

 

在执行了00401029以后,程序会将0040102E压入堆栈,然后JMP到004A3508地址处!

  

  2.RET

 

  与call对应的就是RET了。对于RET我们可以这样来理解:1.将当前的ESP中指向的地址出栈;2.JMP到这个地址。

 

  这个就完成了一次调用子程序的过程。在这里关键的地方是:如果我们要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RET这条指令之前,ESP指向的是我们压入栈中的地址。这也就是著名的“堆栈平衡”原理!

 

3.狭义ESP定律

 

  ESP定律的原理就是“堆栈平衡”原理。

 

  让我们来到程序的入口处看看吧!

 

  1.这个是加了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.

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)

 

  2.这个是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。

 

4.广义ESP定律

 

  很多人看完了教程就会问:ESP定律是不是就是0012FFA4,ESP定律的适用范围是不是只能是压缩壳!

 

  我的回答是:NO!

 

  看完了上面你就知道你如果用0012FFA8也是可以的,ESP定律不仅用于压缩壳他也可以用于加密壳!!!

 

  首先,告诉你一条经验也是事实---当PE文件运行开始的时候,也就是进入壳的第一行代码的时候。寄存器的值总是上面的那些值,不信你自己去试试!而当到达OEP后,绝大多的程序都第一句都是压栈!(除了BC编写的程序,BC一般是在下面几句压栈)

 

  现在,根据上面的ESP原理,我们知道多数壳在运行到OEP的时候ESP=0012FFC4。这就是说程序的第一句是对0012FFC0进行写入操作!

 

  最后我们得到了广义的ESP定律,对只要在0012FFC0下,硬件写入断点,我们就能停在OEP的第二句处!!

 

下面我们来举个例子,就脱壳进阶第一篇吧!

 

  载入OD后,来到这里:

 

0040D042 N>  B8 00D04000      mov eax,Notepad.0040D000 //停在这里

00

相关TAG标签
上一篇:帮MM修电脑的三个步骤-此文绝对实用
下一篇:告诉你防止网页木马最有效果的办法
相关文章
图文推荐

关于我们 | 联系我们 | 广告服务 | 投资合作 | 版权申明 | 在线帮助 | 网站地图 | 作品发布 | Vip技术培训 | 举报中心

版权所有: 红黑联盟--致力于做实用的IT技术学习网站