大家可能对Upack壳这东西一知半解吧?大家知道什么是壳吗?下面就给大家说Upack的壳吧!
1.概述
传统意义上壳分为压缩壳和加密壳。顾名思义压缩壳主要是为了减小程序体积,如经典的UPX, ASPack等,加密壳则侧重保护程序不被逆向分析,他们也被商业软件合法的用于防盗版及非法纂改。但一些病毒和恶意软件也基于同样理由使用壳,除了减小病毒体积外,也能在一定程度上躲避杀毒软件的特征查杀。
2, Upack基本信息
Upack是一个国产的压缩比很高的壳,由Dwing开发,和其他压缩壳不同的是Upack除了对压缩算法作了优化外还对整个PE结构做一定更改以达到最大压缩率,所以Upack也被很多病毒,木马使用。本文通过对Upack 1.0的简单分析以熟悉对壳的基本流程的理解。

首先我们使用PEiD查看文件信息,可以看到PEiD识别为Upack 0.10 - 0.12 beta,当然PEiD也是根据壳的特征码来识别的,下面就是PEiD定义的壳特征。其中??为掩码。
[Upack 0.10 - 0.12 beta -> Dwing]
signature = BE 48 01 40 00 AD 8B F8 95 A5 33 C0 33 C9 AB 48 AB F7 D8 B1 04 F3 AB C1 E0 0A B5 ?? F3 AB AD 50 97 51 AD 87 F5 58 8D 54 86 5C FF D5 72 5A 2C 03 73 02 B0 00 3C 07 72 02 2C 03 50 0F B6 5F FF C1
ep_only = true
再来看一下文件的节信息

节的名称变成了乱码,当然这是不影响程序正常执行的,实际上Upack在此处存放几个API函数地址。第一个节的R偏移和R大小都为0,所以他并不会占用磁盘空间,只有载入内存的时候才更具V偏移和V大小分配空间(R偏移和R大小表示在磁盘文件中的偏移和大小,V偏移和V大小表示当载入到内存中的偏移和大小)。在Upack1.x和2.x版本中,原程序的数据被压缩后放在第2个节和入口之间部分,在这里压缩后的数据位于V偏移0x00009000 – 0x0000A563间,之后为壳自身代码。
3, 解码
要使原程序能够正常运行,就必须对压缩后的数据还原。目前有很多开源的压缩算法,如APLib, LZMA, JCALG1等。如在未加壳的程序的某一偏移处数据为0x12345678,加壳后可能会变成0x87654321,若在程序源码中随意增加一条指令,则该偏移处数据可能会变为0x45678123。所以对加壳程序仅仅依靠带壳特征扫描并不是一个好的解决方案,一个做法就是对脱壳后的程序进行特征匹配。下面分析一下Upack1.0的基本流程。
先使用OD载入,停在入口处。

00400148这个地址位于节表内,通过查看节表可以看到节表内除了必须的几个值,如VirtualAddress, VirtualSize, RawOffset, RawSize和Characteristics字段外都被壳用作保存解码所用的函数地址,数据地址等。
接下来壳进行解压数据。

解压完成后还需要恢复源程序的导入表。

恢复导入表后壳跳转到原入口,至此整个被加壳程序在内存中已经完全恢复,程序开始执行自己的代码。
5,总结
一般壳都是经过这几个步骤,解码,恢复必要数据,然后返回到原入口开始执行的。当然这只是一个很简单的例子,实际中壳可能还需要处理压缩资源,DLL重定位,恢复TLS等其他各种操作。 |