壳的原理

壳是最早出现的一种专用加密软件技术。壳实质上是一个子程序,它在某些方面和病毒类似,都需要比源程序代码更早地获得控制权

壳通过修改源程序执行文件的组织结构,但不会影响源程序的正常运行,在程序运行时抢先取得控制权后,对程序进行压缩等加密操作,隐藏程序真正的 OEP(源程序入口点)(大多数病毒就是基于此原理,防止被杀毒软件扫描)


手动脱壳

对于一些加密壳、修改壳,目前并没有脱壳机,必须手动分析脱壳

手动脱壳的目的就是要找出程序真正的 OEP(源程序入口点)位置

  • 手动脱壳一般分为三步:
    1. 查找真正的程序入口点
    2. 抓取内存映像文件
    3. 重建 PE 文件

在程序执行时,外壳代码会首先获取控制权,模拟 Windows 加载器,将原来的程序恢复到内存中,这时内存中的数据就是加壳前的映像文件了。适时对映像文件进行抓取和修改,就可以将其还原到加壳前的状态


ESP 脱壳定律

ESP 脱壳定律又称堆栈平衡定律,即:通过合理利用程序中的堆栈平衡来进行脱壳

特点:载入程序后只有 ESP 寄存器内容发生变化(单步 F8 后发现只有 ESP 寄存器变红
适用范围:几乎全部的压缩壳, 一些早期的加密壳

以本站的《【攻防世界】BabyXor》这道题为例 ,ESP 脱壳步骤与此类似

  1. pushad 开始

先 F8 单步步过一次

攻防世界_BabyXor6.png

观察右侧寄存器窗口,发现 EAX ~ EDI 中只有 ESP 为红色,说明可以使用 ESP 定律进行脱壳

  1. 在寄存器窗口中选中 ESP,右键 --> 数据窗口中跟随

攻防世界_BabyXor7.png

注意数据窗口中是否跳转:

攻防世界_BabyXor8.png

从该地址处的第一个字节开始(我这里是 00),左键选择任意长度的数据

然后右键 --> 断点 --> 硬件访问 --> Byte/Word/Dword(三选一,均可)

攻防世界_BabyXor9.png

检查一下断点是否成功:调试 --> 硬件断点

攻防世界_BabyXor10.png

直接 F9 运行程序

然后 F8 连续单步步过找到 OEP(程序的入口点)

程序停在地址 0x0043F019 的位置

攻防世界_BabyXor11.png
在脱壳之前,先删除前面下的断点:

攻防世界_BabyXor12.png

在停下的地址处:右键 --> 用 OllyDump脱壳调试进程

攻防世界_BabyXor13.png

点击脱壳,并将脱壳后的程序进行保存

攻防世界_BabyXor14.png

  1. 将保存后的程序用 exeinfo PE 打开:

攻防世界_BabyXor15.png
已经显示无壳

  1. 如果脱壳后的程序,用 IDA 分析是正常的,但是却无法双击运行,可以尝试:
    • 右键 --> 用 OllyDump脱壳调试进程 进行脱壳的时候,左下角选择 方式2:在脱壳文件中搜索 DLL & API 名称
    • 重新勾选重建输入表

ESP 脱壳定律的原理:

  1. 在程序自解密或者自解压过程中,不少壳会先将当前寄存器内容压栈,如使用 pushad
  2. 在解压结束后,会将之前的寄存器值出栈,如使用 popad
  3. 在寄存器出栈时,往往程序代码被自动恢复,此时硬件断点触发(这也是我们下硬件断点的原因)
  4. 然后在程序当前位置,只需要少许 F8 单步跟踪,就很容易到达真正的 OEP 位置

UPX 壳

UPX 壳是一种压缩壳,原理:首先将程序压缩,一方面在程序的开头或者其他合适的地方插入一段代码,另一方面是将程序的其他地方做压缩

压缩也可以叫做加密,因为压缩后的程序比较难看懂,和原来的代码有很大的不同


UPX 脱壳工具

UPX 脱壳有一些自动化工具,比较方便

下载地址:upx 3.96-win64 - Download


脱壳流程

  1. 将加壳文件置于脱壳工具解压后的文件夹下,例如:D:\upx-3.96-win64

  2. 相关命令:

upx -d 文件名   # 脱壳
upx 文件名      # 加壳

CTF - Reverse_upx 脱壳1.png