目标程序
目标程序从FuzzX接收测试用例,运行并报告发现的缺陷。本页介绍如何构建一个目标程序。
每个目标程序包含两部分:
一个可以让
FuzzX
进行传参的方法————像是单元测试框架。fuzzx.yaml
文件中的target字段————描述如何运行目标程序,定义错误的显示格式。
测试方法
要Fuzz您的C语言代码,创建一个使用下述方法的文件:
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
//第一步:读取所需的数据类型
//第二步:运行您的代码(方法)
//第三步:查错,发现错误立即终止并报告
//字节数组长度不够则返回-1
}
您也可以像是在单元测试一样————使用断言查错,反正FuzzX
会把断言失败也当成错误。
该方法接收数组Data
中定义的测试用例并将其转化为目标所需求的测试数据。 例如:如果你的代码(或者说是你要测试的方法)需要两个整数作为输入,则从字节数组中解析两个整数。
这样的接口十分灵活:你可以从输入的字节数组中解析出任意类型的数据、结构体或是对象,进而生成复杂的测试结构体。
当然,如果输入的字节数组不够长,会立马返回-1
。
而我们的FuzzX
将会马上意识到数组长度不够并及时做出调整!
FuzzTarget写法可以参考这里。
配置方法
此部分仅提供一部分参考,具体教程,请您点击这里。
目标程序需要在fuzzx.yaml
文件中用target
字段描述,以下是我们提供的c/c++样例中的配置详情:
# -------- 全局配置
language: c++
target:
name: heartbleed #名称,目标文件的唯一标识
setup: #构建步骤
- cd openssl && CC="$CC -g -fsanitize=address,fuzzer-no-link" ./config && make clean && make && cd ..
- $CXX -g ./target.cc -fsanitize=address,fuzzer openssl/libssl.a openssl/libcrypto.a -std=c++17 -DCERT_PATH=\"$PWD/runtime\" -I openssl/include -lstdc++fs -ldl -lstdc++ -o ./target
corpus: ./corpus #语料库路径
harness: ./target #生成的可执行文件路径
我们在此对target.setup
字段中的各条命令做出简要的解释说明,以帮助理解:
在全局配置部分,我们已将环境变量设置为:CC=clang
,CXX=clang++
;所以第一条的命令等价于:
$ cd openssl
$ CC="$CC -g -fsanitize=address,fuzzer-no-link" ./config
$ make clean
$ make
$ cd ..
进入
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的根目录
第二条的命令,也就等价于:
#别忘了,CXX的值已设置为clang++,所以 $CXX 会被自动替换为 clang++
$ $CXX -g ./target.cc -fsanitize=address,fuzzer openssl/libssl.a openssl/libcrypto.a -std=c++17 -DCERT_PATH=\"$PWD/runtime\" -I openssl/include -lstdc++fs -ldl -lstdc++ -o ./target
./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?