浅析PE文件脱壳技术

2013-09-19 09:22杨东霖
网络安全技术与应用 2013年4期
关键词:脱壳内存代码

杨东霖

国际关系学院 北京 100091

0 前言

PE文件格式(Portable Execute),它是WIN32环境下自带的可执行文件格式, 在Windows系统之下常见的EXE、DLL、SYS、COM 等等文件格式均属于 PE格式。由于 Windows系统的用户众多,故针对PE文件的加壳较为常见。对于知识产权保护来讲,这样的加壳能够较好地保护程序的源代码。此外,加壳可以在改变代码特征的同时不影响程序的执行结果,所以很多的恶意代码也会利用加壳技术来保护自己,从而使杀毒软件无法查杀。当遇到一个未知恶意程序时,对其研究的第一步工作便是对其进行分析,然后找到清除方案。常用的人工分析手段大致分为静态分析和动态分析两种。不论使用那种分析方法,基本上对样本的操作都要从脱壳开始,如果分析人员不能有效地脱壳,那么后面的工作便无法开展。

1 PE文件结构

PE文件的结构是一个统一的地址空间,文件的数据以及代码被整合成为一个统一的结构。其中文件的内容被分为一个个属性相同的区块,每个区块按页边界对齐,没有固定的大小限制。每个区块的功能以不同的名字表示。通过对 PE文件结构各个部分的关系进行分析,可以得到一个PE文件的总体结构框图,如图1所示。如果将PE文件看作一个图书馆,将每个section看作图书馆中的每本书。那么块表就相当于是以每本书的名字建立的书目表,有块表就可以找到相应的块;而data directory就好比是按照每本书的索引号而建立的一个类似于索引的目录,利用它能够更快得找到想要的数据。此外,块表对于区块的定位是一对一的,而数据目录对于区块的定位是多对一的。

图1 PE文件的总体结构框图

2 壳的相关概念

壳是一个相对直观的概念,比如在日常生活中,壳的作用是用来保护重要的东西不受伤害。同样,在计算机领域中的加壳,是一种通过一系列运算处理,将可执行程序文件或动态链接库文件的代码改变,以达到缩小文件体积或加密程序源码的目的。它们一般都是先于程序运行,然后完成它们保护软件的任务。以EXE文件为例,如图2所示,我们能够更加直观的理解其原理。

图2 EXE文件原理

对于恶意程序而言,加壳无疑是一项必需的反检测技术,不论是对于给分析人员增加分析难度还是就传播和隐藏而言,都是起着至关重要的作用。

3 加壳技术现状

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

加密壳与压缩壳最大的不同在于加密壳有较强的反跟踪能力,同时会设置很多 SEH 异常。加密壳通过对堆栈进行检查,调用 IsDebugerPresent函数,检测调试器句柄等方法判断自己是否被跟踪调试。因此脱加密要在脱压缩壳的基础上,隐藏调试器进程,同时处理SEH异常机制。

道高一尺魔高一丈,伴随着加壳技术的精进,脱壳技术的发展速度也是非常之快的,大多数加了壳软件在一段时间之后都能找到特定的方法进行手工脱壳。此外,针对使用一些已有的加壳工具所加的壳还有对应的脱壳机来完成自动脱壳,这也促使加壳软件的进一步发展。

4 脱壳步骤与方法

4.1 脱壳步骤

(1) 识别壳的种类:这个一般都是通过使用工具来实现的,最著名的工具为PEID,其数量已超过470种PE文档的加壳类型和签名。查壳的原理是将程序OEP附近的代码和各种壳代码进行比较,从而判断程序是否加壳以及加哪种壳。

(2) 寻找OEP:OEP(OriginalEntryPoint),及程序原始入口点。我们之前也介绍过,壳在完成功能后会将控制权交给真正的程序,也就是会运行到OEP。一般而言在对有壳PE文件分析时,壳的区段和程序真正开始区段之间会有很大的跳转。而且,根据编写语言的不同,程序的OEP特征也就不同。

(3) Dump内存:所谓dump就是转存, 将内存中的进程数据抓取出来转存为文件格式。一般调试跟踪到程序 OEP时, 就可以dump程序。这里需要用到LordPE工具。

(4) 修复IAT:这一步骤主要是用在脱加密壳之后需要做的。加密壳都会对输入表中的IAT进行加密处理,IAT(ImportAddressTable)是输入地址表, 它保存着 PE程序要调用的外部函数地址信息。如果IAT表出错, 程序将无法运行。修复原理是根据原加壳程序的IAT表重新构造一份IAT表,当加壳程序运行到OEP处时,其IAT已经释放出来,此时就可以重新构造一个区段存放输入表, 从而解密IAT经常会用到的工具是ImportREC。

4.2 脱壳方法

(1) 单步跟踪法:就是一步一步跟踪指令的执行,一直到程序真正的入口点(OEP)。这方法是最简单的,但也是最费时费力的。因为在调试时会遇到大量的跳转语句,为了更加方便的找到OEP,向上的跳转我们是不去理会的,直接跳过。当入到很大段的跳转时,一般也就到达了程序的OEP。

(2) ESP定律:ESP(extended stack pointer)栈指针寄存器,它的内存中存放着一个指针,这个指针默认指向系统栈最顶端的一个栈帧的栈顶。这个方法运用的是堆栈平衡的原理。其原理在于当程序使用函数或者子程序后,当遇到返回时,要保证ESP指向的是刚才压入栈的地址。在加壳程序中,反汇编时一般一开始都会发现 PUSHAD指令,其作用就是将所有寄存器压入堆栈保存,在壳程序运行完毕后,会通过POPAD指令恢复堆栈状态再返回到源程序。

(3) 内存镜像法:内存镜像法的原理是依据壳代码对原程序的解压过程。壳程序运行时需要先对原来压缩的各个区段进行解压,解压完毕后将会跳到解压后的代码段(.text段)开始执行,若在此处下断点,程序则会中断在OEP处。内存镜像法又称为两次内存断点法,但两次内存断点的本质却不一样。第一次是资源解压,程序对资源写入时中断,是内存写入中断。第二次是访问代码段,准备执行代码时中断,是内存执行中断。该方法也有其局限性,当壳在 JMP到 OEP前的一行代码时仍在对代码段解压,则该方法将不再适用。

(4) 快速查找法:该方法使用的就是ESP定律的原理。使用方法是在调试器中查找“POPAD”,基本上就可以到达OEP。

(5) 最后一次异常法:这个方法主要适用于加密壳。加密壳的反跟踪代码中,会设置很多SEH陷阱,从而使OD等调试器产生异常。但是当壳代码运行完毕后,将没有异常。所以可以通过忽略异常让程序运行,记下程序运行到正常时产生异常的次数。那么OEP便在最后一次产生异常的后面附近,通过在最后一个异常处指向的SEH句柄处下断点,然后运行到该位置,继续单步跟踪就会到OEP。

5 结论

本文介绍了PE文件结构、壳的相关概念以及脱壳原理和五种常见的脱壳方法,不过脱壳技术归根到底是不会有太强规律可循的,脱壳技术随着加壳技术的进步而进步,两者在一个相互较量的过程中发展。而且在实践中还会遇到各种各样没有遇到的新壳和组合壳。这些都需要我们自己去花大量的时间和精力去总结和实践,才能不断的去提高自己的能力。

[1]徐向阳,解庆春,刘勇,俞笛,刘寅.PE文件隐型加壳技术的研究与实现[J].计算机应用研究.2009.

[2]王清,张东辉,周浩,王继刚,赵双.0day安全:软件漏洞分析技术[M].2011.

[3]张中华.PE程序加壳的研究与实现[J].2009.

[4]李露,刘秋菊,徐汀荣. PE文件中脱壳技术的研究[J].计算机应用与软件.2010.

猜你喜欢
脱壳内存代码
顶管接收端脱壳及混凝土浇筑关键技术
河蟹脱壳期间注意事项
笔记本内存已经在涨价了,但幅度不大,升级扩容无须等待
“春夏秋冬”的内存
智慧农业助上安村“脱壳”
创世代码
创世代码
创世代码
创世代码
内存搭配DDR4、DDR3L还是DDR3?