1*08b48e0bSAndroid Build Coastguard Worker#!/usr/bin/env sh 2*08b48e0bSAndroid Build Coastguard WorkerSYS=$(uname -s) 3*08b48e0bSAndroid Build Coastguard Workertest "$SYS" = "Darwin" && { 4*08b48e0bSAndroid Build Coastguard Worker echo Error: afl-cmin does not work on Apple currently. please use afl-cmin.bash instead. 5*08b48e0bSAndroid Build Coastguard Worker exit 1 6*08b48e0bSAndroid Build Coastguard Worker} 7*08b48e0bSAndroid Build Coastguard Workerexport AFL_QUIET=1 8*08b48e0bSAndroid Build Coastguard Workerexport ASAN_OPTIONS=detect_leaks=0 9*08b48e0bSAndroid Build Coastguard WorkerTHISPATH=`dirname ${0}` 10*08b48e0bSAndroid Build Coastguard Workerexport PATH="${THISPATH}:$PATH" 11*08b48e0bSAndroid Build Coastguard Workerawk -f - -- ${@+"$@"} <<'EOF' 12*08b48e0bSAndroid Build Coastguard Worker#!/usr/bin/awk -f 13*08b48e0bSAndroid Build Coastguard Worker# awk script to minimize a test corpus of input files 14*08b48e0bSAndroid Build Coastguard Worker# 15*08b48e0bSAndroid Build Coastguard Worker# based on afl-cmin bash script written by Michal Zalewski 16*08b48e0bSAndroid Build Coastguard Worker# rewritten by Heiko Eißfeldt (hexcoder-) 17*08b48e0bSAndroid Build Coastguard Worker# tested with: 18*08b48e0bSAndroid Build Coastguard Worker# gnu awk (x86 Linux) 19*08b48e0bSAndroid Build Coastguard Worker# bsd awk (x86 *BSD) 20*08b48e0bSAndroid Build Coastguard Worker# mawk (arm32 raspbian) 21*08b48e0bSAndroid Build Coastguard Worker# 22*08b48e0bSAndroid Build Coastguard Worker# uses getopt.awk package from Arnold Robbins 23*08b48e0bSAndroid Build Coastguard Worker# 24*08b48e0bSAndroid Build Coastguard Worker# external tools used by this script: 25*08b48e0bSAndroid Build Coastguard Worker# test 26*08b48e0bSAndroid Build Coastguard Worker# grep 27*08b48e0bSAndroid Build Coastguard Worker# rm 28*08b48e0bSAndroid Build Coastguard Worker# mkdir 29*08b48e0bSAndroid Build Coastguard Worker# ln 30*08b48e0bSAndroid Build Coastguard Worker# cp 31*08b48e0bSAndroid Build Coastguard Worker# pwd 32*08b48e0bSAndroid Build Coastguard Worker# type 33*08b48e0bSAndroid Build Coastguard Worker# cd 34*08b48e0bSAndroid Build Coastguard Worker# find 35*08b48e0bSAndroid Build Coastguard Worker# stat 36*08b48e0bSAndroid Build Coastguard Worker# sort 37*08b48e0bSAndroid Build Coastguard Worker# cut 38*08b48e0bSAndroid Build Coastguard Worker# and afl-showmap from this project :-) 39*08b48e0bSAndroid Build Coastguard Worker 40*08b48e0bSAndroid Build Coastguard Worker# getopt.awk --- Do C library getopt(3) function in awk 41*08b48e0bSAndroid Build Coastguard Worker 42*08b48e0bSAndroid Build Coastguard Worker# External variables: 43*08b48e0bSAndroid Build Coastguard Worker# Optind -- index in ARGV of first nonoption argument 44*08b48e0bSAndroid Build Coastguard Worker# Optarg -- string value of argument to current option 45*08b48e0bSAndroid Build Coastguard Worker# Opterr -- if nonzero, print our own diagnostic 46*08b48e0bSAndroid Build Coastguard Worker# Optopt -- current option letter 47*08b48e0bSAndroid Build Coastguard Worker 48*08b48e0bSAndroid Build Coastguard Worker# Returns: 49*08b48e0bSAndroid Build Coastguard Worker# -1 at end of options 50*08b48e0bSAndroid Build Coastguard Worker# "?" for unrecognized option 51*08b48e0bSAndroid Build Coastguard Worker# <c> a character representing the current option 52*08b48e0bSAndroid Build Coastguard Worker 53*08b48e0bSAndroid Build Coastguard Worker# Private Data: 54*08b48e0bSAndroid Build Coastguard Worker# _opti -- index in multiflag option, e.g., -abc 55*08b48e0bSAndroid Build Coastguard Worker 56*08b48e0bSAndroid Build Coastguard Workerfunction getopt(argc, argv, options, thisopt, i) 57*08b48e0bSAndroid Build Coastguard Worker{ 58*08b48e0bSAndroid Build Coastguard Worker if (length(options) == 0) # no options given 59*08b48e0bSAndroid Build Coastguard Worker return -1 60*08b48e0bSAndroid Build Coastguard Worker 61*08b48e0bSAndroid Build Coastguard Worker if (argv[Optind] == "--") { # all done 62*08b48e0bSAndroid Build Coastguard Worker Optind++ 63*08b48e0bSAndroid Build Coastguard Worker _opti = 0 64*08b48e0bSAndroid Build Coastguard Worker return -1 65*08b48e0bSAndroid Build Coastguard Worker } else if (argv[Optind] !~ /^-[^:\t ]/) { 66*08b48e0bSAndroid Build Coastguard Worker _opti = 0 67*08b48e0bSAndroid Build Coastguard Worker return -1 68*08b48e0bSAndroid Build Coastguard Worker } 69*08b48e0bSAndroid Build Coastguard Worker if (_opti == 0) 70*08b48e0bSAndroid Build Coastguard Worker _opti = 2 71*08b48e0bSAndroid Build Coastguard Worker thisopt = substr(argv[Optind], _opti, 1) 72*08b48e0bSAndroid Build Coastguard Worker Optopt = thisopt 73*08b48e0bSAndroid Build Coastguard Worker i = index(options, thisopt) 74*08b48e0bSAndroid Build Coastguard Worker if (i == 0) { 75*08b48e0bSAndroid Build Coastguard Worker if (Opterr) 76*08b48e0bSAndroid Build Coastguard Worker printf("%c -- invalid option\n", thisopt) > "/dev/stderr" 77*08b48e0bSAndroid Build Coastguard Worker if (_opti >= length(argv[Optind])) { 78*08b48e0bSAndroid Build Coastguard Worker Optind++ 79*08b48e0bSAndroid Build Coastguard Worker _opti = 0 80*08b48e0bSAndroid Build Coastguard Worker } else 81*08b48e0bSAndroid Build Coastguard Worker _opti++ 82*08b48e0bSAndroid Build Coastguard Worker return "?" 83*08b48e0bSAndroid Build Coastguard Worker } 84*08b48e0bSAndroid Build Coastguard Worker if (substr(options, i + 1, 1) == ":") { 85*08b48e0bSAndroid Build Coastguard Worker # get option argument 86*08b48e0bSAndroid Build Coastguard Worker if (length(substr(argv[Optind], _opti + 1)) > 0) 87*08b48e0bSAndroid Build Coastguard Worker Optarg = substr(argv[Optind], _opti + 1) 88*08b48e0bSAndroid Build Coastguard Worker else 89*08b48e0bSAndroid Build Coastguard Worker Optarg = argv[++Optind] 90*08b48e0bSAndroid Build Coastguard Worker _opti = 0 91*08b48e0bSAndroid Build Coastguard Worker } else 92*08b48e0bSAndroid Build Coastguard Worker Optarg = "" 93*08b48e0bSAndroid Build Coastguard Worker if (_opti == 0 || _opti >= length(argv[Optind])) { 94*08b48e0bSAndroid Build Coastguard Worker Optind++ 95*08b48e0bSAndroid Build Coastguard Worker _opti = 0 96*08b48e0bSAndroid Build Coastguard Worker } else 97*08b48e0bSAndroid Build Coastguard Worker _opti++ 98*08b48e0bSAndroid Build Coastguard Worker return thisopt 99*08b48e0bSAndroid Build Coastguard Worker} 100*08b48e0bSAndroid Build Coastguard Worker 101*08b48e0bSAndroid Build Coastguard Workerfunction usage() { 102*08b48e0bSAndroid Build Coastguard Worker print \ 103*08b48e0bSAndroid Build Coastguard Worker"afl-cmin [ options ] -- /path/to/target_app [ ... ]\n" \ 104*08b48e0bSAndroid Build Coastguard Worker"\n" \ 105*08b48e0bSAndroid Build Coastguard Worker"Required parameters:\n" \ 106*08b48e0bSAndroid Build Coastguard Worker" -i dir - input directory with starting corpus\n" \ 107*08b48e0bSAndroid Build Coastguard Worker" -o dir - output directory for minimized files\n" \ 108*08b48e0bSAndroid Build Coastguard Worker"\n" \ 109*08b48e0bSAndroid Build Coastguard Worker"Execution control settings:\n" \ 110*08b48e0bSAndroid Build Coastguard Worker" -T tasks - how many parallel tasks to run (default: 1, all=nproc)\n" \ 111*08b48e0bSAndroid Build Coastguard Worker" -f file - location read by the fuzzed program (stdin)\n" \ 112*08b48e0bSAndroid Build Coastguard Worker" -m megs - memory limit for child process ("mem_limit" MB)\n" \ 113*08b48e0bSAndroid Build Coastguard Worker" -t msec - run time limit for child process (default: 5000)\n" \ 114*08b48e0bSAndroid Build Coastguard Worker" -O - use binary-only instrumentation (FRIDA mode)\n" \ 115*08b48e0bSAndroid Build Coastguard Worker" -Q - use binary-only instrumentation (QEMU mode)\n" \ 116*08b48e0bSAndroid Build Coastguard Worker" -U - use unicorn-based instrumentation (unicorn mode)\n" \ 117*08b48e0bSAndroid Build Coastguard Worker" -X - use Nyx mode\n" \ 118*08b48e0bSAndroid Build Coastguard Worker"\n" \ 119*08b48e0bSAndroid Build Coastguard Worker"Minimization settings:\n" \ 120*08b48e0bSAndroid Build Coastguard Worker" -A - allow crashes and timeouts (not recommended)\n" \ 121*08b48e0bSAndroid Build Coastguard Worker" -C - keep crashing inputs, reject everything else\n" \ 122*08b48e0bSAndroid Build Coastguard Worker" -e - solve for edge coverage only, ignore hit counts\n" \ 123*08b48e0bSAndroid Build Coastguard Worker"\n" \ 124*08b48e0bSAndroid Build Coastguard Worker"For additional tips, please consult README.md\n" \ 125*08b48e0bSAndroid Build Coastguard Worker"\n" \ 126*08b48e0bSAndroid Build Coastguard Worker"Environment variables used:\n" \ 127*08b48e0bSAndroid Build Coastguard Worker"AFL_CRASH_EXITCODE: optional child exit code to be interpreted as crash\n" \ 128*08b48e0bSAndroid Build Coastguard Worker"AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \ 129*08b48e0bSAndroid Build Coastguard Worker"AFL_KEEP_TRACES: leave the temporary <out_dir>/.traces directory\n" \ 130*08b48e0bSAndroid Build Coastguard Worker"AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \ 131*08b48e0bSAndroid Build Coastguard Worker"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on\n" \ 132*08b48e0bSAndroid Build Coastguard Worker" termination (default: SIGTERM). If this is not set and AFL_KILL_SIGNAL is\n" \ 133*08b48e0bSAndroid Build Coastguard Worker" set, this will be set to the same value as AFL_KILL_SIGNAL.\n" \ 134*08b48e0bSAndroid Build Coastguard Worker"AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \ 135*08b48e0bSAndroid Build Coastguard Worker"AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\n" \ 136*08b48e0bSAndroid Build Coastguard Worker"AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \ 137*08b48e0bSAndroid Build Coastguard Worker"AFL_PRINT_FILENAMES: If set, the filename currently processed will be " \ 138*08b48e0bSAndroid Build Coastguard Worker "printed to stdout\n" \ 139*08b48e0bSAndroid Build Coastguard Worker"AFL_SKIP_BIN_CHECK: skip afl instrumentation checks for target binary\n" 140*08b48e0bSAndroid Build Coastguard Worker"AFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send)\n" 141*08b48e0bSAndroid Build Coastguard Worker"AFL_PYTHON_MODULE: custom mutator library (post_process and send)\n" 142*08b48e0bSAndroid Build Coastguard Worker exit 1 143*08b48e0bSAndroid Build Coastguard Worker} 144*08b48e0bSAndroid Build Coastguard Worker 145*08b48e0bSAndroid Build Coastguard Workerfunction exists_and_is_executable(binarypath) { 146*08b48e0bSAndroid Build Coastguard Worker return 0 == system("test -f "binarypath" -a -x "binarypath) 147*08b48e0bSAndroid Build Coastguard Worker} 148*08b48e0bSAndroid Build Coastguard Worker 149*08b48e0bSAndroid Build Coastguard WorkerBEGIN { 150*08b48e0bSAndroid Build Coastguard Worker if (0 != system( "test -t 1")) { 151*08b48e0bSAndroid Build Coastguard Worker redirected = 1 152*08b48e0bSAndroid Build Coastguard Worker } else { 153*08b48e0bSAndroid Build Coastguard Worker redirected = 0 154*08b48e0bSAndroid Build Coastguard Worker } 155*08b48e0bSAndroid Build Coastguard Worker 156*08b48e0bSAndroid Build Coastguard Worker print "corpus minimization tool for AFL++ (awk version)\n" 157*08b48e0bSAndroid Build Coastguard Worker 158*08b48e0bSAndroid Build Coastguard Worker # defaults 159*08b48e0bSAndroid Build Coastguard Worker extra_par = "" 160*08b48e0bSAndroid Build Coastguard Worker AFL_CMIN_CRASHES_ONLY = "" 161*08b48e0bSAndroid Build Coastguard Worker AFL_CMIN_ALLOW_ANY = "" 162*08b48e0bSAndroid Build Coastguard Worker 163*08b48e0bSAndroid Build Coastguard Worker # process options 164*08b48e0bSAndroid Build Coastguard Worker Opterr = 1 # default is to diagnose 165*08b48e0bSAndroid Build Coastguard Worker Optind = 1 # skip ARGV[0] 166*08b48e0bSAndroid Build Coastguard Worker while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXYT:?")) != -1) { 167*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "i") { 168*08b48e0bSAndroid Build Coastguard Worker if (!Optarg) usage() 169*08b48e0bSAndroid Build Coastguard Worker if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 170*08b48e0bSAndroid Build Coastguard Worker in_dir = Optarg 171*08b48e0bSAndroid Build Coastguard Worker continue 172*08b48e0bSAndroid Build Coastguard Worker } else 173*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "T") { 174*08b48e0bSAndroid Build Coastguard Worker if (!Optarg) usage() 175*08b48e0bSAndroid Build Coastguard Worker if (threads) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 176*08b48e0bSAndroid Build Coastguard Worker threads = Optarg 177*08b48e0bSAndroid Build Coastguard Worker continue 178*08b48e0bSAndroid Build Coastguard Worker } else 179*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "o") { 180*08b48e0bSAndroid Build Coastguard Worker if (!Optarg) usage() 181*08b48e0bSAndroid Build Coastguard Worker if (out_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 182*08b48e0bSAndroid Build Coastguard Worker out_dir = Optarg 183*08b48e0bSAndroid Build Coastguard Worker continue 184*08b48e0bSAndroid Build Coastguard Worker } else 185*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "f") { 186*08b48e0bSAndroid Build Coastguard Worker if (!Optarg) usage() 187*08b48e0bSAndroid Build Coastguard Worker if (stdin_file) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 188*08b48e0bSAndroid Build Coastguard Worker stdin_file = Optarg 189*08b48e0bSAndroid Build Coastguard Worker continue 190*08b48e0bSAndroid Build Coastguard Worker } else 191*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "m") { 192*08b48e0bSAndroid Build Coastguard Worker if (!Optarg) usage() 193*08b48e0bSAndroid Build Coastguard Worker if (mem_limit) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 194*08b48e0bSAndroid Build Coastguard Worker mem_limit = Optarg 195*08b48e0bSAndroid Build Coastguard Worker mem_limit_given = 1 196*08b48e0bSAndroid Build Coastguard Worker continue 197*08b48e0bSAndroid Build Coastguard Worker } else 198*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "t") { 199*08b48e0bSAndroid Build Coastguard Worker if (!Optarg) usage() 200*08b48e0bSAndroid Build Coastguard Worker if (timeout) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 201*08b48e0bSAndroid Build Coastguard Worker timeout = Optarg 202*08b48e0bSAndroid Build Coastguard Worker continue 203*08b48e0bSAndroid Build Coastguard Worker } else 204*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "C") { 205*08b48e0bSAndroid Build Coastguard Worker AFL_CMIN_CRASHES_ONLY = "AFL_CMIN_CRASHES_ONLY=1 " 206*08b48e0bSAndroid Build Coastguard Worker continue 207*08b48e0bSAndroid Build Coastguard Worker } else 208*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "A") { 209*08b48e0bSAndroid Build Coastguard Worker AFL_CMIN_ALLOW_ANY = "AFL_CMIN_ALLOW_ANY=1 " 210*08b48e0bSAndroid Build Coastguard Worker continue 211*08b48e0bSAndroid Build Coastguard Worker } else 212*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "e") { 213*08b48e0bSAndroid Build Coastguard Worker extra_par = extra_par " -e" 214*08b48e0bSAndroid Build Coastguard Worker continue 215*08b48e0bSAndroid Build Coastguard Worker } else 216*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "O") { 217*08b48e0bSAndroid Build Coastguard Worker if (frida_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 218*08b48e0bSAndroid Build Coastguard Worker extra_par = extra_par " -O" 219*08b48e0bSAndroid Build Coastguard Worker frida_mode = 1 220*08b48e0bSAndroid Build Coastguard Worker continue 221*08b48e0bSAndroid Build Coastguard Worker } else 222*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "Q") { 223*08b48e0bSAndroid Build Coastguard Worker if (qemu_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 224*08b48e0bSAndroid Build Coastguard Worker extra_par = extra_par " -Q" 225*08b48e0bSAndroid Build Coastguard Worker qemu_mode = 1 226*08b48e0bSAndroid Build Coastguard Worker continue 227*08b48e0bSAndroid Build Coastguard Worker } else 228*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "U") { 229*08b48e0bSAndroid Build Coastguard Worker if (unicorn_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 230*08b48e0bSAndroid Build Coastguard Worker extra_par = extra_par " -U" 231*08b48e0bSAndroid Build Coastguard Worker unicorn_mode = 1 232*08b48e0bSAndroid Build Coastguard Worker continue 233*08b48e0bSAndroid Build Coastguard Worker } else 234*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "X" || _go_c == "Y") { 235*08b48e0bSAndroid Build Coastguard Worker if (nyx_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} 236*08b48e0bSAndroid Build Coastguard Worker extra_par = extra_par " -X" 237*08b48e0bSAndroid Build Coastguard Worker nyx_mode = 1 238*08b48e0bSAndroid Build Coastguard Worker continue 239*08b48e0bSAndroid Build Coastguard Worker } else 240*08b48e0bSAndroid Build Coastguard Worker if (_go_c == "?") { 241*08b48e0bSAndroid Build Coastguard Worker exit 1 242*08b48e0bSAndroid Build Coastguard Worker } else 243*08b48e0bSAndroid Build Coastguard Worker usage() 244*08b48e0bSAndroid Build Coastguard Worker } # while options 245*08b48e0bSAndroid Build Coastguard Worker 246*08b48e0bSAndroid Build Coastguard Worker if (!mem_limit) mem_limit = "none" 247*08b48e0bSAndroid Build Coastguard Worker if (!timeout) timeout = "5000" 248*08b48e0bSAndroid Build Coastguard Worker 249*08b48e0bSAndroid Build Coastguard Worker # get program args 250*08b48e0bSAndroid Build Coastguard Worker i = 0 251*08b48e0bSAndroid Build Coastguard Worker prog_args_string = "" 252*08b48e0bSAndroid Build Coastguard Worker for (; Optind < ARGC; Optind++) { 253*08b48e0bSAndroid Build Coastguard Worker prog_args[i++] = ARGV[Optind] 254*08b48e0bSAndroid Build Coastguard Worker if (i > 1) 255*08b48e0bSAndroid Build Coastguard Worker prog_args_string = prog_args_string" '"ARGV[Optind]"'" 256*08b48e0bSAndroid Build Coastguard Worker } 257*08b48e0bSAndroid Build Coastguard Worker 258*08b48e0bSAndroid Build Coastguard Worker # sanity checks 259*08b48e0bSAndroid Build Coastguard Worker if (!prog_args[0] || !in_dir || !out_dir) usage() 260*08b48e0bSAndroid Build Coastguard Worker 261*08b48e0bSAndroid Build Coastguard Worker target_bin = prog_args[0] 262*08b48e0bSAndroid Build Coastguard Worker 263*08b48e0bSAndroid Build Coastguard Worker # Do a sanity check to discourage the use of /tmp, since we can't really 264*08b48e0bSAndroid Build Coastguard Worker # handle this safely from an awk script. 265*08b48e0bSAndroid Build Coastguard Worker 266*08b48e0bSAndroid Build Coastguard Worker if (!ENVIRON["AFL_ALLOW_TMP"]) { 267*08b48e0bSAndroid Build Coastguard Worker dirlist[0] = in_dir 268*08b48e0bSAndroid Build Coastguard Worker dirlist[1] = target_bin 269*08b48e0bSAndroid Build Coastguard Worker dirlist[2] = out_dir 270*08b48e0bSAndroid Build Coastguard Worker dirlist[3] = stdin_file 271*08b48e0bSAndroid Build Coastguard Worker "pwd" | getline dirlist[4] # current directory 272*08b48e0bSAndroid Build Coastguard Worker for (dirind in dirlist) { 273*08b48e0bSAndroid Build Coastguard Worker dir = dirlist[dirind] 274*08b48e0bSAndroid Build Coastguard Worker if (dir ~ /^(\/var)?\/tmp/) { 275*08b48e0bSAndroid Build Coastguard Worker print "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." > "/dev/stderr" 276*08b48e0bSAndroid Build Coastguard Worker } 277*08b48e0bSAndroid Build Coastguard Worker } 278*08b48e0bSAndroid Build Coastguard Worker delete dirlist 279*08b48e0bSAndroid Build Coastguard Worker } 280*08b48e0bSAndroid Build Coastguard Worker 281*08b48e0bSAndroid Build Coastguard Worker if (threads && stdin_file) { 282*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: -T and -f cannot be used together." > "/dev/stderr" 283*08b48e0bSAndroid Build Coastguard Worker exit 1 284*08b48e0bSAndroid Build Coastguard Worker } 285*08b48e0bSAndroid Build Coastguard Worker 286*08b48e0bSAndroid Build Coastguard Worker if (!threads && !stdin_file && !nyx_mode) { 287*08b48e0bSAndroid Build Coastguard Worker print "[*] Are you aware of the '-T all' parallelize option that improves the speed for large/slow corpuses?" 288*08b48e0bSAndroid Build Coastguard Worker } 289*08b48e0bSAndroid Build Coastguard Worker 290*08b48e0bSAndroid Build Coastguard Worker # If @@ is specified, but there's no -f, let's come up with a temporary input 291*08b48e0bSAndroid Build Coastguard Worker # file name. 292*08b48e0bSAndroid Build Coastguard Worker 293*08b48e0bSAndroid Build Coastguard Worker trace_dir = out_dir "/.traces" 294*08b48e0bSAndroid Build Coastguard Worker 295*08b48e0bSAndroid Build Coastguard Worker if (!stdin_file) { 296*08b48e0bSAndroid Build Coastguard Worker found_atat = 0 297*08b48e0bSAndroid Build Coastguard Worker for (prog_args_ind in prog_args) { 298*08b48e0bSAndroid Build Coastguard Worker if (match(prog_args[prog_args_ind], "@@") != 0) { 299*08b48e0bSAndroid Build Coastguard Worker found_atat = 1 300*08b48e0bSAndroid Build Coastguard Worker break 301*08b48e0bSAndroid Build Coastguard Worker } 302*08b48e0bSAndroid Build Coastguard Worker } 303*08b48e0bSAndroid Build Coastguard Worker if (found_atat) { 304*08b48e0bSAndroid Build Coastguard Worker stdin_file = trace_dir "/.cur_input" 305*08b48e0bSAndroid Build Coastguard Worker } 306*08b48e0bSAndroid Build Coastguard Worker } 307*08b48e0bSAndroid Build Coastguard Worker 308*08b48e0bSAndroid Build Coastguard Worker # Check for obvious errors. 309*08b48e0bSAndroid Build Coastguard Worker 310*08b48e0bSAndroid Build Coastguard Worker if (mem_limit && mem_limit != "none" && mem_limit < 5) { 311*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: dangerously low memory limit." > "/dev/stderr" 312*08b48e0bSAndroid Build Coastguard Worker exit 1 313*08b48e0bSAndroid Build Coastguard Worker } 314*08b48e0bSAndroid Build Coastguard Worker 315*08b48e0bSAndroid Build Coastguard Worker if (timeout && timeout != "none" && timeout < 10) { 316*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: dangerously low timeout." > "/dev/stderr" 317*08b48e0bSAndroid Build Coastguard Worker exit 1 318*08b48e0bSAndroid Build Coastguard Worker } 319*08b48e0bSAndroid Build Coastguard Worker 320*08b48e0bSAndroid Build Coastguard Worker 321*08b48e0bSAndroid Build Coastguard Worker if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) { 322*08b48e0bSAndroid Build Coastguard Worker 323*08b48e0bSAndroid Build Coastguard Worker cmd = "command -v "target_bin" 2>/dev/null" 324*08b48e0bSAndroid Build Coastguard Worker cmd | getline tnew 325*08b48e0bSAndroid Build Coastguard Worker close(cmd) 326*08b48e0bSAndroid Build Coastguard Worker if (!tnew || !exists_and_is_executable(tnew)) { 327*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: binary '"target_bin"' not found or not executable." > "/dev/stderr" 328*08b48e0bSAndroid Build Coastguard Worker exit 1 329*08b48e0bSAndroid Build Coastguard Worker } 330*08b48e0bSAndroid Build Coastguard Worker target_bin = tnew 331*08b48e0bSAndroid Build Coastguard Worker } 332*08b48e0bSAndroid Build Coastguard Worker 333*08b48e0bSAndroid Build Coastguard Worker if (0 == system ( "grep -aq AFL_DUMP_MAP_SIZE " target_bin )) { 334*08b48e0bSAndroid Build Coastguard Worker echo "[!] Trying to obtain the map size of the target ..." 335*08b48e0bSAndroid Build Coastguard Worker get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin 336*08b48e0bSAndroid Build Coastguard Worker get_map_size | getline mapsize 337*08b48e0bSAndroid Build Coastguard Worker close(get_map_size) 338*08b48e0bSAndroid Build Coastguard Worker if (mapsize && mapsize > 65535 && mapsize < 100000000) { 339*08b48e0bSAndroid Build Coastguard Worker AFL_MAP_SIZE = "AFL_MAP_SIZE="mapsize" " 340*08b48e0bSAndroid Build Coastguard Worker print "[+] Setting "AFL_MAP_SIZE 341*08b48e0bSAndroid Build Coastguard Worker } 342*08b48e0bSAndroid Build Coastguard Worker } 343*08b48e0bSAndroid Build Coastguard Worker 344*08b48e0bSAndroid Build Coastguard Worker if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode && !nyx_mode) { 345*08b48e0bSAndroid Build Coastguard Worker if (0 != system( "grep -q __AFL_SHM_ID "target_bin )) { 346*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: binary '"target_bin"' doesn't appear to be instrumented." > "/dev/stderr" 347*08b48e0bSAndroid Build Coastguard Worker exit 1 348*08b48e0bSAndroid Build Coastguard Worker } 349*08b48e0bSAndroid Build Coastguard Worker } 350*08b48e0bSAndroid Build Coastguard Worker 351*08b48e0bSAndroid Build Coastguard Worker if (0 != system( "test -d "in_dir )) { 352*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: directory '"in_dir"' not found." > "/dev/stderr" 353*08b48e0bSAndroid Build Coastguard Worker exit 1 354*08b48e0bSAndroid Build Coastguard Worker } 355*08b48e0bSAndroid Build Coastguard Worker 356*08b48e0bSAndroid Build Coastguard Worker #if (0 == system( "test -d "in_dir"/default" )) { 357*08b48e0bSAndroid Build Coastguard Worker # in_dir = in_dir "/default" 358*08b48e0bSAndroid Build Coastguard Worker #} 359*08b48e0bSAndroid Build Coastguard Worker # 360*08b48e0bSAndroid Build Coastguard Worker #if (0 == system( "test -d "in_dir"/queue" )) { 361*08b48e0bSAndroid Build Coastguard Worker # in_dir = in_dir "/queue" 362*08b48e0bSAndroid Build Coastguard Worker #} 363*08b48e0bSAndroid Build Coastguard Worker 364*08b48e0bSAndroid Build Coastguard Worker system("rm -rf "trace_dir" 2>/dev/null"); 365*08b48e0bSAndroid Build Coastguard Worker system("rm "out_dir"/id[:_]* 2>/dev/null") 366*08b48e0bSAndroid Build Coastguard Worker 367*08b48e0bSAndroid Build Coastguard Worker cmd = "ls "out_dir"/* 2>/dev/null | wc -l" 368*08b48e0bSAndroid Build Coastguard Worker cmd | getline noofentries 369*08b48e0bSAndroid Build Coastguard Worker close(cmd) 370*08b48e0bSAndroid Build Coastguard Worker if (0 == system( "test -d "out_dir" -a "noofentries" -gt 0" )) { 371*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: directory '"out_dir"' exists and is not empty - delete it first." > "/dev/stderr" 372*08b48e0bSAndroid Build Coastguard Worker exit 1 373*08b48e0bSAndroid Build Coastguard Worker } 374*08b48e0bSAndroid Build Coastguard Worker 375*08b48e0bSAndroid Build Coastguard Worker if (threads) { 376*08b48e0bSAndroid Build Coastguard Worker cmd = "nproc" 377*08b48e0bSAndroid Build Coastguard Worker cmd | getline nproc 378*08b48e0bSAndroid Build Coastguard Worker close(cmd) 379*08b48e0bSAndroid Build Coastguard Worker if (threads == "all") { 380*08b48e0bSAndroid Build Coastguard Worker threads = nproc 381*08b48e0bSAndroid Build Coastguard Worker } else { 382*08b48e0bSAndroid Build Coastguard Worker if (!(threads > 1 && threads <= nproc)) { 383*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: -T option must be between 1 and "nproc" or \"all\"." > "/dev/stderr" 384*08b48e0bSAndroid Build Coastguard Worker exit 1 385*08b48e0bSAndroid Build Coastguard Worker } 386*08b48e0bSAndroid Build Coastguard Worker } 387*08b48e0bSAndroid Build Coastguard Worker } 388*08b48e0bSAndroid Build Coastguard Worker 389*08b48e0bSAndroid Build Coastguard Worker # Check for the more efficient way to copy files... 390*08b48e0bSAndroid Build Coastguard Worker if (0 != system("mkdir -p -m 0700 "trace_dir)) { 391*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: Cannot create directory "trace_dir > "/dev/stderr" 392*08b48e0bSAndroid Build Coastguard Worker exit 1 393*08b48e0bSAndroid Build Coastguard Worker } 394*08b48e0bSAndroid Build Coastguard Worker 395*08b48e0bSAndroid Build Coastguard Worker if (stdin_file) { 396*08b48e0bSAndroid Build Coastguard Worker # truncate input file 397*08b48e0bSAndroid Build Coastguard Worker printf "" > stdin_file 398*08b48e0bSAndroid Build Coastguard Worker close(stdin_file) 399*08b48e0bSAndroid Build Coastguard Worker } 400*08b48e0bSAndroid Build Coastguard Worker 401*08b48e0bSAndroid Build Coastguard Worker # First we look in PATH 402*08b48e0bSAndroid Build Coastguard Worker if (0 == system("command -v afl-showmap >/dev/null 2>&1")) { 403*08b48e0bSAndroid Build Coastguard Worker cmd = "command -v afl-showmap 2>/dev/null" 404*08b48e0bSAndroid Build Coastguard Worker cmd | getline showmap 405*08b48e0bSAndroid Build Coastguard Worker close(cmd) 406*08b48e0bSAndroid Build Coastguard Worker } else { 407*08b48e0bSAndroid Build Coastguard Worker # then we look in the current directory 408*08b48e0bSAndroid Build Coastguard Worker if (0 == system("test -x ./afl-showmap")) { 409*08b48e0bSAndroid Build Coastguard Worker showmap = "./afl-showmap" 410*08b48e0bSAndroid Build Coastguard Worker } else { 411*08b48e0bSAndroid Build Coastguard Worker if (ENVIRON["AFL_PATH"]) { 412*08b48e0bSAndroid Build Coastguard Worker showmap = ENVIRON["AFL_PATH"] "/afl-showmap" 413*08b48e0bSAndroid Build Coastguard Worker } 414*08b48e0bSAndroid Build Coastguard Worker } 415*08b48e0bSAndroid Build Coastguard Worker } 416*08b48e0bSAndroid Build Coastguard Worker 417*08b48e0bSAndroid Build Coastguard Worker if (!showmap || 0 != system("test -x "showmap )) { 418*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: can't find 'afl-showmap' - please set AFL_PATH." > "/dev/stderr" 419*08b48e0bSAndroid Build Coastguard Worker exit 1 420*08b48e0bSAndroid Build Coastguard Worker } 421*08b48e0bSAndroid Build Coastguard Worker 422*08b48e0bSAndroid Build Coastguard Worker # get list of input filenames sorted by size 423*08b48e0bSAndroid Build Coastguard Worker i = 0 424*08b48e0bSAndroid Build Coastguard Worker # yuck, gnu stat is option incompatible to bsd stat 425*08b48e0bSAndroid Build Coastguard Worker # we use a heuristic to differentiate between 426*08b48e0bSAndroid Build Coastguard Worker # GNU stat and other stats 427*08b48e0bSAndroid Build Coastguard Worker cmd = "stat --version 2>/dev/null" 428*08b48e0bSAndroid Build Coastguard Worker cmd | getline statversion 429*08b48e0bSAndroid Build Coastguard Worker close(cmd) 430*08b48e0bSAndroid Build Coastguard Worker if (statversion ~ /GNU coreutils/ || statversion ~ /BusyBox/) { 431*08b48e0bSAndroid Build Coastguard Worker stat_format = "-c '%s %n'" # GNU 432*08b48e0bSAndroid Build Coastguard Worker } else { 433*08b48e0bSAndroid Build Coastguard Worker stat_format = "-f '%z %N'" # *BSD, MacOS 434*08b48e0bSAndroid Build Coastguard Worker } 435*08b48e0bSAndroid Build Coastguard Worker cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o -type f -exec stat "stat_format" \\{\\} + | sort -k1n -k2r) | grep -Ev '^0'" 436*08b48e0bSAndroid Build Coastguard Worker #cmdline = "ls "in_dir" | (cd "in_dir" && xargs stat "stat_format" 2>/dev/null) | sort -k1n -k2r" 437*08b48e0bSAndroid Build Coastguard Worker #cmdline = "(cd "in_dir" && stat "stat_format" *) | sort -k1n -k2r" 438*08b48e0bSAndroid Build Coastguard Worker #cmdline = "(cd "in_dir" && ls | xargs stat "stat_format" ) | sort -k1n -k2r" 439*08b48e0bSAndroid Build Coastguard Worker while (cmdline | getline) { 440*08b48e0bSAndroid Build Coastguard Worker sub(/^[0-9]+ (\.\/)?/,"",$0) 441*08b48e0bSAndroid Build Coastguard Worker infilesSmallToBigFull[i] = $0 442*08b48e0bSAndroid Build Coastguard Worker sub(/.*\//, "", $0) 443*08b48e0bSAndroid Build Coastguard Worker infilesSmallToBig[i] = $0 444*08b48e0bSAndroid Build Coastguard Worker infilesSmallToBigMap[infilesSmallToBig[i]] = infilesSmallToBigFull[i] 445*08b48e0bSAndroid Build Coastguard Worker infilesSmallToBigFullMap[infilesSmallToBigFull[i]] = infilesSmallToBig[i] 446*08b48e0bSAndroid Build Coastguard Worker i++ 447*08b48e0bSAndroid Build Coastguard Worker } 448*08b48e0bSAndroid Build Coastguard Worker close(cmdline) 449*08b48e0bSAndroid Build Coastguard Worker in_count = i 450*08b48e0bSAndroid Build Coastguard Worker 451*08b48e0bSAndroid Build Coastguard Worker first_file = infilesSmallToBigFull[0] 452*08b48e0bSAndroid Build Coastguard Worker 453*08b48e0bSAndroid Build Coastguard Worker #if (0 == system("test -d ""\""in_dir"/"first_file"\"")) { 454*08b48e0bSAndroid Build Coastguard Worker # print "[-] Error: The input directory is empty or contains subdirectories - please fix." > "/dev/stderr" 455*08b48e0bSAndroid Build Coastguard Worker # exit 1 456*08b48e0bSAndroid Build Coastguard Worker #} 457*08b48e0bSAndroid Build Coastguard Worker 458*08b48e0bSAndroid Build Coastguard Worker system(">\""in_dir"/.afl-cmin.test\"") 459*08b48e0bSAndroid Build Coastguard Worker if (0 == system("ln \""in_dir"/.afl-cmin.test\" "trace_dir"/.link_test")) { 460*08b48e0bSAndroid Build Coastguard Worker cp_tool = "ln" 461*08b48e0bSAndroid Build Coastguard Worker } else { 462*08b48e0bSAndroid Build Coastguard Worker cp_tool = "cp" 463*08b48e0bSAndroid Build Coastguard Worker } 464*08b48e0bSAndroid Build Coastguard Worker system("rm -f \""in_dir"/.afl-cmin.test\"") 465*08b48e0bSAndroid Build Coastguard Worker 466*08b48e0bSAndroid Build Coastguard Worker if (!ENVIRON["AFL_SKIP_BIN_CHECK"]) { 467*08b48e0bSAndroid Build Coastguard Worker # Make sure that we can actually get anything out of afl-showmap before we 468*08b48e0bSAndroid Build Coastguard Worker # waste too much time. 469*08b48e0bSAndroid Build Coastguard Worker 470*08b48e0bSAndroid Build Coastguard Worker print "[*] Testing the target binary..." 471*08b48e0bSAndroid Build Coastguard Worker 472*08b48e0bSAndroid Build Coastguard Worker if (!stdin_file) { 473*08b48e0bSAndroid Build Coastguard Worker system(AFL_MAP_SIZE "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -- \""target_bin"\" "prog_args_string" <\""in_dir"/"first_file"\"") 474*08b48e0bSAndroid Build Coastguard Worker } else { 475*08b48e0bSAndroid Build Coastguard Worker system("cp \""in_dir"/"first_file"\" "stdin_file) 476*08b48e0bSAndroid Build Coastguard Worker system(AFL_MAP_SIZE "AFL_CMIN_ALLOW_ANY=1 "AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"/.run_test\" -Z "extra_par" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null") 477*08b48e0bSAndroid Build Coastguard Worker } 478*08b48e0bSAndroid Build Coastguard Worker 479*08b48e0bSAndroid Build Coastguard Worker first_count = 0 480*08b48e0bSAndroid Build Coastguard Worker 481*08b48e0bSAndroid Build Coastguard Worker runtest = trace_dir"/.run_test" 482*08b48e0bSAndroid Build Coastguard Worker while ((getline < runtest) > 0) { 483*08b48e0bSAndroid Build Coastguard Worker ++first_count 484*08b48e0bSAndroid Build Coastguard Worker } 485*08b48e0bSAndroid Build Coastguard Worker close(runtest) 486*08b48e0bSAndroid Build Coastguard Worker 487*08b48e0bSAndroid Build Coastguard Worker if (first_count) { 488*08b48e0bSAndroid Build Coastguard Worker print "[+] OK, "first_count" tuples recorded." 489*08b48e0bSAndroid Build Coastguard Worker } else { 490*08b48e0bSAndroid Build Coastguard Worker print "[-] Error: no instrumentation output detected (perhaps crash or timeout)." > "/dev/stderr" 491*08b48e0bSAndroid Build Coastguard Worker if (!ENVIRON["AFL_KEEP_TRACES"]) { 492*08b48e0bSAndroid Build Coastguard Worker system("rm -rf "trace_dir" 2>/dev/null") 493*08b48e0bSAndroid Build Coastguard Worker } 494*08b48e0bSAndroid Build Coastguard Worker exit 1 495*08b48e0bSAndroid Build Coastguard Worker } 496*08b48e0bSAndroid Build Coastguard Worker } 497*08b48e0bSAndroid Build Coastguard Worker 498*08b48e0bSAndroid Build Coastguard Worker if (in_count < threads) { 499*08b48e0bSAndroid Build Coastguard Worker threads = in_count 500*08b48e0bSAndroid Build Coastguard Worker print "[!] WARNING: less inputs than threads, reducing threads to "threads" and likely the overhead of threading makes things slower..." 501*08b48e0bSAndroid Build Coastguard Worker } 502*08b48e0bSAndroid Build Coastguard Worker 503*08b48e0bSAndroid Build Coastguard Worker # Let's roll! 504*08b48e0bSAndroid Build Coastguard Worker 505*08b48e0bSAndroid Build Coastguard Worker ############################# 506*08b48e0bSAndroid Build Coastguard Worker # STEP 1: Collecting traces # 507*08b48e0bSAndroid Build Coastguard Worker ############################# 508*08b48e0bSAndroid Build Coastguard Worker 509*08b48e0bSAndroid Build Coastguard Worker if (threads) { 510*08b48e0bSAndroid Build Coastguard Worker 511*08b48e0bSAndroid Build Coastguard Worker inputsperfile = int(in_count / threads) 512*08b48e0bSAndroid Build Coastguard Worker if (in_count % threads) { 513*08b48e0bSAndroid Build Coastguard Worker inputsperfile++; 514*08b48e0bSAndroid Build Coastguard Worker } 515*08b48e0bSAndroid Build Coastguard Worker 516*08b48e0bSAndroid Build Coastguard Worker cnt = 0; 517*08b48e0bSAndroid Build Coastguard Worker tmpfile=out_dir "/.filelist" 518*08b48e0bSAndroid Build Coastguard Worker for (instance = 1; instance < threads; instance++) { 519*08b48e0bSAndroid Build Coastguard Worker for (i = 0; i < inputsperfile; i++) { 520*08b48e0bSAndroid Build Coastguard Worker print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."instance 521*08b48e0bSAndroid Build Coastguard Worker cnt++ 522*08b48e0bSAndroid Build Coastguard Worker } 523*08b48e0bSAndroid Build Coastguard Worker } 524*08b48e0bSAndroid Build Coastguard Worker for (; cnt < in_count; cnt++) { 525*08b48e0bSAndroid Build Coastguard Worker print in_dir"/"infilesSmallToBigFull[cnt] >> tmpfile"."threads 526*08b48e0bSAndroid Build Coastguard Worker } 527*08b48e0bSAndroid Build Coastguard Worker 528*08b48e0bSAndroid Build Coastguard Worker } 529*08b48e0bSAndroid Build Coastguard Worker 530*08b48e0bSAndroid Build Coastguard Worker print "[*] Obtaining traces for "in_count" input files in '"in_dir"'." 531*08b48e0bSAndroid Build Coastguard Worker 532*08b48e0bSAndroid Build Coastguard Worker cur = 0; 533*08b48e0bSAndroid Build Coastguard Worker 534*08b48e0bSAndroid Build Coastguard Worker if (threads > 1) { 535*08b48e0bSAndroid Build Coastguard Worker 536*08b48e0bSAndroid Build Coastguard Worker print "[*] Creating " threads " parallel tasks with about " inputsperfile " items each." 537*08b48e0bSAndroid Build Coastguard Worker for (i = 1; i <= threads; i++) { 538*08b48e0bSAndroid Build Coastguard Worker 539*08b48e0bSAndroid Build Coastguard Worker if (!stdin_file) { 540*08b48e0bSAndroid Build Coastguard Worker# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &" 541*08b48e0bSAndroid Build Coastguard Worker retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -- \""target_bin"\" "prog_args_string"; > "tmpfile"."i".done ; } &") 542*08b48e0bSAndroid Build Coastguard Worker } else { 543*08b48e0bSAndroid Build Coastguard Worker stdin_file=tmpfile"."i".stdin" 544*08b48e0bSAndroid Build Coastguard Worker# print " { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null; > "tmpfile"."i".done ; } &" 545*08b48e0bSAndroid Build Coastguard Worker retval = system(" { "AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -I \""tmpfile"."i"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null; > "tmpfile"."i".done ; } &") 546*08b48e0bSAndroid Build Coastguard Worker } 547*08b48e0bSAndroid Build Coastguard Worker } 548*08b48e0bSAndroid Build Coastguard Worker print "[*] Waiting for parallel tasks to complete ..." 549*08b48e0bSAndroid Build Coastguard Worker # wait for all processes to finish 550*08b48e0bSAndroid Build Coastguard Worker ok=0 551*08b48e0bSAndroid Build Coastguard Worker while (ok < threads) { 552*08b48e0bSAndroid Build Coastguard Worker ok=0 553*08b48e0bSAndroid Build Coastguard Worker for (i = 1; i <= threads; i++) { 554*08b48e0bSAndroid Build Coastguard Worker if (system("test -f "tmpfile"."i".done") == 0) { 555*08b48e0bSAndroid Build Coastguard Worker ok++ 556*08b48e0bSAndroid Build Coastguard Worker } 557*08b48e0bSAndroid Build Coastguard Worker } 558*08b48e0bSAndroid Build Coastguard Worker } 559*08b48e0bSAndroid Build Coastguard Worker print "[*] Done!" 560*08b48e0bSAndroid Build Coastguard Worker system("rm -f "tmpfile"*") 561*08b48e0bSAndroid Build Coastguard Worker } else { 562*08b48e0bSAndroid Build Coastguard Worker if (!stdin_file) { 563*08b48e0bSAndroid Build Coastguard Worker print " Processing "in_count" files (forkserver mode)..." 564*08b48e0bSAndroid Build Coastguard Worker# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string 565*08b48e0bSAndroid Build Coastguard Worker retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string) 566*08b48e0bSAndroid Build Coastguard Worker } else { 567*08b48e0bSAndroid Build Coastguard Worker print " Processing "in_count" files (forkserver mode)..." 568*08b48e0bSAndroid Build Coastguard Worker# print AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null" 569*08b48e0bSAndroid Build Coastguard Worker retval = system(AFL_MAP_SIZE AFL_CMIN_ALLOW_ANY AFL_CMIN_CRASHES_ONLY"\""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -H \""stdin_file"\" -- \""target_bin"\" "prog_args_string" </dev/null") 570*08b48e0bSAndroid Build Coastguard Worker } 571*08b48e0bSAndroid Build Coastguard Worker 572*08b48e0bSAndroid Build Coastguard Worker if (retval && (!AFL_CMIN_CRASHES_ONLY && !AFL_CMIN_ALLOW_ANY)) { 573*08b48e0bSAndroid Build Coastguard Worker print "[!] Exit code "retval" != 0 received from afl-showmap (this means a crashing or timeout input is likely present), terminating..." 574*08b48e0bSAndroid Build Coastguard Worker 575*08b48e0bSAndroid Build Coastguard Worker if (!ENVIRON["AFL_KEEP_TRACES"]) { 576*08b48e0bSAndroid Build Coastguard Worker system("rm -rf "trace_dir" 2>/dev/null") 577*08b48e0bSAndroid Build Coastguard Worker system("rmdir "out_dir) 578*08b48e0bSAndroid Build Coastguard Worker } 579*08b48e0bSAndroid Build Coastguard Worker exit retval 580*08b48e0bSAndroid Build Coastguard Worker } 581*08b48e0bSAndroid Build Coastguard Worker 582*08b48e0bSAndroid Build Coastguard Worker } 583*08b48e0bSAndroid Build Coastguard Worker 584*08b48e0bSAndroid Build Coastguard Worker ####################################################### 585*08b48e0bSAndroid Build Coastguard Worker # STEP 2: register smallest input file for each tuple # 586*08b48e0bSAndroid Build Coastguard Worker # STEP 3: copy that file (at most once) # 587*08b48e0bSAndroid Build Coastguard Worker ####################################################### 588*08b48e0bSAndroid Build Coastguard Worker 589*08b48e0bSAndroid Build Coastguard Worker print "[*] Processing traces for input files in '"in_dir"'." 590*08b48e0bSAndroid Build Coastguard Worker 591*08b48e0bSAndroid Build Coastguard Worker cur = 0 592*08b48e0bSAndroid Build Coastguard Worker out_count = 0 593*08b48e0bSAndroid Build Coastguard Worker tuple_count = 0 594*08b48e0bSAndroid Build Coastguard Worker 595*08b48e0bSAndroid Build Coastguard Worker # from rare to frequent new tuples 596*08b48e0bSAndroid Build Coastguard Worker # get the best (smallest) file for it 597*08b48e0bSAndroid Build Coastguard Worker # and copy it 598*08b48e0bSAndroid Build Coastguard Worker while (cur < in_count) { 599*08b48e0bSAndroid Build Coastguard Worker fn = infilesSmallToBig[cur] 600*08b48e0bSAndroid Build Coastguard Worker ++cur 601*08b48e0bSAndroid Build Coastguard Worker if (redirected == 0) { printf "\r Processing file "cur"/"in_count } 602*08b48e0bSAndroid Build Coastguard Worker else { print " Processing file "cur"/"in_count } 603*08b48e0bSAndroid Build Coastguard Worker # create path for the trace file from afl-showmap 604*08b48e0bSAndroid Build Coastguard Worker tracefile_path = trace_dir"/"fn 605*08b48e0bSAndroid Build Coastguard Worker # ensure the file size is not zero 606*08b48e0bSAndroid Build Coastguard Worker cmd = "du -b "tracefile_path 607*08b48e0bSAndroid Build Coastguard Worker "ls -l "tracefile_path 608*08b48e0bSAndroid Build Coastguard Worker cmd | getline output 609*08b48e0bSAndroid Build Coastguard Worker close(cmd) 610*08b48e0bSAndroid Build Coastguard Worker split(output, result, "\t") 611*08b48e0bSAndroid Build Coastguard Worker if (result[1] == 0) { 612*08b48e0bSAndroid Build Coastguard Worker print "[!] WARNING: file "fn" is crashing the target, ignoring..." 613*08b48e0bSAndroid Build Coastguard Worker } 614*08b48e0bSAndroid Build Coastguard Worker # gather all keys, and count them 615*08b48e0bSAndroid Build Coastguard Worker while ((getline line < tracefile_path) > 0) { 616*08b48e0bSAndroid Build Coastguard Worker key = line 617*08b48e0bSAndroid Build Coastguard Worker if (!(key in key_count)) { 618*08b48e0bSAndroid Build Coastguard Worker ++tuple_count 619*08b48e0bSAndroid Build Coastguard Worker } 620*08b48e0bSAndroid Build Coastguard Worker ++key_count[key] 621*08b48e0bSAndroid Build Coastguard Worker if (! (key in best_file)) { 622*08b48e0bSAndroid Build Coastguard Worker # this is the best file for this key 623*08b48e0bSAndroid Build Coastguard Worker best_file[key] = fn 624*08b48e0bSAndroid Build Coastguard Worker#printf "BEST_FILE[%d]=\"%s\"\n",key,fn | "sort -t'[' -k2 > "trace_dir"/.candidate_script" 625*08b48e0bSAndroid Build Coastguard Worker } 626*08b48e0bSAndroid Build Coastguard Worker#printf "%d %s\n",key,fn > trace_dir"/.candidate_list" 627*08b48e0bSAndroid Build Coastguard Worker } 628*08b48e0bSAndroid Build Coastguard Worker close(tracefile_path) 629*08b48e0bSAndroid Build Coastguard Worker } 630*08b48e0bSAndroid Build Coastguard Worker print "" 631*08b48e0bSAndroid Build Coastguard Worker 632*08b48e0bSAndroid Build Coastguard Worker # sort keys 633*08b48e0bSAndroid Build Coastguard Worker sortedKeys = trace_dir"/.all_uniq" 634*08b48e0bSAndroid Build Coastguard Worker sortKeysCmd = "sort -k1n > "sortedKeys 635*08b48e0bSAndroid Build Coastguard Worker for (key in key_count) { 636*08b48e0bSAndroid Build Coastguard Worker printf "%7d %s\n",key_count[key],key | sortKeysCmd 637*08b48e0bSAndroid Build Coastguard Worker } 638*08b48e0bSAndroid Build Coastguard Worker close(sortKeysCmd) 639*08b48e0bSAndroid Build Coastguard Worker 640*08b48e0bSAndroid Build Coastguard Worker # iterate over keys from rare to frequent and 641*08b48e0bSAndroid Build Coastguard Worker # copy best file 642*08b48e0bSAndroid Build Coastguard Worker while ((getline < sortedKeys) > 0) { 643*08b48e0bSAndroid Build Coastguard Worker 644*08b48e0bSAndroid Build Coastguard Worker # split 645*08b48e0bSAndroid Build Coastguard Worker nrFields = split($0, field, / +/) 646*08b48e0bSAndroid Build Coastguard Worker#print nrFields" Felder: '"field[0]"', '"field[1]"', '"field[2]"', '"field[3]"'" 647*08b48e0bSAndroid Build Coastguard Worker key = field[nrFields] 648*08b48e0bSAndroid Build Coastguard Worker 649*08b48e0bSAndroid Build Coastguard Worker ++tcnt; 650*08b48e0bSAndroid Build Coastguard Worker if (redirected == 0) { printf "\r Processing tuple "tcnt"/"tuple_count" with count "key_count[key]"..." } 651*08b48e0bSAndroid Build Coastguard Worker else { print " Processing tuple "tcnt"/"tuple_count" with count "key_count[key]"..." } 652*08b48e0bSAndroid Build Coastguard Worker 653*08b48e0bSAndroid Build Coastguard Worker if (key in keyAlreadyKnown) { 654*08b48e0bSAndroid Build Coastguard Worker continue 655*08b48e0bSAndroid Build Coastguard Worker } 656*08b48e0bSAndroid Build Coastguard Worker 657*08b48e0bSAndroid Build Coastguard Worker fn = best_file[key] 658*08b48e0bSAndroid Build Coastguard Worker # gather all tuples from the best file for this key 659*08b48e0bSAndroid Build Coastguard Worker tracedfn = trace_dir"/"fn 660*08b48e0bSAndroid Build Coastguard Worker while ((getline < tracedfn) > 0) { 661*08b48e0bSAndroid Build Coastguard Worker keyAlreadyKnown[$0] = "" 662*08b48e0bSAndroid Build Coastguard Worker } 663*08b48e0bSAndroid Build Coastguard Worker close(tracedfn) 664*08b48e0bSAndroid Build Coastguard Worker 665*08b48e0bSAndroid Build Coastguard Worker # copy file unless already done 666*08b48e0bSAndroid Build Coastguard Worker if (! (fn in file_already_copied)) { 667*08b48e0bSAndroid Build Coastguard Worker realfile = infilesSmallToBigMap[fn] 668*08b48e0bSAndroid Build Coastguard Worker system(cp_tool" \""in_dir"/"realfile"\" \""out_dir"/"fn"\"") 669*08b48e0bSAndroid Build Coastguard Worker file_already_copied[fn] = "" 670*08b48e0bSAndroid Build Coastguard Worker ++out_count 671*08b48e0bSAndroid Build Coastguard Worker #printf "tuple nr %d (%d cnt=%d) -> %s\n",tcnt,key,key_count[key],fn > trace_dir"/.log" 672*08b48e0bSAndroid Build Coastguard Worker } 673*08b48e0bSAndroid Build Coastguard Worker } 674*08b48e0bSAndroid Build Coastguard Worker close(sortedKeys) 675*08b48e0bSAndroid Build Coastguard Worker print "" 676*08b48e0bSAndroid Build Coastguard Worker print "[+] Found "tuple_count" unique tuples across "in_count" files." 677*08b48e0bSAndroid Build Coastguard Worker 678*08b48e0bSAndroid Build Coastguard Worker if (out_count == 1) { 679*08b48e0bSAndroid Build Coastguard Worker print "[!] WARNING: All test cases had the same traces, check syntax!" 680*08b48e0bSAndroid Build Coastguard Worker } 681*08b48e0bSAndroid Build Coastguard Worker print "[+] Narrowed down to "out_count" files, saved in '"out_dir"'." 682*08b48e0bSAndroid Build Coastguard Worker 683*08b48e0bSAndroid Build Coastguard Worker if (!ENVIRON["AFL_KEEP_TRACES"]) { 684*08b48e0bSAndroid Build Coastguard Worker system("rm -rf "trace_dir" 2>/dev/null") 685*08b48e0bSAndroid Build Coastguard Worker } 686*08b48e0bSAndroid Build Coastguard Worker 687*08b48e0bSAndroid Build Coastguard Worker exit 0 688*08b48e0bSAndroid Build Coastguard Worker} 689*08b48e0bSAndroid Build Coastguard WorkerEOF 690