1#!/bin/bash 2 3# if you want a specific performance file (e.g. to compare features to another) 4# you can set the AFL_PERFORMANCE_FILE environment variable: 5FILE=$AFL_PERFORMANCE_FILE 6# otherwise we use ~/.afl_performance 7test -z "$FILE" && FILE=.afl_performance 8 9test -e $FILE || { 10 echo Warning: This script measure the performance of AFL++ and saves the result for future comparisons into $FILE 11 echo Press ENTER to continue or CONTROL-C to abort 12 read IN 13} 14 15test -e ./test-performance.sh || { echo Error: this script must be run from the directory in which it lies. ; exit 1 ; } 16 17export AFL_QUIET=1 18export AFL_PATH=`pwd`/.. 19 20unset AFL_EXIT_WHEN_DONE 21unset AFL_EXIT_ON_TIME 22unset AFL_SKIP_CPUFREQ 23unset AFL_DEBUG 24unset AFL_HARDEN 25unset AFL_USE_ASAN 26unset AFL_USE_MSAN 27unset AFL_CC 28unset AFL_PRELOAD 29unset AFL_GCC_INSTRUMENT_FILE 30unset AFL_LLVM_INSTRUMENT_FILE 31unset AFL_LLVM_INSTRIM 32unset AFL_LLVM_LAF_SPLIT_SWITCHES 33unset AFL_LLVM_LAF_TRANSFORM_COMPARES 34unset AFL_LLVM_LAF_SPLIT_COMPARES 35 36# on OpenBSD we need to work with llvm from /usr/local/bin 37test -e /usr/local/bin/opt && { 38 export PATH=/usr/local/bin:${PATH} 39} 40# on MacOS X we prefer afl-clang over afl-gcc, because 41# afl-gcc does not work there 42test `uname -s` = 'Darwin' -o `uname -s` = 'FreeBSD' && { 43 AFL_GCC=afl-clang 44 CC=clang 45} || { 46 AFL_GCC=afl-gcc 47 CC=gcc 48} 49 50ECHO="printf %b\\n" 51$ECHO \\101 2>&1 | grep -qE '^A' || { 52 ECHO= 53 test -e /bin/printf && { 54 ECHO="/bin/printf %b\\n" 55 $ECHO '\\101' 2>&1 | grep -qE '^A' || ECHO= 56 } 57} 58test -z "$ECHO" && { printf Error: printf command does not support octal character codes ; exit 1 ; } 59 60GREY="\\033[1;90m" 61BLUE="\\033[1;94m" 62GREEN="\\033[0;32m" 63RED="\\033[0;31m" 64YELLOW="\\033[1;93m" 65RESET="\\033[0m" 66 67MEM_LIMIT=500 68 69touch $FILE || { echo Error: can not write to $FILE ; exit 1 ; } 70 71echo Warning: this script is setting performance parameters with afl-system-config 72sleep 1 73afl-system-config > /dev/null 2>&1 74echo Performance settings applied. 75echo 76 77$ECHO "${RESET}${GREY}[*] starting AFL++ performance test framework ..." 78 79$ECHO "$BLUE[*] Testing: ${AFL_GCC}" 80GCC=x 81test -e ../${AFL_GCC} -a -e ../afl-fuzz && { 82 ../${AFL_GCC} -o test-instr.plain ../test-instr.c > /dev/null 2>&1 83 test -e test-instr.plain && { 84 $ECHO "$GREEN[+] ${AFL_GCC} compilation succeeded" 85 mkdir -p in 86 echo 0 > in/in 87 $ECHO "$GREY[*] running afl-fuzz for ${AFL_GCC} for 30 seconds" 88 { 89 ../afl-fuzz -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-gcc -- ./test-instr.plain 90 } >>errors 2>&1 91 test -n "$( ls out-gcc/default/queue/id:000002* 2> /dev/null )" && { 92 GCC=`grep execs_done out-gcc/default/fuzzer_stats | awk '{print$3}'` 93 } || { 94 echo CUT---------------------------------------------------------------- 95 cat errors 96 echo CUT---------------------------------------------------------------- 97 $ECHO "$RED[!] afl-fuzz is not working correctly with ${AFL_GCC}" 98 } 99 rm -rf in out-gcc errors test-instr.plain 100 } || $ECHO "$RED[!] ${AFL_GCC} instrumentation failed" 101} || $ECHO "$YELLOW[-] afl is not compiled, cannot test" 102 103$ECHO "$BLUE[*] Testing: llvm_mode" 104LLVM=x 105test -e ../afl-clang-fast -a -e ../afl-fuzz && { 106 ../afl-clang-fast -o test-instr.llvm ../test-instr.c > /dev/null 2>&1 107 test -e test-instr.llvm && { 108 $ECHO "$GREEN[+] llvm_mode compilation succeeded" 109 mkdir -p in 110 echo 0 > in/in 111 $ECHO "$GREY[*] running afl-fuzz for llvm_mode for 30 seconds" 112 { 113 ../afl-fuzz -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-llvm -- ./test-instr.llvm 114 } >>errors 2>&1 115 test -n "$( ls out-llvm/default/queue/id:000002* 2> /dev/null )" && { 116 LLVM=`grep execs_done out-llvm/default/fuzzer_stats | awk '{print$3}'` 117 } || { 118 echo CUT---------------------------------------------------------------- 119 cat errors 120 echo CUT---------------------------------------------------------------- 121 $ECHO "$RED[!] afl-fuzz is not working correctly with llvm_mode" 122 } 123 rm -rf in out-llvm errors test-instr.llvm 124 } || $ECHO "$RED[!] llvm_mode instrumentation failed" 125} || $ECHO "$YELLOW[-] llvm_mode is not compiled, cannot test" 126 127$ECHO "$BLUE[*] Testing: gcc_plugin" 128GCCP=x 129test -e ../afl-gcc-fast -a -e ../afl-fuzz && { 130 ../afl-gcc-fast -o test-instr.gccp ../test-instr.c > /dev/null 2>&1 131 test -e test-instr.gccp && { 132 $ECHO "$GREEN[+] gcc_plugin compilation succeeded" 133 mkdir -p in 134 echo 0 > in/in 135 $ECHO "$GREY[*] running afl-fuzz for gcc_plugin for 30 seconds" 136 { 137 ../afl-fuzz -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-gccp -- ./test-instr.gccp 138 } >>errors 2>&1 139 test -n "$( ls out-gccp/default/queue/id:000002* 2> /dev/null )" && { 140 GCCP=`grep execs_done out-gccp/default/fuzzer_stats | awk '{print$3}'` 141 } || { 142 echo CUT---------------------------------------------------------------- 143 cat errors 144 echo CUT---------------------------------------------------------------- 145 $ECHO "$RED[!] afl-fuzz is not working correctly with gcc_plugin" 146 } 147 rm -rf in out-gccp errors test-instr.gccp 148 } || $ECHO "$RED[!] gcc_plugin instrumentation failed" 149} || $ECHO "$YELLOW[-] gcc_plugin is not compiled, cannot test" 150 151$ECHO "$BLUE[*] Testing: qemu_mode" 152QEMU=x 153test -e ../afl-qemu-trace -a -e ../afl-fuzz && { 154 $CC -o test-instr.qemu ../test-instr.c > /dev/null 2>&1 155 test -e test-instr.qemu && { 156 $ECHO "$GREEN[+] native compilation with cc succeeded" 157 mkdir -p in 158 echo 0 > in/in 159 $ECHO "$GREY[*] running afl-fuzz for qemu_mode for 30 seconds" 160 { 161 ../afl-fuzz -Q -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-qemu -- ./test-instr.qemu 162 } >>errors 2>&1 163 test -n "$( ls out-qemu/default/queue/id:000002* 2> /dev/null )" && { 164 QEMU=`grep execs_done out-qemu/default/fuzzer_stats | awk '{print$3}'` 165 } || { 166 echo CUT---------------------------------------------------------------- 167 echo ../afl-fuzz -Q -V 30 -s 123 -m ${MEM_LIMIT} -i in -o out-qemu -- ./test-instr.qemu 168 cat errors 169 echo CUT---------------------------------------------------------------- 170 $ECHO "$RED[!] afl-fuzz is not working correctly with qemu_mode" 171 } 172 rm -rf in out-qemu errors test-instr.qemu 173 } || $ECHO "$RED[!] qemu_mode instrumentation failed" 174} || $ECHO "$YELLOW[-] qemu_mode is not compiled, cannot test" 175 176LOW_GCC= 177HIGH_GCC= 178LAST_GCC= 179LOW_LLVM= 180HIGH_LLVM= 181LAST_LLVM= 182LOW_GCCP= 183HIGH_GCCP= 184LAST_GCCP= 185LOW_QEMU= 186HIGH_QEMU= 187LAST_QEMU= 188 189test -s $FILE && { 190 while read LINE; do 191 G=`echo $LINE | awk '{print$1}'` 192 L=`echo $LINE | awk '{print$2}'` 193 P=`echo $LINE | awk '{print$3}'` 194 Q=`echo $LINE | awk '{print$4}'` 195 test "$G" = x && G= 196 test "$L" = x && L= 197 test "$P" = x && P= 198 test "$Q" = x && Q= 199 test -n "$G" && LAST_GCC=$G 200 test -n "$L" && LAST_LLVM=$L 201 test -n "$P" && LAST_GCCP=$P 202 test -n "$Q" && LAST_QEMU=$Q 203 test -n "$G" -a -z "$LOW_GCC" && LOW_GCC=$G || { 204 test -n "$G" -a "$G" -lt "$LOW_GCC" 2> /dev/null && LOW_GCC=$G 205 } 206 test -n "$L" -a -z "$LOW_LLVM" && LOW_LLVM=$L || { 207 test -n "$L" -a "$L" -lt "$LOW_LLVM" 2> /dev/null && LOW_LLVM=$L 208 } 209 test -n "$P" -a -z "$LOW_GCCP" && LOW_GCCP=$P || { 210 test -n "$P" -a "$P" -lt "$LOW_GCCP" 2> /dev/null && LOW_GCCP=$P 211 } 212 test -n "$Q" -a -z "$LOW_QEMU" && LOW_QEMU=$Q || { 213 test -n "$Q" -a "$Q" -lt "$LOW_QEMU" 2> /dev/null && LOW_QEMU=$Q 214 } 215 test -n "$G" -a -z "$HIGH_GCC" && HIGH_GCC=$G || { 216 test -n "$G" -a "$G" -gt "$HIGH_GCC" 2> /dev/null && HIGH_GCC=$G 217 } 218 test -n "$L" -a -z "$HIGH_LLVM" && HIGH_LLVM=$L || { 219 test -n "$L" -a "$L" -gt "$HIGH_LLVM" 2> /dev/null && HIGH_LLVM=$L 220 } 221 test -n "$P" -a -z "$HIGH_GCCP" && HIGH_GCCP=$P || { 222 test -n "$P" -a "$P" -gt "$HIGH_GCCP" 2> /dev/null && HIGH_GCCP=$P 223 } 224 test -n "$Q" -a -z "$HIGH_QEMU" && HIGH_QEMU=$Q || { 225 test -n "$Q" -a "$Q" -gt "$HIGH_QEMU" 2> /dev/null && HIGH_QEMU=$Q 226 } 227 done < $FILE 228 $ECHO "$YELLOW[!] Reading saved data from $FILE completed, please compare the results:" 229 $ECHO "$BLUE[!] afl-cc: lowest=$LOW_GCC highest=$HIGH_GCC last=$LAST_GCC current=$GCC" 230 $ECHO "$BLUE[!] llvm_mode: lowest=$LOW_LLVM highest=$HIGH_LLVM last=$LAST_LLVM current=$LLVM" 231 $ECHO "$BLUE[!] gcc_plugin: lowest=$LOW_GCCP highest=$HIGH_GCCP last=$LAST_GCCP current=$GCCP" 232 $ECHO "$BLUE[!] qemu_mode: lowest=$LOW_QEMU highest=$HIGH_QEMU last=$LAST_QEMU current=$QEMU" 233} || { 234 $ECHO "$YELLOW[!] First run, just saving data" 235 $ECHO "$BLUE[!] afl-gcc=$GCC llvm_mode=$LLVM gcc_plugin=$GCCP qemu_mode=$QEMU" 236} 237echo "$GCC $LLVM $GCCP $QEMU" >> $FILE 238$ECHO "$GREY[*] done." 239$ECHO "$RESET" 240