.上节说的是单步跟踪法,这节讲的是利用堆栈平衡(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. js/jquery 元素是否存在

    <!DOCTYPE html><html><head><meta charset="UTF-8"><title>spli ...

  2. JMeter-充值-生成随机数

    1.随机数,orderId每次需要变化,需要用到随机数 验证生成的随机数:

  3. 抓取html 生成图片

      <!DOCTYPE html>   <html>   <head>   <script type="text/javascript" ...

  4. 钉钉调试应用Inspect不显示或显示空白的解决方法

    首先必须使用钉钉开发版,并确保已经通过此链接打开了调试功能: https://open-doc.dingtalk.com/docs/doc.htm?spm=5176.10694750.0.0.3tPH ...

  5. idea快捷键使用

    idea                                 eclipse project                           workspace module     ...

  6. [ Build Tools ] Repositories

    仓库介绍 http://hao.jobbole.com/central-repository/ https://my.oschina.net/pingjiangyetan/blog/423380 ht ...

  7. CentOS 7 系统优化

    系统调优4大子系统 1:找出系统中使用CPU最多的进程 2:找出系统中使用内存最多的进程 3:找出系统中对磁盘读写最多的进程 4:找出系统中使用网络最多的进程 系统调优概述 系统的运行状况:  CPU ...

  8. 压缩图片 Image

    图片压缩 class resizeImg: """缩略图""" def __init__(self,**args): self.args_k ...

  9. PyQt5学习笔记

    setMouseTracking bool mouseTracking这个属性保存的是窗口部件跟踪鼠标是否生效.如果鼠标跟踪失效(默认),当鼠标被移动的时候只有在至少一个鼠标按键被按下时,这个窗口部件 ...

  10. CSS——对position定位和margin-top的理解

    一.常见定位方式 1.positon:absolute (脱离文档流) 生成绝对定位的元素,相对于 static 定位以外的第一个父元素进行定位 (这里的父元素是指定位方式为relative和abso ...