概念

在一些计算机软件里有一段专门负责保护软件不被非法修改或反编译的程序。它们一般都是先于程序运行,拿到控制权,然后完成它们保护软件的任务。就像动植物的壳一般都是在身体外面一样理所当然。由于这段程序和自然界的壳在功能上有很多相同的地方,基于命名的规则,大家就把这样的程序称为“壳”。就像计算机病毒和自然界的病毒一样,其实都是命名上的方法罢了。

从功能上抽象,软件的壳和自然界中的壳相差无几。无非是保护、隐蔽壳内的东西。而从技术的角度出发,壳是一段执行于原始程序前的代码。原始程序的代码在加壳的过程中可能被压缩、加密等。当加壳后的文件执行时,壳-这段代码先于原始程序运行,他把压缩、加密后的代码还原成原始程序代码,然后再把执行权交还给原始代码。软件的壳分为加密壳、压缩壳等类,目的都是为了隐藏程序真正的OEP(入口点,防止被破解)。

程序员编写好软件后,编译成exe可执行文件。有一些信息需要保护起来、有时需要程序存储空间小一点、黑客给木马等加壳以躲避杀毒软件。实现上述功能的软件称为加壳软件。

软件脱壳,顾名思义,就是对软件加壳的逆操作,把软件上存在的壳去掉。

分类

所谓的“壳”就是一种对软件进行保护的加密程序,它可以具体分为三种:

(1)压缩壳

压缩壳的主要目的是压缩应用程序的体积,例如最稳定的UPX可以将一般的应用程序压缩到原体积的30%左右。

压缩壳并不会对被加壳程序本身做任何修改,而是直至将其换成一种更加节省空间的存储方式,其目的大致类似于我们经常使用的RAR或ZIP。经过压缩壳处理过的程序在真正被CPU执行前是会自动解压缩(解密)的。

(2)加密壳

加密壳的主要目的是保护原程序不被破解,一般情况下,经过加密壳处理的应用程序体积会增加,但也有部分加密壳结合了压缩壳的特性,会在加密完成后再进行压缩。

而且一般情况下,加密壳会对原程序进行一定的修改,例如代码乱序、代码混淆等,因此经过加密壳处理的程序即便是提交给CPU去执行,原程序的代码也还是发生了改变。

(3)虚拟机保护壳

虚拟机保护壳是近几年在软件安全领域内流行起来的一种非常强悍的加密保护方案。它的关键技术就在于实现了一个软件版的CPU,被加密的可执行代码已经不再遵守Intel制定的OPCode标准了,而是执行由虚拟机作者本身制定的非公开的、动态的CPU指令编码解码标准,我们通常称之为TextCode。

虚拟机保护壳会将被保护程序的可执行代码重新编码为自己的软件CPU可以识别的格式,并进行存储、加载及模拟执行。因此在任何时候,原程序代码对外界来说都将是一个彻底的黑盒,任何人都很难破解。

作用

1.有一些版权信息需要保护起来,不想让别人随便改动,如作者的姓名,即为了保护软件不被破解,通常都是采用加壳来进行保护。
2.需要把程序搞的小一点,从而方便使用。于是,需要用到一些软件,它们能将exe可执行文件压缩。
3.在黑客界给木马等软件加壳脱壳以躲避杀毒软件。

基本过程

我们以使用频率较高的UPX为例,为大家简述加壳与手动解除UPX壳的过程,以加强各位对于加壳去壳这一过程的理解。

从官网下载UPX程序之后,就可以在命令行中使用它了。它的常见命令有两种,一种是加壳时用“upx.exe 目标程序”,另一种是对已经加壳的程序进行解壳“upx.exe -d 目标程序”。

我们将目标程序设定为之前的helloworld.exe,加壳过程如下所示。

img

加壳之后为了确定是否成功,我们使用PEiD来检测加壳后的程序,发现提示了UPX,说明加壳已经成功。

img

我们将加壳后的Helloworld拖入OllyDbg进行解析,通常情况下有三种脱壳的方法:单独跟踪法、ESP平衡法和一步到ESP法,这里我们为大家演示使用ESP平衡法脱壳的过程。

一般来说,外壳程序首先需要保存原程序的寄存器信息,等外壳程序恢复原程序的ESP寄存器的值,常常就到了OEP位置附近,这就是ESP平衡法的思路。

在我们将加壳程序拖入OD后,我们F8单步走走,同时注意右面寄存器FPU的显示,当有且只有ESP和EIP为红色时,我们就可以用ESP定律了。具体在下图中,我们走了一步,就发现只有ESP与EIP变红了。

img

此时我们在ESP后面的地址右键,选择在数据窗口跟随,这样在下面的内存数据窗口与堆栈窗口都会转移到该地址的位置,在本例中即数据窗口中跟随到0012FFA4这个地址,随后我们右键该地址中数值设置断点→硬件访问→word型。

image-20190919210937881

随后我们正常运行程序(F9),此时程序会暂停在我们设置的断点位置。

image-20190919211112002 image-20190919211036343

然后我们F8单步走,注意到了jnz位置后不要再按F8了(这是向上跳转的),我们用鼠标点击她的下一行然后按F4,让程序强制转到跳转下面继续运行,到达jmp后我们可以跳转,因为接下来有极大可能是程序的OEP。在jmp跳转后,我们就看到了该helloworld程序的OEP。

image-20190919211112002

之后我们就可以进行脱壳,但是为了避免脱壳过程受到影响,脱壳之前我们先把断点给清理掉。之后在OEP的程序第一行我们右键选择OD的脱壳调试选项。

img

最终我们生成tk_helloworld.exe程序,检查后发现程序能够正常运行。将其拖入PEiD中发现信息已经改变,脱壳成功。

img