Page 28 - 《软件学报》2025年第7期
P. 28
欧先飞 等: 语义可感知的灰盒编译器模糊测试 2949
作符的崩溃频率降至 GrayC 的 2% 以下, 并采用进程隔离机制将变异操作从 AFL++主程序中分离, 以防止模糊测
试过程中断. 这些改进有效填补了基于语义信息的变异操作符与灰盒模糊测试之间的技术空白, 显著提升了灰盒
模糊测试工具在复杂的编译器系统上的适用性和稳定性.
挑战 2: 现有灰盒模糊测试工具中的变异操作符选择策略无法匹配语义感知的变异操作符. 当前模糊测试工
具中, 变异直接在字符级别进行, 变异总能获得新的输入变体, 因此随机选择即可满足测试需求. 然而, 语义级别的
变异操作符通常带有使用前置条件 (如修改分支语句的前提是程序存在分支语句), 随机选择将导致无效的变异尝
试. 此外, 基于语义信息的变异操作符可进行变异的变异点通常较少 (如分支语句), 同一操作符应用在同一个程序
上多次后极易生成重复的程序. 这两个问题使灰盒模糊测试工具常用的随机策略效率有数量级的提升空间.
为应对这一挑战, 本文设计了一套动态权重匹配算法, 从随机尝试操作符和输入的组合开始, 随着模糊测试的
进展, 基于操作成功与否的历史记录动态调整输入程序和操作符组合的权重, 并在生成变异后代时给予高权重组
合以更高的选择概率.
综上所述, 本文主要贡献如下.
(1) 为灰盒模糊测试引入了基于语义信息的变异操作符, 有效填补了灰盒模糊测试在处理需要高度语义化输
入的软件系统中的应用空白.
(2) 为知名模糊测试工具 AFL++实现基于语义信息的变异操作, 并将 AFL++扩展为工具 SemaAFL. 相比
AFL++和 GrayC, SemaAFL 在 GCC 和 Clang 上的代码覆盖率分别提高了 14.5% 和 11.2%. 此外, SemaAFL 在最新
版本的 GCC-14 和 Clang-18 上发现并上报了 6 个缺陷, 均已获得开发者确认.
本文第 1 节阐述基于语义信息的变异操作符相对于传统灰盒模糊测试中字符串级变异操作符的优势. 第 2 节
详细介绍基于语义信息的变异操作符的设计理念和具体实现方案. 第 3 节重点探讨变异操作符的选择策略. 第
4 节展示实验结果, 其中包括我们的工具 SemaAFL 成功发现的 6 个已获 GCC/Clang 开发团队确认的新漏洞. 第
5 节分析当前工具的局限性, 并探讨未来向多语言支持扩展的可能性. 第 6 节详细介绍模糊测试领域的相关研究
工作.
1 基于语义信息的变异操作符的优势
在灰盒模糊测试中, 变异操作通过修改测试输入来探索待测程序的执行路径. 对于编译器这一特殊测试对象,
由于大部分编译器代码只在完成语法和语义检查后才执行, 因此保持输入的语义合法性是探索编译器不同行为的
关键. 这样可以触发编译器的后端逻辑, 避免在前端就被基本的语法语义检查拦截.
传统灰盒模糊测试中的字符级变异操作符在保持输入程序合法性方面存在局限. 这些操作符会盲目地插入或
删除字符串, 破坏程序的词法结构, 更难以维持语义合法性. 因此, 生成的程序在探索编译器行为上效率低下, 通常
[1]
只能触及浅层的语法语义检查逻辑. 尽管一些工作如 Gramatron [23] 和 Superion 致力于为灰盒模糊测试引入结构
化输入感知能力, 但这些方法仅支持语法级别的感知, 对程序的语义结构仍缺乏理解.
图 2 中①展示了 AFL++基于字典的字符级变异操作. 该操作从预设字典中选取 char 字符串, 将其插入第 6 行
变量 i 定义尾部. 生成的程序因 char 和 for 直接相连而在语法上不合法, 在编译器前端的语法检查阶段被拒绝. 实
践中, 此操作未能探索到新的编译器分支.
图 2 中②展示了语法级变异操作. 该操作以语法树为单位, 将第 8 行表达式节点 p-&q 替换为 a. 虽然生成的
程序通过语法检查, 但因尝试将数组类型和指针类型直接相加而无法通过语义检查. 编译器处理该表达式时会报
错“检测到非法的加法操作数”. 实践中, 此操作同样未能探索新的编译器分支.
图 2 中③展示了本文实现的“降低数组维度”变异操作符效果. 该操作符选中数组 a, 将其定义降为与数组元素
相同的简单指针类型. 得益于对程序语义的感知能力, 该操作在修改 a 的定义后, 还相应调整了所有对 a 元素的访
问为直接对 a 的访问. 这不仅保证了变异后程序的语义合法性, 还触发了循环展开优化, 成功探索到新的编译器
分支.
如图 2 所示, 利用语义级别信息的变异操作符具有多重优势. 首先, 它能有效感知和维护程序变异前后的语义

