#!/bin/sh # # american fuzzy lop++ - Advanced Persistent Graphing # ------------------------------------------------- # # Originally written by Michal Zalewski # Based on a design & prototype by Michael Rash. # # Copyright 2014, 2015 Google Inc. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. # You may obtain a copy of the License at: # # http://www.apache.org/licenses/LICENSE-2.0 # get_abs_path() { echo $(cd "`dirname "$1"`" && pwd)/"`basename "$1"`" } echo "progress plotting utility for afl-fuzz by Michal Zalewski" echo if [ ! "$#" = "2" ]; then cat 1>&2 <<_EOF_ $0 afl_state_dir graph_output_dir This program generates gnuplot images from afl-fuzz output data. Usage: The afl_state_dir parameter should point to an existing state directory for any active or stopped instance of afl-fuzz; while graph_output_dir should point to an empty directory where this tool can write the resulting plots to. The program will put index.html and three PNG images in the output directory; you should be able to view it with any web browser of your choice. _EOF_ exit 1 fi inputdir=`get_abs_path "$1"` outputdir=`get_abs_path "$2"` #if [ "$AFL_ALLOW_TMP" = "" ]; then # # echo "$inputdir" | grep -qE '^(/var)?/tmp/' # T1="$?" # # echo "$outputdir" | grep -qE '^(/var)?/tmp/' # T2="$?" # # if [ "$T1" = "0" -o "$T2" = "0" ]; then # # echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2 # exit 1 # # fi # #fi if [ ! -f "$inputdir/plot_data" ]; then echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2 exit 1 fi LINES=`cat "$inputdir/plot_data" | wc -l` if [ "$LINES" -lt 3 ]; then echo "[-] Error: plot_data carries too little data, let it run longer." 1>&2 exit 1 fi BANNER="`cat "$inputdir/fuzzer_stats" 2> /dev/null | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`" test "$BANNER" = "" && BANNER="(none)" GNUPLOT=`command -v gnuplot 2>/dev/null` if [ "$GNUPLOT" = "" ]; then echo "[-] Error: can't find 'gnuplot' in your \$PATH." 1>&2 exit 1 fi mkdir "$outputdir" 2>/dev/null if [ ! -d "$outputdir" ]; then echo "[-] Error: unable to create the output directory - pick another location." 1>&2 exit 1 fi rm -f "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" mv -f "$outputdir/index.html" "$outputdir/index.html.orig" 2>/dev/null echo "[*] Generating plots..." ( cat <<_EOF_ set terminal png truecolor enhanced size 1000,300 butt set output '$outputdir/high_freq.png' set xdata time set timefmt '%s' set format x "%b %d\n%H:%M" set tics font 'small' unset mxtics unset mytics set grid xtics linetype 0 linecolor rgb '#e0e0e0' set grid ytics linetype 0 linecolor rgb '#e0e0e0' set border linecolor rgb '#50c0f0' set tics textcolor rgb '#000000' set key outside set autoscale xfixmin set autoscale xfixmax set xlabel "all times in UTC" font "small" set ytics auto plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'total paths' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ '' using 1:3 with filledcurve x1 title 'current path' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ '' using 1:5 with lines title 'pending paths' linecolor rgb '#0090ff' linewidth 3, \\ '' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\ '' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3 set terminal png truecolor enhanced size 1000,200 butt set output '$outputdir/low_freq.png' set ytics 1 plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\ '' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\ '' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\ '' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3 set terminal png truecolor enhanced size 1000,200 butt set output '$outputdir/exec_speed.png' set ytics auto plot '$inputdir/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\ '$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier; _EOF_ ) | gnuplot if [ ! -s "$outputdir/exec_speed.png" ]; then echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2 exit 1 fi echo "[*] Generating index.html..." cat >"$outputdir/index.html" <<_EOF_
Banner:$BANNER
Directory:$inputdir
Generated on:`date`

_EOF_ # Make it easy to remotely view results when outputting directly to a directory # served by Apache or other HTTP daemon. Since the plots aren't horribly # sensitive, this seems like a reasonable trade-off. chmod 755 "$outputdir" chmod 644 "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/index.html" echo "[+] All done - enjoy your charts!" exit 0