目前可用的一些模糊测试框架是用C语言编写的,而其它的框架则是用Python或者Ruby来编写的。有一些框架是通过开发语言自身来实现的,而其它框架则是利用了一个定制的语言。例如,Peach模糊测试框架是使用Python来构建的,而dfuz则实现了它自己的模糊测试对象集(本章的后面将对这两种框架进行更加详细的讨论)。有一些框架将数据的生成进行了抽象,而另外一些则没有。还有一些框架是面向对象并且公开的,而其它的框架在大多数时候只能被创建者所使用。然而,所有模糊测试框架的共同目标都是相同的,即为模糊器的开发者提供一个快速的、灵活的、可重用的以及同构的开发环境。

一个好的模糊测试框架应当将一些单调的工作进行抽象化,并且将这些工作减少到少的程度。为了帮助实现协议建模的第一个阶段,有一些框架包含这样的工具,即将被捕获的网络通信转换为该框架能够理解的一种格式。这样以来,研究者可以导入大量的经验数据,并且将其关注的重点放在更加适合于人工完成的工作上,比如确定协议字段的边界。

对于一个成熟的框架来说,自动化的长度计算是必需的。许多协议是使用类似于ASN.1 标准的一个TLV(类型,长度,值)风格的语法来实现的。考虑这样一个例子,数据通信的第一个字节定义了后面跟着的数据的类型:0x01表示纯文本,0x02表示原始二进制数据。接下来的两个字节定义了后面数据的长度。后,剩余的字节定义了特定于通信的值或者数据,如下所示:

当对这个协议的值字段进行模糊测试时,我们必须要在每个测试用例中计算并更新该协议中两个字节的长度字段。否则的话,当违背协议规范而进行通信时,我们的测试用例将面临无法被执行风险。CRC(Calculating Cyclic Redundancy Check)计算以及其它的校验和算法作为完成其它任务的工具,应当被一个有用的框架所包含。CRC值通常被嵌入到文件和协议规范中以识别潜在的被破坏的数据。例如,如果接收到的CRC与所计算的CRC值不匹配,那么PNG图像文件可以利用CRC值以允许程序避免处理一个图像。尽管这对于安全性和功能性来说是一个非常重要的特性,但是如果当协议被变异时CRC值没有被正确的更新,那么会阻碍模糊测试的进行。作为一个更加极端的例子,可以考虑分布式网络协议(Distributed Network Protocol,DNP3) 规范,该规范在监督控制和数据获取(Supervisory Control and Data Acquisition,SCADA)通信中被利用。数据流被单个的划分为250字节的块,并且每个块的前面增加了一个CRC-16的校验和。后,考虑一下客户端和服务器的IP地址,它们中的一者或两者经常是处于所传输的数据中,并且在模糊测试的过程中,这两者的地址可能会经常发生变化。如果一个模糊测试框架能够提供这样一个方法,即在所生成的模糊测试用例中自动化的确定并包含这些值,那么将是非常方便的。

即使不是所有的,那么也是大多数的框架都提供了生成伪随机数的方法。一个好的框架将通过包含一个启发式攻击的完整列表来提供更强大的功能。一个启发式攻击实际上是一个被存储的数据序列,并且已知该数据序列将会导致一个软件错误。格式化字符串(%n%n%n%n)和目录遍历序列是简单的启发式攻击的常用例子。在重新回到随机测试数据生成之前,遍历包含这样的测试用例的一个有限列表,将会在许多情形下节省时间,同时它还是一个值得进一步研究的课题。

错误检测在模糊测试中发挥着重要的作用,我们将在第24章"智能故障检测"中对它进行深入的探讨。一个模糊器可以发现如果其测试目标不能接收一个新的连接的话,那么它可能会在一个非常简单的层次上执行失败。更加高级的错误检测通常是借助于一个调试器来完成的。一个高级的模糊测试框架应当允许模糊器与关联到目标应用的一个调试器直接进行通信,甚或是在其框架内绑定一个定制的调试器技术。

依赖于你个人的喜好,这里可能会有一个很长的包含各种细微特性的清单,可以显著的提高你的模糊器的开发经验。例如,有一些框架包含对解析范围很广的一类格式化数据的支持。例如,当将原始字节复制并粘贴到一个模糊测试脚本时,能够以如下格式0x41 0x42,x41x42,4142等中的任意一种来粘贴十六进制字节将会是非常方便的。

到目前为止,人们对模糊测试的度量(查看第23章"模糊器跟踪")的关注也相对较少。一个高级的模糊测试框架应当包含一个接口,以同一个度量收集工具如代码覆盖监视器进行通信。

后,理想的模糊测试框架将提供便利条件以大程度的实现代码重用,方法是通过使已开发的构件能够很容易的用于后续项目。如果被正确的加以实现,那么这个概念将使得一个模糊器变得更加智能化。在深入讨论特定于任务的以及面向通用目的这两种框架的设计和创建过程之前,当我们对一些模糊测试框架进行研究时,要牢记所讨论的这些概念。