admin管理员组

文章数量:1567296

2024年3月4日发(作者:)

加壳与脱壳的应用与实现

加壳与脱壳的应用与实现

一、加壳 .................................................................................................... 2

1.什么是壳 .......................................................................................... 2

2.加壳原因 .......................................................................................... 2

3.壳的加载过程 .................................................................................. 3

4.压缩引擎 .......................................................................................... 5

5.常见的加壳工具 .............................................................................. 6

a.常用压缩壳介绍 ........................................................................ 6

b.加密保护壳介绍 ........................................................................ 7

二、脱壳 .................................................................................................. 10

1.侦壳 ................................................................................................ 10

2.脱壳 ................................................................................................ 13

a.查找程序的真正入口点(OEP) ............................................ 13

b.抓取内存映像文件 .................................................................. 15

c.输入表重建 .............................................................................. 15

附:视频“加壳与脱壳(软件)”和“手动脱壳” ............................ 17

1

加壳与脱壳的应用与实现

加壳与脱壳

一、加壳

1.什么是壳

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

图1.1

2.加壳原因

就把这样的程序称为“壳”了。

作者编好软件后,编译成exe可执行文件。

1)有一些版权信息需要保护起来,不想让别人随便改动,如作者

2

加壳与脱壳的应用与实现

的姓名,即为了保护软件不被破解,通常都是采用加壳来进行保护。

2)需要把程序搞的小一点,从而方便使用。于是,需要用到一些软件,它们能将exe可执行文件压缩。

3)在黑客界给木马等软件加壳脱壳以躲避杀毒软件。实现上述功能,这些软件称为加壳软件。

3.壳的加载过程

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

如果用PE编辑工具查看加壳后的文件,会发现未加壳的文件和加壳后的文件的输入表不一样,加壳后的输入表一般所引入的DLL和API函数很少,甚至只有以及GetProcAddress这个API函数。

壳实际上还需要其他的API函数来完成它的工作,为了隐藏这些API,它一般只在壳的代码中用显式链接方式动态加载这些API函数

2)解密原程序的各个区块(Section)的数据

壳出于保护原程序代码和数据的目的,一般都会加密原程序文件的各个区块。在程序执行时外壳将会对这些区块数据解密,以让程序能正常运行。 壳一般按区块加密的,那么在解密时也按区块解密,并且把解密的区块数据按照区块的定义放在合适的内存位置。

如果加壳时用到了压缩技术,那么在解密之前还有一道工序,当然是解压缩。这也是一些壳的特色之一,比如说原来的程序文件未加壳时1~2M大小,加壳后反而只有几百K。

3

加壳与脱壳的应用与实现

3)重定位

文件执行时将被映像到指定内存地址中,这个初始内存地址称为基地址(ImageBase)。当然这只是程序文件中声明的,程序运行时能够保证系统一定满足其要求吗?

对于EXE的程序文件来说,Windows系统会尽量满足。例如某EXE文件的基地址为0x400000,而运行时Windows系统提供给程序的基地址也同样是0x400000。在这种情况下就不需要进行地址“重定位”了。由于不需要对EXE文件进行“重定位”,所以加壳软件把原程序文件中用于保存重定位信息的区块干脆也删除了,这样使得加壳后的文件更加小巧。有些工具提供“Wipe Reloc”的功能,其实就是这个作用。

不过对于DLL的动态链接库文件来说,Windows系统没有办法保证每一次DLL运行时提供相同的基地址。这样“重定位”就很重要了,此时壳中也需要提供进行“重定位”的代码,否则原程序中的代码是无法正常运行起来的。从这点来说,加壳的DLL比加壳的EXE更难修正。

4)HOOK-API

Windows API是一套用来控制Windows的各个部件的外观和行为的一套预先定义的Windows函数。

程序文件中的输入表的作用是让Windows系统在程序运行时提供API的实际地址给程序使用。在程序的第一行代码执行之前,Windows系统就完成了这个工作。

4

加壳与脱壳的应用与实现

壳一般都修改了原程序文件的输入表,然后自己模仿Windows系统的工作来填充输入表中相关的数据。在填充过程中,外壳就可填

充HOOK-API的代码的地址,这样就可间接地获得程序的控制权。

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

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

4.压缩引擎

各类加壳软件,其压缩算法一般不是自己实现的,大多是调用其他的压缩引擎。目前压缩引擎种类比较多,不同的压缩引擎有不同特点,如一些对图像压缩效果好,一些对数据压缩效果好。而加壳软件选择压缩引擎有一个特点,在保证压缩比的条件下,压缩速度慢些关系不是太大,但解压速度一定要快,这样加了壳的EXE文件运行起来速度才不会受太大的影响。例如下面几个压缩引擎就能满足这要求:

1). aPLib压缩引擎 /,这个库对于低于64K的文件压缩效果较好,速度较快。

2). JCALG1压缩引擎,相对于aPlib,JCALG1对于大文件效果好些。

3). LZMA压缩引擎 /zh-cn/,LZMA 是 7-Zip 程序中 7z 格式 的默认压缩算法,压缩率很高。

5

加壳与脱壳的应用与实现

5.常见的加壳工具

加壳软件按照其加壳目的和作用,可分为两类:一是压缩(Packers),二是保护(Protectors)。压缩这类壳主要目的是减小程序体积,如ASPacK、UPX和PECompact等。另一类是保护程序,用上了各种反跟踪技术保护程序不被调试、脱壳等,其加壳后的体积大小不是其考虑的主要因素,如ASProtect、Armadillo、EXECryptor等。随着加壳技术的发展,这两类软件之间的界线越来越模糊,很

多加壳软件除具有较强的压缩性能,同时也有了较强的保护性能。

a.常用压缩壳介绍

1) ASPacK

ASPack是款Win32可执行文件压缩软件,可压缩Windows 32位可执行文件(.exe)以及库文件(.dll、.ocx),文件压缩比率高

达40%~70%。

图1.2

6

加壳与脱壳的应用与实现

2) UPX

UPX是一个以命令行方式操作的可执行文件经典免费压缩程序,压缩算法自己实现,速度极快。(开源)

3) PECompact

PECompact同样也是一款能压缩可执行文件的工具(支持EXE、DLL、SCR、OCX等文件)。相比同类软件,PECompact提供了多种压缩项目的选择,用户可以根据需要确定哪些内部资源需要压缩处理。同时,该软件还提供了加解密的插件接口功能。

图1.3

b.加密保护壳介绍

为了保护自己的软件不轻易被他人“借鉴”,有必要对软件进行一些加密保护,而这方面目前己有成熟的专业加密软件可选择。但不要太依赖壳的保护,大多数壳是可以被攻破的,还是在自身保护上下

7

加壳与脱壳的应用与实现

些功夫。加密软件比较多,但在强度与兼容性上做的好的并不多,这里向大家介绍几款常见的。

现在壳的发展一个趋势就是虚拟机保护,利用虚拟机保护后,能大大提高强度,因此建议尽可能使用此类技术保护软件。如Themida ,WinLicense,EXECryptor等壳带有虚拟机保护功能,因此得用好其SDK。

1) ASProtect

ASProtect是一款非常强大的Windows 32位保护工具,这4、5年来,其一直在更新进步。其开发者是俄国人Alexey Solodovnikov。它拥有压缩、加密、反跟踪代码、反-反汇编代码、CRC校验和花指令等保护措施。它使用Blowfish、Twofish、TEA等强劲的加密算法,还用RSA1024作为注册密钥生成器。它还通过API钩子(API hooks,包括Import hooks(GPA hook)和Export hooks)与加壳的程序进行通信。甚至用到了多态变形引擎(Polymorphic Engine)。反Apihook代码(Anti-Apihook Code)和BPE32的多态变形引擎(BPE32的Polymorphic Engine)。并且ASProtect为软件开发人员提供SDK,实现加密程序内外结合。

ASProtect SKE系列己采用了部分虚拟机技术,主要是在Protect Original EntryPoint与SDK上。保护过程中建议大量里使用SDK, SDK使用请参考其帮助文档,在使用时注意SDK不要嵌套,并且同一组标签用在同一个子程序段里。ASProtect使用相当的简单,打开被保护的EXE/DLL文件后,选上保护的选项。再单击菜单Modes,

8

加壳与脱壳的应用与实现

单击Add Mode按钮,将Is this Mode Avtive选上,最后,单击Protection标签,对软件进行保护即可。ASProtect加壳过程中也可外挂用户自己写的DLL文件,方法是在上图中的External Options选项加上目标DLL即可。这样,用户可以在DLL加入自己的反跟踪代码,以提高软件的反跟踪能力。

图1.4

2) Armadillo加密壳

Armadillo也称穿山甲,是一款应用面较广的壳。可以运用各种手段来保护你的软件,同时也可以为软件加上种种限制,包括时间、次数,启动画面等等!很多商用软件采用其加壳。Armadillo对外发行时有Public,Custom两个版本。Public是公开演示的版本,Custom

9

加壳与脱壳的应用与实现

是注册用户拿到的版本。只有Custom才有完整的功能,Public版有功能限制,没什么强度,不建议采用。

图1.5

二、脱壳

1.侦壳

侦测壳和软件所用编写语言的软件,因为脱壳之前要查他的壳的类型。

1).侦测壳的软件 、PEID等等。

2).侦测壳和软件所用编写语言的软件(两个功能合为一体,很棒) 推荐language2000中文版(专门检测加壳类型)

3).软件常用编写语言Delphi,VisualBasic(VB)---最难破,VisualC(VC)。

10

加壳与脱壳的应用与实现

PEiD的GUI界面操作非常方便直观。它的原理是利用查特征串搜索来完成识别工作的。各种开发语言都有固定的启动代码部分,利用这点就可识别出是何种语言编编译的。同样,不同的壳也有其特征码,利用这点就可识别是被何种壳所加密。PEiD提供了一个扩展接口文件 ,用户可以自定义一些特征码,这样就可识别出新的文件类型。

有些外壳程序为了欺骗PEiD等文件识别软件,会伪造启动代码部分,例如将入口代码改成与Visual C++ 6.0所编程程序入口处类似代码,即可达到欺骗目的。所以,文件识别工具所给出的结果只是个参考,文件是否被加壳处理过,还得跟踪分析程序代码才可得知。 目前Hying的壳PE-Armor伪装能力是最强的:

图2.1

PEiD分析不出类型的文件就报告是“Nothing found *”,如出现这情况一般都是未知壳或新版的壳。

11

加壳与脱壳的应用与实现

下面PEiD识别出这个软件是用Asprotect 1.2x加的壳。

图2.2

FileInfo(简称Fi)另一款不错的文件检测工具。Fi运行时是DOS界面,在DOS窗口中运行程序相当不便,建议采用下面的技巧:

首先,用鼠标将文件拖到Fi主文件上。

然后,将Fi快捷方放进Windows的SendTo文件夹里.以后要分析某文件,只需右击“发送到”功能就可打开Fi。

FileInfo升级慢,其识别库不能自定义。而PEiD升级比较频繁,用户也可自定义特征码,因此PEiD用的比较普遍。

有时,FileInfo和PEID会报“PE Win GUI”,Win GUI就是Windows图形用户界面程序统称,表明程序可能没加壳。但不排除也有加壳的可能性,下图是一个ExeCryptor 2.2x的壳,FileInfo报“*PE Win GUI *section* ??”,其不能识别出来。识别信息中带了个问号,表明FI对给出的结果不是太肯定。

12

加壳与脱壳的应用与实现

图2.3

2.脱壳

一般的压缩壳,都有专用的脱壳机。如:ASPacke和 UnASPack。或者用万能脱壳机也可以,如:procdump。而加密壳一般很少有脱壳机,必须手动脱壳手动脱壳----三步

a.查找程序的真正入口点(OEP)

A.根据跨段指令寻找OEP

B.根据堆栈平衡原理找OEP

C.根据变异语言特点找OEP

D.用内存断点找OEP

注:可以使用OllyIce工具来实现。

本次实验主要利用第一种方法来实现寻找OEP:

运行Ollydbg,点击菜单“选项/调试设置”,将第一次暂停设在WinMain函数上。再用Ollydbg打开实例就可中断

13

加壳与脱壳的应用与实现

在外壳的入口点处了:

图2.4

上图相关代码如下:

0040E8C0 > 60 pushad //一开始Ollydbg就会中断这行,这个就是外壳的入口点,注意这个pushad指令

绝大多数加壳程序在被加密的程序中加上一个或多个段,所以依据跨段的转移指令(JMP)就可找到真正的入口点,此时就会有POPAD/POPFD指令出现。UPX 用了一次跨段的转移指令(JMP),在跳到OEP处会看到虚拟地址的值有一个突变,此时就能确定OEP了。

UPX壳比较简单,大家不必要跟踪去找这个跨段的转移指令,中断WinMain后,只需要在Ollydbg里往下翻屏,就会发现这个跨段转移指令:

图2.5

上图相关代码如下:

14

加壳与脱壳的应用与实现

0040EA0E 61 popad //注意这里的popad指令,和开始的pushad对应。

0040EA0F - E9 B826FFFF jmp 004010CC //这里跳到OEP,将光标移到这,按F4执行到这行这一句0040EA0F jmp 004010CC 就是跳到OEP的指令,执行到这,UPX外壳己将程序解压完毕,并模拟Windows加载器的将原始程序加载到内存,004010CC 就是映射到内存目标程序的入口点,此时就可抓取内存映像文件了。

b.抓取内存映像文件

外壳程序解压还原后就会跳到OEP处执行,此时内存映像文件是己解压的程序。这时就可抓取内存映像文件了(该过程称为Dump)。

注:可以使用LordPE工具来实现。

c.输入表重建

在脱壳中输入表处理是很关键的一个环节,因此要求脱壳者对PE格式中的输入表概念非常清楚。在磁盘文件中,PE文件的输入表结构如下图所示:

图2.6

PE文件运行时,Windows系统加载器首先搜索

15

加壳与脱壳的应用与实现

OriginalFirstThunk,如果存在,装载程序迭代搜索数组中的每个指针,找到每个IMAGE_IMPORT_BY_NAME结构所指向的输入函数的地址,然后用函数入口地址来替代由FirstThunk指向的 IMAGE_THUNK_DATA 数组里的元素值(即用真实的函数地址填充到IAT里)。因当PE文件装载内存后准备执行时,上图己转换成这种情况了:

图2.7

此时输入表中其它部分就不重要了,程序依靠IAT提供的函数地址就可正常运行(图8.2 红圈部分)。如果程序加壳了,那壳自己模仿Windows装载器的工作来填充IAT中相关的数据,此时内存中就一张IAT表,输入表的其他部分是不存的(当然不是绝对的,也有不少壳,如Aspack等,内存中会出现完整的输入表结构),如图

图2.8

输入表重建就是根据图8.3这张IAT恢复整个输入表的结构(即图2.8这个结构),ImpREC这款工具就是这个功能。

一些压缩壳,填充IAT过程中没做什么手脚,用ImpREC工具可

16

加壳与脱壳的应用与实现

以直接重建输入表。而一些加密壳为了防止输入表被还原,就在IAT加密上大作文章,此时壳填充IAT里的不是实际的API地址,而是填充壳中用来HOOK-API的外壳代码的地址。这样壳中的代码一旦完成了加载工作,在进入原程序的代码之后,仍然能够间接地获得程序的控制权。 因为程序总是需要与系统打交道,与系统交道的途径是API,而API的地址已经替换成了壳的HOOK-API的地址,那程序每一次与系统打交道,都会让壳的代码获得一次控制权,这样壳可以进行反跟踪继续保护软件,同时也可完成某些特殊的任务。所以重建输入表的关键是获得没加密的IAT ,一般的做法是跟踪加壳程序对IAT处理过程,修改相关指令,不让外壳加密IAT。

注:可以使用ImportREC工具来实现。

附:视频“加壳与脱壳(软件)”和“手动脱壳”

17

本文标签: 程序文件软件加壳保护