ChoiceTable的内容:环境信息、call-to-call的优先级以及当前可用的系统调用集合。
runs[X][Y]
。runs[X]!=nil
。ChoiceTable的作用:基于call-to-call的优先级和当前可用的系统调用集合,针对某个给定的系统调用,去加权选择一个系统调用。
call-to-call的优先级由静态优先级和动态优先级两部分组成,后者的计算依赖于 Corpus
,两者计算完毕后相加即可。
静态优先级的计算是基于对系统调用对的参数类型的分析,如果系统调用X和Y都接受相同类型的参数,那么包含它们的Prog更有可能出现新覆盖。
静态优先级的计算过程:
uses的类型是map[string]map[int]weights,weights结构体包含系统调用编号以及in和inout权值,含义是uses[参数类型/返回值类型][系统调用编号]=weights。
动态优先级的计算是基于系统调用对出现在同一个Prog的情况在Corpus中的频率,如果系统调用对出现在同一个Prog的情况在Corpus中很常见,那么就会拥有更高的优先级。
动态优先级的计算过程:
当需要读ChoiceTable(生成或变异Prog),且当Corpus中的程序增多n个时,fuzzer会更新ChoiceTable。
ChoiceTable的更新过程:
在生成Prog和Prog变异(插入一个系统调用)时,会需要生成系统调用,此时会从ChoiceTable中加权选择系统调用Y。
加权选择的过程:
runs[X]
进行加权选择。关于指定系统调用X:
- 如果是生成Prog,那么就是随机指定一个系统调用X;
- 如果是Prog变异(插入一个系统调用),那么首先会随机选择一个要插入的位置idx(越靠后被选中的概率越大),然后从Prog的头到idx之间随机选择一个系统调用X。