做好前期准备,比如git Mopt的源码,在Mopt的目录下打开终端。
1.make (Mopt AFL)
2.准备被测程序
编写一个简单的程序,该程序从文件或标准输入读取数据,以测试的方式处理数据。
命名为simple_reader.c
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
int main(int argc, char **argv) {
char buffer[4096]; // 定义缓冲区大小,可以根据需要调整
size_t len = 0;
FILE *input;
// 根据命令行参数决定从文件还是标准输入读取
if (argc > 1) {
input = fopen(argv[1], "rb");
if (!input) {
perror("Error opening input file");
return EXIT_FAILURE;
}
} else {
input = stdin;
}
// 读取数据直到 EOF
while ((len = fread(buffer, 1, sizeof(buffer), input)) > 0) {
fwrite(buffer, 1, len, stdout); // 输出读取的数据
}
if (input != stdin) fclose(input);
// 清理并退出
return EXIT_SUCCESS;
}
3.编译程序
第一次使用下方的代码报错:没有插桩
CC=/afl-gcc CXX=/afl-g++ gcc -o simple_reader -fsanitize=coverage-edges simple_reader.c
改而使用 AFL 的 GCC 包装器编译 simple_reader
: 确认编译命令中包含了必要的插桩标志。
确保你正在使用 Mopt-AFL 的 afl-gcc
和 afl-fuzz
工具。
CC=afl-gcc CXX=afl-g++ \
CFLAGS='-g -O3 -funroll-loops -fsanitize=address -fsanitize=coverage' \
LDFLAGS='-lasan' \
afl-gcc -o simple_reader simple_reader.c
编译成功:
4.准备测试用例
获取一个小的有效输入文件,该文件对程序有意义。如果是模糊测试复杂的语法(如 SQL、HTTP 等),则需要创建一个字典文件,具体方法见 dictionaries/README.dictionaries
。
5.运行 Mopt-AFL
./afl-fuzz -i testcases -o findings_dir -- ./simple_reader @@
./afl-fuzz -i testcase_dir -o findings_dir -- ./simple_reader @@
注:这里的 testcase_dir
是你的初始测试用例目录,findings_dir
是你希望保存模糊测试结果的目录。