版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/linjingtu/article/details/79982597

壳的装载过程(模拟window加载器)

获取壳自己所需要使用的API地址

        如果用PE编辑工具查看加壳后的文件,会发现未加壳的文件和加壳后的文件的输入表不一样,加壳后的输入表一般所引入的DLL和API函数很少,甚至只有Kernel32.dll以及GetProcAddress这个API函数。
  壳实际上还需要其他的API函数来完成它的工作,为了隐藏这些API,它一般只在壳的代码中用显式链接方式动态加载这些API函数。

解压或解密源程序的各个区块

    壳出于保护原程序代码和数据的目的,一般都会加密原程序文件的各个区块。在程序执行时外壳将会对这些区块数据解密,以让程序能正常运行。
  壳一般是按区块加密的,那么在解密时也按区块解密,并且把解密的区块数据按照区块的定义放在合适的内存位置。
  如果加壳时用到了压缩技术,那么在解密之前还有一道工序,就是解压缩。这也是一些壳的特色之一,比如说原来的程序文件未加壳时1~2M大小,加壳后反而只有几百K。

进行必要的重定位

            文件执行时将被映像到指定内存地址中,这个初始内存地址称为基地址(ImageBase)。
      对于EXE的程序文件来说,Windows系统会尽量满足。例如某EXE文件的基地址为0x400000,而运行时Windows系统提供给程序的基地址也同样是0x400000。在这种情况下就不需要进行地址“重定位”了。由于不需要对EXE文件进行“重定位”,所以加壳软件把原程序文件中用于保存重定位信息的区块干脆也删除了,这样使得加壳后的文件更加小巧。有些工具提供“Wipe Reloc”的功能,其实就是这个作用。
      不过对于DLL的动态链接库文件来说,Windows系统没有办法保证每一次DLL运行时都提供相同的基地址。这样“重定位”就很重要了,此时壳中也需要提供进行“重定位”的代码,否则原程序中的代码是无法正常运行起来的。从这点来说,加壳的DLL比加壳的EXE更难修正。

HOOK-API

        程序文件中的输入表的作用是让Windows系统在程序运行时提供API的实际地址给程序使用。在程序的第一行代码执行之前,Windows系统就完成了这个工作。
  壳一般都修改了原程序文件的输入表,然后自己模仿Windows系统的工作来填充输入表中相关的数据。在填充过程中,外壳就可填充HOOK-API代码的地址,这样就可间接地获得程序的控制权.

跳转到程序原入口点(OEP)

从这个时候起壳就把控制权交还给原程序了,一般的壳在这里会有明显的一个“分界线”。但现在的猛壳己没这界限了,壳里有肉,肉里有壳。

壳的分类

压缩壳:ASPack,UPX,PECompact

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

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

加密壳:ASProtect,Armadillo,EXECryptor,Themida,VMProtect

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

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

虚拟机保护壳

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

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

由于CPU指令本身的复杂性(OPCode的解析需要通过3张复杂的表相对照才能顺利进行),因此被虚拟机加密过的可执行代码在业内至今仍没有人可以完全攻破。而更为强悍的是,现今的虚拟机软件CPU的编码格式已经是随机生成的了。

猜你喜欢

转载自blog.csdn.net/linjingtu/article/details/79982597