自己最近在做总结,看到之前所做的两个upx加壳的题目,于是总结一下。
upx
大家应该都不陌生,在做题时算是比较容易遇到的一种壳,代码开源。
UPX(the Ultimate Packer for eXecutables)是一个免费且开源的可执行程序文件加壳器,支持许多不同操作系统下的可执行文件格式
能用upx -d
直接脱壳的就不举例了。
强网杯有一题hide
,鹏城杯有一题C++ note
都是无法一键脱壳的,关于hide
可以参考我之前写的博客(网上也有很多资料)。
具体的解题过程在此不做讲解
首先我们写一个简单的验证过程,这里就直接拿之前写的题xxTea
的代码,源代码在之前的文章里有。
如果因为程序过小而压缩失败可以通过添加如下代码进行解决:
int const dummy_to_make_this_compressible[10000] = {1,2,3};
我在ubuntu
下进行压缩,版本3.91
如下:
通常我们使用upx main -o main-upx
命令进行压缩,对比下压缩前后的文件信息。
压缩前
压缩后
使用strings
查看
尝试使用upx -d main-upx
脱壳
直接就能脱,这种题目会有,一般只是考查对upx的基本使用,并没有任何难度。
往往upx
压缩的题目是不会让做题者直接使用工具解压的,因此这里面可以做许多文章,可以通过编译源码,隐藏UPX版本、标志等信息,这里讲一下自己遇到过的隐藏UPX版本、标志进行的混淆。
首先要来了解一下upx
加壳之后的ELF
文件格式
文件格式参考自这位大神的分析
具体分析看分析哦,这里只说明如何隐藏标志,防止一键脱壳。
实验过程如下:
upx 3.95
版本,mac
下进行实验
压缩
能正常解压
修改UPX!
标志位
修改前:
修改后:
尝试解压,提示l_info corrupted
此时程序能正常运行
除此之外我还试了下在3.91
版本下修改标志位,发现upx -d
仍然能直接脱(不明所以)。
如果upx -d
命令无法直接脱壳,那么我们可以选择手动脱壳,方法也很简单,不需要复杂的操作。(头铁的我一般直接动态逆)
这里选取的样本为upx 3.95
压缩,修改标志位。
运行程序后,查看进程的内存信息
脱壳的基本原理是程序在运行时会将代码释放到内存中,我们只需在运行时将内存中的可执行代码段dump
出来即可。
如下命令:
sudo dd if=/proc/$(pidof mac-main-upx)/mem of=main_dump skip=0x400000 bs=1c count=786432
当然使用gdb附加,使用(gdb) dump memory /root/memory.dump 0x400000 0x40c000
也是一样的效果。
这时便可以动静结合来进行调试了。
当然如果你有能力修复的,那么把dump的程序修复下也是可以的。
upx防脱的方法还有好多,不过网上公开的源代码并不多,但我觉得没必要在混淆上做太多文章,毕竟混淆只是增加了调试的速度而已,头铁直接刚就是了,哪怕面目全非。
一点总结,有不当之处还请指出。