pvz122/PromeFuzz

GitHub: pvz122/PromeFuzz

PromeFuzz 是一个基于大语言模型的知识驱动型框架,用于自动为 C/C++ 库生成高质量的模糊测试 harness 并分析崩溃。

Stars: 51 | Forks: 10

Reproduced Functional Available
Logo

PromeFuzz

A Knowledge-Driven Approach to Fuzzing Harness Generation with Large Language Models



![workflow](https://static.pigsec.cn/wp-content/uploads/repos/2026/03/2290a43ba0181116.svg)
**PromeFuzz** 是一个最先进的框架,用于自动为 C 和 C++ 库生成模糊测试 harness(fuzz driver)。它采用知识驱动的方法,利用来自代码元数据、文档和 API 使用模式的结构化信息,生成高效的模糊测试 harness。 PromeFuzz 在分支覆盖率和漏洞发现方面均优于现有方法——包括 [Google OSS-Fuzz-Gen](https://github.com/google/oss-fuzz-gen)、[PromptFuzz](https://github.com/FuzzAnything/PromptFuzz) 和 [CKGFuzzer](https://github.com/security-pride/CKGFuzzer)。 有关更多详细信息,请参阅我们被 ACM CCS 2025 接收的 [预印本论文](paper/ccs25-full.pdf)。 ## ✨ 亮点 - **系统性知识集成:** PromeFuzz 系统地整合了来自各种来源的知识,包括代码元数据、文档和 API 使用模式,以确保生成的模糊测试 harness 在语法和语义上的正确性。 - **智能 API 调度:** PromeFuzz 采用先进的 API 关联分析来优化生成的 harness 内的 API 调用调度,从而提高其有效性。 - **内置崩溃分析:** PromeFuzz 包含一个专用的崩溃分析器,可以自动检测、分类和分析由生成的模糊测试 harness 触发的崩溃,从而促进可靠的漏洞发现。 - **实用且生产就绪的设计:** PromeFuzz 经过稳健的实现,支持 C 和 C++ 库,具有端到端的流水线,确保在实际软件测试环境中实现无缝集成和实用性。 ## 📦 设置 PromeFuzz 设置 PromeFuzz 的推荐方法是使用 Docker,以获得一致且隔离的环境。或者,您可以在系统上手动安装它。 ### 🐳 使用 Docker 设置 1. **安装 Docker** 确保已安装 Docker,并且您的用户已添加到 `docker` 组: sudo apt update sudo apt install docker.io sudo usermod -aG docker $USER newgrp docker # 刷新组成员身份 2. **构建 Docker 镜像** 在 PromeFuzz 根目录下: docker build -t promefuzz:latest . 3. **运行容器** 我们分配额外的共享内存 (`shm`) 以提高文件处理期间的性能: docker run -itd --shm-size=16g --name promefuzz promefuzz:latest /bin/bash 4. **访问容器** 进入正在运行的容器: docker exec -it promefuzz /bin/bash ### 🛠️ 手动设置 如果您更喜欢原生安装,请按照以下步骤操作: 1. **设置 Python 环境** PromeFuzz 使用 [`uv`](https://github.com/astral-sh/uv) 作为 Python 包管理器,以实现更快的依赖解析: # 安装 uv curl -LsSf https://astral.sh/uv/install.sh | sh # 恢复依赖 uv sync # 激活虚拟环境 source .venv/bin/activate 2. **安装系统依赖** 安装所需的构建工具和库: sudo apt install bear build-essential cmake clang llvm libclang-dev clang-format libomp-dev 3. **构建处理器二进制文件** 编译核心分析工具: ./setup.sh ## ⚙️ 使用 PromeFuzz PromeFuzz 通过命令行脚本 `PromeFuzz.py` 控制,该脚本支持以下子命令: - `configure`:设置 PromeFuzz 的配置。 - `preprocess`:预处理库以提取代码元数据知识。 - `comprehend`:使用 LLM 理解库以提取文档知识。 - `generate`:使用提取的知识生成模糊测试 harness。 - `analyze`:分析 ASan 崩溃以生成报告。 - `stats`:收集统计数据。 有关每个子命令的详细用法,请运行: ``` ./PromeFuzz.py [subcommand] --help ``` 此外,在 `database/utils/` 目录中提供了一组 [实用脚本](database/utils/README.md),用于协助完成常见任务,如模糊测试执行、覆盖率收集和结果评估。 下面,我们将使用 `pugixml` 演示一个完整的示例,以展示端到端的工作流程。 ### 1. **配置 PromeFuzz** PromeFuzz 依赖两个配置文件: - `config.toml` — 控制框架的全局行为(例如,LLM 设置、分析参数)。 - `libraries.toml` — 定义目标库的元数据(例如,头文件路径、构建参数)。 我们建议使用内置的交互式配置向导来设置 PromeFuzz。它会指导您完成基本设置,并确保所有必填字段都已正确填写。 要启动向导: ``` ./PromeFuzz.py configure setup ``` 在设置过程中,您需要访问两种类型的 LLM: - **生成模型**(例如 `gpt-5`、`qwen-3`)用于 harness 生成、库理解和崩溃分析。我们建议: - 一个**标准模型**用于 harness 生成。 - 一个**轻量级模型**用于高效的库理解。 - 一个**推理模型**用于崩溃分析。 - **嵌入模型**(例如 `mxbai-embed-large`)支持从文档和源代码中进行语义检索。 ##### 示例:使用 DeepSeek-V3.2-Exp 和 Ollama 嵌入 如果您想使用 **DeepSeek-V3.2-Exp** 作为主 LLM,并使用 **`mxbai-embed-large`**(通过 Ollama)进行嵌入,请按如下方式配置 `config.toml`: ``` [comprehender] # [修改此项] 用于 RAG embedding 的 llm。 embedding_llm = "mxbai" [analyzer] analysis_llm = "deepseek-reasoner" [llm] # [修改此项] 用于生成、理解和分析的默认 llm。 # 如果未在相应部分指定 llm,则将使用默认 llm。 default_llm = "deepseek-chat" # [修改此项] 您的自定义 llm 名称。 [llm.deepseek-chat] # llm 类型,当前支持 "ollama"、"openai"、"ollama-reasoning"、"openai-reasoning"。 llm_type = "openai" # openai api 的 base url。 base_url = "https://api.deepseek.com/v1" # openai api 的 api key,默认使用环境变量 "OPENAI_API_KEY"。 api_key = "" # 用于 llm query 的模型。 model = "deepseek-chat" # llm query 的 temperature。建议在生成代码时将其设置得更低。 temperature = 0.5 [llm.deepseek-reasoner] llm_type = "openai-reasoning" base_url = "https://api.deepseek.com/v1" api_key = "" model = "deepseek-reasoner" temperature = 0.5 max_tokens = -1 query_timeout = 2000 # [修改此项] 您的自定义 llm 名称。 [llm.mxbai] # llm 类型,当前支持 "ollama" 和 "openai"。 llm_type = "ollama" # ollama server host。 host = "localhost" # ollama server port。 port = 11434 # 用于 llm query 的模型。 model = "mxbai-embed-large" ``` 配置完成后,PromeFuzz 将在所有阶段使用这些设置:理解、harness 生成和崩溃分析。 ### 2. **获取并构建库** 在生成模糊测试 harness 之前,您需要获取并编译目标库,且需支持编译数据库 (`compile_commands.json`)。这使 PromeFuzz 能够准确分析构建上下文和依赖项。 #### 对于数据集中的库 对于我们 [数据集](database/README.md) 中包含的库,我们提供了自动化脚本以简化此过程。 例如,要设置 **pugixml**: ``` cd database/pugixml ./fetch.sh # Clone the latest version cd latest ./build.sh normal && ./build.sh asan # Build normal + ASan instrumented versions ``` 这会在 `build_asan` 目录中生成一个 `compile_commands.json` 文件,PromeFuzz 将其用于代码分析。 #### 对于自定义库(不在数据集中) 如果您正在测试**不包含**在我们数据集中的库,请按照以下手动步骤操作。以下是使用 `pugixml` 的示例: ``` mkdir library && cd library git clone https://github.com/zeux/pugixml.git pugixml && cd pugixml mkdir build && cd build cmake .. bear -- make ``` 这会在 `library/pugixml/build` 中生成 `compile_commands.json`。 ### 3. **配置库** 每个目标库都必须在配置文件 (`libraries.toml`) 中进行描述,该文件指定了基本的元数据,如头文件位置、文档路径、编译详细信息和输出设置。 #### 对于数据集中的库 对于我们 [数据集](database/README.md) 中包含的库,我们提供了即用型配置文件。例如,**pugixml** 的配置位于: ``` database/pugixml/latest/lib.toml ``` 要使用它,只需将文件路径传递给 PromeFuzz: ``` ./PromeFuzz.py -F database/pugixml/latest/lib.toml [subcommand] ``` 这可以通过经过验证的优化设置立即启用使用。 #### 对于自定义库(不在数据集中) 要添加自定义库,请复制模板: ``` cp libraries.template.toml libraries.toml ``` 然后相应地编辑 `libraries.toml`。所有标记为 `[MODIFY THIS]` 的字段都必须填写。有关指导,请参阅 [模板文件](./libraries.template.toml) 中的注释。 ##### 示例:`pugixml` 的手动配置 以下是 `pugixml` 的完整示例配置: ``` # [修改此项] 库的名称。 [pugixml] # [修改此项] 库的语言。可能的值为 "c" 和 "c++"。 language = "c++" # [修改此项] 库的 header paths。header path 是声明 API 函数的目录或文件。 header_paths = ["library/pugixml/src/pugixml.hpp"] # [修改此项] 记录库的编译数据库的 "compile_commands.json" 的路径。 # 您可以使用 Bear 或带有 -DCMAKE_EXPORT_COMPILE_COMMANDS=ON 标志的 CMake 生成 "compile_commands.json"。 compile_commands_path = "library/pugixml/build/compile_commands.json" # [修改此项] 库的文档文件路径。它可以是: # 1. 像 README.md 这样的文档文件。 # 2. 包含文档文件的目录。PromeFuzz 将读取所有扩展名为 .md/.txt/.html/.htm/.pdf/.adoc/.rst 或名为 "README"/"USAGE" 的文件。 # 3. 网站 URL。PromeFuzz 将下载网站并提取文本内容。 document_paths = ["https://pugixml.org/docs/manual.html"] # [修改此项] 文档是否包含 API 用法。如果为 true,PromeFuzz 将尝试从文档中理解 API 用法。 document_has_api_usage = true # [修改此项] PromeFuzz 存储结果的 output path。 output_path = "out/pugixml" # [修改此项] 构建 fuzz driver 时的 compile arguments。fuzz driver 将使用类似如下的命令构建: # clang++ path/to/fuzz/driver.cpp -o path/to/output -fsanitize=fuzzer,address,undefined -Ipath/to/headers [configured build args] # 此选项通常包含库二进制文件(.so/.a 文件)的路径。强烈建议您在编译库时 # 使用 -g 标志以在二进制文件中包含调试信息,PromeFuzz Sanitizer 和 ConstraintLearner 依赖这些信息来分析源代码。 driver_build_args = ["library/pugixml/build/libpugixml.a", "-DPUGIXML_NO_EXCEPTIONS"] # 库的 consumer case source paths,例如,使用该库的测试用例或示例。 # 这些案例将用于推断 API 关系。 consumer_case_paths = ["database/pugixml/latest/code/tests"] ``` 有了此配置,PromeFuzz 可以有效地分析库并生成高质量的模糊测试 harness。 ### 4. **预处理库** 运行 `preprocess` 命令以从库中提取基本的代码信息,例如 API 签名、调用模式和元数据依赖项。 准备好库配置文件(例如 `lib.toml`)后,执行: ``` ./PromeFuzz.py -F database/pugixml/latest/lib.toml preprocess ``` 提取的知识将保存到配置中指定的输出目录——默认为: `database/pugixml/latest/out/preprocessor/`。 ##### 输出产物 预处理器生成一组结构化文件: - `sources.json`:源文件。 - `api.pkl` & `api.json`:API 函数。 - `info.pkl` & `info.json`:元数据依赖图。 - `call_graph.json` & `call_graph.pkl`:消费者调用图。 - `call_order.json` & `call_order.pkl`:API 调用序列。 - `type_relev.pkl`:类型相关性。 - `call_scope_relev.csv` & `call_scope_relev.pkl`:调用范围相关性。 - `class_scope_relev.csv` & `class_scope_relev.pkl`:类范围相关性。 ### 5. **理解库语义** 运行 `comprehend` 步骤,从库的源代码及其文档中提取语义知识。 此步骤是可选的,但强烈建议执行,以提高生成的模糊测试 harness 的质量和正确性。 准备好 `lib.toml` 配置后,执行: ``` ./PromeFuzz.py -F database/pugixml/latest/lib.toml comprehend --pool-size 50 ``` ##### 输出产物 理解器在输出目录(例如 `database/pugixml/latest/out/comprehender/`)下生成结构化知识产物: - `comp.pkl` & `comp.json`:文档知识,包括库用途和 API 用法。 - `semantic_relev.csv` & `semantic_relev.pkl`:语义相关性。 - `documents/`:用于语义搜索的向量数据库。 ### 6. **生成模糊测试 Harness** 运行 `generate` 命令,根据预处理和理解期间提取的知识生成模糊测试 harness。 默认情况下,PromeFuzz 以 **ALL-COVER 模式** 运行,旨在生成模糊测试 harness,使得每个 API 函数至少被调用一次。您可以使用 `--task` 选项自定义停止条件。 准备好 `lib.toml` 配置后,执行: ``` ./PromeFuzz.py -F database/pugixml/latest/lib.toml generate ``` ##### 输出产物 生成的 harness 存储在 `database/pugixml/latest/out/fuzz_driver/` 中: - `fuzz_driver_{id}.c(pp)`:使用 libFuzzer 的单个 C/C++ 模糊测试 harness。 - `build_fuzz_driver_{id}.sh`:编译 harness 的构建脚本。 - `synthesize_into_one`:将所有单个 harness 合并为单个统一模糊测试 harness 的辅助脚本。 ### 7. **执行模糊测试** 可以使用位于 `fuzz_driver` 目录中的 `synthesize_into_one` 脚本将生成的模糊测试 harness 合并为统一的 driver。要合并它们,只需运行: ``` ./synthesize_into_one ``` 合并后的 harness 使模糊测试引擎(例如 LibFuzzer 或 AFL++)能够利用其变异和状态探索能力来选择有效的 harness。 该脚本生成一个目录 `synthesized/`,其中包含合并后的模糊测试 harness 和以下构建脚本: - `build_synthesized_driver.sh`:使用 **LibFuzzer** 和 AddressSanitizer (ASan) 构建合并后的 harness。 - `build_aflpp_synthesized_driver.sh`:为 **AFL++** 构建 harness。 - `build_gcov_synthesized_driver.sh`:使用 **GCov** 插桩构建,用于覆盖率分析。 - `build_cov_synthesized_driver.sh`:使用 **Clang Coverage** 构建。 构建完成后,您可以以您偏好的方式开始模糊测试活动。例如,使用 AFL++: ``` ./build_aflpp_synthesized_driver.sh # initial seeds 位于 database/pugixml/in/ afl-fuzz -i ../../../in/ -o fuzz/ -- ./aflpp_synthesized_driver @@ ``` ### 8. **收集统计数据** #### 生成指标 PromeFuzz 包含一个内置的 `stats` 命令,用于在整个 harness 生成过程中收集详细的指标。这包括对 API 覆盖率、token 使用情况、崩溃学习等的洞察。 要生成报告,请运行: ``` ./PromeFuzz.py -F database/pugixml/latest/lib.toml stats ``` 这会在 `database/pugixml/latest/out/statistics_for_pugixml.xlsx` 生成一个 Excel 工作簿。 #### 模糊测试阶段指标 对于运行时统计数据(例如代码覆盖率)以及模糊测试期间的崩溃报告,PromeFuzz 集成了位于 `database/utils/` 中的实用脚本。这些工具支持覆盖率收集和崩溃重现。有关说明,请参阅 [`database/utils/README.md`](database/utils/README.md)。 ### 9. **分析崩溃** 在模糊测试期间,可能会触发崩溃——其中一些是库中真正的漏洞(**真阳性**,TP),而另一些则源于不正确的 harness 使用或无效假设(**假阳性**,FP)。为了帮助区分它们,PromeFuzz 包含一个**崩溃分析器**,用于分类和解释崩溃报告。 此崩溃分析器在生成阶段自动运行。如果您想用它来分析来自您自己模糊测试活动的崩溃,请按照以下步骤操作: 如果 AddressSanitizer (ASan) 日志存储在诸如 `database/pugixml/latest/crashes/*.log` 的目录中,您可以使用 `analyze` 子命令分析它们: ``` ./PromeFuzz.py -F database/pugixml/latest/lib.toml analyze database/pugixml/latest/crashes/*.log -O database/pugixml/latest/reports ``` 此命令处理每个崩溃日志,对其进行去重,并在输出目录中生成详细的分析报告。 每个报告的命名方式为: - `TP-{crash_type}@{crash_location}`:这可能是一个真阳性 (TP) 漏洞。 - `FP-{crash_type}@{crash_location}`:这可能是由于 API 误用导致的假阳性 (FP)。 - `UN-{crash_type}@{crash_location}`:这是一个未分类的崩溃,需要进一步调查。 ## 📚 引用 如果您在研究中使用 PromeFuzz,请引用我们的 ACM CCS 2025 论文: ``` @inproceedings{promefuzz-ccs25, author = {Liu, Yuwei and Deng, Junquan and Jia, Xiangkun and Wang, Yanhao and Wang, Minghua and Huang, Lin and Wei, Tao and Su, Purui}, title = {PromeFuzz: A Knowledge-Driven Approach to Fuzzing Harness Generation with Large Language Models}, year = {2025}, isbn = {9798400715259}, publisher = {Association for Computing Machinery}, address = {New York, NY, USA}, url = {https://doi.org/10.1145/3719027.3765222}, doi = {10.1145/3719027.3765222}, booktitle = {Proceedings of the 2025 ACM SIGSAC Conference on Computer and Communications Security}, pages = {1559–1573}, numpages = {15}, keywords = {api-level fuzzing, fuzzing, fuzzing harness generation, large language model}, location = {Taipei, Taiwan}, series = {CCS '25} } ```
标签:AI风险缓解, API安全, Bash脚本, C/C++, DLL 劫持, Fuzz Driver生成, Fuzzing, JSON输出, LLM, OSS-Fuzz, Petitpotam, Security, Static Analysis, TLS抓取, Unmanaged PE, 事务性I/O, 人工智能, 代码生成, 凭据导出, 可配置连接, 大语言模型, 渗透测试工具, 用户模式Hook绕过, 知识驱动, 程序分析, 网络安全, 覆盖率测试, 请求拦截, 软件安全, 逆向工具, 隐私保护