论文阅读_Same Coverage, Less Bloat: Accelerating Binary-only Fuzzing with Coverage-preserving Coverage-g

作者:Stefan Nagy(hawkeye的同一作者),Anh Nguyen-Tuong,Jason D. Hiser,Jack W. Davidson,Matthew Hicks
出处:CCS‘21

背景

  相比于源码插桩,二进制层面插桩来获取代码覆盖率效率很低。一些研究提出coverage-guided tracing(CGT)概念,也就是只有新的代码被覆盖的时候才收集代码覆盖率。然而,作者调查了27个fuzzer发现CGT只支持基本块覆盖,但是大部分的fuzzers依赖更细粒度的代码覆盖率指标的。也就是说这个概念很好但是没有被用起来。所以这篇论文将CGT应用到edge和hit count层面的代码覆盖率获取,解决了其中遇到的挑战和难题。
  简单介绍一下CGT的原理,如下图所示,给定一个目标程序,CGT会在这个程序的每个基本块周围插桩,插入一个中断。也就是说一旦输入覆盖了这个基本块,程序就会中断,这时候CGT把已覆盖的这条路径上的中断去掉。那么如果一个输入没有覆盖新的基本块,它运行的时候就不会中断,不需要获取trace。CGT在runtime overhead方面仅0.3%,但是能够提升5-6倍的fuzzing throughput。
在这里插入图片描述

方法设计

  作者提出了两个策略来实现edge和hit count层面的CGT。对于edge提出一个coverage-jump mistargeting,对hit count提出unrolling。

coverage-jump mistargeting

  相比于基本块层面的代码覆盖率,edge会更细粒度。比如有三个基本块A,B,C。分支A->B表示从A跳转到B,B->C同理。从基本模块角度A->B、B->C表示基本块A,B,C都被覆盖了,这时候如果有A->C它便不会认为是新的程序状态。但是edge层面就可以感知这一变化。
  针对这一问题,LLVM的SanitizerCoverage这个工具他会为这样的分支创建一个假的基本块,比如A->C这种情况它就会生成一个D,然后A->C就会转化成A->D,D->C。这样就会适配基本块层面代码覆盖率获取。然而,这么做会带来很大的开销。
  作者通过实验发现89%的类似A->C的分支是conditional jump,这时候edge的目的地址是在指令的操作数里面的,可以对其进行静态地修改去转向其它的edge,作者把这个操作叫“mistarget”。具体来说,x86中跳转指令有三种:short, near和far。前两个是同一个段内的跳转,涉及到PC以及偏移。far是段间的跳转通过绝对地址。

具体做法

把jump的目的地址改成触发中断。这样做不需要引入新的基本块。

  1. Embedded interrupts:让jump指向嵌入的中断,比如[00 CC]。这种方法的一个关键挑战(和瓶颈)是扫描跳转的位移范围内的字节空间有没有能利用的中断。
  2. Zero-address interrupts:让jump跳转到0x00,这个有一个限制是jump要有32-bit的替换空间,但大多数x86-64的分支都符合这一条件。

unrolling

  对于hit count,AFL-style的工具会划分8个区间0-1,2,3,4-7,8-15,16-31,32-127,128+。深挖的话,loops类型的代码是容易有hit count的变化的,但事实上我们只需要知道loop了几次并不需要监控每个基本块被覆盖的次数。

具体做法

  如下图所示,根据hit count的区间,在每个loop头加一些条件判断,每个条件判断会转到一个中断。
在这里插入图片描述

方法实现

  工具名称叫做HEXCITE,由三部分组成:二进制生成模块、控制流映射模块、模糊测试模块。

  1. 二进制生成模块:HEXCITE会生成两个二进制程序,一个是在每个基本快上加了中断的Oracle,另一个是tracer用来获取代码覆盖率的。需要用到静态二进制重写技术,HEXCITE在ZAFL的基础上进行了一些修改,满足本论文中需要的CGT功能。
  2. 控制流映射模块:当中断发生后,用这个输入跑tracer获取他覆盖的基本块编号,按照这个编号把Oracle里面对应的中断给去掉。
  3. 模糊测试模块:在AFL的基础上做了修改,就是不对每一个输入trace,改为先跑Oracle如果中断了,就用tracer再跑一遍获取代码覆盖信息,然后加入到queue里面。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值