1.了解EBP寄存器

在寄存器里面有很多寄存器虽然他们的功能和使用没有任何的区别,但是在长期的编程和使用 中,在程序员习惯中已经默认的给每个寄存器赋上了特殊的含义,比如:EAX一般用来做返回值,ECX用于记数等等。在win32的环境下EBP寄存器用与 存放在进入call以后的ESP的值,便于退出的时候回复ESP的值,达到堆栈平衡的目的。

应用以前说过的一段话:

原程序的OEP,通常是一开始以 Push EBP 和MOV Ebp,Esp这两句开始的,不用我多说大家也知道这两句的意思是以EBP代替ESP,作为访问堆栈的指针。

为什么要这样呢?为什么几乎每个程序都是的开头能?因为如果我们写过C等函数的时候就应该清楚,程序的开始是以一个主函数main()为开始的,而函数在访问的过程中最重要的事情就是要确保堆栈的平衡,而在win32的环境下保持平衡的办法是这样的:

1.让EBP保存ESP的值;

2.在结束的时候调用

mov esp,ebp
pop ebp
retn

或者是

leave
retn

两个形式是一个意思。

这样做的好处是不用考虑ESP等于多少,PUSH了多少次,要POP多少次了,因为我们知道EBP里面放的是开始时候的ESP值。

2.推广的ESP定律

在寻找OEP的时候,往往下断HW ESP-4不成功,除了壳代码将硬件断点删除了以外,很可能的情况就是因为壳代码在运行到OEP的时候他的ESP已经不再是在EP时候的ESP(12FFC4)了,这样我们下断当然是不成功的。

那么如何找到在壳到达OEP的时候的堆栈的值将是关键。

在这里我们应用的关键是

Push EBP
MOV Ebp,Esp----》关键是这句

我来解释一下,当程序到达OEP的时候Push EBP这句对于ESP的值来说就是ESP-4,然后是ESP-4赋给了EBP,而做为保存ESP值作用的EBP寄存器在这个“最上层的程序”中的值将始终 不会改变。虽然他可能在进入子call里面以后会暂时的改变(用于子程序的堆栈平衡)但是在退出了以后依*pop ebp这一句将还原原来的EBP的值。

以这句做为突破口,就是说只要我们能断在“最上层的程序”中,就能通过观察EBP的值得到壳在JMP到OEP的时候的ESP的值了。

3.实战

来看看pespin1.1的壳,在pespin1.0的壳中,我们使用HW 12FFC0能很容易的找到stolen code的地方,但是到pespin1.1的时候,我们就不行了。用HW 12FFC0根本断不下来。

现在我们就使用这个推广的ESP定律,载入程序后来到最后的一个异常

0040ED85     2BDB             sub ebx,ebx                           //停在这里
0040ED87 64:8F03 pop dword ptr fs:[ebx]
0040ED8A 58 pop eax
0040ED8B 5D pop ebp
0040ED8C 2BFF sub edi,edi
0040ED8E EB 01 jmp short pespin1_.0040ED91
0040ED90 C466 81 les esp,fword ptr ds:[esi-7F]

我用使用内存断点办法来到FOEP处

004010D3     0000             add byte ptr ds:[eax],al
004010D5 0000 add byte ptr ds:[eax],al
004010D7 0000 add byte ptr ds:[eax],al
004010D9 0000 add byte ptr ds:[eax],al
004010DB 0000 add byte ptr ds:[eax],al
004010DD 0000 add byte ptr ds:[eax],al
004010DF 75 1B jnz short pespin1_.004010FC //这里是FOEP
004010E1 56 push esi
004010E2 FF15 99F44000 call dword ptr ds:[40F499]
004010E8 8BF0 mov esi,eax
004010EA 8A00 mov al,byte ptr ds:[eax]

好了,这里就是“最上层的程序”的地方了,看看寄存器

EAX 00141E22
ECX 0040C708 pespin1_.0040C708
EDX 0040C708 pespin1_.0040C708
EBX 0040C708 pespin1_.0040C708
ESP 0012F978
EBP 0012F9C0 //注意这里
ESI 00141EE0
EDI 0040E5CD pespin1_.0040E5CD
EIP 004010DF pespin1_.004010DF

看到了吧,EBP=0012F9C0,我们来想象一下这个值是怎么得到的。

首先肯定是通过MOV ESP,EBP这一句,也就是说ESP这时是0012F9C0的,然而上面还有一句PUSH EBP也就是说ESP在到达OEP的时候应该是0012F9C4的。好了得到这个结论我们就能很快的找到stolen code的所在了。

重来停在最后的异常

0040ED85     2BDB             sub ebx,ebx                           //停在这里
0040ED87 64:8F03 pop dword ptr fs:[ebx]
0040ED8A 58 pop eax
0040ED8B 5D pop ebp
0040ED8C 2BFF sub edi,edi
0040ED8E EB 01 jmp short pespin1_.0040ED91
0040ED90 C466 81 les esp,fword ptr ds:[esi-7F]

然后下断HW 0012F9C0 ,F9运行,来到这里

0040D8FB     61               popad
0040D8FC 55 push ebp
0040D8FD EB 01 jmp short pespin1_.0040D900 //停在这里
0040D8FF 318B ECEB01AC xor dword ptr ds:[ebx+AC01EBEC],ecx
0040D905 83EC 44 sub esp,44
0040D908 EB 01 jmp short pespin1_.0040D90B
0040D90A 72 56 jb short pespin1_.0040D962
0040D90C EB 01 jmp short pespin1_.0040D90F
0040D90E 95 xchg eax,ebp
0040D90F FF15 6CF34000 call dword ptr ds:[40F36C]
0040D915 EB 01 jmp short pespin1_.0040D918

于是就很快的找到了stolen code的所在了。

4.总结

上面的这个办法大概可以总结以下的步骤:

(1).直接或间接的断在“最上层的程序”的地方。

(2).得到“最上层的程序”的EBP的值。

(3).利用程序初始化的两个固定语句找到壳JMP到OEP的堆栈值。这个办法有很大的局限性,因为只有VC和delphi程序使用这个初始化的开头。

但是找到“最上层的程序”的办法除了内存断点还有很多办法,例如对于VC来说使用 bp ExitProcess也是一个很好的断点,可以直接得到EBP的数值。

5.后话

原来这个办法有很强的前提条件,不是一个很具普遍性的办法,我原来也不想单独的提出来,但是对于jney2兄弟的anti-ESP定律来说这个办法却是一个解决之道。

当然还有更多的办法,在这里我只想说很多事情有矛就有盾,没有什么办法是一定没有漏洞的,只是希望这篇文章给大家阔宽思路,起到抛砖引玉的作用。

EBP的妙用[无法使用ESP定律时]的更多相关文章

  1. “破解大牛是怎么炼成的”之壳与ESP定律

    文章难易度:★★★ 文章阅读点/知识点:逆向破解 文章作者:Sp4ce 文章来源:i春秋   关键字:网络 信息安全技术 本文参与i春秋社区原创文章奖励计划,未经许可禁止转载! 一.前言 通过前面几篇 ...

  2. 寻找真正的入口(OEP)--广义ESP定律

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

  3. 菜鸟脱壳之脱壳的基础知识(四)——利用ESP定律来寻找OEP

    .上节说的是单步跟踪法,这节讲的是利用堆栈平衡(ESP定律)来进行脱壳!想必大家都听说过ESP定律这个大名吧!ESP定律运用的就是堆栈平衡原理!一般的加壳软件在执行时,首先要初始化,保存环境(保存各个 ...

  4. ESP定律脱壳

     ESP定律是比较常用的脱壳方式,作为新手用的也比较多简单写一下我的看法. esp定律的使用过程大致为: 1.开始就点F8,注意观察OD右上角的寄存器中ESP有没突现(变成红色),并且只有sp和ip为 ...

  5. 脱壳第一讲,手工脱壳ASPack2.12的壳.ESP定律

    脱壳第一讲,手工脱壳ASPack2.12的壳.ESP定律 一丶什么是ESP定律 首先我们要明白什么是壳.壳的作用就是加密PE的. 而ESP定律就是壳在加密之前,肯定会保存所有寄存器环境,而出来的时候, ...

  6. ESP定律学习

    ESP = 堆栈平衡 ESP定理脱壳: (1)开始就点F8,注意观察OD右上角的寄存器中ESP有没突现(变成红色)(这只是一  般情况下,更确切的说我们选择的ESP值是关键句之后的第一个ESP值) ( ...

  7. ESP定律脱壳——NsPack3.x脱壳

    首先进行查壳,NsPack 将程序拖入x64dbg 程序入口处标志性的push F8单步,发现仅有esp寄存器有变化 在esp上右键,在内存窗口查看,下硬件断点 F9运行程序,程序断在pop之后. 使 ...

  8. eax,ebx,ecx,edx,esi,edi,ebp,esp寄存器的作用

    位的寄存器.如果用C语言来解释,可以把这些寄存器当作变量看待. 比方说:add eax,-2 ;   //可以认为是给变量eax加上-2这样的一个值. 位寄存器有多种用途,但每一个都有"专长 ...

  9. esp跟ebp跟踪记录

    发现文字描述还是太没有快感.上几幅图,来说明这个调试过程更好.此文对于深刻理解ebp,esp是具有长远意义的 可以看到,初始情况下,ebp此时值为0012FEDC,也就是栈帧的地址,而栈顶地址esp值 ...

随机推荐

  1. php面向对象的基础:创建OOP的方法

    方法的创建 class Computer{ public function _run(){ return '我是类的一个公共方法'; } } $computer = new Computer(); / ...

  2. (转)Couchbase介绍,更好的Cache系统

    在移动互联网时代,我们面对的是更多的客户端,更低的请求延迟,这当然需要对数据做大量的 Cache 以提高读写速度. 术语 节点:指集群里的一台服务器. 现有 Cache 系统的特点 目前业界使用得最多 ...

  3. (转)RabbitMQ 集群与高可用配置

    集群概述 环境 配置步骤 集群概述 通过 Erlang 的分布式特性(通过 magic cookie 认证节点)进行 RabbitMQ 集群,各 RabbitMQ 服务为对等节点,即每个节点都提供服务 ...

  4. 数列平方根的和 java

    题目描述: 数列的定义如下:数列的第一项为n,以后各项为前一项的平方根,求数列的前m项的和. 输入 输入数据有多组,每组占一行,由两个整数n(n<10000)和m(m<1000)组成,n和 ...

  5. 10.NFS V4.2

    这里只演示使用keytab,也就是客户端与服务端进行keberos进行安全验证连接(注意时间服务器要同步!如果不同步,Kerberos无法通过验证) server端:192.168.1.109 1.y ...

  6. Apache+lvs高可用+keepalive(主从+双主模型)

    Apache+lvs高可用+keepalive(主从+双主模型)     keepalive实验准备环境: httpd-2.2.15-39.el6.centos.x86_64 keepalived-1 ...

  7. svn不能更新也不能提交【svn A conflict in the working copy obstructs the current operation】

    SVN不能提交解决方法:          最近发现了svn有一种特殊的冲突,跟svn版本库同步的时候,还提示代码没有不一样的,但是文件图标上又是一个特殊的冲突符号,不是那种大红的冲突符号.更新不了也 ...

  8. 【Qt】Qt之Tab键切换焦点顺序【转】

    简介 Qt的窗口部件按用户的习惯来处理键盘焦点.也就是说,其出发点是用户的焦点能定向到任何一个窗口,或者窗口中任何一个部件. 焦点获取方式比较多,例如:鼠标点击.Tab键切换.快捷键.鼠标滚轮等. 习 ...

  9. ThoughtWorks FizzBuzzWhizz 代码实现

    当时拉钩网ThoughtWorks出了一道面试题(https://www.jinshuju.net/f/EGQL3D),本人用PHP实现了一下,当时忘记了把代码分享出来,今天特来补上. FizzBuz ...

  10. 仿UC天气下拉和微信下拉眼睛头部淡入淡出--第三方开源--PullLayout

    Android-PullLayout是github上的一个第三方开源项目,该项目主页是:https://github.com/BlueMor/Android-PullLayout 原作者项目意图实现类 ...