Hash-AV: Fast Virus Signature Scanning by Cache-Resident Filters 译

Hash-AV是一种利用缓存驻留的布鲁姆过滤器和一系列廉价哈希函数来显著提高病毒扫描速度的技术。它能快速识别非病毒数据,避免主内存访问,尤其在大量非病毒数据中表现优异,适用于网络病毒扫描。

论文:
Hash-AV: Fast Virus Signature Scanning by  Cache-Resident Filters    哈希-AV:一种基于cashe常驻过滤的快速特征扫描器
 
 
概要:
快速病毒扫描器是变的越来越重要在今天的网络中。伴随着罗尔定律的失效,受困于随机存储器频率,病毒扫描器的性能挑战也失败了。
这篇论文提出的hash-av,就是一种极大提升的病毒扫描技术用来提升cpu的性能。它使用一系列的哈希函数和一个驻留在l2缓存的bloom filter数组,
它将会使得大多数非命中的例子不会接触到真正的内存。试验展示了hash-av提升了开源病毒扫描器calm-av的性能在选取factor在2到10之间时。成功的
关键在于一系列的“bad but cheap”(即单个函数的识别率不高,但是其相对简单,对硬件的要求低)哈希函数作为初始哈希集。
hash-av的速度使得它非常适合片上病毒扫描,给用户提供了一个更好的保护。通过拦截系统的调用和包装的glibc库,我们已经完成了一个片上版本
hash-av + clam-av。这个片上扫描器可以检测数据达到200M/s的吞吐量,这使得它非常适合于基于网络的病毒扫描。
 
1. 介绍
在英特网、万维网的时代,病毒的产生和传播是非常容易的。
因此,反病毒技术在今天的有线世界是必须的。
有效的防御需要在每个主要网络流量停止点和终端主机计算机上进行病毒扫描。
今天,防病毒软件扫描邮件网关和企业代理网关的流量,它们运行在终端上,例如文件服务器、台式机和笔记本电脑。
不幸的是,当基于网络的入侵检测速度在过去的一年中有所提高,已达到了1Gb/s时,病毒扫描远远没有跟不上这个速度。
 
几乎所有的病毒扫描程序都要花费大量的时间来匹配一组已知病毒特征的数据流,并且它们都使用某种形式的多模式字符串匹配算法。
病毒特征数目已经超过10万个而且还在持续增长。
与入侵检测特征不同,病毒特征不能整齐地分成由少量字符串组成的规则集。
因此,算法中使用的数据结构通常不嵌合CPU cache,作为代替驻留在内存中。
然而,随机存储的性能所能达到的程度,没能跟上CPU速度的提升,甚至是顺序内存的吞吐量(硬盘的容量)。
例如,在过去的10年中,CPU处理速度每18个月就会翻倍,然而内存速度仅仅提升不足10%每年。
 
在本文中,我们提出了一种新的病毒扫描技术,旨在跟上CPU的速度曲线。
我们的解决方案称为“Hash-AV”,结合了一组散列函数和适合CPU二级(L2)缓存的布鲁姆过滤器数组。
Hash-AV可以快速确定大多数“不匹配”情况,而不会引发主内存访问。
由于大多数网络流量不包含病毒,大多数数据流属于“不匹配”情况。
 
哈希- av背后的直觉是这样的。
目前,一次L2缓存丢失大约需要150-200个CPU周期,而且速度差距还在不断扩大。
在读取新传入数据时,CPU必须执行一次缓存丢失。
一旦将一段数据从主内存载入到CPU缓存,Hash-AV就可以在CPU等待下一次缓存丢失时使用驻留在缓存中的布鲁姆过滤器扫描数据。
 
使用bloom filter来加速特征匹配并不是什么新想法。
例如,研究小组已经提出了专门的硬件解决方案,使用并行布鲁姆过滤器来高速扫描数据包。
然而,硬件解决方案与软件解决方案最主要的区别在于,前者无需关心哈希函数在cpu上的计算成本。
如果没有很好地选择散列函数,计算散列很容易占用足够的CPU周期,从而消除缓存驻留过滤器的优势。
 
哈希- av通过使用“糟糕但便宜”的哈希函数作为初始哈希,并依赖于串行哈希查找来解决这个问题。 
只有当廉价的初始哈希表示匹配时,才会调用“好的但昂贵的”哈希函数计算,从而有效地减少用在布鲁姆过滤器上的CPU算力。
 
我们已经将hash-av应用于目前最流行的开源杀毒软件Clam-AV上。
在Athlon XP 2000+上,HASH-AV将Clam-AV的扫描吞吐量提高到可执行文件29.4 MB/s、网页16.6 MB/s和随机数据29.5 MB/s。
这代表了1.7到4.4的加速因子。
即使特征数据库的容量由20K增加到120K,依旧能达到原有的速度提升一倍。
此外,如果使用模拟单独处理多态病毒,则带有HASH-AV的Clam-AV可以扫描85 MB/s的可执行文件、91 MB/s的web页面和120MB/s的随机数据。
 
此为,在模拟环境下,单独处理多态病毒,带有HASH-AV的Clam-AV可以达到扫描可执行文件85MB/s、web页面91MB/s和随机数据120MB/s。
考虑到Athlon XP 2000+的内存复制速度为260mb /s,这一结果证实了我们的直觉,即病毒扫描可能达到内存复制速度。
 
通过使用系统调用和glibc库包装,我们实现了“on-access”扫描模式。
在这种模式下,Hash-AV+Clam-AV可以扫描超过200Mb/s的输入,使得在具有应用识别和重构能力的网络路由器和交换机中嵌入病毒扫描成为可能。
在网络设备中嵌入病毒扫描可以更快地更新病毒签名数据库,是对网络中现有安全机制的宝贵补充。
 
另外,Hash-AV的使用场景不仅限于病毒扫描。
它可以使任何具有以下特征的字符串匹配应用程序受益:
a)需要精确匹配,特征数量高(例如> 10000);
b)大多数情况为“不匹配”情况;
c)不存在简单的“标记化”方法,因此必须逐字节测试匹配。
对于任何这样类似的系统,Hash-AV原则和设计都适用,尽管哈希函数的具体选择可能有所不同。
 
 
2. 病毒扫描技术和Clam-AV
以下是三个主要应用于病毒扫描的技术:
特征匹配:通过搜索数据中的固定字符串字节(病毒中的特征)来检查文件是否包含已知病毒。
模拟:通过在模拟环境中执行可执行文件的指令,然后在进程的内存区域中查找固定字符串(特征),检查文件是否包含多态病毒(时刻发生变化的病毒)。
行为检查:通过在模拟环境中运行文件并观察其行为,检查文件是否包含未知病毒。
 
行为检查通常在特定文件上运行,以确定该文件是否包含新病毒。
由于它不是常规运行,所以性能通常不受关注。
模拟通常只在符合某些标准的可执行文件上使用。
特征匹配通常在所有文件上运行。
 
在特征匹配和仿真中,cpu的大部分时间都花费在用一组字符串匹配数据上。
商业病毒扫描软件拥有包含超过100,000个病毒特征的数据库。
每个特征通常至少包含15个字节。
 
Clam-AV: 目前使用最广泛的开源杀毒扫描器。
它被应用于许多组织中的邮件服务器,同时也被整合到商业防病毒网关产品中。
截至2005年7月,它拥有超过30,000个病毒的数据库,包括一个核心扫描程序库和各种命令行程序。
该数据库包括超过28000个纯文本字符串和1300多个嵌入了通配符的字符串。
纯文本字符串用于非多态病毒,带有通配符的字符串用于多态病毒。
 
目前版本的Clam-AV使用的是Boyer-Moore(BM)算法的一个优化版本,用于非多态特征匹配,而Aho-Corasick(AC)算法用于多态特征匹配。
 
Clam-AV中的Boyer-Moore实现使用移位表来减少调用Boyer-Moore例程的次数。
在启动时,Clav-AV遍历每个特征,逐个字节,并散列三个字节的数据块至初始化全局移位表。
然后,在输入流中的任何一点,Clam-AV可以通过对它们执行快速散列来确定是否可以跳过三个字节。
Clam-AV还根据特征的前三个字节创建一个哈希表,并在shift table返回匹配项时在运行这个表。
由于该算法对特征的所有字节都使用哈希函数,所以它只适用于非多态特征匹配。
 
Aho-Corasick算法使用trie存储多态签名生成的自动机。
为了在这个trie中快速执行查找,Clam-AV中每个节点包含256个元素数组。
同时改进了Aho-Corasick算法,使trie的高度为2,并且叶节点包含可能模式的链表。
Clam-AV之所以将其trie深度固定为2,是因为它的多态病毒数据库包含前缀短至两个字节的特征。
 
 
3. Hash-AV的设计
 
Hash-Av是基于这样的的事实,虽然病毒扫描必须在网络流量上进行,但绝大多数数据不包含病毒。
因此,它的目标是以高精度、最小的主存访问和少量的CPU指令来确定不匹配的情况。
它通过使用一个适合于CPU缓存的过滤器来并充当第一次扫描来确定数据是否需要经过精确匹配算法来达到这一目标。
 
具体来说,Hash-AV将一个β字节的滑动窗口沿输入流移动。
对于窗口下的每个字节,使用k个哈希函数来计算它们的哈希。
然后,哈希结果用于探测N位的位数组,这是一个由病毒特征预先构造的布鲁姆过滤器。
 
A 基本机制
Hash-AV使用明文特征集来构建一个布鲁姆过滤器。
布鲁姆过滤器是一个N位向量,最初都被设置为0。
对于每个纯文本特征,对其前β个字节a使用k个哈希函数,结果h1(a)、h2(a)、…,hk(a),其范围在1,…,N。
h1(a)、h2(a)、…,hk(a)对应的位则设为1。
 
在扫描时,Hash-AV每次在输入数据流上移动一个字节。 
对于每个β字节块b,扫描算法应用第一个哈希函数h1(b),并检查布鲁姆过滤器中相应的位。
如果这一位是1,就接着计算下一个哈希函数h2(b)。
如果不是,它会立即转到下一个字节,并开始在下一个β字节块上应用哈希函数。
 
如果所有k个函数都返回正的布鲁姆过滤器匹配,那么接下来Hash-AV就需要对其进行精确匹配。
这里有两种选择。
一种是使用Boyer-Moore。
另一种方法是使用最后一个哈希函数hk预构造一个“辅助哈希表”,这个哈希表的每个条目下是一条特征冲突链表,然后进行逐个匹配。
Hash-AV采用后一种方法,因为每个条目中的特征数很低。
 
Hash-AV的几个方面与其他方法是不同的。
大多数商业扫描程序使用哈希表来加速字符串匹配,类似于使用辅助哈希表的Hash-AV。
然而,所涉及的数据结构通常不适合缓存,且假阳性率为单个哈希函数比布鲁姆过滤器高。
Clam-AV使用一个缓存驻留移位表来减少调用Boyer-Moore算法的次数。
不幸的是,由于移位表必须适应缓存,所以只使用了3个字节,因此产生的假阳性比率很高。
本质上,与这些方案相比,布鲁姆过滤器更加紧凑,并且使用多个哈希函数可以大大降低误报率。
其他研究人员已经提出使用硬件布鲁姆过滤器来执行高速网络入侵检测。
然而,在这些设计中,所有哈希函数都是在并行ASIC硬件上同时计算。
Hash-AV串行使用哈希函数,从而减少CPU指令的消耗。
 
根据我们之前使用布鲁姆过滤器的经验,k = 4可以很好地工作。
因此,这里有三个选择项需要设置:
选择4个哈希函数
选择布鲁姆过滤器的大小
选择β值
下面,我们使用一个简单的模型来简要分析每个选择的影响。
 
B. 一个简单的性能模型
假设这四个哈希函数是h1、h2、h3和h4,按照这个顺序被调用
此外,假设函数hi可以以ci MB/s计算。
假设特征总数为M, 布鲁姆过滤器的大小为M*K位。
函数h1在布鲁姆过滤器中假阳的概率为p1。
概率p1由哈希函数和布鲁姆过滤器的扩展因子K决定。
 
同样,在h1的假阳性情况下,h2的假阳概率为p2,1。
也就是说,p2,1是假设h1为假阳,h2为假阳的的条件概率。
p3,2,1和p4,3,2,1的定义类似。
 
扫描算法的性能可以用上述参数进行建模。
注意,当h1在布鲁姆过滤器中命中时,h2被调用(即h1的位是1),当h1和h2都在布鲁姆过滤器中命中时,h3被调用,当前面三个哈希函数都在布鲁姆过滤器中命中时,h4被调用。
因此,扫描算法的吞吐量为:
c1 + p1* c2 + p1* p2,1*c3 + p1*p2,1*p3;2;1*c4 + p1*p2,1*p3,2,1*p4,3,2,1*C
 
其中C是精确字符串匹配算法的代价。
显然,由于所有的概率都在0到1之间,所以哈希函数应该按照从开销最小(计算上)到最大的顺序排列。
 
上面的公式引出了一些见解。
首先,对于h1和h2使用非常快但普通的哈希函数是有好处的。
一个哈希函数有15%的错误率,但是仅需要5个CPU周期来计算,在其他情况下这不是一个好的选择,但是非常适合我们的目的。
事实上,这些廉价的(开销小)函数帮助我们从理论上论证了Hash-AV扫描算法可以在接近内存系统吞吐量的性能。
 
其次,选择独立的哈希函数很重要。
完全独立的哈希函数的条件假阳性概率和无条件假阳性概率是一样的。
另一方面,非独立哈希函数的条件概率往往接近1,违背了多个哈希函数的目的。
 
第三,概率受布鲁姆过滤器的展开因子K的影响。
由于精确的字符串匹配算法C的代价可能比哈希函数的代价高一到两个数量级,所以布鲁姆过滤器对假阳性比率的显著控制是很重要的。
在下面的部分中,我们使用实验来确定适当的K。
 
最后,概率p1*p2,1*p3,2,1*p4,3,2,1有一个下界,由参数β决定。
换句话说,匹配前β个字符的字符串有可能不匹配完整特征。
一般来说,越长越好。
然而,较长的β还意味着较短的特征(长度小于β + 3的特征)必须由不同的机制处理。
因此,β的选择也会影响性能。
 
C. 评估方法
我们评估了Hash-AV在当前Clam-AV数据库(大约30,000个特征)和包含120,000个特征的数据库下的优势。
Clam-AV的特征数据库增长非常迅速。因此,对于大型特征数据库,Hash-AV的伸缩性至关重要。
 
为了生成更多的特征,我们编写了一个合成病毒生成器,它检查当前Clam-AV数据库的属性,并尝试生成真实的病毒特征。
 
生成器的工作原理如下。
在启动时,它将Clam-AV数据库中的非多态和多态特征读入内存中的不同数组。
然后提取两条信息:病毒签名长度的分布情况和数据库中多态模式的百分比。
基于这些数据片段,对于每个“新”病毒,生成器首先选择其长度和类型(即非多态或多态)。
对于新病毒中的字节i,生成器随机选择一个现有特征,并复制其字节i。
对于每个字节索引,该算法统计上倾向于该索引最常用的字节。
由于Clam-AV的多态特征只使用通配符ASCII字符*和??在字节之间(*匹配任何字符串和??匹配任何单个字符),该方法生成与数据库中的病毒一样多态的病毒。
 
对于大多数实验,示例文件是一个120MB的文件,它由被广泛使用的Windows可执行文件(大小超过3mb)组成,包括MS Office可执行文件、messenger程序、用于科学和娱乐目的的第三方软件。
我们关注windows可执行文件,因为大多数病毒传播通过可执行文件和商业扫描程序,尤其是可执行文件。
在我们的选择中,我们注意只包含可执行的二进制文件,并避免安装程序,因为Hash-AV在这些文件上运行得更快。
我们的实验在Athlon 64 3200+ PC上运行,CPU为2.0 Ghz, L1为128KB, L2为512KB。
我们还在Athlon XP 2000+和奔腾4 2.6Ghz PC上进行了实验,并得到了匹配的结果。
 
4. Hash-AV的组成部分
 
要实际构建一个哈希- av过滤器,我们需要确定上一节中列出的变量。
下面,我们使用实验来确定过滤器的每个组件。
由于选择是相互交织的,我们首先将β固定为7,并研究散列函数和布鲁姆过滤器的大小。
最后确定β的值。
 
A. 选择hash函数
选择哈希函数的标准是它们应该不耗费太多cpu性能,并且应该产生相对随机的分布。
我们首先从开源社区中选择了一组著名的快速散列函数。
在我们的示例文件上,函数通常有0.2%到1%的冲突率,并且在输入大于4字节时运行良好。
表1列出了散列函数,给出了它们在120mb的示例可执行文件上的性能度量,以及过滤器中误报的百分比。
对于这些测试,β的值为7,布鲁姆过滤器的大小为256KB。
吞吐量度量包含散列每个块的成本和其天花板,从而来探测布鲁姆过滤器是否合适。
 
我们对这些哈希函数很失望。
与其他散列函数相比,它们可能被认为速度更快,但与内存复制速度(在台式机上的速度为260MB/s)相比就不那么快了。
 
然后我们尝试了两个非常快的“哈希”函数:“mask”和“xor+shift”。
“mask”取前4个字节,将它们转换为整数,并选择最低的log2(N)位,其中N是布鲁姆过滤器的大小。
“Xor+shift”取前6个字节,将字节0-3转换为整数,然后余下的两个字节与0进行异或来获取第一个散列值。
然后,对于字节1-4和字节2-5,它将重复相同的操作两次,始终使用xoring获取下一个哈希值的前一个哈希值。
然后,它从最后一个整数中选择较低的log2(N)位,以对筛选器进行检查。
连续计算“mask”和“xor+shift”的吞吐量分别为160mb /s和120mb /s。
 
在病毒特征识别方面,“mask”和“xor+shift”哈希算法可以过滤掉88%和96%的输入字节。
作为独立的哈希函数,它们的误报会太高。
然而,作为第一级哈希函数,它们可以有效地减少这个数字,因为哈希函数的规划是按照一定的级别排序的。
 
因此,hashav包含以下四个散列函数:mask、xor+shift、来自hashlib.c的快速散列和sdbm。
之所以选择Sdbm而不是djb2,是因为快速散列和djb2之间的相关性很高。
B. 选择布鲁姆过滤器的大小
 
传统的布鲁姆过滤器在进行大小选择时,一办的过滤位为1。
然而,在Hash-AV中,许多因素会影响布鲁姆过滤器大小的选择:
CPU中cache的影响:适合CPU缓存的筛选器部分,以及当筛选器不能全部适合缓存时的缓存错过率。
 
初始哈希函数的影响:初始哈希函数比后一个快得多。然而,初始散列过滤掉的输入数据有多少取决于布鲁姆过滤器的稀疏性。
 
假命中率:如果假命中率的代价仅比下一个过滤器探测的代价高一个数量级,那么布鲁姆过滤器中3%的假命中率是可以接受的。
但是,如果错误命中的代价高出两个数量级,则无法接受。
显然,这些选择是相互交织的,并取决于缓存大小和筛选器大小的相对比例。
下面,我们用各种各样的实验来逐一检验这些因素。
 
1) 纯粹的哈希速度:
给定我们对哈希函数的前提下,我们首先看一下下面的纯“哈希和查找”在不同的过滤器大小下的速度,分别在包含30000和120000个特征的数据库。
这种“纯哈希”速度排除了错误命中率的影响,取而代之的是CPU缓存和廉价哈希函数的影响。
图1显示了AMD桌面上的结果。
 
对于30,000个签名,结果峰值在AMD的二级缓存大小。
这并不奇怪,因为只要过滤器适合缓存,大的过滤器就会导致更多的输入通过“mask”和“xor+shift”消除,但如果过滤器不适合缓存,缓存miss延迟将会决定吞吐量。
 
对于120,000个签名,512KB的过滤器和较大的过滤器之间的性能差异并不显著。
这有两个原因。
首先,在小型筛选器中,初始散列函数产生了太多的误报,导致更多的散列计算控制了运行时性能。
其次,由于过滤器中访问的局域性,即使对于大型过滤器,也可以从CPU缓存中验证大量特征。
 
我们使用Cachegrind,一款缓存和分支预测分析器,来检查Hash-AV在120000特征下的缓存miss率。
执行时,Cachegrind在模拟的x86 CPU上运行目标程序,并报告miss的次数。
Cachegrind实现了“包含L2缓存”语义,这是奔腾机器上的标准。
因此,从Cachegrind跟踪得到的结果是足够准确的,但不是AMD Athlon缓存行为的精确表示。
 
图2显示了Cachegrind报告的120MB示例文件和100MB随机文件的CPU缓存命中率。
对于可执行文件,即使对于非常大的布鲁姆过滤器,这种低的遗漏率也意味着输入流是围绕某些值聚集的。  
为了进一步分析示例可执行文件,我们实现了一个每次检查输入4个字节的程序,并构造了掩码操作值的直方图。
图3显示了256个箱子的直方图。此外,从直方图中删除数组中的索引0,因为该值的出现次数是第二大值的3倍。
总的来说,所有掩码访问的37.9%包含在布鲁姆过滤器的5.47%之内。
 
除了上面的倾斜分布之外,我们还发现可执行文件中的大多数单词都是紧密相关的,我们的mask函数在布鲁姆过滤器中保留了这种相关性。
由于缓存架构依赖于访问的局部性,包括时间和空间,因此可执行文件的缓存失误率可以保持在一个合理的水平,即使对于较大的筛选器大小也是如此。
这有助于提高大型筛选器的性能,因为大量访问频繁的数据仍然适合放在CPU缓存中。
 
总之,对于少量病毒特征,应该选择CPU缓存大小作为布鲁姆过滤器大小。
对于大量的签名,其他因素起着更大的作用。
 
 
 
2) 扫描速度和布鲁姆过滤器的大小;
 
虽然上述实验考察的是纯哈希和探测速度,但Hash-AV的实际性能还取决于精确匹配算法的开销。
图4显示了Athlon 64 3200+桌面上的Hash-AV在示例120MB可执行文件上的速度。
首先将文件映射到内存中,然后在一个热缓存上运行测试,以消除磁盘访问开销。
 
结果表明,最佳的过滤大小主要由CPU L2缓存大小决定。
对于30,000和120,000个签名,hashav使用512KB(即L2缓存大小)布鲁姆过滤器。
较大的过滤器对120,000个特征的影响不太明显,但是可以快速降低这组特征的假阳性率。
 
C 选择合适的β
 
β的选择主要受签名数据库中签名长度分布的影响。
通常,更大的是β首选,因为匹配特征中第一个字节的字符串更可能匹配实际特征。
另一方面,急剧增加β有两个副作用。
首先,哈希函数需要更多的时间来计算结果,这反过来又降低了算法的速度。
其次,对于较大的β, Hash-AV必须忽略短特征。
然后使用Aho-Corasick算法在单独的扫描中处理短特征和多态特征。
“xor+shift”函数被设计为对6字节的数据进行操作,其他哈希函数无法准确区分输入的小输入流。
因此,β的设置下限是6。
 
图5显示了在Athlon 64 3200+上具有30,000和120,000个特征选择不同β时的Hash-AV吞吐量。
增加β首先会导致显著的性能提升;
这是因为消除了大量的误报。
然后图像收敛到最大值,这是在消除更多的误报和花费更多时间在哈希函数之间的权衡使性能达到平衡状态的阶段。
权衡β的这些影响,我们决定在算法中选择= 7。
 
D 用于不同CPU的辅助工具
 
Hash-AV中各参数的选择在很大程度上取决于系统硬件的特点。
Hash-AV试图通过高效地使用内存和CPU将扫描性能提高到最大限度。
今天构建的计算机使用各种硬件组件,具有不同的CPU速度、CPU缓存大小、内存总线带宽和内存访问速度。  
为了帮助针对不同的系统优化Hash-AV,我们构建了两个工具。
 
第一个工具称为散列性能测试器,它试图确定CPU体系结构上的最佳散列函数。
我们选择的函数在x86架构上可以很好地执行。
然而,不同的CPU架构有不同的特征。
例如,基于Pentium 4的体系结构上的移位操作比较慢,而基于Sun的系统上的乘法比较慢。
因此,该工具包含7个散列函数的实现,并使用脚本比较它们在目标系统上的速度。
然后该工具推荐4个最快的散列函数。
 
第二个工具选择合适的布鲁姆过滤器大小和β。
该脚本生成、编译和执行分别在过滤器大小在64 KB - 128 MB之间(变量可以由用户设置)。
它可以选择导致最快执行速度的筛选器大小
β选择器执行同样的操作,从6-15中选择合适的β。
它从图中平衡态取最小值。
 
这些工具帮助我们确定奔腾4 2.6 Ghz的合适参数设置。
尽管这些工具不了解CPU体系结构,但它们确实确定了这一点
奔腾架构的合适布鲁姆过滤器大小应该是512KB。
 
5. Hash-AV的性能优势
 
我们使用30000个和120K个特征数据库来比较Hash-AV和Clam-AV的吞吐量。
当前Hash-AV的实现重点在于提高纯文本签名的扫描速度。
它使用与Clam-AV相同的Aho-Corasick(AC)实现,因此该模块会导致性能下降。
为了分离AC模块的效果,我们比较了两种扫描模式,一种是只扫描明文特征(即Hash-AV vs. ClamAV-BM),另一种是同时扫描明文特征和多态特征(即Hash-AV+AC vs. ClamAV-BM+AC)。
 
商业产品不包括在这个评估中有两个原因。
首先,商业病毒数据库与Clam-AV的病毒数据库有很大的不同。
其次,商用扫描仪使用的一些技术还没有在Clam-AV中实现。
例如,文件类型或病毒类型的特定信息只能用于扫描文件的部分,仿真引擎可用于处理多态病毒等。
Hash-AV是这些技术的补充,可以与它们结合使用,进一步提高扫描速度。
然而,这些技术使得商业扫描仪的性能很难与Clam-AV进行比较。
 
实验中使用了三种不同类型的输入:如第IIIC节所述的120MB的示例可执行文件,一个从web爬行的99MB HTML数据文件,以及一个100MB的随机文件。
我们选择使用HTML文件,是因为Clam-AV通常用于Web代理网关和电子邮件服务器,这些服务器往往会看到大量HTML文本。
我们在测试中包含一个随机文件,因为它们通常用于多模式字符串匹配算法的基准测试。
 
图6显示了Hash-AV和ClamAV-BM扫描来自ClamAV当前病毒数据库的28000个明文特征的吞吐量。
图7显示了Hash-AV+AC和ClamAV-BM+AC在当前的ClamAv数据库中扫描所有特征时的吞吐量。
图6展示了hashav中的方法提供的加速效果;扫描速度提高了8到15倍。
尽管扫描多态特征(即AC模块)会导致速度减慢,但图7显示,在完整的特征集上,Hash-AV仍然比Clam-AV性能好1.8到4.4倍。
 
为了检验Hash-AV和Clam-AV的可伸缩性,我们在120,000个特征集上重复了实验。
图8和图9显示了结果。
Hash-AV比Clam-AV有更好的伸缩性。
随着数据库大小的增加,Hash-AV中的吞吐量降低要比Clam-AV小得多,特别是在可执行输入和随机输入上。
 
a) 最糟糕情况下的Hash-AV性能:
所有的字符串匹配算法都有不同的性能取决于对应的输入。
Hash-AV也不例外。
攻击者可以构造输入,使Hash-AV的扫描速度降低到精确字符串匹配算法的扫描速度。
这通常不会给桌面带来问题,但会给应用程序网关(如邮件服务器和web代理)带来问题。
然而,应用程序网关通常有其他方法来减轻这些攻击。
例如,它们可以在单独的进程中扫描不同的邮箱或不同的HTTP流,并使用CPU调度来确保缓慢扫描的进程不会影响其他进程。
 

6. 嵌入式的AV扫描器
由于其高性能,Hash-AV非常适合于“on-access”病毒扫描。
在“on-access”模式下,无论何时使用文件和数据,都会自动扫描该文件,当应用程序接收到网络时(即套接字读取),将对网络进行扫描。
“On-access”病毒扫描通常为用户提供更大的保护。
 
我们已经实现了两种在Linux上对Hash-AV进行on-access扫描的方法。
第一种方法使用Dazuko向Hash-AV传递打开/关闭/执行系统调用。
第二种方法实现了对glibc read()、write()、send()和recv()代码的包装,以将数据传递给Hash-AV进行扫描。
该实现被打包为动态链接库libcav。因此,应用程序链接到这个库而不是常规的libc。这样才能进行病毒扫描。
第一种方法适用于文件访问,第二种方法适用于套接字访问。
 
在on-access扫描模式下使用时,hashav将跨调用保持状态。
在Hash-AV扫描缓冲区之后,如果调用了精确匹配的代码并到达缓冲区的末尾,则执行该操作对于部分扫描的模式,该模式与偏移量一起保存。
在下一次调用时,Hash-AV代码首先检查保存的模式与现在是否完全匹配还是扩展的部分匹配。
如果发生扩展的部分匹配,则会保存模式。
对于足够大的读取,保存和处理状态的成本可以忽略不计。
 
我们通过发出在以前测试中使用的120MB可执行文件样本的读操作来比较嵌入式扫描的不同方法的性能开销。
实验中使用Clam-AV的病毒数据库。
下表显示了与每种方法相关的性能成本。
 
第一行是Hash-AV+AC在文件上的执行速度。
第二行是通过Dazuko截取open()并在调用后扫描文件的吞吐量。
吞吐量的变化是由于截获调用并将其传递给用户级程序的开销造成的。
第三行显示了以4MB为单位读取可执行文件的结果,每次读取都调用libcav.so。
吞吐量的变化是由于扫描器代码的重复调用,以及实现中的额外内存副本。
 
注意,在on-access模式下,Hash-AV+AC的吞吐量接近200Mb/s。
由于大多数台式电脑与互联网的连接远低于200Mb/s,因此将病毒扫描附加到套接字读写不会影响从互联网接收数据的应用程序。
我们通过将wget应用程序与libcav链接来确认这一期望,测量机器之间读取文件的速度。
当通过100 baseT交换机在两台计算机之间传输120MB的可执行文件时,不扫描病毒的wget需要8704毫秒,扫描病毒的wget需要10453毫秒。
大约470 ms的开销来自Clam-AV和Hash-AV的数据结构的初始化时间。
其余的放缓主要是由于wget中以8 KB为单位的连续读取之间的状态保存和恢复。
 
传输HTML文档的类似性能测试显示了更好的结果,这主要是因为部分匹配和相关状态保存的减少。
对于一个示例99MB HTML文档,原始数据传输的传输时间为10021毫秒,而对于带AV扫描的传输,传输时间为10660毫秒。
综上所述,Hash-AV+AC非常适合于大多数桌面的网络传输的on-access扫描,并且可以作为文件系统on-access扫描实现(例如avfs)中的组件使用。
 
7. 相关工作
 
多字符串模式匹配算法是一个应用广泛的研究课题。
在网络领域,两个突出的应用是IDS(入侵检测系统)和病毒扫描器。
最近,在IDS模式匹配方面提出了一些创新,例如,基于硬件的并行布鲁姆过滤器,以及减少IDS内存需求和提高硬件实现性能的新压缩技术。
然而,这些研究并没有研究病毒扫描的应用,这与IDS系统有很大的不同。
 
我们对病毒扫描应用程序和软件实现的关注使我们的研究有别于上述工作。
病毒扫描应用程序通常基于主机,而IDS系统通常基于网络。
因此,在通用处理器上运行的软件实现比硬件实现更适合于病毒扫描程序。
软件实现不同于硬件实现,主要是由于串行应用的哈希函数、对CPU开销的严格要求以及良好的缓存局部性对性能的影响。
因此,软件实现的设计选择与硬件实现的设计选择是完全不同的。
 
最近,人们重新关注于提高Clam-AV的可伸缩性。
此外,Avfs论文还对在文件系统实现中集成病毒扫描程序所涉及的问题进行了很好的研究。
这些研究中描述的技术是对Hash-AV的补充,应该将这些技术结合起来,进一步提高Clam-AV的性能。
 
由于它们的重要性,多字符串匹配算法及其变体得到了不断的改进。
Hash-AV是一种“booster”技术,独立于底层字符串匹配算法,可以与任何改进的匹配算法组合使用。
Hash-AV的好处是可以以一种CPU缓存友好的方式快速确定不匹配的情况,而且对于任何不匹配情况占绝大多数的系统来说,Hash-AV都是有益的。
 
8. 结论和未来的工作
 
在本文中,我们已经证明,通过合理使用CPU缓存,Hash-AV可以显著提高开源病毒扫描Clam-AV的性能。
通过使用驻留缓存的布鲁姆过滤器,Hash-AV确定了绝大多数没有主内存访问的“不匹配”情况。
通过使用廉价的散列函数(其计算成本被内存访问延迟所隐藏),Hash-AV可以以三分之一的内存复制速度扫描输入。
由于CPU计算和随机内存访问之间的速度差距继续增加,我们预计Hash-AV对于病毒扫描性能将变得更加关键。
 
Hash-AV成功的关键是使用了非常便宜的函数,如“mask”和“xor+shift”。
虽然在一般情况下,它们不是很好的哈希函数,但作为一组哈希函数的串行应用程序中的初始函数,它们非常有效。
虽然我们的特定选择可能被认为是针对病毒特征的,但我们相信,在任何“不匹配”情况占多数的应用程序中,
都可以找到一种非常便宜的操作,消除很大一部分输入数据。
 
在未来的工作中,我们计划改进多态病毒检测。
目前,Clam-AV和Hash-AV都依赖于多态病毒的多部分签名,这些签名由Aho-Corasick算法处理。
我们计划研究缓存友好技术,以加快这些多部分的匹配特征。
我们还计划研究用于多态病毒检测的高效仿真引擎。
例如,有效模拟引擎的一种可能性是通过使用虚拟机技术。
 
最后,我们计划将Hash-AV应用于其他大特征集模式匹配应用程序,例如某些信息检索和反垃圾邮件应用程序。
在这些应用程序中,Hash-AV的配置可能有所不同,可能还需要处理“不关心”字符等新功能。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值