“壳”是一种对程序进行加密的程序,“壳”形象地表达了这个功能。我们可以把加壳的程序看成是食物,加壳的程序就是在外面加了一层硬壳,防止别人窃取程序。打包后的程序仍然可以直接运行。程序运行时,先运行shell的代码,再运行原程序。主要目的是隐藏程序的OEP(入口点),防止外部软件对程序进行反汇编分析或动态分析。很多病毒都是通过加壳来达到免杀的目的,但是加壳也是为了保护正版软件不被破解。技术没有对错之分,关键看使用目的。一、shell的分类(1)压缩shell压缩shell的作用是压缩程序的大小。压缩壳并没有修改程序,只是改变了存储方式,使程序变小了。运行程序时,先运行shell的解压程序,将源程序解压到内存中,然后执行。一种常见的压缩外壳是UPX,它可以将一般程序压缩到其原始体积的30%。压缩upx_test,原始大小为188KB,压缩后大小为33KB,仅为原始大小的17.54%。详细信息如图1所示。图1压缩upx_test使用PEiD查壳,测试是否有壳。如图2所示,确实存在一个UPX压缩壳。图2PEiDshell校验(UPX)(2)加密shell加密shell的作用是保护程序不被破解。一般来说,加密程序的大小视情况而定,有些加密的shell还有压缩shell的作用。加密外壳会对程序进行修改,如扰乱代码、混淆等。常见的加密shell有ASProtect、EXECrptor、Armadillo等,如图3所示,是用ASProtect加密的。图3ASProtect加密使用PEiD查壳,测试是否有壳,如图4所示,确实有APS加密壳。图4PEiDshell校验(APS)(3)虚拟机保护壳虚拟机保护壳是近几年流行的一种加密保护方案。关键技术是实现CPU功能的软件。由于程序没有遵循Intel的OPCode标识,分析起来会比较麻烦。2.解包针对不同的shell,网上有很多对应的解包工具。解包前,一般使用查壳工具查看加了什么壳,然后找到对应的脱壳工具进行脱壳。以前面UPXshell压缩后的upx_test.exe为例,演示解包。图5显示了PEiD的shell检查结果。通过查壳,我们知道这是一个UPX壳,然后使用相应的脱壳工具进行解包。图5PEiDshell校验结果这里我们使用UPXshell进行演示。将程序拖入UPXshell,点击“GO”,即可得到解压后的程序。解包后,原来的脱壳程序会被覆盖,所以在解包前做好备份,如图6所示。图6解包解包是逆向分析的必备技能之一。虽然用软件解包很方便,但是还是有很多限制,比如要找到对应的解包软件,更新更强的壳一般不能用软件解包等等。所以了解一些脱壳的基础知识还是很有必要的.(1)OEP解包的第一步是找到源程序的OEP(OriginalEntryPoint)。OEP标志是否已经运行到源程序。对于一些简单的压缩shell,找到OEP就说明shell解包成功了。单步调试法:当打包后的程序开始运行时,栈的状态与解压后的主程序完全一样。所以很多packer加载OD后会停留在pushad/pushfd,先保存原来的栈,所以pushad/pushfd必须有对应的popad/popfd。只要找到popad/popfd,就可以很快找到OEP。将upx_test.exe加载到OllyDbg中,一直按F8,如果遇到向上跳转,按F4运行到下一行。直到遇到popad,下面会有比较大的jmp跳转。如图7和图8所示。跳转后的地方就是程序的OEP,如图9所示。图7单步调试1图8单步调试2图9寻找OEP这里只做一个比较简单的并介绍了常用的解包方法。在实践中,有很多巧妙的方法,如ESP法,利用编辑语言的特性等。(2)内存映像转储找到OEP后,程序已经在内存中,内存中的程序距离最近打包前的程序。只需要将内存中的图片dump出来,一般的shell就结束了。内存映像转储工具有很多,例如LordPE和PETools。在OllyDbg中还有一个OllyDump插件可用。可以解包如下。右击“pushebp”选择dumpprocess,点击“dump”按钮解包。将生成解压后的程序,默认文件名会在原文件名后加上“_dump”。最后查看shell,显示没有shell,运行成功,说明解包成功,如图10所示。图10内存映像转储(3)重建导出表很多加密的shell都会操作导入表。这时候即使成功解壳,程序也无法运行。IAT在导入表中起着关键作用,所以修复导出表很多时候也称为修复IAT。可以使用importREC重建导出表,如图11所示。图11重建导出表
