UPX简介

1
2
3
4
5
6
7
8
9
10
11
UPX (the Ultimate Packer for eXecutables)是一个著名的压缩壳,主要功能是压缩PE文件(比如exe,dll等文件),有时候也可能被病毒用于免杀。壳upx是一种保护程 序。一般是EXE文件的一种外保护措施,主要用途:

1、让正规文件被保护起来,不容易被修改和破解。

2、使文件压缩变小。

3、保护杀毒软件安装程序,使之不受病毒侵害。

4、木马,病毒的保护外壳,使之难以为攻破。

利用特殊的算法,对EXE、DLL文件里的资源进行压缩。类似WINZIP 的效果,只不过这个压缩之后的文件,可以独立运行,解压过程完全隐蔽,都在内存中完成。解压原理,是加壳工具在文件头里加了一段指令,告诉CPU,怎么才 能解压自己。当加壳时,其实就是给可执行的文件加上个外衣。用户执行的只是这个外壳程序。当执行这个程序的时候这个壳就会把原来的程序在内存中解开,解开 后,以后的就交给真正的程序。

脱壳工具

upx壳的官网是:https://upx.github.io/
下载最新版的upx:https://github.com/upx/upx/releases/

ESP定律

(“堆栈平衡”原理)

call指令:
1.向堆栈中压入下一行程序的地址;
2.JMP到call的子程序地址处。

RETN指令:
1.将当前的ESP中指向的地址出栈;
2.JMP到这个地址。这个就完成了一次调用子程序的过程

如果我们要返回父程序,则当我们在堆栈中进行堆栈的操作的时候,一定要保证在RETN这条指令之前,ESP指向的是我们压入栈中的地址。

在程序自解密或者自解压过程中, 多数壳会先将当前寄存器状态压栈, 如使用pushad, 而在解压结束后, 会将之前的寄存器值出栈, 如使用popad. 因此在寄存器出栈时, 往往程序代码被恢复, 此时硬件断点触发(这就是我们要下硬件断点的原因),然后在程序当前位置, 只需要一些单步操作, 就会到达正确的OEP位置

载入程序后只有esp寄存器内容发生变化,那么这个程序多半可以用ESP定律(存疑)

手动脱壳

脱壳三步法

① 寻找原始OEP
这一步骤的主要作用就是要确定原始程序代码到底在哪里,能找到原始程序的代码,说明壳代码执行完了,我们只有找到原始OEP才能进行下一步的动作。

② dump内存到文件
当我们找到原始OEP,调试运行到原始OEP时,只要代码被还原,我们就可以在这个地方进行dump内存,将内存中被还原的代码和数据抓取下来,重新保存成一个文件,这样脱完壳时,我们就可以用静态分析工具分析程序了。

③ 修复文件
这一步主要就是修复IAT,对从内存中转储到本地的文件进行修复。

示例:BUUCTF_Reverse_新年快乐

image-20200803160918611

使用ExeinfoPE查壳,确认是UPX

x32dbg打开,寻找原始OEP

image-20200803161135150

不需要下ESP硬件断点,F9运行,可以看到popad在上方

image-20200803161244521

有一系列jmp指令,选择跳转较远的,地址00401280,一般就是原始OEP,可以下一个断电F9运行,确认是原始OEP

使用Scylla插件,Dump,自动寻找IAT,获取导入表,修复Dump文件

IDA打开脱壳文件,确认成功

注:原始OEP也可以通过逐条分析汇编指令寻找,难度较大;有经验的话可以直接搜索popad

参考

https://www.52pojie.cn/forum.php?mod=viewthread&tid=314918

https://www.anquanke.com/post/id/99750

https://blog.csdn.net/qq_42967398/article/details/96444954

https://baijiahao.baidu.com/s?id=1662196196423030806&wfr=spider&for=pc