AFL的覆盖率分析
AFL是逃不过的,看一看看一看。
找起来才发现,AFL的插入位置感觉并不多
覆盖率
https://github.com/mrash/afl-cov 这是一款显示AFL实时覆盖率信息的工具,显示Lines,Functions和Branches
分支信息
AFL使用二元元组进行分支流程的记录。
AFL对每个插桩处生成一个0到MAP_SIZE之间的随机数,为这一块的位置记录。
AFL会保存期前一个位置的信息__afl_prev_loc ,然后与当前位置异或,为分支的对应信息。
" movl __afl_prev_loc, %edi\n"
" xorl %ecx, %edi\n"
" shrl $1, %ecx\n"
" movl %ecx, __afl_prev_loc\n"
上述代码中,ecx为当前位置生成的随机数,AFL会将当前位置右移1位之后再保存在__afl_prev_loc里,官方解释这是用于使A->A这样的跳转不为0,也是为了区分A->B和B->A。
AFL使用hashmap来存储这些随机数,该hashmap保存在共享内存中,且AFL还会在界面中显示出当前hashmap的密度。如果密度过大,那碰撞概率就会很高,解决方案见官方文档。
在每次调用__afl_maybe_log
或者__afl_maybe_log0
来进行该处执行信息的记录的时候,都会先mov一个数到rcx,这就是那个随机数。
crash去重
在crash去重方面,AFL是采用这样的方法:如果符合下列情况之一,认为其唯一:
- The crash trace includes a tuple not seen in any of the previous crashes
- The crash trace is missing a tuple that was always present in earlier faults.