ESP定律原理详解,只看这一篇文章就够了
前言
闲着也是闲着,在逆向某软件时深入了解了下ESP定律,然后就想写个文章记录并分享下。
ESP定律又称堆栈平衡定律,是应用频率最高的脱壳方法之一 ,不论是新手还是老手都经常用到。据我所知,ESP定律是一位外国大牛发现的,但目前已无从考证(未找到相关资料)。
前置知识
栈
栈(stack)是内存中分配的一段空间。
向一个栈插入新元素又称作入(push)放到栈顶元素的上面,使之成为新的栈顶元素;
从一个栈删除元素又称作出栈(pop),它把栈顶元素删除掉,使其相邻的元素成为新的栈顶元素。
call
相当于高级语言中的函数调用。当执行call指令时,进行两步操作:将下一条的指令的地址压入栈中,再跳转到该地址处。相当于:
push ip
jmp near ptr 地址
ret && retf
与call指令相对应,将当前的ESP寄存器中指向的地址出栈,然后跳转到这个地址。相当于:
pop ip
#ret
pop IP
pop CS
#retf
操作示例
这是我写的一个带壳的32位小程序,用来当做esp定律应用的一个示例。这是一个比较机械的方法,但可以对esp定律有一个感性的认识。
- 首先用Exeinfo Pe查壳,发现是nspack壳。
- 接下来用od载入程序,单步步入后,如箭头所示发现ESP寄存器变红。
- 此时单击右键选中该寄存器进行数据窗口跟随。然后选中数据窗口任意字符下硬件断点(byte,word,dword均可)。
- f9运行后,f8连续单步步过找到OEP( 程序的入口点 )。选中该地址单击右键选中用OllyDump脱壳调试进程,然后进行脱壳(如果发现程序不能打开,可以试试勾选重建输入表)。
- 接着用Exeinfo Pe查壳,壳已经被去掉了。
原理详解
首先,壳实质上是一个子程序,它在程序运行时首先取得控制权并对程序进行压缩。同时隐藏程序真正的OEP。大多数病毒就是基于此原理,从而防止被杀毒软件扫描。
壳的类型:
• 解压->运行
• 解压->运行->解压.->运行
• 解压 decoder|encoded code->decode ->exc
• Run the virtual machine
而脱壳的目的就是找到真正的OEP(入口点)。
而我们所讲到的ESP定律的本质是堆栈平衡,具体如下:
- 让我们看下加了壳的这个小程序的入口的各个寄存器的情况
EAX 00000000
ECX 004E820D offset r1.<ModuleEntryPoint>
EDX 004E820D offset r1.<ModuleEntryPoint>
EBX 0036C000
ESP 0072FF74
EBP 0072FF80
ESI 004E820D offset r1.<ModuleEntryPoint>
EDI 004E820D offset r1.<ModuleEntryPoint>
EIP 004E820D r1.<ModuleEntryPoint>
- 然后是到OEP时各寄存器的情况
EAX 0072FFCC
ECX 004E820D offset r1.<ModuleEntryPoint>
EDX 004E820D offset r1.<ModuleEntryPoint>
EBX 0036A000
ESP 0072FF74
EBP 0072FF80
ESI 004E820D offset r1.<ModuleEntryPoint>
EDI 004E820D offset r1.<ModuleEntryPoint>
EIP 00401500 r1.00401500
我们发现只有EIP和EAX寄存器的数值发生了变化,而EAX保存的是OEP的地址,这是什么原因呢?
由于在程序自解密或者自解压过程中, 多数壳会先将当前寄存器状态压栈, 如使用pushad, 而在解压结束后, 会将之前的寄存器值出栈, 如使用popad. 因此在寄存器出栈时, 往往程序代码被恢复, 此时硬件断点触发(这就是我们要下硬件断点的原因),然后在程序当前位置, 只需要一些单步操作, 就会到达正确的OEP位置.
适用范围
我自己总结了一个比较小白的方法,那就是载入程序后只有esp寄存器内容发生变化,那么这个程序多半可以用ESP定律(如有错误多谢指正)。
几乎全部的压缩壳, 一些早期的加密壳 (这是在网上收集到的资料总结的,经过我自己的实践,基本准确)。
总结
以上就是我对ESP定律的理解,如有错误,请轻喷 ^-^ ,我也还只一只刚迈入二进制世界的菜鸟,希望我这篇文章对刚入门的小白有所帮助>_<
最后再加一句找OEP不是最难的,最难的还是修复。如果对OEP的识别有所疑惑可以问我也可以在网上收集相关资料,还是比较多的。
利用ESP定律进行脱壳
http://www.hetianlab.com/expc.do?ec=ECID4054-1b54-4b49-9aa7-61ed981ca101
理解ESP原理的操作机理并掌握使用ESP原理进行脱壳的流程。)
相关文章
- DNS的原理介绍
- zigbee学习之路(十二):zigbee协议原理介绍
- 原码,反码,补码的深入理解与原理答案_原码反码补码例题详解
- 第一性原理计算框架 CONQUEST 的安装与测试
- springcloud原理详解_SpringMVC运行原理
- 全卷积网络fcn详解_全卷积神经网络原理
- 学好RANKX,从搞懂排名原理开始
- Ribbon的负载均衡策略及原理[通俗易懂]
- 详解布隆过滤器的原理和实现「建议收藏」
- 通过Java实现双色球原理
- 技术文档丨 OpenSCA技术原理之npm依赖解析
- 【Android应用开发】 推送原理解析 极光推送使用详解 (零基础精通推送)
- 页表工作原理详解
- Oracle rownum原理和使用详解数据库
- MySQL主从复制原理详解数据库
- java注解及在butternife中的实践和原理详解编程语言
- Java语法糖1:可变长度参数以及foreach循环原理详解编程语言
- 装饰器原理剖析详解编程语言
- 进程间通信(IPC):共享内存和消息队列原理详解
- 使用Linux测试丢包:原理与技巧(linux测试丢包)
- MYSQL锁机制:揭秘编程中的高科技(mysql锁机制原理)
- Linux按键驱动:探索键盘事件的工作原理(linux按键驱动)
- 深入剖析Linux LVM实现原理,详解LVM常见使用场景和操作技巧(linuxlvm详解)
- MySQL 两阶锁机制的实现原理简述(mysql 两阶锁)
- Oracle中三表关联删除的实现原理(oracle三表关联删除)
- javaScript中的this示例学习详解及工作原理
- 纯js实现遮罩层效果原理分析