Communitygithub.com

AFL++

AFL++ 是原始 AFL 模糊测试器的一个分支,具有更好的模糊测试性能和高级特性。适用于 C/C++ 项目的多核模糊测试。

AFL++ 是什么?

AFL++ 是原始 AFL 模糊测试器的一个功能增强分支,在保持稳定性的同时提供了更优的模糊测试性能和高级特性。相比于 libFuzzer,AFL++ 的核心优势在于对多核模糊测试活动的稳定支持,使其非常适合大规模模糊测试任务。该工具通过编译插桩、多种变异策略和多核并行执行来实现高效的代码覆盖率探索。它支持多种编译模式(LTO、LLVM、GCC 插件)、多种编译方法(Docker、源码编译)、并提供丰富的模糊测试技术,如 CMPLOG(RedQueen)路径约束求解、sanitizer 集成(ASan、UBSan)以及全面的语料库管理(最小化、去重)。AFL++ 适用于需要最大化吞吐量、项目可用 Clang 或 GCC 编译、且已具备一定模糊测试基础的场景。用户可通过 Docker 或源码进行安装,并利用封装脚本在主机或 Docker 环境中运行。

兼容平台~Claude Code~Codex CLI~Cursor
npx skills add https://github.com/SamuelChien/mega-skills-collection/tree/HEAD/aflpp

在你喜欢的 AI 中提问

打开一个已预加载此 Agent Skill 的新对话。

文档

AFL++ 是做什么的?

AFL++ 是原始 AFL 模糊测试器的一个分支,在保持稳定性的同时,提供了更优的模糊测试性能和更高级的特性。相比于 libFuzzer,AFL++ 的主要优势在于对多核模糊测试活动具有稳定的支持,使其成为大规模模糊测试工作的理想选择。

何时使用

模糊测试器最佳适用场景复杂度
AFL++多核模糊测试、多样化变异、成熟项目中等
libFuzzer快速设置、单线程、简单测试桩低
LibAFL自定义模糊测试器、研究、高级用例高

在以下情况选择 AFL++:

  • 你需要多核模糊测试来最大化吞吐量
  • 你的项目可以使用 Clang 或 GCC 编译
  • 你想要多样化的变异策略和成熟的工具链
  • libFuzzer 已经达到瓶颈,你需要更多覆盖率
  • 你正在模糊测试受益于并行执行的生产级代码库

快速开始

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    // 使用模糊测试器提供的数据调用你的代码
    check_buf((char*)data, size);
    return 0;
}

编译并运行:

# 先设置 AFL++ 封装脚本(参见安装章节)
./afl++ docker afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz
mkdir seeds && echo "aaaa" > seeds/minimal_seed
./afl++ docker afl-fuzz -i seeds -o out -- ./fuzz

安装

AFL++ 有许多依赖项,包括 LLVM、Python 和 Rust。我们建议使用当前的 Debian 或 Ubuntu 发行版进行 AFL++ 模糊测试。

方法何时使用支持的编译器
Ubuntu/Debian 仓库较新的 Ubuntu,仅基本功能Ubuntu 23.10: Clang 14 & GCC 13Debian 12: Clang 14 & GCC 12
Docker(从 Docker Hub)特定 AFL++ 版本,Apple Silicon 支持截至 4.35c: Clang 19 & GCC 11
Docker(从源码)测试未发布功能,应用补丁可在 Dockerfile 中配置
从源码避免 Docker,需要特定补丁可通过 LLVM_CONFIG 环境变量调整

Ubuntu/Debian

在安装 afl++ 之前,使用 apt-cache show afl++ 检查包的 clang 版本依赖,并安装匹配的 lld 版本(例如 lld-17)。

apt install afl++ lld-17

Docker(从 Docker Hub)

docker pull aflplusplus/aflplusplus:stable

Docker(从源码)

git clone --depth 1 --branch stable https://github.com/AFLplusplus/AFLplusplus
cd AFLplusplus
docker build -t aflplusplus .

从源码编译

关于 Ubuntu 版本要求及依赖项,请参考 Dockerfile。设置 LLVM_CONFIG 来指定 Clang 版本(例如 llvm-config-18)。

封装脚本设置

创建一个封装脚本,用于在主机或 Docker 上运行 AFL++:

cat <<'EOF' > ./afl++
#!/bin/sh
AFL_VERSION="${AFL_VERSION:-"stable"}"
case "$1" in
   host)
        shift
        bash -c "$*"
        ;;
    docker)
        shift
        /usr/bin/env docker run -ti \
            --privileged \
            -v ./:/src \
            --rm \
            --name afl_fuzzing \
            "aflplusplus/aflplusplus:$AFL_VERSION" \
            bash -c "cd /src && bash -c \"$*\""
        ;;
    *)
        echo "Usage: $0 {host|docker}"
        exit 1
        ;;
esac
EOF
chmod +x ./afl++

安全警告: afl-system-config 和 afl-persistent-config 脚本需要 root 权限,并且会禁用操作系统的安全特性。不要在生成系统或开发环境中进行模糊测试。请使用专用的虚拟机。

系统配置

每次重启后运行,可使每秒执行次数提升最多 15%:

./afl++ <host/docker> afl-system-config

为获得最大性能,禁用内核安全缓解措施(需要 grub 引导加载程序,Docker 中不支持):

./afl++ host afl-persistent-config
update-grub
reboot
./afl++ <host/docker> afl-system-config

使用 cat /proc/cmdline 验证——输出应包含 mitigations=off。

编写测试桩

测试桩结构

AFL++ 支持 libFuzzer 风格的测试桩:

#include <stdint.h>
#include <stddef.h>

extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
    // 1. 必要时验证输入大小
    if (size < MIN_SIZE || size > MAX_SIZE) return 0;

    // 2. 使用模糊测试数据调用目标函数
    target_function(data, size);

    // 3. 返回 0(非零值保留给将来使用)
    return 0;
}

测试桩规则

应该做不应该做
在每次运行之间重置全局状态依赖上一次运行的状态
优雅处理边界情况在无效输入时退出
保持测试桩确定性使用随机数生成器
释放分配的内存造成内存泄漏
验证输入大小处理无界输入

另请参阅: 关于编写测试桩的详细技术、处理复杂输入的模式以及高级策略,请参见 fuzz-harness-writing 技术技能。

编译

AFL++ 提供了多种编译模式,各有不同的权衡。

编译模式决策树

选择你的编译模式:

  • LTO 模式 (afl-clang-lto):最佳性能和插桩。首先尝试此模式。
  • LLVM 模式 (afl-clang-fast):如果 LTO 编译失败,则回退到此模式。
  • GCC 插件 (afl-gcc-fast):适用于需要使用 GCC 的项目。

基本编译(LLVM 模式)

./afl++ <host/docker> afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz

GCC 编译

./afl++ <host/docker> afl-g++-fast -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz

重要提示: GCC 版本必须与编译 AFL++ GCC 插件时使用的版本一致。

使用 Sanitizer

./afl++ <host/docker> AFL_USE_ASAN=1 afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz

另请参阅: 关于详细的 sanitizer 配置、常见问题和高级标志,请参见 address-sanitizer 和 undefined-behavior-sanitizer 技术技能。

构建标志

注意 -g 不是必需的,AFL++ 编译器默认会添加。

标志用途
-DNO_MAIN=1使用 libFuzzer 测试桩时跳过 main 函数
-O2生产优化级别(建议用于模糊测试)
-fsanitize=fuzzer启用 libFuzzer 兼容模式,并在链接可执行文件时添加模糊测试运行时
-fsanitize=fuzzer-no-link进行插桩但不链接模糊测试运行时(用于静态库和目标文件)

语料库管理

创建初始语料库

AFL++ 至少需要一个非空的种子文件:

mkdir seeds
echo "aaaa" > seeds/minimal_seed

对于真实项目,收集有代表性的输入:

  • 下载你正在模糊测试的格式的示例文件
  • 从项目的测试套件中提取测试用例
  • 为你的文件格式使用最小的有效输入

语料库最小化

在模糊测试活动之后,最小化语料库以只保留唯一的覆盖率:

./afl++ <host/docker> afl-cmin -i out/default/queue -o minimized_corpus -- ./fuzz

另请参阅: 关于语料库创建策略、字典和种子选择,请参见 fuzzing-corpus 技术技能。

运行模糊测试活动

基本运行

./afl++ <host/docker> afl-fuzz -i seeds -o out -- ./fuzz

设置环境变量

./afl++ <host/docker> AFL_FAST_CAL=1 afl-fuzz -i seeds -o out -- ./fuzz

解释输出

AFL++ 用户界面显示实时模糊测试统计数据:

输出含义
execs/sec执行速度——越高越好
cycles done完成的队列遍历次数
corpus count队列中的唯一测试用例数
saved crashes发现的唯一崩溃数
stability稳定边的百分比(应接近 100%)

输出目录结构

out/default/
├── cmdline          # 被测系统是如何被调用的?
├── crashes/         # 使被测系统崩溃的输入
│   └── id:000000,sig:06,src:000002,time:286,execs:13105,op:havoc,rep:4
├── hangs/           # 使被测系统挂起的输入
├── queue/           # 重现最终模糊测试器状态的测试用例
│   ├── id:000000,time:0,execs:0,orig:minimal_seed
│   └── id:000001,src:000000,time:0,execs:8,op:havoc,rep:6,+cov
├── fuzzer_stats     # 模糊测试活动统计数据
└── plot_data        # 用于绘图的数据

分析结果

查看实时模糊测试活动统计数据:

./afl++ <host/docker> afl-whatsup out

创建覆盖率图:

apt install gnuplot
./afl++ <host/docker> afl-plot out/default out_graph/

重新执行测试用例

./afl++ <host/docker> ./fuzz out/default/crashes/<test_case>

模糊测试器选项

选项用途
-G 4000最大测试输入长度(默认:1048576 字节)
-t 1000每个测试用例的超时时间,单位毫秒(默认:1000ms)
-m 1000内存限制,单位兆字节(默认:0 = 无限制)
-x ./dict.dict使用字典文件来指导变异

多核模糊测试

AFL++ 在多核模糊测试方面表现出色,有两个主要优势:

  1. 每秒更多的执行次数(与物理核心成线性比例)
  2. 非对称模糊测试(例如,一个 ASan 作业,其余不带 sanitizer)

启动一次模糊测试活动

启动主模糊测试器(在后台):

./afl++ <host/docker> afl-fuzz -M primary -i seeds -o state -- ./fuzz 1>primary.log 2>primary.error &

启动从模糊测试器(你有多少个核心就启动多少个):

./afl++ <host/docker> afl-fuzz -S secondary01 -i seeds -o state -- ./fuzz 1>secondary01.log 2>secondary01.error &
./afl++ <host/docker> afl-fuzz -S secondary02 -i seeds -o state -- ./fuzz 1>secondary02.log 2>secondary02.error &

监控多核模糊测试活动

列出所有正在运行的作业:

jobs

查看实时统计数据(每秒更新一次):

./afl++ <host/docker> watch -n1 --color afl-whatsup state/

停止所有模糊测试器

kill $(jobs -p)

覆盖率分析

AFL++ 通过边插桩自动跟踪覆盖率。覆盖率信息存储在 fuzzer_stats 和 plot_data 中。

测量覆盖率

使用 afl-plot 可视化覆盖率随时间的变化:

./afl++ <host/docker> afl-plot out/default out_graph/

提升覆盖率

  • 使用字典进行格式感知的模糊测试
  • 运行更长时间的模糊测试活动(cycles_wo_finds 表示平台期)
  • 通过多核模糊测试尝试不同的变异策略
  • 分析覆盖率缺口并添加针对性的种子输入

另请参阅: 关于详细的覆盖率分析技术、识别覆盖率缺口和系统性覆盖率提升,请参见 coverage-analysis 技术技能。

CMPLOG

CMPLOG/RedQueen 是所有模糊测试器中可用的最佳路径约束求解机制。 要启用它,需要对模糊测试目标进行相应插桩。 在构建模糊测试目标之前设置环境变量:

./afl++ <host/docker> AFL_LLVM_CMPLOG=1 make

编译和链接测试桩不需要特殊操作。

要运行带有 CMPLOG 插桩模糊测试目标的模糊测试器实例,请在命令行参数中添加 -c0:

./afl++ <host/docker> afl-fuzz -c0 -S cmplog -i seeds -o state -- ./fuzz 1>secondary02.log 2>secondary02.error &

Sanitizer 集成

Sanitizer 对于发现不会立即导致崩溃的内存损坏错误至关重要。

AddressSanitizer (ASan)

./afl++ <host/docker> AFL_USE_ASAN=1 afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer harness.cc main.cc -o fuzz

注意: 由于 ASan 保留了 20TB 的虚拟内存,因此不支持内存限制 (-m) 选项。

UndefinedBehaviorSanitizer (UBSan)

./afl++ <host/docker> AFL_USE_UBSAN=1 afl-clang-fast++ -DNO_MAIN=1 -O2 -fsanitize=fuzzer,undefined harness.cc main.cc -o fuzz

常见 Sanitizer 问题

问题解决方案
ASan 降低模糊测试速度在多核设置中仅使用 1 个 ASan 作业
栈耗尽使用 ASAN_OPTIONS=stack_size=... 增加栈大小
GCC 版本不匹配确保系统 GCC 与 AFL++ 插件版本匹配

另请参阅: 关于全面的 sanitizer 配置和故障排除,请参见 address-sanitizer 技术技能。

高级用法

技巧和窍门

技巧为何有帮助
尽可能使用 LLVMFuzzerTestOneInput 测试桩如果模糊测试活动至少有 85% 的稳定性,这是最高效的模糊测试风格。如果不是,则尝试标准输入或文件输入模糊测试
使用字典帮助模糊测试器发现特定格式的关键字和 magic 字节
设置合理的超时时间防止系统负载导致的误报
限制输入大小更大的输入不一定探索更多空间
监控稳定性低稳定性表明确定性行为不佳

标准输入模糊测试

AFL++ 可以在没有 libFuzzer 测试桩的情况下模糊测试从 stdin 读取的程序:

./afl++ <host/docker> afl-clang-fast++ -O2 main_stdin.c -o fuzz_stdin
./afl++ <host/docker> afl-fuzz -i seeds -o out -- ./fuzz_stdin

这比持久化模式慢,但不需要任何测试桩代码。

文件输入模糊测试

对于读取文件的程序,使用 @@ 占位符:

./afl++ <host/docker> afl-clang-fast++ -O2 main_file.c -o fuzz_file
./afl++ <host/docker> afl-fuzz -i seeds -o out -- ./fuzz_file @@

为了获得更好的性能,使用 fmemopen 从内存创建文件描述符。

参数模糊测试

使用 argv-fuzz-inl.h 模糊测试命令行参数:

#include <stdio.h>
#include <stdlib.h>
#include <string.h>

#ifdef __AFL_COMPILER
#include "argv-fuzz-inl.h"
#endif

void check_buf(char *buf, size_t buf_len) {
    if(buf_len > 0 && buf[0] == 'a') {
        if(buf_len > 1 && buf[1] == 'b') {
            if(buf_len > 2 && buf[2] == 'c') {
                abort();
            }


…

[为翻译而截断]

Individual skills in this repo

This repo contains 20 individual skills — each has its own dedicated page.

SamuelChien/mega-skills-collection

Security audit, hardening, threat modeling (STRIDE/PASTA), Red/Blue Team, OWASP checks, code review, incident response, and infrastructure security for any project.

SamuelChien/mega-skills-collection

Arquitecto de Soluciones Principal y Consultor Tecnológico de Andru.ia. Diagnostica y traza la hoja de ruta óptima para proyectos de IA en español.

SamuelChien/mega-skills-collection

Ingeniero de Sistemas de Andru.ia. Diseña, redacta y despliega nuevas habilidades (skills) dentro del repositorio siguiendo el Estándar de Diamante.

SamuelChien/mega-skills-collection

Estratega de Inteligencia de Dominio de Andru.ia. Analiza el nicho específico de un proyecto para inyectar conocimientos, regulaciones y estándares únicos del sector. Actívalo tras definir el nicho.

SamuelChien/mega-skills-collection

2D game development principles. Sprites, tilemaps, physics, camera.

SamuelChien/mega-skills-collection

3D game development principles. Rendering, shaders, physics, cameras.

SamuelChien/mega-skills-collection

Expert in building 3D experiences for the web - Three.js, React Three Fiber, Spline, WebGL, and interactive 3D scenes. Covers product configurators, 3D portfolios, immersive websites, and bringing depth to web experiences.

SamuelChien/mega-skills-collection

Accessibility audit skill for scanning, fixing, and verifying WCAG 2.2 Level A and AA compliance across React, Next.js, Vue, Angular, Svelte, and plain HTML codebases. Use when auditing accessibility, fixing a11y violations, checking color contrast, generating compliance reports, or integrating accessibility checks into CI/CD pipelines.

SamuelChien/mega-skills-collection

Ab Test Analyzer - Auto-activating skill for Data Analytics. Triggers on: ab test analyzer, ab test analyzer Part of the Data Analytics skill category.

SamuelChien/mega-skills-collection

A B Test Config Creator - Auto-activating skill for ML Deployment. Triggers on: a b test config creator, a b test config creator Part of the ML Deployment skill category.

SamuelChien/mega-skills-collection

When the user wants to plan, design, or implement an A/B test or experiment. Also use when the user mentions "A/B test," "split test," "experiment," "test this change," "variant copy," "multivariate test," "hypothesis," "conversion experiment," "statistical significance," or "test this." For tracking implementation, see analytics-tracking.

SamuelChien/mega-skills-collection

Acceptance Criteria Creator - Auto-activating skill for Enterprise Workflows. Triggers on: acceptance criteria creator, acceptance criteria creator Part of the Enterprise Workflows skill category.

SamuelChien/mega-skills-collection

Use when a coding task should be driven end-to-end from issue intake through implementation, review, deployment, and acceptance verification with minimal human re-intervention.

SamuelChien/mega-skills-collection

Accessibility Audit Runner - Auto-activating skill for Frontend Development. Triggers on: accessibility audit runner, accessibility audit runner Part of the Frontend Development skill category.

SamuelChien/mega-skills-collection

You are an accessibility expert specializing in WCAG compliance, inclusive design, and assistive technology compatibility. Conduct audits, identify barriers, and provide remediation guidance.

SamuelChien/mega-skills-collection

Web accessibility patterns for WCAG 2.2 compliance including ARIA, keyboard navigation, screen readers, and testing

SamuelChien/mega-skills-collection

Manage Discord channel access — approve pairings, edit allowlists, set DM/group policy. Use when the user asks to pair, approve someone, check who's allowed, or change policy for the Discord channel.

SamuelChien/mega-skills-collection

Create unified specification packages across Business, Development, and Design teams. Staged elaboration (L0 Vision → L1 Requirements → L2 Team Detail → L3 Acceptance Criteria) to build shared understanding. Does not write code.

SamuelChien/mega-skills-collection

Research a company or person and get actionable sales intel. Works standalone with web search, supercharged when you connect enrichment tools or your CRM. Trigger with "research [company]", "look up [person]", "intel on [prospect]", "who is [name] at [company]", or "tell me about [company]".

SamuelChien/mega-skills-collection

Validate messaging consistency across website, GitHub repos, and local documentation generating read-only discrepancy reports. Use when checking content alignment or finding mixed messaging. Trigger with phrases like "check consistency", "validate documentation", or "audit messaging".

相关技能