运行时压缩

不管哪一种形态的文件,在计算机中本质都是由0和1组成的,可以使用合适的压缩算法然后缩减大小

经过压缩的文件若能100%恢复,则称压缩为无损压缩(Lossless Data Compression)

若不能恢复原状,则称压缩为有损压缩(Loss Data Compression)

无损压缩

无损压缩用来缩减文件(数据)的大小,压缩后的文件更保管,移动。使用经过压缩的文件之前,需要对文件进行解压缩

例如7-zip等压缩程序

最具代表性的无损压缩算法有Run-Length,Lempel-Ziv,Huffman

Zip,RAR等是具有代表性的压缩文件格式,但是根本压缩理念也是基于Run-Length

Lempel-ZivHuffman,然后应用了一些各自特有的技术(压缩率,压缩/解压时间)

有损压缩

有损压缩允许压缩文件时损失一定信息,以此换取高压缩率。

压缩多媒体文件(jpg,mp3,mp4)时,大部分都使用这种有损压缩方式

从压缩特性来看,有损压缩虽然不能完全恢复原始数据,但是人类的肉眼和听觉几乎无法察觉其区别

例如Mp3核心算法通过删除超越人类听觉范围的波长区段来缩减不需要的数据大小

运行时压缩器

运行时压缩器你针对PE而言的

就是,经过压缩后的PE,内部含有解压代码,文件在运行瞬间在内存中解压缩然后再执行

image-20240712200844770

把普通PE文件创建成运行时压缩文件的使用程序称为Packer,

经过反逆向技术特别处理的压缩器称为Protector

PEPacker

  • 缩减PE文件大小
  • 隐藏PE文件内部代码与资源
  • UPX是单纯用于压缩PE文件的压缩器
  • 也有一些Virtus,TrojanWorm专门用于恶意程序的意图不纯的压缩器

PEProtector

  • 用于保护PE文件免受逆向分析的使用程序(不仅运行时压缩,还应用了反调试,反模拟,代码混乱,多态代码,垃圾代码,调试器监视等反逆向技术)
  • 防止破解,用于商业程序

一些商用的保护器

ASProtect,Themida,SVKP

公用保护器

UltraProtrxt,VMProtect

Compare

image-20240712201514549

经过upx压缩后的应用程序

区别如下

  • PE头大小一样(0~400h)
  • 节区名称发生改变(.text->UPX0,“.data”->“UPX1”)
  • UPX0的RawDataSize为0,说明第一个节区在磁盘文件中不存在
  • EP位于第二个节区,而原来的notepad的EP在第一个截取
  • 资源区无变化

经过UPX压缩的PE文件在运行瞬间将(文件中的)压缩的代码解压到第一个节区

解压缩代码与压缩的源代码都在第二个节区

文件运行时首先执行解压缩代码

然后把处于压缩状态的源代码解压到内存中的第一个截取

然后解压结束将运行源文件的EP代码

调试UPX

逆向分析中,称源文件的EP为OEP

对于普通的运行时压缩文件,源文件代码,数据,资源解压缩之后先设置IAT

再转到OEP

  1. 循环次数ECX=36B,循环内容为从EDX读取一个字节写入EDI

    EDI寄存器所致的地址即是第一个截取的起始地址 ,

  2. 第二个开始正式的解码循环

    先从ESI所指的第二个分区UPX1地址中一次读取值

    然后经过适当的运算解压缩后

    将值写入UPX0

  3. 第三个循环用于恢复源代码的CALL/JMP指令,

    其实就是设置好IAT

  4. UPX压缩原文件时先分析IAT,然后提取出程序中调用的API名称列表,形成API名称字符串

    恢复源文件的IAT

    然后将程序控制返回到OEP

快速查找UPX OEP的方法

在POPAD后的JMP指令设置断点

  • upx压缩器的特征就是 EP代码被包含在了PUSHAD/POPAD之间

    并且跳转到OEP代码的JMP指令紧跟在POPAD之后

    因此只要在JMP指令处设置好断点

    运行后就能直接找到OEP

PUSHAD 指令将8个通用寄存器(EAX~EDI)保存到栈中

POPAD 把pushad名称存储在栈的值恢复到各个寄存器

在栈中设置硬件断点

也是利用UPX的PUSHAD/POPAD指令的特点

在程序的开始,OEP已经就被加载到栈中

设置硬件断点,硬件一访问OEP(jmp OEP)就暂停