【How2RE】 UPX壳及脱壳方式

0x00 什么是壳

壳是另外在PE文件中包含的代码,并且不影响PE文件正常的执行。而壳也分为很多种,这里从UPX壳开始介绍。

0x01 压缩壳

压缩的分类

压缩的目的就是将体积大的可执行文件缩小的过程。分为损失压缩非损失压缩两种。损失压缩是指不能100%还原的压缩,常见的有JPG,MP4等格式。非损失压缩就是可以100%还原的压缩方式,一般有ZIP,7z等格式。

压缩壳

压缩壳的目的就是将PE文件变小。压缩有UPX, ASPack等方式。

Run-Time Packing

将原本的可执行文件的代码和数据压缩之后加入解压代码。压缩后的可执行文件很难进行静态分析。
可执行文件的起始地址称为OEP
压缩后的可执行文件起始地址称为EP

Unpacking

unpacking就是将packing后的可执行文件还原的过程,一般有以下几个步骤。

  • 找出解除压缩时的地址
  • 在压缩后的可执行文件中找出OEP地址
  • 找到OEP地址中断后取得原本可执行文件的内存数据
  • 最后将内存数据以可执行文件的方式重新整合

0x02 实验需要用到的工具

UPX: 用于压缩
https://github.com/upx/upx
OllyDumpEx: 找到OEP后可以直接通过这个工具还原导入表
https://low-priority.appspot.com/ollydumpex/

0x03 开始实验

首先准备个C语言的简单程序

#include<stdio.h>

int add(int a, int b) {
	return a + b;
}

int a = 0x11;

int main() {
	printf("Hello World!\n");
	add(a, 0x22);

	return 0;
}

找到可执行文件之后拖入DIE后看一下程序大小
可执行文件大小
然后用UPX加了压缩壳之后的文件进行对比
在这里插入图片描述
可以发现经过压缩之后的可执行文件大小缩小了,这里可以用HxD打开看一下。之前的data,bss段等都被UPX0,UPX1代替,只有rsrc段和压缩前相同。
在这里插入图片描述

0x04 ESP定律

由于在程序自解密或者自解压过程中, 不少壳会先将当前寄存器状态压栈, 如使用pushad, 在解压结束后, 会将之前的寄存器值出栈, 如使用popad. 因此在寄存器出栈时, 往往程序代码被恢复, 此时硬件断点触发. 然后在程序当前位置, 只需要少许单步操作, 就很容易到达正确的 OEP 位置.
ESP定律法 - CTF WIKI

首先打开经过upx压缩过的程序,F9来到程序起始的位置,并且F8单步执行pushad指令保存寄存器状态。观察旁边寄存器的状态可以得知,ESP的值发生了变化。
ESP位置发生变化
在寄存器视图中右键在ESP上设置断点。然后按下F9前往ESP所指向的地址。
设置ESP断点
跳转到00AD7FEF之后观察这里的汇编代码,我们会发现在00AD7FFC处有一个jmp指令,这是一次大跳转,极有可能是OEP所处的地址。在00AD7FFC处设置断点,F9运行至此处。
第一次跳转到ESP
按下F8单步进入,下面这个00AD1633就是OEP的位置。
最后到达OEP
最后来恢复整个程序,在插件中使用Dump process,选择Get EIP as OEP,最后Dump文件并保存。
DUMP
在这里插入图片描述
但是有时会出现Dump了程序却依然无法打开的情况,这是因为在Dump程序的过程中IAT表可能出现了丢失的情况。这个时候用Scylla来修复IAT表,在入OEP的位置打开Scylla,按下IAT Autosearch -> Get Imports 将 Import 中红色的部分删去最后再Fix Dump覆盖之前的程序,或者是重新生成一个Dump的程序。

在这里插入图片描述

如果文章中存在错误,请评论或者私信我

  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值