fightingman 发表于 2020-4-20 15:40

UPX源码粗略解析

源码的分析实际上很粗浅。起因就是每次想查看脱壳原理都是一段话或者几张图进行说明。虽然不否定这个对理解很有帮助,但是总感觉理论性比加强,实践性不高,所以就自己找源码进行分析
(我是萌新,大佬请绕过)

一、UPX原理

虽然在开头讲了(也算打自己的脸吧),但是理论确实能够帮助理解。

UPX这个壳的产生初始的目的起始是为了压缩,它产生的那个年代,机器的内存容量还很小,为了便于文件的传输,压缩文件是一个很有效的手段,UPX应运而生。到了后来才演变为为了安全为目的,当然对现在的一些分析工具,UPX的安全效能已经很低了

UPX的原理其实比较容易理解。假设原始程序是分为以下几个段


那么UPX会在程序入口点加上自己的壳代码,同时原来的1、2、3被UPX压缩算法所压缩(假设压缩之后变为A、B、C)
之后程序开始运行,这个时候会执行0处的代码,这个代码的功能是将A、B、C的代码解压,恢复成1、2、3,这样程序的执行与源程序是一样的。
二、源码分析
我们知道对应不同的压缩级别、不同的文件类型,对应的UPX解压缩算法是不同的,针对不同的目的可以选择不同级别的压缩算法。所以因为时间原因不可能把所有的压缩算法都审计一遍
这里就以一种压缩算法为例,这里是以文件类的形式写的,每种文件的压缩算法都是虚函数,然后再自己的类中再进行描述,这里以windows32的压缩算法为例。Windows32的压缩算法是 PackW32Pe::pack,文件路径是upx实例分析\源代码\upx-3.91-src\src\p_w32pe.cpp。首先可以先看一下这个类的定义,可以看到几个比较关键的函数:


① virtual const int *getCompressionMethods(int method, int level) const;从函数的参数可以看出确实选择不同的方法和级别,压缩的算法是不同的。跟进去之后发现,这个函数又调用一个函数getDefaultCompressionMethods_le32,

而getDefaultCompressionMethods_le32这个函数里面就预先定义了一些方法,当然了目前还不清楚这些方法具体的压缩算法是什么。但是可以清楚确实有选择压缩算法这一功能

② virtual const int *getFilters() const;我们知道filters在UPX算法中代表着数据预处理的方法,而根据不同的数据处理方法,压缩算法的效率也不同。数据中的值可能代表着就是不同的数据处理方法
③ virtual void pack(OutputFile *fo);这个就是最关键的压缩算法了。首先是一个检查PE头,来判断是否能压缩,否则抛出异常

接着是对程序的一些保护措施进行处理,比如地址随机化之类的。这里还有对文件的大小进行限制,过于小的也不能压缩,限制区间是0x200


接着是处理绑定导入表,如果不符合压缩条件的也会抛出异常

然后通过调用程序内自己的API处理程序的一些段表,比如导入表、导出表、资源段等

还是对二进制程序的内存进行处理

接着开始压缩,先准备压缩后的PE头,以及确定压缩算法

接着调用了一个关键的函数compressWithFilters
这里跟进去进行分析,首先将原有结构进行一个拷贝,之后获取压缩方法

如果压缩方法有效那么会先分配一片空间为了接下来的压缩程序,然后会调用upx_compress
在compress.cpp中找到这个函数(也找到了upx_decompress),在这里就可以看出来,这里还是先判断了一些选择的压缩算法,之后再用不同的API进行压缩

这里就以upx_lzma_compress为例子,可以找到这里又有一个比较重要的函数LzmaEncode。这个就是以lzma作为压缩算法进行压缩数据。
这里压缩算法比较明了了,由于这里调用其他文件中的API所以就不继续深入分析了,具体压缩算法网上都可以找得到
但是以lzma为例可以知道这个UPX比较粗浅的一个压缩流程:


④ virtual void buildLoader(const Filter *ft);这个函数是为了重建区段的。从UPX的原理可以知道,壳代码会插入在程序的入口点,插入之后为了能够成功运行程序,需要重建一下区段。可以看到这个函数里面调用了addloader()这个函数,这个函数的功能就是插入壳代码段


⑤ virtual unsigned processImports();我们知道一个程序基本上都会调用系统的API函数,为了调用这些函数需要在内存某个地方存放这些函数的地址----IAT表,但是再加壳之后,程序发生了变化,原有的函数地址就会被改变,这个时候就需要对导入表进行处理。这里截取一部分代码为例

三、后记

这个分析难免比较粗浅而且可能还有错误,虚心接受大佬批评{:1_889:}
源码压缩包

跌宕起伏 发表于 2020-4-20 15:58

看不懂就只会用UPX加个压缩壳

庞晓晓 发表于 2020-4-20 16:59

xglys 发表于 2020-4-20 19:49

谢谢分享
页: [1]
查看完整版本: UPX源码粗略解析