PE文件结构分析技术在杀毒中的应用介绍_

来源:百度文库 编辑:神马文学网 时间:2024/04/29 20:19:03
PE文件结构分析技术在杀毒中的应用介绍2010-01-25 09:11

  作者向大家概述了病毒的分类和相关病毒技术的应用,并且编写了一个简单的反病毒静态引擎框架。在本期文章中,我们会继续深入探讨反病毒技术,从PE 文件结构入手,来进一步说明反病毒软件是如何利用PE 文件结构查杀病毒的。

  PE的意思就是Portable Executable(可移植的执行体)。它是 Win32 环境自身所带的执行体文件格式,如:Exe文件,DLL 文件均为PE 格式。它的一些特性继承自 Unix 的Coff (common object file format)文件格式。"portable executable"(可移植的执行体)意味着此文件格式是跨win32平台的:即使Windows 运行在非Intel 的CPU 上,任何win32平台的PE装载器都能识别和使用该文件格式。当然,移植到不同的CPU上PE执行体必然得有一些改变。所有 win32执行体 (除了VxD和16位的Dll)都使用PE文件格式,包括NT的内核模式驱动程序(kernel mode drivers)。我们着重讨论的事Win32 平台下的PE文件。

  所有常见的PE结构定义在winnt.h头文件中都有。我们一般关心以下几项:

  IMAGE_DOS_HEADER
  IMAGE_FILE_HEADER
  IMAGE_OPTIONAL_HEADER32
  IMAGE_SECTION_HEADER
  IMAGE_NT_HEADERS
  IMAGE_IMPORT_DESCRIPTOR
  IMAGE_EXPORT_DIRECTORY
  IMAGE_RESOURCE_DIRECTORY

  由于我们的重点是从PE文件格式分析病毒表现和反病毒的原理,所以过多的关于PE文件格式的细节内容就不占用篇幅详细的介绍了,读者朋友可以参考相关的文章来学习其中的细节内容。我们只对要用到的PE文件结构中的内容进行简单的介绍。

  首先我们看到PE文件最开头的是DOS MZ Header部分,有了它一旦程序在DOS下执行,DOS就能识别出这是有效的执行体。并且操作系统中的PE文件装载器可以通过DOS MZ Header 中的内容定位到PE Header 的起始偏移量。在这里我们最关心的部分是IMAGE_DOS_HEADER的e_lfanew这个成员,通过它我们可以找到PE Header。

  紧随DOS MZ Header 部分的是DOS stub,这部分我们不关心,因为它只是为了在在不支持 PE文件格式的操作系统中,简单显示一个错误提示,如" This program cannot run in DOS mode”。这个部分通常由编译器自动生成,当然程序员也可以自定义该部分的代码。

  接下来是最重要的PE Header,PE Header 是PE 相关结构 IMAGE_NT_HEADERS 的简称,其中包含了许多PE 装载器用到的重要域。我们非常关心的入口点AddressOfEntryPoint 就在IMAGE_NT_HEADERS 中IMAGE_OPTIONAL_HEADER32 中。PE Header 后面的内容被称为节表,ection Table(节表)。 每个结构包含对应节的属性、文件偏移量、虚拟偏移量等。如果PE 文件里有5 个节,那么此结构数组内就有5个成员。如此PE装载器就可以根据节表定位每个节的属性和位置。PE文件的真正内容划分成块,称之为Section(节)。每节是一块拥有共同属性的数据,比如代码/ 数据、读/写等。

  PE 文件有效性检查

  前面我们已经对PE文件结构进行了简单的介绍,下面我们来分部份讲解杀毒软件引擎是如何根据病毒的原理和PE结构进行病毒查杀的。由于大多数感染型病毒都是感染的PE文件,因为这样才可以在PE文件运行的同时运行自身的病毒代码。从而继续感染其他的正常文件,以达到传播的自身的目的。所以从杀毒角度讲,应该先判断一个文件是否为PE结构,再去进一步决定应该使用何种方法对文件进行扫描处理。那么,如何判断一个文件是否为PE结构呢。

  我们可以检测PE文件中的每个数据结构,但是PE文件中包含的数据结构很多,如果逐一进行检查,则会耗费过多的CPU 时间,影响效率。通常的检查利用前面提到过的PE Header。PE Header实际上是一个IMAGE_NT_HEADERS STRUCT结构,定义如下:

typedef struct _IMAGE_NT_HEADERS {
 DWORD Signature;
 IMAGE_FILE_HEADER FileHeader;
 IMAGE_OPTIONAL_HEADER32 OptionalHeader;
} IMAGE_NT_HEADERS32, *PIMAGE_NT_HEADERS32;
  其中的Signature属性如果是等于"PE\0\0",那么就是PE格式的文件。所以杀毒软件在检测时只需要先通过DOS MZ Header 中的内容定位到PE Header 的具体位置,然后通过检查Signature 即可断定一个文件是否为PE文件。

//check "PE\0\0" signature
if( IMAGE_NT_SIGNATURE != pFSPE->m_pNtHeaders->Signature)
{
 pFSPE->m_bPEFile = false;
 return true;
}
pFSPE->m_bPEFile = true;
  当然即使Signature 检测通过了,也可能不是一个有效的PE文件,还有各种可能性导致这个PE文件破损,您可以自己分析CParsePE类的代码,其中有各种不同的检测点。这个PE分析类还是不完善的,实际的反病毒引擎中的有效性检测都是经过多年积累的对于错误文件的分析,这是一个长期的过程。

  判断PE 文件中程序入口点是否异常

  在前面我们提到过入口点,即AddressOfEntryPoint,这个成员的含义是PE装载器准备运行的PE文件的第一个指令的RVA(相对虚拟地址)。若要改变整个PE程序的执行的流程,可以将该值指定到新的RVA,这样新RVA处的指令首先被执行。很多病毒在感染了PE文件后,通常都会向PE文件中添加一部分代码, 然后更改P E 头中的AddressOfEntryPoint,将他指向的地址定位到病毒插入的代码处,这样每当这个文件运行时,病毒代码都会最先得到运行。

  一般情况,很多病毒都将插入到PE文件中的代码放到PE文件的后面,然后在代码尾部放置一条语句再跳回到原来PE文件真正入口点处。使得用户在毫无察觉的情况下执行病毒代码。杀毒软件可以根据PE文件入口点是否异常来判断文件是否有被病毒感染的嫌疑。通常入口点所指的相对虚拟地址比较靠前,不会在靠近文件末尾处,或者指向最后一个节后的内容,如果一个PE文件的入口点的指向不是这样,那么就说明这个文件有被病毒感染的嫌疑。当然,这种主观的判断不一定准确,但是可以算是一种判断的依据。上期我们提到的启发式扫描就会用到这样的特征来帮助判断未知病毒。

  有些病毒为了防止反病毒软件的这种探测,也想出了很多不修改入口点改变程序流程的方法。例如,改变原入口点程序的代码,再跳转到病毒体。