.上节说的是单步跟踪法,这节讲的是利用堆栈平衡(ESP定律)来进行脱壳!想必大家都听说过ESP定律这个大名吧!ESP定律运用的就是堆栈平衡原理!
一般的加壳软件在执行时,首先要初始化,保存环境(保存各个寄存器的值),一般利用PUSHAD(相当于把eax,ecx,edx,ebx,esp,ebp,esi,edi都压栈),当加壳程序的外壳执行完毕以后,再来恢复各个寄存器的内容,通常会用POPAD(相当与把eax,ecx,edx,ebx,esp,ebp,esi,edi都出栈),通过跨区段的转移来跳到程序的OEP来执行原程序!
在脱壳的时候,我们可以根据堆栈平衡来对ESP进行下断,进而快速到达OEP!
我们用OD来载入上节课加了UPX的壳的Delphi7.0的程序,当单步过pushad以后,会把各个寄存器的值压入堆栈中!

004629D0 >  60                      PUSHAD   // 把所有的寄存器压栈!
004629D1    BE 00F04300            MOV ESI,0043F000
004629D6    8DBE 0020FCFF         LEA EDI,DWORD PTR DS:[ESI+FFFC2000]

这个为寄存器窗口各个寄存器的值:

这个为没有步过pushad语句的堆栈窗口的值:

这个为步过pushad语句的堆栈窗口的值:

很明显,经过pushad语句以后,所有的寄存器的值都进行了压栈,也就是保存环境!
此时的ESP指向是 0012FF6C,我们来对它下硬件访问断点,我们在寄存器窗口,右键==》数据窗口跟随,在数据窗口的前四个字节,下硬件访问断点 ==》 dword断点!

按F9运行程序,外壳代码处理结束以后,调用popad指令来恢复环境,在访问这些堆栈的时候,会被OD捕获并中断下来,此时,已经离程序的OEP不再遥远了!

00462B75    61               POPAD
00462B76    8D4424 80       LEA EAX,DWORD PTR SS:[ESP-80]            ; 断在了这里
00462B7A    6A 00            PUSH 0
00462B7C    39C4            CMP ESP,EAX
00462B7E  ^ 75 FA            JNZ SHORT 00462B7A
00462B80    83EC 80          SUB ESP,-80
00462B83  ^ E9 109FFEFF      JMP 0044CA98  //经过上节的分析,得知这个跨区段的转移是跳向OEP的!

ESP定律不一定非得在ESP的值为0012FFA4的时候才能运用,合理的运用会使脱壳变得很简单!再告诉大家一个经验吧!ESP定律不只是适用于压缩壳,ESP定律灵活的运用,同样的适用于加密壳(类似VMP等!)。下面我引用看雪论坛的Lenus在他的广义ESP定律里说过的几句话(顺便PS下,我把堆栈平衡原理放到了附录):
“ 首先,告诉你一条经验也是事实---当PE文件运行开始的时候,也就是进入壳的第一行代码的时候。寄存器的值总是上面的那些值,不信你自己去试试!而当到达OEP后,绝大多的程序都第一句都是压栈!(除了BC编写的程序,BC一般是在下面几句压栈)
  现在,根据上面的ESP原理,我们知道多数壳在运行到OEP的时候ESP=0012FFC4。这就是说程序的第一句是对0012FFC0进行写入操作!
最后我们得到了广义的ESP定律,对只要在0012FFC0下,硬件写入断点,我们就能停在OEP的第二句处! ”
附下载版文章:
http://www.2cto.com/uploadfile/2012/1205/20121205071227412.zip

菜鸟脱壳之脱壳的基础知识(四)——利用ESP定律来寻找OEP的更多相关文章

  1. Python基础知识(四)

    Python基础知识(四) 一丶列表 定义格式: 是一个容器,由 [ ]表示,元素与元素之间用逗号隔开. 如:name=["张三","李四"] 作用: 存储任意 ...

  2. C# 基础知识 (四).C#简单介绍及托管代码

            暑假转瞬即逝,从10天的支教生活到1周的江浙沪旅游,在这个漫长的暑假中我经历了非常多东西,也学到了非常多东西,也认识到了非常多不足之处!闲暇之余我准备又一次进一步巩固C#相关知识,包含 ...

  3. C语言基础知识(四)——位操作

    一.进制基础知识 1.通常,1字节(Byte)包含8位(bit).C语言用字节表示储存系统字符集所需的大小. 2.对于一个1字节8位的二进制数,最右边(第0位)是最低阶位,最左边(第1位)是最高阶位, ...

  4. SDL的基础知识以及利用SDL播放视频

    原文地址:http://blog.csdn.net/i_scream_/article/details/52714378 此博文相关知识点从雷神的博客以及视频学习,截图也是用了他的课件, 雷神博客地址 ...

  5. Java的基础知识四

    一.Java 流(Stream).文件(File)和IO Java.io 包几乎包含了所有操作输入.输出需要的类.所有这些流类代表了输入源和输出目标. Java.io 包中的流支持很多种格式,比如:基 ...

  6. Android学习之基础知识四-Activity活动7讲(活动的启动模式)

    在实际的项目开发中,我们需要根据特定的需求为每个活动指定恰当的启动模式.Activity的启动模式一共有4种:standard.singleTop.singleTask.singleInstance. ...

  7. Android学习之基础知识四-Activity活动3讲(Intent的使用)

    主活动名称FirstActivity.java改为了MenuTest.java 一.什么是Intent: 1.Intent是Android程序中各组件之间进行交互的重要方式,不仅可以指明当前组件想要进 ...

  8. for、while循环(java基础知识四)

    1.循环结构概述和for语句的格式及其使用 * 什么是循环结构 循环语句可以在满足循环条件的情况下,反复执行某一段代码,这段被重复执行的代码被称为循环体语句,当反复执行这个循环体时,需要在合适的时候把 ...

  9. Dapper基础知识四之 利用Dapper获取不同类型的主键值

    在下刚毕业工作,之前实习有用到Dapper?这几天新项目想用上Dapper,在下比较菜鸟,这块只是个人对Dapper的一种总结. 一下是Dapper源码几种主键,当主键不包含"ID" ...

随机推荐

  1. 【Common】NO.81.Note.1.Common.1.001-【各种英文符号的表示及念法】

    1.0.0 Summary Tittle:[Common]NO.81.Note.1.Common.1.001-[各种英文符号的表示及念法] Style:Common Series:Common Sin ...

  2. Elasticsearch 快速入门教程

    面向文档 应用中的对象很少只是简单的键值列表,更多时候它拥有复杂的数据结构,比如包含日期.地理位置.另一个对象或者数组. 总有一天你会想到把这些对象存储到数据库中.将这些数据保存到由行和列组成的关系数 ...

  3. 查看容器IP地址

    我们可以通过以下命令查看容器运行的各种数据 docker inspect 容器名称(容器ID)  也可以直接执行下面的命令直接输出IP地址 docker inspect --format='{{.Ne ...

  4. java之搭建webservice服务端

    1.新建工程. 2.配置项目名称和位置. 3.得到的项目结构如下: 4.配置tomcat服务器. (1) (2)新建一个tomcat服务. (3)配置tomcat参数. 5.配置WSDL文件. url ...

  5. 国内老版本ubuntu更新源地址以及sources.list的配置方法

    在终端输入并运行 sudo apt-get install vimsudo cp /etc/apt/sources.list /etc/apt/sources.list.backup (备份当前的源列 ...

  6. sitecore 数字化营销-path funnel

    路径分析器是一个应用程序,允许您查看联系人在浏览网站时所采用的各种路径.您可以查看联系人在转换目标并与广告系列互动时所采用的路径,让您深入了解哪些路径为每次转化提供最佳参与价值,以及哪些路径效率较低且 ...

  7. rsync 守护进程备份报错

    [root@nfs01 backup]# rsync -avz  /backup rsync_backup@172.16.1.41::backupPassword: @ERROR: auth fail ...

  8. openresty lua 文件上传与删除

    [1]openresty 上传upload源码库 Github:https://github.com/openresty/lua-resty-upload 源码文件upload.lua文件 [2]上传 ...

  9. Unable to construct api.Node object for kubelet: can't get ip address of node master.example.com: lookup master.example.com on : no such host

    openshift首页进不去 启动openshift时报的错,大意是: 无法为kubelet构造api.Node对象:无法获取节点master.example.com的IP地址: 所以就联想到新装的c ...

  10. CSS中一个冒号和两个冒号有什么区别

    一个冒号是伪类,两个冒号是伪元素 伪类可以独立于文档的元素来分配样式,且可以分配给任何元素,逻辑上和功能上类类似,但是其是预定义的.不存在于文档树中且表达方式也不同,所以叫伪类.伪元素所控制的内容和一 ...