引擎技术对比
各种引擎技术相比,虚拟机就像是一个侦探,可以根据对人的行为识别犯罪活动;启发式扫描就像是警察,看你身上携带了枪支而怀疑你;广谱特征是拿着照片追查已知的罪犯,但是会注意是否带了假发或者墨镜来逃避检查;而特征码识别就只是通过对人的外貌来判断。
简单总结一下各种引擎技术的优缺点:
| 特征码技术 | 静态广谱特征扫描技术 | 启发式扫描技术(静态扫描+未知特征) | 行为判定技术 |
| 速度快,准确率高 | 可以检测部分变形病毒 | 误报率低,能检测变形病毒和病毒变种 | 基于强大而完整的虚拟机技术能够对未知病毒进行判别,对标准病毒准确率高 |
| 不能对付变形病毒或加密病毒 | 误报率高 | 对未知病毒的检测能力较低 | 实现难度大,速度慢 |
解压缩与去壳
病毒隐藏自身的方法还有加壳和压缩两种方法。加壳是通过一系列的数学运算,将可执行程序或动态链接文件的编码进行改变,以达到缩小程序体积或加密程序编码的目的。通常常见的加壳工具有UPX、ASPack等。病毒通过使用不同种类或者版本的加壳软件,对自身进行加壳,使得杀毒软件无法发现真正的病毒体,以逃避查杀。并且由于加壳的工具种类很多,同一个工具也存在不同的版本。为了检测已加壳的病毒,就必须要针对不同种类不同版本的壳编写脱壳程序才可以发现壳内隐藏的真正病毒体。所以,杀毒软件对病毒的查杀能力也在一定程度上取决于他自身的脱壳能力。
压缩是普通用户日常经常使用的减小文件体积的方法,常见的工具软件有WinZip、WinRAR等。病毒有时候会隐藏在压缩包内部,如果一个杀毒软件没有解压缩的能力就不可能查杀压缩包内的病毒。同时,如果杀毒软件不具备相应格式的压缩能力,在查杀病毒后就不能复原压缩包,导致压缩包破坏。可见,杀毒软件要想做到对病毒的全面捕获与查杀,脱壳解压能力也是至关重要的。
利用特征码技术的静态杀毒引擎
特征码的选取
在进入程序的详细讲解之前,先来讲一下对于病毒程序的特征码通常是如何选取出来的,以及特征码的结构是什么样子的。
通常选择特征码是按照以下思路。1. 获取一个病毒程序的长度,根据长度可以将文件分为几份,份数根据样本长度而定,可以是3~5份,也可以更多。分成几段获取特征码的方法可以很大程度上避免采用单一特征码误报病毒现象的发生,也可以避免特征码过于集中造成的误报。
2. 每份中选取通常为16或32个字节长的特征串。
在选取时,应该采取如下的原则:
1. 如果选出来的信息是通用信息,即很多文件该位置都是一样的信息,那么舍弃,调整偏移量后重新选取。
2. 如果选取出来的信息是全零的字节。那么也要调整偏移后重新选取。
当然调整的偏移量多少可以人为事先规定,也可以自动随机调节。最后,将选取出来的几段特征码及它们的偏移量存入病毒库,标示出病毒的名称即可。为了方便选取特征码,通常根据以上的思路编写出特征码提取程序,自动提取特征码并作为病毒记录存入病毒库。
关键数据结构
下面我们来介绍一下整个引擎中关于特征码扫描部分的代码,整个引擎框架的结构由于篇幅有限,放在下期文章中进行介绍。
首先介绍程序中的两个重要结构VSIGNATURE和VRECORD。一个VSIGNATURE是一个特征,很多个特征组成了一条病毒记录,也就是一个VRECORD。
typedef struct tagVSIGNATURE { BAV_SIGN_TYPE eType; DWORD dwOffset; DWORD dwSize; BYTE Signature[MAX_SIGNATURE_LEN]; }VSIGNATURE,*PVSIGNATURE; typedef struct tagVRECORD { int nSize; DWORD dwVirusID; DWORD dwSignCount; PVSIGNATURE pVSing[8]; DWORD dwTreatCount; PVTREATMENT pVTreat[8]; }VRECORD,*PVRECORD;
VSIGNATURE结构是用于存放单一特征码的,其中的eType成员变量是一个枚举结构,用来定义特征码的类型,这里演示工程里目前我们只定义了一种简单文件特征。dwOffset成员存储该特征码的偏移量。dwSize成员存储特征码的长度。字节型的Signature数组成员存放特征码串,最大长度由 MAX_SIGNATURE_LEN宏控制,目前为32字节。VRECORD结构用于存放病毒库中每个病毒记录的内容。其中nSize用于控制结构的版本,目前我们不用过多关心。dwVirusID成员指定病毒的ID编号。dwSignCount成员存放特征码(VSIGNATURE)的段数,也就是对于该病毒取了多少段特征码。pVSing数组成员存放每段特征码的内容,这里用数组是为了演示方便,以后我们会改为可变长度的数据结构。dwTreatCount成员存放处理该病毒的方法数量。pVTreat数组成员存放处理该病毒的每种方法的内容。这两个成员要到我们增加杀毒方法的时候才会用到。
为了演示程序的简单,这一版的病毒库没有从文件加载,而是直接在CVirusDB::Load()中编码进去的。比如第一个eicar测试病毒的第一条特征是这样的:
{ BS_PHY_FILE, 0, 32, 0x58, 0x35, 0x4F, 0x21, 0x50, 0x25, 0x40, 0x41, 0x50, 0x5B, 0x34, 0x5C, 0x50, 0x5A, 0x58, 0x35, 0x34, 0x28, 0x50, 0x5E, 0x29, 0x37, 0x43, 0x43, 0x29, 0x37, 0x7D, 0x24, 0x45, 0x49, 0x43, 0x41,
}
它表明这是一个简单文件特征,特征起始地址0,特征长度32,后面32个字节是具体特征值。
