本文档提供了American Fuzzy Lop的简单的概述,原文

想了解一般的使用说明,请参见README

想了解AFL背后的动机和设计目标,请参见historical_notes.txt

0.设计说明(Design statement)

American Fuzzy Lop 不关注任何单一的操作规则(singular principle of operation),也不是一个针对任何特定理论的概念验证(proof of concept)。这个工具可以被认为是一系列在实践中测试过的hacks行为,我们发现这个工具惊人的有效。我们用目前最simple且最robust的方法实现了这个工具。

..

1.覆盖率计算(Coverage measurements)

在编译程序中注入的插桩(instrumentation)能够捕获分支(边缘)覆盖率,并且还能检测到粗略的分支执行命中次数(branch-taken hit counts)。在分支点注入的代码大致如下:

cur_location = <COMPILE_TIME_RANDOM>; shared_mem[cur_location ^ prev_location]++; prev_location = cur_location >> 1;

cur_location的值是随机产生的,为的是简化连接复杂对象的过程和保持XOR输出分布是均匀的。

shared_mem[] 数组是一个调用者 (caller) 传给被插桩的二进制程序的64kb的共享空间。其中的每一位可以理解成对于特别的(branch_src, branch_dst)式的tuple的一次命中(hit)。

选择这个数组大小的原因是让冲突(collisions)尽可能减少。这样通常能处理2k到10k的分支点。同时,它的大小也足以达到毫秒级的分析。

https://s3-us-west-2.amazonaws.com/secure.notion-static.com/4739916b-d01e-4152-95ce-51615c849919/Untitled.png

这种形式的覆盖率,相对于简单的基本块覆盖率来说,对程序运行路径提供了一个更好的描述(insight)。特别地,它能很好地区分以下两个执行路径:

A -> B -> C -> D -> E (tuples: AB, BC, CD, DE) A -> B -> D -> C -> E (tuples: AB, BD, DC, CE)

这有助于发现底层代码的微小错误条件。因为安全漏洞通常是一些非预期(或不正确)的语句转移(一个tuple就是一个语句转移),而不是没覆盖到某块代码。

上边伪代码的最后一行移位操作是为了让tuple具有定向性(没有这一行的话,AB和BA就没区别了,同样,AA和BB也没区别了)。采用左移的原因跟Intel CPU的一些特性有关。

2.发现新路径(Detecting new behaviors)