Fast Cov
Fast binary coverage using Qemu and a Forkserver
You want to inspect the coverage produced by your fuzzer, but kcov/gcov are slow and require special builds of the target? You misplaced the sourcecode and can’t even build the target with coverage instrumentation?
cov.py to the rescue!
Based on AFL’s Qemu mode, cov.py quickly produces edge coverage information on binary targets. It uses the AFL’s forkserver to speed up coverage calculation massively and generates precise trace files.
Setup
git@github.com:eqv/aflq_fast_cov.git
cd aflq_fast_cov.git
sh build_qemu.sh
Usage
$ python cov.py -h
usage: cov.py [-h] -i input_folder -o output_folder -m wordize [-t [timeout]]
...
Fast Forkserver Base Binary Coverage
positional arguments:
... Command to run, @@ is replaced by input file
optional arguments:
-h, --help show this help message and exit
-i input_folder Where to look for input files
-o output_folder Where to store the trace files
-m wordize Architecture to use for QEMU
-t [timeout] Timeout in seconds
$ python cov.py -i workdir/in -o workdir/out -m64 workdir/test
Running workdir/test with timeout 1.000000 on 3 inputs
run workdir/in/a
run workdir/in/c
run workdir/in/b
Output Format
cov.py
create one or more input_$(input_basename)_thread_$(threadid).qemu
trace files per input file and thread used by the target.
# input: in/test1 -. .- Thread: 10702
# v v
$ cat out/input_test1_thread_10702.qemu
Each .qemu
trace file contains all CFG edges in the order they were encountered by the given thread.
The format is src_bb_entry_addr, dst_bb_entry_addr, dst_bb_size
. The addresses are in hex, the size in decimal. The
basic block “ffffffffffffffff” encodes any basic block outside of the trace region.
$ cat out/input_test1_thread_10702.qemu
ffffffffffffffff,400550,41 # jump to the basic block at 0x400550 with size 41 from outside of the trace region
400550,400520,6 # jump to the basic block at 0x400520 with size 41 from the cofi at the end of 0x400550
400520,400526,10
400526,4004e0,12
4004e0,ffffffffffffffff,67 # program exits trace range, (e.g. call a library)
ffffffffffffffff,400770,49 # library returns to the program
400770,4004b8,16
...