Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
158 changes: 132 additions & 26 deletions README.md
Original file line number Diff line number Diff line change
@@ -1,33 +1,139 @@
测试方法:
* 在app# 输入 ./run_fuzz_task.sh 后回车

进入Ubuntu系统:
* docker ps -a
* docker start nju_fuzzer(或者在上一步完成之后的ID里选择一个复制)
* docker exec -it nju_fuzzer(同上) /bin/bash

fuzzer文件夹负责模糊测试代码<br>
out存放数据的输出和图片<br>
seeds存放测试的种子<br>
target存放测试用的C语言程序<br>
# 简易灰盒模糊测试工具 (Simple GreyBox Fuzzer)

这是一个基于 Python 实现的覆盖率引导(Coverage-Guided)灰盒模糊测试工具。本项目利用 **AFL++** 的插装组件进行编译,通过 **System V 共享内存** 获取程序的边覆盖率(Edge Coverage)反馈,实现了完整的“种子选择-变异-执行-评估”循环。

## 系统设计方案 (System Design)

### 1. 总体架构 (Architecture)
系统主要由 **Fuzzer Core** (核心测试引擎) 和 **Analyzer** (结果分析器) 两部分组成,运行在 Docker 容器环境中。

```mermaid
graph TD
A[种子队列 Corpus] -->|按长度排序/选择| B(种子调度器 Scheduler)
B -->|计算能量 Energy| C{变异引擎 Mutator}
C -->|Bitflip/Havoc/Splice| D[生成测试用例]
D -->|Fork & Exec| E[插装目标 Target]
E -->|更新 Bitmap| F(共享内存 Monitor)
F -->|发现新路径?| A
F -->|无新路径| B
```

### 2. 类层次与核心组件 (Class Hierarchy)

核心逻辑封装在 `fuzzer/main.py` 的 `GreyBoxFuzzer` 类中:

* **`Monitor` (监控模块)**:
* 使用 `sysv_ipc` 创建大小为 64KB 的共享内存。
* 负责读取 AFL++ 插装程序写入的覆盖率位图 (Bitmap)。
* 实现了心跳机制 (Heartbeat),即使无新路径发现也能持续记录存活状态。


* **`Mutator` (变异引擎)**:
* 实现了全套 AFL 基础算子:`Bitflip` (位翻转), `Byteflip`, `Arith` (算术运算), `Interest` (感兴趣值替换), `Havoc` (随机破坏)。
* **(加分项)** `Splice`: 实现了种子拼接功能,能够融合两个父代种子的特征。


* **`Scheduler` (调度器)**:
* **种子选择**: 优先选择长度较短的种子 (Top 20%),提高执行吞吐率。
* **能量调度 (Power Schedule)**: 根据当前种子的覆盖贡献动态计算变异次数。


* **`Executor` (执行器)**:
* 使用 `subprocess` 启动子进程,通过标准输入 (stdin) 投递测试数据。



### 3. 可视化分析

`fuzzer/analyze.py` 负责读取运行时生成的 CSV 日志,基于 `matplotlib` 绘制覆盖率随时间变化的增长曲线,并生成 Markdown 格式的测试报告。

---

## 🚀 快速开始 (Quick Start)

### 1. 环境构建

本项目依赖 Docker 环境,请确保已安装 Docker Desktop。

```bash
# 1. 进入项目根目录
cd FuzzingTest_Project

# 2. 构建镜像 (自动配置 AFL++ 和 Python 环境)
# 注意:构建过程使用了南京大学镜像源加速
docker build -t my-fuzzer:v1 -f docker/Dockerfile .

结构:<br>
```

### 2. 启动测试

所有测试任务均在容器内自动完成。

```bash
# 1. 启动并进入容器 (将当前目录挂载到容器内的 /app,以便保存测试结果)
docker run -it -v ${PWD}:/app --name fuzzer_env my-fuzzer:v1

# --- 以下命令在容器终端内执行 ---

# 2. 解决潜在的 Windows 换行符问题 (如果脚本无法运行)
dos2unix run_fuzz_task.sh

# 3. 运行自动化测试任务
# 该脚本会自动编译 targets/ 下的 10 个目标程序,并依次并行进行模糊测试
cd /app
./run_fuzz_task.sh

```

**提示**: 默认测试时间可能较短,如需进行 24 小时完整测试,请修改 `run_fuzz_task.sh` 中的超时参数。

### 3. 查看结果

测试完成后,结果文件会保存在 `out/` 目录下:

* 📄 **`experiment_report.md`**: 包含所有目标的最终覆盖率和耗时统计。
* 📈 **`multi_target_comparison.png`**: 10 个测试目标的覆盖率增长趋势对比图。
* 📊 **`stats_targetX.csv`**: 详细的运行时数据日志。

---

## 📂 项目结构 (Structure)

```text
FuzzingTest
|-docker
| |-Dockerfile
|-docs
| |-devlog.md #工作日志
|-fuzzer
| |-analyze.py #数据转图片
| |-其余测试文件可以随意删除替换
|-out
|-seeds
|-target
| |-C语言程序
|-.gitignore
|-README.md
|-run_fuzz_task.sh #自动化测试脚本
|-requirements.txt #需要配置的环境
├── docker/ # Docker 配置文件
│ └── Dockerfile # 镜像构建脚本 (Ubuntu 22.04 + AFL++)
├── docs/ # 文档
│ └── devlog.md # 开发日志 (记录踩坑与解决过程)
├── fuzzer/ # 核心代码目录
│ ├── main.py # Fuzzer 主程序 (核心逻辑实现)
│ ├── analyze.py # 数据分析与可视化脚本
│ └── check_coverage.py # 辅助验证工具
├── out/ # [自动生成] 测试结果输出目录
├── targets/ # 待测目标程序 (C 源码)
├── seeds/ # 初始种子文件
├── run_fuzz_task.sh # 自动化运行脚本 (编译+测试+报告)
├── requirements.txt # Python 依赖库
└── README.md # 项目说明文档

```

## ✨ 功能特性 (Features)

* [x] **Docker 环境**: 一键部署,集成 AFL++ 工具链。
* [x] **AFL++ 插装对接**: 兼容 `afl-cc` 编译的二进制文件。
* [x] **完整变异策略**: Bitflip, Byteflip, Arith, Interest, Havoc。
* [x] **高级特性**:
* Splice 拼接算子。
* 基于覆盖率的能量调度 (Power Schedule)。
* 心跳日志记录 (Heartbeat Logging)。


* [x] **自动化报表**: 自动生成 Markdown 表格和覆盖率趋势图。

```

```

76 changes: 47 additions & 29 deletions docker/Dockerfile
Original file line number Diff line number Diff line change
@@ -1,29 +1,47 @@
FROM ubuntu:22.04

RUN sed -i 's/archive.ubuntu.com/mirrors.nju.edu.cn/g' /etc/apt/sources.list && \
sed -i 's/security.ubuntu.com/mirrors.nju.edu.cn/g' /etc/apt/sources.list

ENV DEBIAN_FRONTEND=noninteractive

RUN apt-get update && apt-get install -y \
build-essential \
python3-dev \
automake \
cmake \
git \
flex \
bison \
libglib2.0-dev \
libpixman-1-dev \
clang \
llvm-dev \
libtool-bin \
wget \
&& rm -rf /var/lib/apt/lists/*

RUN git clone --depth 1 https://github.com/AFLplusplus/AFLplusplus.git /opt/aflplusplus && \
cd /opt/aflplusplus && \
make distrib && \
make install

WORKDIR /app
FROM ubuntu:22.04

FROM ubuntu:22.04

# 1. 基础配置与换源 (保持你原有的南京大学源)
RUN sed -i 's/archive.ubuntu.com/mirrors.nju.edu.cn/g' /etc/apt/sources.list && \
sed -i 's/security.ubuntu.com/mirrors.nju.edu.cn/g' /etc/apt/sources.list

ENV DEBIAN_FRONTEND=noninteractive

# 2. 安装系统依赖
# [修复点] 新增 python3-pip (装库用) 和 vim (调试用)
RUN apt-get update && apt-get install -y \
build-essential \
python3-dev \
python3-pip \
automake \
cmake \
git \
flex \
dos2unix \
bison \
libglib2.0-dev \
libpixman-1-dev \
clang \
llvm-dev \
libtool-bin \
wget \
vim \
&& rm -rf /var/lib/apt/lists/*

# 3. 安装 AFL++ (AFLplusplus)
# [修复点] 确保命令在一行,或者使用 \ 正确换行
RUN git clone --depth 1 https://github.com/AFLplusplus/AFLplusplus.git /opt/aflplusplus && \
cd /opt/aflplusplus && \
make distrib && \
make install

WORKDIR /app

# 4. [修复点] 安装 Python 项目依赖
# 这一步非常关键!没有它你的 fuzzer 跑不起来
COPY requirements.txt /app/requirements.txt
RUN pip3 install --no-cache-dir -r requirements.txt -i https://pypi.tuna.tsinghua.edu.cn/simple

# 5. 设置环境变量 (防止中文乱码)
ENV LANG C.UTF-8
37 changes: 25 additions & 12 deletions docs/devlog.md
Original file line number Diff line number Diff line change
@@ -1,12 +1,25 @@
#### 2026-01-02: 开始构建 Docker 镜像。
* 遇到的情况:执行 `apt-get install` 步骤较慢,约持续了数分钟。
* 反思:因为安装了 LLVM/Clang 等大型编译工具,这是正常耗时。

#### 2026-01-02: 尝试使用国外网站后依然存在波动,改用南京大学镜像站 (mirrors.nju.edu.cn)。
* 结果:网络连接显著改善,下载速度提升。
* 状态:正在完成 Docker 镜像的最后构建。

#### 2026-01-02:
* 克服了 LLVM/Clang 庞大的下载量,成功构建 fuzzer-env 镜像。
* 手动在容器内完成了 AFL++ 的编译与安装 (make distrib)。
* 成功生成了插装版二进制文件 `target_instrumented`。
# 开发日志 (DevLog)

#### 2026-01-02: 环境搭建
* **工作内容**: 编写 `Dockerfile`,配置基础编译环境。
* **遇到的问题**: 执行 `apt-get install` 下载速度极慢,导致构建超时。
* **解决方案**: 将软件源替换为南京大学镜像源 (`mirrors.nju.edu.cn`),构建速度显著提升。成功编译安装 AFL++。

#### 2026-01-03: 核心逻辑实现
* **工作内容**: 编写 `main.py`,实现 `GreyBoxFuzzer` 类的基础骨架。
* **攻克难点**:
* **共享内存通信**: Python 的 `sysv_ipc` 库与 C 语言 `shmget` 的对接。通过阅读 AFL 源码,确定了 `__AFL_SHM_ID` 环境变量的传递方式。
* **覆盖率获取**: 实现了从共享内存读取 64KB Bitmap 并统计非零字节的逻辑,成功获取程序执行反馈。

#### 2026-01-04: 算法增强与 Bug 修复
* **算法增强**:
* 实现了完整的变异算子库:`Bitflip` (位翻转), `Arith` (算术), `Interest` (感兴趣值), `Havoc` (随机破坏)。
* **新增加分项**: 实现了 `Splice` 算子,能够将两个种子拼接产生新样本;优化了种子调度策略,优先选择短种子以提升吞吐率。
* **Bug 修复**:
* **Docker 依赖缺失**: 运行脚本时提示 `ModuleNotFoundError: pandas`。原因是在 Dockerfile 中漏掉了 Python 库的安装。**修复**: 在 Dockerfile 中添加了 `pip install -r requirements.txt`。
* **可视化图表为空**: 发现生成的 CSV 文件只有表头,导致画图失败。**原因**: 代码逻辑只在“发现新路径”时才记录,若无新发现则无数据。**修复**: 引入“心跳机制”,强制每秒记录一次状态,确保图表数据的连续性。
* **脚本容错**: 优化 `run_fuzz_task.sh`,增加了对编译结果的检查,防止因编译失败导致 Python 脚本空转。

#### 2026-01-04: 最终测试与交付
* **工作内容**: 在 10 个真实目标上进行集成测试。
* **结果**: 脚本稳定运行,能够生成清晰的覆盖率增长曲线 (`multi_target_comparison.png`)。整理项目文档与架构图,准备提交。
2 changes: 1 addition & 1 deletion fuzzer/analyze.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@


def generate_multi_target_report():
out_dir = "/app/out"
out_dir = "./out"
# 获取目录下所有 stats_*.csv 文件
csv_files = glob.glob(os.path.join(out_dir, "stats_target*.csv"))

Expand Down
2 changes: 1 addition & 1 deletion fuzzer/check_coverage.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
import subprocess
import sysv_ipc

TARGET_PATH = "/app/target/target_instrumented"
TARGET_PATH = "./target/target_instrumented"
MAP_SIZE = 65536


Expand Down
Loading