首页 > 后端开发 > C++ > 正文

C++如何进行模糊测试(Fuzz Testing)?libFuzzer在C++中的应用【软件测试】

穿越時空
发布: 2025-12-14 19:21:37
原创
944人浏览过
C++中最主流、集成度最高的模糊测试方案是libFuzzer,它以静态库形式链接代码,需编写LLVMFuzzerTestOneInput函数,配合Clang与Sanitizer进行覆盖率引导 fuzzing。

c++如何进行模糊测试(fuzz testing)?libfuzzer在c++中的应用【软件测试】

在C++中做模糊测试,最主流、集成度最高、适合开发者日常使用的方案是 libFuzzer —— 它不是独立运行的黑盒工具,而是以静态库形式链接进你的代码,通过编写一个轻量级的 fuzz target 函数,就能让编译器(Clang)自动注入覆盖率引导的随机输入,持续发现崩溃、断言失败、内存越界等缺陷。

libFuzzer 的核心使用流程

它依赖 Clang 编译器和 Sanitizer(尤其是 AddressSanitizer 和 UndefinedBehaviorSanitizer),整个过程是白盒+覆盖率驱动的:

  • 写一个函数 LLVMFuzzerTestOneInput(const uint8_t *data, size_t size),把待测逻辑“塞进去”
  • clang++ -fsanitize=fuzzer,address,undefined 编译(注意:必须用 Clang,GCC 不支持)
  • 直接运行生成的可执行文件,libFuzzer 自动启动 fuzz loop,生成输入、执行、监控崩溃、保存用例
  • 崩溃时会自动生成 crash-xxx 文件,可用 gdb ./fuzz_target crash-xxx 直接复现定位

一个最小可运行的 fuzz target 示例

比如你要测试一个解析 JSON 字符串的函数 parse_json(const char* s)

#include <cstdint>
#include <cstddef>
<p>extern "C" int LLVMFuzzerTestOneInput(const uint8_t <em>data, size_t size) {
// 确保 data 是以 \0 结尾的字符串(避免越界读)
if (size == 0) return 0;
// 构造临时缓冲区,保证结尾有 \0
char </em>buf = new char[size + 1];
memcpy(buf, data, size);
buf[size] = '\0';</p><p>parse_json(buf);  // 调用你的真实函数</p><p><span>立即学习</span>“<a href="https://pan.quark.cn/s/6e7abc4abb9f" style="text-decoration: underline !important; color: blue; font-weight: bolder;" rel="nofollow" target="_blank">C++免费学习笔记(深入)</a>”;</p>
                    <div class="aritcle_card">
                        <a class="aritcle_card_img" href="/ai/859">
                            <img src="https://img.php.cn/upload/ai_manual/000/000/000/175679992061586.jpg" alt="Tome">
                        </a>
                        <div class="aritcle_card_info">
                            <a href="/ai/859">Tome</a>
                            <p>先进的AI智能PPT制作工具</p>
                            <div class="">
                                <img src="/static/images/card_xiazai.png" alt="Tome">
                                <span>143</span>
                            </div>
                        </div>
                        <a href="/ai/859" class="aritcle_card_btn">
                            <span>查看详情</span>
                            <img src="/static/images/cardxiayige-3.png" alt="Tome">
                        </a>
                    </div>
                <p>delete[] buf;
return 0;
}
登录后复制

⚠️ 注意:所有外部依赖(如 parse_json)必须被编译进同一个二进制;若函数在单独的 .cpp 文件里,记得一起编译进去。

提升 fuzz 效果的关键技巧

libFuzzer 不是“扔进去就完事”,合理设计能显著提升发现深度漏洞的能力:

  • 避免非确定性行为:关闭随机数、时间戳、多线程、文件/网络 I/O——fuzz target 必须纯函数式、可重入、每次输入相同就输出相同
  • __AFL_LOOP-runs= 控制迭代次数:适合 CI 中做轻量回归,例如 ./fuzz_target -runs=100000
  • 提供语料库(corpus):把已知合法/非法样例放进目录,用 ./fuzz_target seed_corpus/ 启动,libFuzzer 会基于它们变异出新输入
  • 加字典(dictionary):对协议类代码(如 JSON、HTTP),用 -dict=json.dict 告诉 fuzzer 常见关键字("{", "name", ":"),大幅提升结构化输入生成效率

常见问题与绕过方法

实际用起来容易卡在几个典型问题上:

  • “undefined reference to `LLVMFuzzerTestOneInput`”:没定义该函数,或拼写错误(必须是 extern "C",大小写严格)
  • “Failed to allocate” 或快速退出:检查是否在 fuzz target 内部做了大量堆分配但没释放,触发 sanitizer 的内存限制;可加 -max_len=4096 限制输入长度
  • 找不到崩溃?试试 -detect_leaks=1(检测内存泄漏)、-timeout=20(超时检测挂起)
  • 想测 C++ 类成员函数?:把它包装成静态函数或 lambda(捕获 this 需谨慎),确保无状态残留

基本上就这些。libFuzzer 上手门槛低,但威力很强——尤其适合单元级别、库级别、parser / serializer / codec 这类数据驱动模块的自动化健壮性验证。不需要额外部署服务,不依赖 Python 脚本,一次编译,反复运行,崩溃即证据。

以上就是C++如何进行模糊测试(Fuzz Testing)?libFuzzer在C++中的应用【软件测试】的详细内容,更多请关注php中文网其它相关文章!

最佳 Windows 性能的顶级免费优化软件
最佳 Windows 性能的顶级免费优化软件

每个人都需要一台速度更快、更稳定的 PC。随着时间的推移,垃圾文件、旧注册表数据和不必要的后台进程会占用资源并降低性能。幸运的是,许多工具可以让 Windows 保持平稳运行。

下载
来源:php中文网
本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn
最新问题
开源免费商场系统广告
热门教程
更多>
最新下载
更多>
网站特效
网站源码
网站素材
前端模板
关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新 English
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2025 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号