开始测试
相比于示例中比较简单的用法,对于实际项目,可能需要对测试过程做更多的定制。
本章节会介绍测试中常用的参数。这些参数可以任意组合,以达到您的测试需求。
在命令行中输入 wfuzz fuzz --help
也可以看到更详细的参数列表。
多测试入口
如果您的程序比较复杂,从单一的测试入口,可能不能达到满意的覆盖率。 如果针对每个测试入口,编译一个二进制文件,可能会增加构建系统配置的复杂性。
WINGFUZZ支持在同一个二进制文件中,定义多个测试入口,并且连接到同一个可执行文件中。 后续在测试的时候,可以指定某一个测试入口执行。
您可以使用下方的例程来测试多入口功能,将下面的内容存为 multi-entrypoint.cpp
文件:
#include <wfuzz.h>
int add(int a, int b) {
return a + b;
}
int sub(int a, int b) {
return a - b;
}
WFUZZ_TEST_ENTRYPOINT(add);
WFUZZ_TEST_ENTRYPOINT(sub);
使用WINGFUZZ编译器编译上面的程序:
wfuzz-c++ -o multi-entrypoint multi-entrypoint.cpp
编译完成后,启动测试:
wfuzz fuzz multi-entrypoint
您会发现此时测试并未启动,而是显示了一个提示:
There are multiple candidate entries. Use -e/--entrypoint argument to choose one from them:
add
sub
这个错误提示的意思就是说该程序中有多个测试入口,需要用户指定一个入口才能开始测试。
wfuzz fuzz
命令支持用 -e
或 --entrypoint
指定测试入口。
如果想要测试其中的 add
函数,可以使用下面的命令:
wfuzz fuzz multi-entrypoint -e add
使用这个命令后,就可以开始测试了,此时平台上,进入应用multi-entrypoint后,看到正在测试的模块名称是add。
如果想要测试sub函数,将上面命令行参数改为 -e sub
即可
指定测试时间
由于模糊测试的运行是反复迭代的,因此可以一直运行下去。
默认的启动参数并未限制测试的时间,如果用户想要停止,只能使用 Ctrl-C
键中断当前的测试。
如果您想通过脚本自动运行模糊测试,一般情况您可能会希望测试跑一段时间后就停止。
我们提供了 -t
或 --timeout
参数,可以限制测试的运行时间。
该参数后面可以跟一个数字,单位是秒。
以【我的第一次模糊测试】章节中提供的运行命令为例, 如果想要加上时间限制,可以使用下面的命令:
wfuzz fuzz first-fuzz --timeout 300
这里限制了时间长度为300秒,运行到这个时间后就会结束测试。
并行化测试
使用默认参数启动测试的情况下,我们只会启动一个目标程序。 如果您的测试机器性能比较强,有比较多的核心可用于测试,则利用多核心测试可以明显的提高测试效率。
我们提供了 -j
或 --jobs
参数,可以设置测试的并行数量。该参数后面可以跟一个数字,数值就是并行的数量。
一般情况下,如果想要充分利用机器资源,可以使用(CPU数量-1)作为并行的数量,保留一个核心给WINGFUZZ SDK用于用例分析。
以【我的第一次模糊测试】章节中提供的运行命令为例, 如果想要加上并行测试,可以使用下面的命令:
wfuzz fuzz first-fuzz -j4
此时会同时启动4个模糊测试器和目标程序。 在网站上可以看到这4个模糊测试器的详细信息:
- 在网站上的“应用测试” -> “测试列表”中找到这个测试
- 点击列表最右边的“查看报告”链接。
- 在“测试详情” -> “节点分布数” 下方点击“查看详情”
- 在打开的页面中,可以看到模糊测试器列表,此处可以查看每个测试器的详细状态。
初始种子
模糊测试算法类似于遗传算法,会从一个简单的初始输入开始,进行一些随机的修改,生成新的输入。 最初用到的测试输入集合就是初始种子。 初始种子库对于测试效果的影响是比较明显的。
默认情况下,我们的模糊测试器会随机生成比较简单的初始输入。 但如果程序需要比较复杂的输入,此时默认初始种子的效果可能就不太好。 此时可以手动生成一些输入文件,用它们作为初始的种子。 例如,可以使用单元测试的输入样例,作为初始种子。
另一种情况是,我们的程序经过一段时间测试之后,会有一个代码覆盖率。 通过分析这个覆盖率可以检查测试的效果,是否覆盖到了我们关心的代码位置。 如果有我们关心的地方未覆盖到,说明这个分支的条件比较复杂,全自动的生成方式可能不容易进入这个分支。 此时,我们可以在初始种子中加入一个样例,这个样例可以覆盖到此分支。 后续的测试中,模糊测试器就会对这个样例进行修改变异,生成更多的样例,就能更好的测到这部分代码。
初始种子库是一个目录,这个目录中的每个文件会被系统视为一个种子。
以【我的第一次模糊测试】章节中提供的运行命令为例,
如果想要指定初始种子库,可以使用下面的命令,其中 DIR
是初始种子库的目录路径。
wfuzz fuzz first-fuzz -i DIR
项目/模块名称
项目模块名称是在网站上显示的名称。 在每次测试开始的时候,SDK会先从平台获取到之前跑过的输入样例,进行一次回归。 这个回归就是按照项目模块名称来查找的。
另外,我们在测出程序缺陷的时候,会进行去重,去重也是按照项目模块为单位进行的。 不属于同一个项目/模块的问题,即使内容完全一样,也不会被认为是重复的。
默认情况下,我们会使用可执行文件的名称作为项目名称, 使用测试函数的名称作为模块名称。 如果想要修改默认行为,可以使用以下的参数:
-p
/--project
参数可以设定项目名称。-m
/--module
参数可以设定模块名称。
以【我的第一次模糊测试】章节中提供的运行命令为例, 如果想要更换项目模块名称,可以使用下面的命令:
wfuzz fuzz first-fuzz -p first-fuzz-2 -m echo2
此时运行起来后,在平台上看到的项目名称就是 first-fuzz-2
,模块名称是 echo2
。
如果您之前启动过first-fuzz
,此时在平台上可以看到两个项目。
它们的数据是不同的,发现的缺陷也是分开的。