一、手动加壳
壳是一种较为特殊的软件。壳分为两类,一类是压缩壳,另一类是加密壳。当然,还有介于两者之间的混合壳。下面先来手动为一个可执行文件加一层外壳,需要准备的工具有C32ASM、LordPE、添加节表工具和OD。
首先用LordPE查看可执行文件,并对需要的几个数据做一个简单的记录,如图1所示。
在LordPE中,需要查看几个对于我们需要的数据,包括PE文件的入口RVA、映像地址和代码节的相关数据。有了这些数据以后就可以通过C32ASM对代码进行加密了。用C32ASM以十六进制的方式打开可执行文件,然后从代码节的文件偏移开始选择,也就是从1000h的位置开始选择,一直选到4fffh的位置。然后单击右键,在弹出的快捷菜单上选择“修改数据”命令,在“修改数据”对话框中选择“异或”算法来对代码节进行加密,如图2所示。
使用0x88来对代码节进行异或加密,单击“确定”按钮后代码节被修改。保存以后使用添加节表的软件对可执行文件添加一个新的节,如图3所示。
添加新的节区以后使用OD对可执行文件添加一些代码,用OD打开可执行程序,来到00408000地址处,添加如下代码:
以上代码的作用是将上面修改的代码节内容还原,然后进行保存。用LordPE修改该可执行文件的入口和代码节的属性,如图4、图5和图6所示。
运行修改过的可执行文件,可以正常运行。
下面整理一下思路,以方便我们写代码。最开始用LordPE查看了将要用到的一些PE信息,然后用C32ASM对代码节进行了简单的异或加密,接下来新添加了一个节并在新节中写入了还原代码节的解密指令,最后用LordPE修改了文件的入口地址、代码节属性和新添加节的属性。对照一下前后两个文件的不同之处,如图7所示。
从图中可以看出这两个PE文件的差别,相信大家对此已经没有不理解的地方了。下面开始手动打造一个这样简单的加壳软件。
二、编写简单的加壳工具
其实不按照上面的步骤进行也可以,只要步骤是合理的就可以了。我们主要有4个函数需要实现,分别是获取PE信息GetPeInfo()、添加新节AddSection()、加密代码节Encode()和写入解密代码WriteDecode()。我们主要看两个函数的代码,分别是Encode()和WriteDecode()。
00408000 > 60 PUSHAD
00408001 B8 00104000 MOV EAX,HelloWor.00401000
00408006 8030 88 XOR BYTE PTR DS:[EAX],88
00408009 40 INC EAX
0040800A 3D 464B4000 CMP EAX,HelloWor.00404B46
0040800F ^ 75 F5 JNZ SHORT HelloWor.00408006
00408011 61 POPAD
00408012 B8 41104000 MOV EAX,HelloWor.00401041
00408017 FFE0 JMP EAX
在虚拟地址和汇编指令的中间部分就是汇编指令对应的机器码,将其取出并定义为C语言的数组,定义如下:
这个机器码在解密的过程中要根据实际的PE信息进行修改,修改的位置有3处,分别是代码节的起始虚拟地址、代码节的结束虚拟地址和程序的原始入口点,代码如下:
这就是解密代码,大家可以找个用VC写的程序来进行测试。在这里使用Release版的helloworld测试通过。
这个壳属于袖珍版的壳,严格来说,算不上是一个壳,但是这个壳在免杀领域是有用的,也就是把定位到的特征码进行加密,然后再写入解密代码从而隐藏特征码。一个真正的壳会对导入表、导出表、资源、TLS、附加数据等相关的部分进行处理。加密壳会加入很多反调试的功能,而且还会让壳和可执行文件融合在一起,达到“骨肉相连”的程度来增加脱壳的难度。