1#!/bin/sh 2# 3# american fuzzy lop++ - Advanced Persistent Graphing 4# ------------------------------------------------- 5# 6# Originally written by Michal Zalewski 7# Based on a design & prototype by Michael Rash. 8# 9# Copyright 2014, 2015 Google Inc. All rights reserved. 10# 11# Licensed under the Apache License, Version 2.0 (the "License"); 12# you may not use this file except in compliance with the License. 13# You may obtain a copy of the License at: 14# 15# https://www.apache.org/licenses/LICENSE-2.0 16# 17 18get_abs_path() { 19 echo $(cd "`dirname "$1"`" && pwd)/"`basename "$1"`" 20} 21 22echo "progress plotting utility for afl-fuzz by Michal Zalewski" 23echo 24 25GRAPHICAL="0" 26 27if [ "$1" = "-g" ] || [ "$1" = "--graphical" ]; then 28GRAPHICAL="1" 29shift 30fi 31 32if [ "$#" != "2" ]; then 33 34 cat 1>&2 <<_EOF_ 35$0 [ -g | --graphical ] afl_state_dir graph_output_dir 36 37This program generates gnuplot images from afl-fuzz output data. 38 39Usage: 40 41 afl_state_dir should point to an existing state directory for any 42 active or stopped instance of afl-fuzz 43 graph_output_dir should point to an empty directory where this 44 tool can write the resulting plots to 45 -g, --graphical (optional) display the plots in a graphical window 46 (you should have built afl-plot-ui to use this option) 47 48The program will put index.html and three PNG images in the output directory; 49you should be able to view it with any web browser of your choice. 50_EOF_ 51 52 exit 1 53 54fi 55 56inputdir=`get_abs_path "$1"` 57outputdir=`get_abs_path "$2"` 58 59#if [ "$AFL_ALLOW_TMP" = "" ]; then 60# 61# echo "$inputdir" | grep -qE '^(/var)?/tmp/' 62# T1="$?" 63# 64# echo "$outputdir" | grep -qE '^(/var)?/tmp/' 65# T2="$?" 66# 67# if [ "$T1" = "0" -o "$T2" = "0" ]; then 68# 69# echo "[-] Error: this script shouldn't be used with shared /tmp directories." 1>&2 70# exit 1 71# 72# fi 73# 74#fi 75 76if [ ! -f "$inputdir/plot_data" ]; then 77 78 if [ -f "$inputdir/default/plot_data" ]; then 79 80 echo "[-] Error: input directory is not valid (missing 'plot_data'), likely you mean $inputdir/default?" 1>&2 81 exit 1 82 83 else 84 85 echo "[-] Error: input directory is not valid (missing 'plot_data')." 1>&2 86 exit 1 87 88 fi 89 90fi 91 92LINES=`cat "$inputdir/plot_data" | wc -l` 93 94if [ "$LINES" -lt 3 ]; then 95 96 echo "[-] Error: plot_data carries too little data, let it run longer." 1>&2 97 exit 1 98 99fi 100 101BANNER="`cat "$inputdir/fuzzer_stats" 2> /dev/null | grep '^afl_banner ' | cut -d: -f2- | cut -b2-`" 102 103test "$BANNER" = "" && BANNER="(none)" 104 105GNUPLOT=`command -v gnuplot 2>/dev/null` 106 107if [ "$GNUPLOT" = "" ]; then 108 109 echo "[-] Error: can't find 'gnuplot' in your \$PATH." 1>&2 110 exit 1 111 112fi 113 114mkdir "$outputdir" 2>/dev/null 115 116if [ ! -d "$outputdir" ]; then 117 118 echo "[-] Error: unable to create the output directory - pick another location." 1>&2 119 exit 1 120 121fi 122 123rm -f "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/edges.png" 124mv -f "$outputdir/index.html" "$outputdir/index.html.orig" 2>/dev/null 125 126GNUPLOT_SETUP=" 127#set xdata time 128#set timefmt '%s' 129#set format x \"%b %d\n%H:%M\" 130set tics font 'small' 131unset mxtics 132unset mytics 133 134set grid xtics linetype 0 linecolor rgb '#e0e0e0' 135set grid ytics linetype 0 linecolor rgb '#e0e0e0' 136set border linecolor rgb '#50c0f0' 137set tics textcolor rgb '#000000' 138set key outside 139 140set autoscale xfixmin 141set autoscale xfixmax 142 143set xlabel \"relative time in seconds\" font \"small\" 144" 145 146PLOT_HF=" 147set terminal png truecolor enhanced size 1000,300 butt 148set output '$outputdir/high_freq.png' 149 150$GNUPLOT_SETUP 151 152plot '$inputdir/plot_data' using 1:4 with filledcurve x1 title 'corpus count' linecolor rgb '#000000' fillstyle transparent solid 0.2 noborder, \\ 153 '' using 1:3 with filledcurve x1 title 'current item' linecolor rgb '#f0f0f0' fillstyle transparent solid 0.5 noborder, \\ 154 '' using 1:5 with lines title 'pending items' linecolor rgb '#0090ff' linewidth 3, \\ 155 '' using 1:6 with lines title 'pending favs' linecolor rgb '#c00080' linewidth 3, \\ 156 '' using 1:2 with lines title 'cycles done' linecolor rgb '#c000f0' linewidth 3 157" 158 159PLOT_LF=" 160set terminal png truecolor enhanced size 1000,200 butt 161set output '$outputdir/low_freq.png' 162 163$GNUPLOT_SETUP 164 165plot '$inputdir/plot_data' using 1:8 with filledcurve x1 title '' linecolor rgb '#c00080' fillstyle transparent solid 0.2 noborder, \\ 166 '' using 1:8 with lines title ' uniq crashes' linecolor rgb '#c00080' linewidth 3, \\ 167 '' using 1:9 with lines title 'uniq hangs' linecolor rgb '#c000f0' linewidth 3, \\ 168 '' using 1:10 with lines title 'levels' linecolor rgb '#0090ff' linewidth 3 169" 170 171PLOT_ES=" 172set terminal png truecolor enhanced size 1000,200 butt 173set output '$outputdir/exec_speed.png' 174 175$GNUPLOT_SETUP 176 177plot '$inputdir/plot_data' using 1:11 with filledcurve x1 title '' linecolor rgb '#0090ff' fillstyle transparent solid 0.2 noborder, \\ 178 '$inputdir/plot_data' using 1:11 with lines title ' execs/sec' linecolor rgb '#0090ff' linewidth 3 smooth bezier; 179" 180 181PLOT_EG=" 182set terminal png truecolor enhanced size 1000,300 butt 183set output '$outputdir/edges.png' 184 185$GNUPLOT_SETUP 186 187plot '$inputdir/plot_data' using 1:13 with lines title ' edges' linecolor rgb '#0090ff' linewidth 3 188" 189 190if [ "$#" = "2" ] && [ "$GRAPHICAL" = "1" ]; then 191 192afl-plot-ui -h > /dev/null 2>&1 193 194if [ "$?" != "0" ]; then 195 196cat 1>&2 <<_EOF_ 197You do not seem to have the afl-plot-ui utility installed. If you have installed afl-plot-ui, make sure the afl-plot-ui executable is in your PATH. 198If you are still facing any problems, please open an issue at https://github.com/AFLplusplus/AFLplusplus/issues. 199 200No plots have been generated. Please rerun without the "-g" or "--graphical" flag to generate the plots. 201_EOF_ 202 203exit 1 204 205fi 206 207rm -rf "$outputdir/.tmp" 208mkdir -p "$outputdir/.tmp" 209mkfifo "$outputdir/.tmp/win_ids" || exit 1 210 211afl-plot-ui > "$outputdir/.tmp/win_ids" & 212W_IDS=$(cat "$outputdir/.tmp/win_ids") 213 214rm -rf "$outputdir/.tmp" 215 216W_ID1=$(echo "$W_IDS" | head -n 1) 217W_ID2=$(echo "$W_IDS" | head -n 2 | tail -n 1) 218W_ID3=$(echo "$W_IDS" | head -n 3 | tail -n 1) 219W_ID4=$(echo "$W_IDS" | tail -n 1) 220 221echo "[*] Generating plots..." 222 223( 224 225cat << _EOF_ 226 227$PLOT_HF 228set term x11 window "$W_ID3" 229set output 230replot 231pause mouse close 232 233_EOF_ 234 235) | gnuplot 2> /dev/null & 236 237( 238 239cat << _EOF_ 240 241$PLOT_LF 242set term x11 window "$W_ID4" 243set output 244replot 245pause mouse close 246 247_EOF_ 248 249) | gnuplot 2> /dev/null & 250 251( 252 253cat << _EOF_ 254 255$PLOT_ES 256set term x11 window "$W_ID2" 257set output 258replot 259pause mouse close 260 261_EOF_ 262 263) | gnuplot 2> /dev/null & 264 265( 266 267cat << _EOF_ 268 269$PLOT_EG 270set term x11 window "$W_ID1" 271set output 272replot 273pause mouse close 274 275_EOF_ 276 277) | gnuplot 2> /dev/null & 278 279sleep 1 280 281else 282 283echo "[*] Generating plots..." 284 285( 286 287cat << _EOF_ 288 289$PLOT_HF 290 291$PLOT_LF 292 293$PLOT_ES 294 295$PLOT_EG 296 297_EOF_ 298 299) | gnuplot || echo "Note: if you see errors concerning 'unknown or ambiguous terminal type' then you need to use a gnuplot that has png support compiled in." 300 301echo "[?] You can also use -g flag to view the plots in an GUI window, and interact with the plots (if you have built afl-plot-ui). Run \"afl-plot -h\" to know more." 302 303fi 304 305if [ ! -s "$outputdir/exec_speed.png" ]; then 306 307 echo "[-] Error: something went wrong! Perhaps you have an ancient version of gnuplot?" 1>&2 308 exit 1 309 310fi 311 312echo "[*] Generating index.html..." 313 314cat >"$outputdir/index.html" <<_EOF_ 315<table style="font-family: 'Trebuchet MS', 'Tahoma', 'Arial', 'Helvetica'"> 316<tr><td style="width: 18ex"><b>Banner:</b></td><td>$BANNER</td></tr> 317<tr><td><b>Directory:</b></td><td>$inputdir</td></tr> 318<tr><td><b>Generated on:</b></td><td>`date`</td></tr> 319</table> 320<p> 321<img src="edges.png" width=1000 height=300> 322<img src="high_freq.png" width=1000 height=300><p> 323<img src="low_freq.png" width=1000 height=200><p> 324<img src="exec_speed.png" width=1000 height=200> 325 326_EOF_ 327 328# Make it easy to remotely view results when outputting directly to a directory 329# served by Apache or other HTTP daemon. Since the plots aren't horribly 330# sensitive, this seems like a reasonable trade-off. 331 332chmod 755 "$outputdir" 333chmod 644 "$outputdir/high_freq.png" "$outputdir/low_freq.png" "$outputdir/exec_speed.png" "$outputdir/edges.png" "$outputdir/index.html" 334 335echo "[+] All done - enjoy your charts!" 336 337exit 0 338