如何使用AFL测试带有结构体参数的函数?
使用AFL测试结构体参数函数的解决方案
针对你的需求,核心思路是编写一个包装器程序,将AFL生成的字节流直接映射为目标结构体,再调用被测函数,既不需要手动拆分字符数组,也不会额外引入随机性。
具体实现步骤
明确结构体内存布局
为避免内存对齐产生的填充字节干扰测试,可给结构体添加__attribute__((packed))属性(GCC/Clang支持),确保成员连续存储:struct Node{ int a; float b; } __attribute__((packed));编写包装器程序
这个程序作为AFL的测试目标,负责读取AFL输入的字节流,转换成结构体后调用被测函数:#include <stdio.h> #include <string.h> // 定义被测结构体 struct Node{ int a; float b; } __attribute__((packed)); // 声明被测函数(替换为你的实际函数) void foo(struct Node node); int main() { struct Node input_node; // 读取刚好等于结构体大小的字节数据 size_t read_bytes = fread(&input_node, sizeof(struct Node), 1, stdin); // 输入长度不符合则退出,AFL会自动处理这类无效输入 if (read_bytes != 1) return 1; // 调用被测函数 foo(input_node); return 0; }编译与运行AFL
用AFL自带的编译器编译包装器和被测函数:afl-gcc wrapper.c your_target_functions.c -o afl_test_target准备初始测试用例目录(比如
input_dir),放入几个手动构造的二进制测试用例(可用Python快速生成):import struct # 构造a=100,b=2.718的结构体二进制数据 test_data = struct.pack('if', 100, 2.718) with open('input_dir/sample_case', 'wb') as f: f.write(test_data)启动AFL模糊测试:
afl-fuzz -i input_dir -o output_dir ./afl_test_target
关键说明
- 直接通过
fread把字节流写入结构体变量,本质是利用内存布局的一致性,AFL变异的每一个字节都直接对应结构体成员的二进制位,完全没有额外随机性,比手动拆分字符数组更准确高效。 - 如果结构体有默认对齐的填充字节,AFL变异这些填充字节不会影响被测函数逻辑,可忽略;若想让所有变异都作用于有效成员,就用
packed属性去掉填充。
内容的提问来源于stack exchange,提问作者urlyy
相关产品推荐
相关产品推荐

