目标程序
目标程序从FuzzX接收测试用例,运行并报告发现的缺陷。本页介绍如何构建一个目标程序。
每个目标程序包含两部分:
一个可以让
FuzzX进行传参的方法————像是单元测试框架。fuzzx.yaml文件中的target字段————描述如何运行目标程序,定义错误的显示格式。
测试方法
要Fuzz您的C语言代码,创建一个使用下述方法的文件:
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
//第一步:读取所需的数据类型
//第二步:运行您的代码(方法)
//第三步:查错,发现错误立即终止并报告
//字节数组长度不够则返回-1
}要Fuzz您的C++语言代码,创建一个使用下述方法的文件:
extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
//第一步:读取所需的数据类型
//第二步:运行您的代码(方法)
//第三步:查错,发现错误立即终止并报告
//字节数组长度不够则返回-1
}您也可以像是在单元测试一样————使用断言查错,反正FuzzX会把断言失败也当成错误。
该方法接收数组Data中定义的测试用例并将其转化为目标所需求的测试数据。 例如:如果你的代码(或者说是你要测试的方法)需要两个整数作为输入,则从字节数组中解析两个整数。
这样的接口十分灵活:你可以从输入的字节数组中解析出任意类型的数据、结构体或是对象,进而生成复杂的测试结构体。
当然,如果输入的字节数组不够长,会立马返回-1。
而我们的FuzzX将会马上意识到数组长度不够并及时做出调整!
FuzzTarget写法可以参考这里。
配置方法
此部分仅提供一部分参考,具体教程,请您点击这里。
目标程序需要在fuzzx.yaml文件中用target字段描述,以下是我们提供的c/c++样例中的配置详情:
我们在此对target.setup字段中的各条命令做出简要的解释说明,以帮助理解:
在全局配置部分,我们已将环境变量设置为:CC=clang,CXX=clang++ ;所以第一条的命令等价于:
进入
openssl文件夹,该文件夹即对应您要测试的项目的文件夹;将环境变量
CC重新设置为clang -g -fsanitize=address,fuzzer-no-link,执行当前文件夹下的config(当然,您可以在我们给出的C/C++示例中的对应目录下找到到我们所说的文件)。即config中所有出现CC的地方都换为了新值,而新增flag的含义是:-g的含义为保留调试信息(该选项为非必须选项,也可以去掉);-fsanitize=address,fuzzer-no-link选项声明了需要启动libFuzzer,同时启动了地址检查。(由于此处的目的仅仅是编译,所以选择了fuzzer-no-link而不是fuzzer,但实际实验发现二者在编译期的功能完全一致,只不过fuzzer-no-link强制在链接阶段不生效,而后者在链接阶段也生效。当然,如果您追求简单统一,也可以直接使用fuzzer关键词替换掉fuzzer-no-link。)
而
make clean就是清除之前的make信息;(别忘了,我们已经在全局配置中添加了make的安装)然后运行
make,生成Makefile;退回FuzzX的根目录
第二条的命令,也就等价于:
./target.cc 即为我们在目录下已经写好的目标文件;-fsanitize=address,fuzzer 如前所说,开启了libFuzzer和 地址分析 ;openssl/libssl.a openssl/libcrypto.a 静态库的引用路径;-std=c++17 定义编译语言标准;-I openssl/include 将目录添加到clang++的搜索目录里;-lstdc++fs -ldl -lstdc++ 为引用的标准库;-o ./target 生成的可执行文件保存至当前目录下命名为target。
其实就相当于在您正常编译target.cc的基础上,添加了-g 和-fsanitize=address,fuzzer。
做完这些准备工作之后,把项目提交到FuzzX,它就会自行检测您的目标程序了。
了解具体操作,请点击这里。
Last updated
Was this helpful?