1*08b48e0bSAndroid Build Coastguard Worker#!/usr/bin/env bash 2*08b48e0bSAndroid Build Coastguard Worker# 3*08b48e0bSAndroid Build Coastguard Worker# american fuzzy lop++ - corpus minimization tool 4*08b48e0bSAndroid Build Coastguard Worker# --------------------------------------------- 5*08b48e0bSAndroid Build Coastguard Worker# 6*08b48e0bSAndroid Build Coastguard Worker# Originally written by Michal Zalewski 7*08b48e0bSAndroid Build Coastguard Worker# 8*08b48e0bSAndroid Build Coastguard Worker# Copyright 2014, 2015 Google Inc. All rights reserved. 9*08b48e0bSAndroid Build Coastguard Worker# 10*08b48e0bSAndroid Build Coastguard Worker# Copyright 2019-2024 AFLplusplus 11*08b48e0bSAndroid Build Coastguard Worker# 12*08b48e0bSAndroid Build Coastguard Worker# Licensed under the Apache License, Version 2.0 (the "License"); 13*08b48e0bSAndroid Build Coastguard Worker# you may not use this file except in compliance with the License. 14*08b48e0bSAndroid Build Coastguard Worker# You may obtain a copy of the License at: 15*08b48e0bSAndroid Build Coastguard Worker# 16*08b48e0bSAndroid Build Coastguard Worker# https://www.apache.org/licenses/LICENSE-2.0 17*08b48e0bSAndroid Build Coastguard Worker# 18*08b48e0bSAndroid Build Coastguard Worker# This tool tries to find the smallest subset of files in the input directory 19*08b48e0bSAndroid Build Coastguard Worker# that still trigger the full range of instrumentation data points seen in 20*08b48e0bSAndroid Build Coastguard Worker# the starting corpus. This has two uses: 21*08b48e0bSAndroid Build Coastguard Worker# 22*08b48e0bSAndroid Build Coastguard Worker# - Screening large corpora of input files before using them as a seed for 23*08b48e0bSAndroid Build Coastguard Worker# afl-fuzz. The tool will remove functionally redundant files and likely 24*08b48e0bSAndroid Build Coastguard Worker# leave you with a much smaller set. 25*08b48e0bSAndroid Build Coastguard Worker# 26*08b48e0bSAndroid Build Coastguard Worker# (In this case, you probably also want to consider running afl-tmin on 27*08b48e0bSAndroid Build Coastguard Worker# the individual files later on to reduce their size.) 28*08b48e0bSAndroid Build Coastguard Worker# 29*08b48e0bSAndroid Build Coastguard Worker# - Minimizing the corpus generated organically by afl-fuzz, perhaps when 30*08b48e0bSAndroid Build Coastguard Worker# planning to feed it to more resource-intensive tools. The tool achieves 31*08b48e0bSAndroid Build Coastguard Worker# this by removing all entries that used to trigger unique behaviors in the 32*08b48e0bSAndroid Build Coastguard Worker# past, but have been made obsolete by later finds. 33*08b48e0bSAndroid Build Coastguard Worker# 34*08b48e0bSAndroid Build Coastguard Worker# Note that the tool doesn't modify the files themselves. For that, you want 35*08b48e0bSAndroid Build Coastguard Worker# afl-tmin. 36*08b48e0bSAndroid Build Coastguard Worker# 37*08b48e0bSAndroid Build Coastguard Worker# This script must use bash because other shells may have hardcoded limits on 38*08b48e0bSAndroid Build Coastguard Worker# array sizes. 39*08b48e0bSAndroid Build Coastguard Worker# 40*08b48e0bSAndroid Build Coastguard Worker 41*08b48e0bSAndroid Build Coastguard Workerecho "corpus minimization tool for afl-fuzz" 42*08b48e0bSAndroid Build Coastguard Workerecho 43*08b48e0bSAndroid Build Coastguard Worker 44*08b48e0bSAndroid Build Coastguard Worker######### 45*08b48e0bSAndroid Build Coastguard Worker# SETUP # 46*08b48e0bSAndroid Build Coastguard Worker######### 47*08b48e0bSAndroid Build Coastguard Worker 48*08b48e0bSAndroid Build Coastguard Worker# Process command-line options... 49*08b48e0bSAndroid Build Coastguard Worker 50*08b48e0bSAndroid Build Coastguard WorkerMEM_LIMIT=none 51*08b48e0bSAndroid Build Coastguard WorkerTIMEOUT=5000 52*08b48e0bSAndroid Build Coastguard Worker 53*08b48e0bSAndroid Build Coastguard Workerunset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN F_ARG \ 54*08b48e0bSAndroid Build Coastguard Worker AFL_CMIN_CRASHES_ONLY AFL_CMIN_ALLOW_ANY QEMU_MODE UNICORN_MODE T_ARG 55*08b48e0bSAndroid Build Coastguard Worker 56*08b48e0bSAndroid Build Coastguard Workerexport AFL_QUIET=1 57*08b48e0bSAndroid Build Coastguard Worker 58*08b48e0bSAndroid Build Coastguard Workerwhile getopts "+i:o:f:m:t:T:eOQUAChXY" opt; do 59*08b48e0bSAndroid Build Coastguard Worker 60*08b48e0bSAndroid Build Coastguard Worker case "$opt" in 61*08b48e0bSAndroid Build Coastguard Worker 62*08b48e0bSAndroid Build Coastguard Worker "h") 63*08b48e0bSAndroid Build Coastguard Worker ;; 64*08b48e0bSAndroid Build Coastguard Worker 65*08b48e0bSAndroid Build Coastguard Worker "i") 66*08b48e0bSAndroid Build Coastguard Worker IN_DIR="$OPTARG" 67*08b48e0bSAndroid Build Coastguard Worker ;; 68*08b48e0bSAndroid Build Coastguard Worker 69*08b48e0bSAndroid Build Coastguard Worker "o") 70*08b48e0bSAndroid Build Coastguard Worker OUT_DIR="$OPTARG" 71*08b48e0bSAndroid Build Coastguard Worker ;; 72*08b48e0bSAndroid Build Coastguard Worker "f") 73*08b48e0bSAndroid Build Coastguard Worker STDIN_FILE="$OPTARG" 74*08b48e0bSAndroid Build Coastguard Worker F_ARG=1 75*08b48e0bSAndroid Build Coastguard Worker ;; 76*08b48e0bSAndroid Build Coastguard Worker "m") 77*08b48e0bSAndroid Build Coastguard Worker MEM_LIMIT="$OPTARG" 78*08b48e0bSAndroid Build Coastguard Worker MEM_LIMIT_GIVEN=1 79*08b48e0bSAndroid Build Coastguard Worker ;; 80*08b48e0bSAndroid Build Coastguard Worker "t") 81*08b48e0bSAndroid Build Coastguard Worker TIMEOUT="$OPTARG" 82*08b48e0bSAndroid Build Coastguard Worker ;; 83*08b48e0bSAndroid Build Coastguard Worker "e") 84*08b48e0bSAndroid Build Coastguard Worker EXTRA_PAR="$EXTRA_PAR -e" 85*08b48e0bSAndroid Build Coastguard Worker ;; 86*08b48e0bSAndroid Build Coastguard Worker "A") 87*08b48e0bSAndroid Build Coastguard Worker export AFL_CMIN_ALLOW_ANY=1 88*08b48e0bSAndroid Build Coastguard Worker ;; 89*08b48e0bSAndroid Build Coastguard Worker "C") 90*08b48e0bSAndroid Build Coastguard Worker export AFL_CMIN_CRASHES_ONLY=1 91*08b48e0bSAndroid Build Coastguard Worker ;; 92*08b48e0bSAndroid Build Coastguard Worker "O") 93*08b48e0bSAndroid Build Coastguard Worker EXTRA_PAR="$EXTRA_PAR -O" 94*08b48e0bSAndroid Build Coastguard Worker FRIDA_MODE=1 95*08b48e0bSAndroid Build Coastguard Worker ;; 96*08b48e0bSAndroid Build Coastguard Worker "Q") 97*08b48e0bSAndroid Build Coastguard Worker EXTRA_PAR="$EXTRA_PAR -Q" 98*08b48e0bSAndroid Build Coastguard Worker QEMU_MODE=1 99*08b48e0bSAndroid Build Coastguard Worker ;; 100*08b48e0bSAndroid Build Coastguard Worker "Y") 101*08b48e0bSAndroid Build Coastguard Worker EXTRA_PAR="$EXTRA_PAR -X" 102*08b48e0bSAndroid Build Coastguard Worker NYX_MODE=1 103*08b48e0bSAndroid Build Coastguard Worker ;; 104*08b48e0bSAndroid Build Coastguard Worker "X") 105*08b48e0bSAndroid Build Coastguard Worker EXTRA_PAR="$EXTRA_PAR -X" 106*08b48e0bSAndroid Build Coastguard Worker NYX_MODE=1 107*08b48e0bSAndroid Build Coastguard Worker ;; 108*08b48e0bSAndroid Build Coastguard Worker "U") 109*08b48e0bSAndroid Build Coastguard Worker EXTRA_PAR="$EXTRA_PAR -U" 110*08b48e0bSAndroid Build Coastguard Worker UNICORN_MODE=1 111*08b48e0bSAndroid Build Coastguard Worker ;; 112*08b48e0bSAndroid Build Coastguard Worker "T") 113*08b48e0bSAndroid Build Coastguard Worker T_ARG="$OPTARG" 114*08b48e0bSAndroid Build Coastguard Worker ;; 115*08b48e0bSAndroid Build Coastguard Worker "?") 116*08b48e0bSAndroid Build Coastguard Worker exit 1 117*08b48e0bSAndroid Build Coastguard Worker ;; 118*08b48e0bSAndroid Build Coastguard Worker 119*08b48e0bSAndroid Build Coastguard Worker esac 120*08b48e0bSAndroid Build Coastguard Worker 121*08b48e0bSAndroid Build Coastguard Workerdone 122*08b48e0bSAndroid Build Coastguard Worker 123*08b48e0bSAndroid Build Coastguard Workershift $((OPTIND-1)) 124*08b48e0bSAndroid Build Coastguard Worker 125*08b48e0bSAndroid Build Coastguard WorkerTARGET_BIN="$1" 126*08b48e0bSAndroid Build Coastguard Worker 127*08b48e0bSAndroid Build Coastguard Workerif [ "$TARGET_BIN" = "" -o "$IN_DIR" = "" -o "$OUT_DIR" = "" ]; then 128*08b48e0bSAndroid Build Coastguard Worker 129*08b48e0bSAndroid Build Coastguard Worker cat 1>&2 <<_EOF_ 130*08b48e0bSAndroid Build Coastguard WorkerUsage: $0 [ options ] -- /path/to/target_app [ ... ] 131*08b48e0bSAndroid Build Coastguard Worker 132*08b48e0bSAndroid Build Coastguard WorkerRequired parameters: 133*08b48e0bSAndroid Build Coastguard Worker 134*08b48e0bSAndroid Build Coastguard Worker -i dir - input directory with the starting corpus 135*08b48e0bSAndroid Build Coastguard Worker -o dir - output directory for minimized files 136*08b48e0bSAndroid Build Coastguard Worker 137*08b48e0bSAndroid Build Coastguard WorkerExecution control settings: 138*08b48e0bSAndroid Build Coastguard Worker 139*08b48e0bSAndroid Build Coastguard Worker -T tasks - how many parallel processes to create (default=1, "all"=nproc) 140*08b48e0bSAndroid Build Coastguard Worker -f file - location read by the fuzzed program (default: stdin) 141*08b48e0bSAndroid Build Coastguard Worker -m megs - memory limit for child process (default=$MEM_LIMIT MB) 142*08b48e0bSAndroid Build Coastguard Worker -t msec - run time limit for child process (default: 5000ms) 143*08b48e0bSAndroid Build Coastguard Worker -O - use binary-only instrumentation (FRIDA mode) 144*08b48e0bSAndroid Build Coastguard Worker -Q - use binary-only instrumentation (QEMU mode) 145*08b48e0bSAndroid Build Coastguard Worker -U - use unicorn-based instrumentation (Unicorn mode) 146*08b48e0bSAndroid Build Coastguard Worker -X - use Nyx mode 147*08b48e0bSAndroid Build Coastguard Worker 148*08b48e0bSAndroid Build Coastguard WorkerMinimization settings: 149*08b48e0bSAndroid Build Coastguard Worker 150*08b48e0bSAndroid Build Coastguard Worker -A - allow crashing and timeout inputs 151*08b48e0bSAndroid Build Coastguard Worker -C - keep crashing inputs, reject everything else 152*08b48e0bSAndroid Build Coastguard Worker -e - solve for edge coverage only, ignore hit counts 153*08b48e0bSAndroid Build Coastguard Worker 154*08b48e0bSAndroid Build Coastguard WorkerFor additional tips, please consult README.md. 155*08b48e0bSAndroid Build Coastguard Worker 156*08b48e0bSAndroid Build Coastguard WorkerEnvironment variables used: 157*08b48e0bSAndroid Build Coastguard WorkerAFL_KEEP_TRACES: leave the temporary <out_dir>\.traces directory 158*08b48e0bSAndroid Build Coastguard WorkerAFL_NO_FORKSRV: run target via execve instead of using the forkserver 159*08b48e0bSAndroid Build Coastguard WorkerAFL_PATH: last resort location to find the afl-showmap binary 160*08b48e0bSAndroid Build Coastguard WorkerAFL_SKIP_BIN_CHECK: skip check for target binary 161*08b48e0bSAndroid Build Coastguard WorkerAFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send) 162*08b48e0bSAndroid Build Coastguard WorkerAFL_PYTHON_MODULE: custom mutator library (post_process and send) 163*08b48e0bSAndroid Build Coastguard Worker_EOF_ 164*08b48e0bSAndroid Build Coastguard Worker exit 1 165*08b48e0bSAndroid Build Coastguard Workerfi 166*08b48e0bSAndroid Build Coastguard Worker 167*08b48e0bSAndroid Build Coastguard Worker# Do a sanity check to discourage the use of /tmp, since we can't really 168*08b48e0bSAndroid Build Coastguard Worker# handle this safely from a shell script. 169*08b48e0bSAndroid Build Coastguard Worker 170*08b48e0bSAndroid Build Coastguard Workerif [ "$AFL_ALLOW_TMP" = "" ]; then 171*08b48e0bSAndroid Build Coastguard Worker 172*08b48e0bSAndroid Build Coastguard Worker echo "$IN_DIR" | grep -qE '^(/var)?/tmp/' 173*08b48e0bSAndroid Build Coastguard Worker T1="$?" 174*08b48e0bSAndroid Build Coastguard Worker 175*08b48e0bSAndroid Build Coastguard Worker echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/' 176*08b48e0bSAndroid Build Coastguard Worker T2="$?" 177*08b48e0bSAndroid Build Coastguard Worker 178*08b48e0bSAndroid Build Coastguard Worker echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/' 179*08b48e0bSAndroid Build Coastguard Worker T3="$?" 180*08b48e0bSAndroid Build Coastguard Worker 181*08b48e0bSAndroid Build Coastguard Worker echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/' 182*08b48e0bSAndroid Build Coastguard Worker T4="$?" 183*08b48e0bSAndroid Build Coastguard Worker 184*08b48e0bSAndroid Build Coastguard Worker echo "$PWD" | grep -qE '^(/var)?/tmp/' 185*08b48e0bSAndroid Build Coastguard Worker T5="$?" 186*08b48e0bSAndroid Build Coastguard Worker 187*08b48e0bSAndroid Build Coastguard Worker if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then 188*08b48e0bSAndroid Build Coastguard Worker echo "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." 1>&2 189*08b48e0bSAndroid Build Coastguard Worker fi 190*08b48e0bSAndroid Build Coastguard Worker 191*08b48e0bSAndroid Build Coastguard Workerfi 192*08b48e0bSAndroid Build Coastguard Worker 193*08b48e0bSAndroid Build Coastguard Worker# If @@ is specified, but there's no -f, let's come up with a temporary input 194*08b48e0bSAndroid Build Coastguard Worker# file name. 195*08b48e0bSAndroid Build Coastguard Worker 196*08b48e0bSAndroid Build Coastguard WorkerTRACE_DIR="$OUT_DIR/.traces" 197*08b48e0bSAndroid Build Coastguard Worker 198*08b48e0bSAndroid Build Coastguard Workerif [ "$STDIN_FILE" = "" ]; then 199*08b48e0bSAndroid Build Coastguard Worker 200*08b48e0bSAndroid Build Coastguard Worker if echo "$*" | grep -qF '@@'; then 201*08b48e0bSAndroid Build Coastguard Worker STDIN_FILE="$TRACE_DIR/.cur_input" 202*08b48e0bSAndroid Build Coastguard Worker fi 203*08b48e0bSAndroid Build Coastguard Worker 204*08b48e0bSAndroid Build Coastguard Workerfi 205*08b48e0bSAndroid Build Coastguard Worker 206*08b48e0bSAndroid Build Coastguard Worker# Check for obvious errors. 207*08b48e0bSAndroid Build Coastguard Worker 208*08b48e0bSAndroid Build Coastguard Workerif [ ! "$T_ARG" = "" -a -n "$F_ARG" -a ! "$NYX_MODE" == 1 ]; then 209*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: -T and -f can not be used together." 1>&2 210*08b48e0bSAndroid Build Coastguard Worker exit 1 211*08b48e0bSAndroid Build Coastguard Workerfi 212*08b48e0bSAndroid Build Coastguard Worker 213*08b48e0bSAndroid Build Coastguard Workerif [ ! "$MEM_LIMIT" = "none" ]; then 214*08b48e0bSAndroid Build Coastguard Worker 215*08b48e0bSAndroid Build Coastguard Worker if [ "$MEM_LIMIT" -lt "5" ]; then 216*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: dangerously low memory limit." 1>&2 217*08b48e0bSAndroid Build Coastguard Worker exit 1 218*08b48e0bSAndroid Build Coastguard Worker fi 219*08b48e0bSAndroid Build Coastguard Worker 220*08b48e0bSAndroid Build Coastguard Workerfi 221*08b48e0bSAndroid Build Coastguard Worker 222*08b48e0bSAndroid Build Coastguard Workerif [ ! "$TIMEOUT" = "none" ]; then 223*08b48e0bSAndroid Build Coastguard Worker 224*08b48e0bSAndroid Build Coastguard Worker if [ "$TIMEOUT" -lt "10" ]; then 225*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: dangerously low timeout." 1>&2 226*08b48e0bSAndroid Build Coastguard Worker exit 1 227*08b48e0bSAndroid Build Coastguard Worker fi 228*08b48e0bSAndroid Build Coastguard Worker 229*08b48e0bSAndroid Build Coastguard Workerfi 230*08b48e0bSAndroid Build Coastguard Worker 231*08b48e0bSAndroid Build Coastguard Workerif [ "$NYX_MODE" = "" ]; then 232*08b48e0bSAndroid Build Coastguard Worker if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then 233*08b48e0bSAndroid Build Coastguard Worker 234*08b48e0bSAndroid Build Coastguard Worker TNEW="`which "$TARGET_BIN" 2>/dev/null`" 235*08b48e0bSAndroid Build Coastguard Worker 236*08b48e0bSAndroid Build Coastguard Worker if [ ! -f "$TNEW" -o ! -x "$TNEW" ]; then 237*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: binary '$TARGET_BIN' not found or not executable." 1>&2 238*08b48e0bSAndroid Build Coastguard Worker exit 1 239*08b48e0bSAndroid Build Coastguard Worker fi 240*08b48e0bSAndroid Build Coastguard Worker 241*08b48e0bSAndroid Build Coastguard Worker TARGET_BIN="$TNEW" 242*08b48e0bSAndroid Build Coastguard Worker 243*08b48e0bSAndroid Build Coastguard Worker fi 244*08b48e0bSAndroid Build Coastguard Worker 245*08b48e0bSAndroid Build Coastguard Workerfi 246*08b48e0bSAndroid Build Coastguard Worker 247*08b48e0bSAndroid Build Coastguard Workergrep -aq AFL_DUMP_MAP_SIZE "$TARGET_BIN" && { 248*08b48e0bSAndroid Build Coastguard Worker echo "[!] Trying to obtain the map size of the target ..." 249*08b48e0bSAndroid Build Coastguard Worker MAPSIZE=`AFL_DUMP_MAP_SIZE=1 "./$TARGET_BIN" 2>/dev/null` 250*08b48e0bSAndroid Build Coastguard Worker test -n "$MAPSIZE" && { 251*08b48e0bSAndroid Build Coastguard Worker export AFL_MAP_SIZE=$MAPSIZE 252*08b48e0bSAndroid Build Coastguard Worker echo "[+] Setting AFL_MAP_SIZE=$MAPSIZE" 253*08b48e0bSAndroid Build Coastguard Worker } 254*08b48e0bSAndroid Build Coastguard Worker} 255*08b48e0bSAndroid Build Coastguard Worker 256*08b48e0bSAndroid Build Coastguard Workerif [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" -a "$NYX_MODE" = "" ]; then 257*08b48e0bSAndroid Build Coastguard Worker 258*08b48e0bSAndroid Build Coastguard Worker if ! grep -qF "__AFL_SHM_ID" "$TARGET_BIN"; then 259*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: binary '$TARGET_BIN' doesn't appear to be instrumented." 1>&2 260*08b48e0bSAndroid Build Coastguard Worker exit 1 261*08b48e0bSAndroid Build Coastguard Worker fi 262*08b48e0bSAndroid Build Coastguard Worker 263*08b48e0bSAndroid Build Coastguard Workerfi 264*08b48e0bSAndroid Build Coastguard Worker 265*08b48e0bSAndroid Build Coastguard Workerif [ ! -d "$IN_DIR" ]; then 266*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: directory '$IN_DIR' not found." 1>&2 267*08b48e0bSAndroid Build Coastguard Worker exit 1 268*08b48e0bSAndroid Build Coastguard Workerfi 269*08b48e0bSAndroid Build Coastguard Worker 270*08b48e0bSAndroid Build Coastguard Workertest -d "$IN_DIR/default" && IN_DIR="$IN_DIR/default" 271*08b48e0bSAndroid Build Coastguard Workertest -d "$IN_DIR/queue" && IN_DIR="$IN_DIR/queue" 272*08b48e0bSAndroid Build Coastguard Worker 273*08b48e0bSAndroid Build Coastguard Workerfind "$OUT_DIR" -name 'id[:_]*' -maxdepth 1 -exec rm -- {} \; 2>/dev/null 274*08b48e0bSAndroid Build Coastguard Workerrm -rf "$TRACE_DIR" 2>/dev/null 275*08b48e0bSAndroid Build Coastguard Worker 276*08b48e0bSAndroid Build Coastguard Workerrmdir "$OUT_DIR" 2>/dev/null 277*08b48e0bSAndroid Build Coastguard Worker 278*08b48e0bSAndroid Build Coastguard Workerif [ -d "$OUT_DIR" ]; then 279*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: directory '$OUT_DIR' exists and is not empty - delete it first." 1>&2 280*08b48e0bSAndroid Build Coastguard Worker exit 1 281*08b48e0bSAndroid Build Coastguard Workerfi 282*08b48e0bSAndroid Build Coastguard Worker 283*08b48e0bSAndroid Build Coastguard Workermkdir -m 700 -p "$TRACE_DIR" || exit 1 284*08b48e0bSAndroid Build Coastguard Worker 285*08b48e0bSAndroid Build Coastguard Workerif [ ! "$STDIN_FILE" = "" ]; then 286*08b48e0bSAndroid Build Coastguard Worker rm -f "$STDIN_FILE" || exit 1 287*08b48e0bSAndroid Build Coastguard Worker touch "$STDIN_FILE" || exit 1 288*08b48e0bSAndroid Build Coastguard Workerfi 289*08b48e0bSAndroid Build Coastguard Worker 290*08b48e0bSAndroid Build Coastguard WorkerSHOWMAP=`command -v afl-showmap 2>/dev/null` 291*08b48e0bSAndroid Build Coastguard Worker 292*08b48e0bSAndroid Build Coastguard Workerif [ -z "$SHOWMAP" ]; then 293*08b48e0bSAndroid Build Coastguard Worker TMP="${0%/afl-cmin.bash}/afl-showmap" 294*08b48e0bSAndroid Build Coastguard Worker if [ -x "$TMP" ]; then 295*08b48e0bSAndroid Build Coastguard Worker SHOWMAP=$TMP 296*08b48e0bSAndroid Build Coastguard Worker fi 297*08b48e0bSAndroid Build Coastguard Workerfi 298*08b48e0bSAndroid Build Coastguard Worker 299*08b48e0bSAndroid Build Coastguard Workerif [ -z "$SHOWMAP" -a -x "./afl-showmap" ]; then 300*08b48e0bSAndroid Build Coastguard Worker SHOWMAP="./afl-showmap" 301*08b48e0bSAndroid Build Coastguard Workerelse 302*08b48e0bSAndroid Build Coastguard Worker if [ -n "$AFL_PATH" ]; then 303*08b48e0bSAndroid Build Coastguard Worker SHOWMAP="$AFL_PATH/afl-showmap" 304*08b48e0bSAndroid Build Coastguard Worker fi 305*08b48e0bSAndroid Build Coastguard Workerfi 306*08b48e0bSAndroid Build Coastguard Worker 307*08b48e0bSAndroid Build Coastguard Workerif [ ! -x "$SHOWMAP" ]; then 308*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: can't find 'afl-showmap' - please set AFL_PATH." 1>&2 309*08b48e0bSAndroid Build Coastguard Worker rm -rf "$TRACE_DIR" 310*08b48e0bSAndroid Build Coastguard Worker exit 1 311*08b48e0bSAndroid Build Coastguard Workerfi 312*08b48e0bSAndroid Build Coastguard Worker 313*08b48e0bSAndroid Build Coastguard WorkerTHREADS= 314*08b48e0bSAndroid Build Coastguard Workerif [ ! "$T_ARG" = "" ]; then 315*08b48e0bSAndroid Build Coastguard Worker if [ "$T_ARG" = "all" ]; then 316*08b48e0bSAndroid Build Coastguard Worker THREADS=$(nproc) 317*08b48e0bSAndroid Build Coastguard Worker else 318*08b48e0bSAndroid Build Coastguard Worker if [ "$T_ARG" -gt 1 -a "$T_ARG" -le "$(nproc)" ]; then 319*08b48e0bSAndroid Build Coastguard Worker THREADS=$T_ARG 320*08b48e0bSAndroid Build Coastguard Worker else 321*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: -T parameter must between 2 and $(nproc) or \"all\"." 1>&2 322*08b48e0bSAndroid Build Coastguard Worker fi 323*08b48e0bSAndroid Build Coastguard Worker fi 324*08b48e0bSAndroid Build Coastguard Workerelse 325*08b48e0bSAndroid Build Coastguard Worker if [ -z "$F_ARG" ]; then 326*08b48e0bSAndroid Build Coastguard Worker echo "[*] Are you aware of the '-T all' parallelize option that massively improves the speed?" 327*08b48e0bSAndroid Build Coastguard Worker fi 328*08b48e0bSAndroid Build Coastguard Workerfi 329*08b48e0bSAndroid Build Coastguard Worker 330*08b48e0bSAndroid Build Coastguard WorkerIN_COUNT=$((`ls -- "$IN_DIR" 2>/dev/null | wc -l`)) 331*08b48e0bSAndroid Build Coastguard Worker 332*08b48e0bSAndroid Build Coastguard Workerif [ "$IN_COUNT" = "0" ]; then 333*08b48e0bSAndroid Build Coastguard Worker echo "[-] Hmm, no inputs in the target directory. Nothing to be done." 334*08b48e0bSAndroid Build Coastguard Worker rm -rf "$TRACE_DIR" 335*08b48e0bSAndroid Build Coastguard Worker exit 1 336*08b48e0bSAndroid Build Coastguard Workerfi 337*08b48e0bSAndroid Build Coastguard Worker 338*08b48e0bSAndroid Build Coastguard Workerecho "[*] Are you aware that afl-cmin is faster than this afl-cmin.bash script?" 339*08b48e0bSAndroid Build Coastguard Workerecho "[+] Found $IN_COUNT files for minimizing." 340*08b48e0bSAndroid Build Coastguard Worker 341*08b48e0bSAndroid Build Coastguard Workerif [ -n "$THREADS" ]; then 342*08b48e0bSAndroid Build Coastguard Worker if [ "$IN_COUNT" -lt "$THREADS" ]; then 343*08b48e0bSAndroid Build Coastguard Worker THREADS=$IN_COUNT 344*08b48e0bSAndroid Build Coastguard Worker echo "[!] WARNING: less inputs than threads, reducing threads to $THREADS and likely the overhead of threading makes things slower..." 345*08b48e0bSAndroid Build Coastguard Worker fi 346*08b48e0bSAndroid Build Coastguard Workerfi 347*08b48e0bSAndroid Build Coastguard Worker 348*08b48e0bSAndroid Build Coastguard WorkerFIRST_FILE=`ls "$IN_DIR" | head -1` 349*08b48e0bSAndroid Build Coastguard Worker 350*08b48e0bSAndroid Build Coastguard Worker# Make sure that we're not dealing with a directory. 351*08b48e0bSAndroid Build Coastguard Worker 352*08b48e0bSAndroid Build Coastguard Workerif [ -d "$IN_DIR/$FIRST_FILE" ]; then 353*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: The target directory contains subdirectories - please fix." 1>&2 354*08b48e0bSAndroid Build Coastguard Worker rm -rf "$TRACE_DIR" 355*08b48e0bSAndroid Build Coastguard Worker exit 1 356*08b48e0bSAndroid Build Coastguard Workerfi 357*08b48e0bSAndroid Build Coastguard Worker 358*08b48e0bSAndroid Build Coastguard Worker# Check for the more efficient way to copy files... 359*08b48e0bSAndroid Build Coastguard Worker 360*08b48e0bSAndroid Build Coastguard Workerif ln "$IN_DIR/$FIRST_FILE" "$TRACE_DIR/.link_test" 2>/dev/null; then 361*08b48e0bSAndroid Build Coastguard Worker CP_TOOL=ln 362*08b48e0bSAndroid Build Coastguard Workerelse 363*08b48e0bSAndroid Build Coastguard Worker CP_TOOL=cp 364*08b48e0bSAndroid Build Coastguard Workerfi 365*08b48e0bSAndroid Build Coastguard Worker 366*08b48e0bSAndroid Build Coastguard Worker# Make sure that we can actually get anything out of afl-showmap before we 367*08b48e0bSAndroid Build Coastguard Worker# waste too much time. 368*08b48e0bSAndroid Build Coastguard Worker 369*08b48e0bSAndroid Build Coastguard Workerecho "[*] Testing the target binary..." 370*08b48e0bSAndroid Build Coastguard Worker 371*08b48e0bSAndroid Build Coastguard Workerif [ "$STDIN_FILE" = "" ]; then 372*08b48e0bSAndroid Build Coastguard Worker 373*08b48e0bSAndroid Build Coastguard Worker AFL_CMIN_ALLOW_ANY=1 "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/.run_test" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$FIRST_FILE" 374*08b48e0bSAndroid Build Coastguard Worker 375*08b48e0bSAndroid Build Coastguard Workerelse 376*08b48e0bSAndroid Build Coastguard Worker 377*08b48e0bSAndroid Build Coastguard Worker cp "$IN_DIR/$FIRST_FILE" "$STDIN_FILE" 378*08b48e0bSAndroid Build Coastguard Worker AFL_CMIN_ALLOW_ANY=1 "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/.run_test" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null 379*08b48e0bSAndroid Build Coastguard Worker 380*08b48e0bSAndroid Build Coastguard Workerfi 381*08b48e0bSAndroid Build Coastguard Worker 382*08b48e0bSAndroid Build Coastguard WorkerFIRST_COUNT=$((`grep -c . "$TRACE_DIR/.run_test"`)) 383*08b48e0bSAndroid Build Coastguard Worker 384*08b48e0bSAndroid Build Coastguard Workerif [ "$FIRST_COUNT" -gt "0" ]; then 385*08b48e0bSAndroid Build Coastguard Worker 386*08b48e0bSAndroid Build Coastguard Worker echo "[+] OK, $FIRST_COUNT tuples recorded." 387*08b48e0bSAndroid Build Coastguard Worker 388*08b48e0bSAndroid Build Coastguard Workerelse 389*08b48e0bSAndroid Build Coastguard Worker 390*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: no instrumentation output detected (perhaps crash or timeout)." 1>&2 391*08b48e0bSAndroid Build Coastguard Worker test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR" 392*08b48e0bSAndroid Build Coastguard Worker exit 1 393*08b48e0bSAndroid Build Coastguard Worker 394*08b48e0bSAndroid Build Coastguard Workerfi 395*08b48e0bSAndroid Build Coastguard Worker 396*08b48e0bSAndroid Build Coastguard WorkerTMPFILE=$OUT_DIR/.list.$$ 397*08b48e0bSAndroid Build Coastguard Workerif [ ! "$THREADS" = "" ]; then 398*08b48e0bSAndroid Build Coastguard Worker ls -- "$IN_DIR" > $TMPFILE 2>/dev/null 399*08b48e0bSAndroid Build Coastguard Worker IN_COUNT=$(cat $TMPFILE | wc -l) 400*08b48e0bSAndroid Build Coastguard Worker SPLIT=$(($IN_COUNT / $THREADS)) 401*08b48e0bSAndroid Build Coastguard Worker if [ "$(($IN_COUNT % $THREADS))" -gt 0 ]; then 402*08b48e0bSAndroid Build Coastguard Worker SPLIT=$(($SPLIT + 1)) 403*08b48e0bSAndroid Build Coastguard Worker fi 404*08b48e0bSAndroid Build Coastguard Worker echo "[+] Splitting workload into $THREADS tasks with $SPLIT items on average each." 405*08b48e0bSAndroid Build Coastguard Worker split -l $SPLIT $TMPFILE $TMPFILE. 406*08b48e0bSAndroid Build Coastguard Workerfi 407*08b48e0bSAndroid Build Coastguard Worker 408*08b48e0bSAndroid Build Coastguard Worker# Let's roll! 409*08b48e0bSAndroid Build Coastguard Worker 410*08b48e0bSAndroid Build Coastguard Worker############################# 411*08b48e0bSAndroid Build Coastguard Worker# STEP 1: COLLECTING TRACES # 412*08b48e0bSAndroid Build Coastguard Worker############################# 413*08b48e0bSAndroid Build Coastguard Worker 414*08b48e0bSAndroid Build Coastguard Workerecho "[*] Obtaining traces for input files in '$IN_DIR'..." 415*08b48e0bSAndroid Build Coastguard Worker 416*08b48e0bSAndroid Build Coastguard Workerif [ "$THREADS" = "" ]; then 417*08b48e0bSAndroid Build Coastguard Worker( 418*08b48e0bSAndroid Build Coastguard Worker 419*08b48e0bSAndroid Build Coastguard Worker CUR=0 420*08b48e0bSAndroid Build Coastguard Worker 421*08b48e0bSAndroid Build Coastguard Worker if [ "$STDIN_FILE" = "" ]; then 422*08b48e0bSAndroid Build Coastguard Worker 423*08b48e0bSAndroid Build Coastguard Worker ls "$IN_DIR" | while read -r fn; do 424*08b48e0bSAndroid Build Coastguard Worker 425*08b48e0bSAndroid Build Coastguard Worker if [ -s "$IN_DIR/$fn" ]; then 426*08b48e0bSAndroid Build Coastguard Worker 427*08b48e0bSAndroid Build Coastguard Worker CUR=$((CUR+1)) 428*08b48e0bSAndroid Build Coastguard Worker printf "\\r Processing file $CUR/$IN_COUNT... " 429*08b48e0bSAndroid Build Coastguard Worker 430*08b48e0bSAndroid Build Coastguard Worker "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn" 431*08b48e0bSAndroid Build Coastguard Worker 432*08b48e0bSAndroid Build Coastguard Worker fi 433*08b48e0bSAndroid Build Coastguard Worker 434*08b48e0bSAndroid Build Coastguard Worker done 435*08b48e0bSAndroid Build Coastguard Worker 436*08b48e0bSAndroid Build Coastguard Worker else 437*08b48e0bSAndroid Build Coastguard Worker 438*08b48e0bSAndroid Build Coastguard Worker ls "$IN_DIR" | while read -r fn; do 439*08b48e0bSAndroid Build Coastguard Worker 440*08b48e0bSAndroid Build Coastguard Worker if [ -s "$IN_DIR/$fn" ]; then 441*08b48e0bSAndroid Build Coastguard Worker 442*08b48e0bSAndroid Build Coastguard Worker CUR=$((CUR+1)) 443*08b48e0bSAndroid Build Coastguard Worker printf "\\r Processing file $CUR/$IN_COUNT... " 444*08b48e0bSAndroid Build Coastguard Worker 445*08b48e0bSAndroid Build Coastguard Worker cp "$IN_DIR/$fn" "$STDIN_FILE" 446*08b48e0bSAndroid Build Coastguard Worker "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null 447*08b48e0bSAndroid Build Coastguard Worker 448*08b48e0bSAndroid Build Coastguard Worker fi 449*08b48e0bSAndroid Build Coastguard Worker 450*08b48e0bSAndroid Build Coastguard Worker done 451*08b48e0bSAndroid Build Coastguard Worker 452*08b48e0bSAndroid Build Coastguard Worker fi 453*08b48e0bSAndroid Build Coastguard Worker 454*08b48e0bSAndroid Build Coastguard Worker echo 455*08b48e0bSAndroid Build Coastguard Worker 456*08b48e0bSAndroid Build Coastguard Worker) 457*08b48e0bSAndroid Build Coastguard Worker 458*08b48e0bSAndroid Build Coastguard Workerelse 459*08b48e0bSAndroid Build Coastguard Worker 460*08b48e0bSAndroid Build Coastguard Worker PIDS= 461*08b48e0bSAndroid Build Coastguard Worker CNT=0 462*08b48e0bSAndroid Build Coastguard Worker for inputs in $(ls ${TMPFILE}.*); do 463*08b48e0bSAndroid Build Coastguard Worker 464*08b48e0bSAndroid Build Coastguard Worker( 465*08b48e0bSAndroid Build Coastguard Worker 466*08b48e0bSAndroid Build Coastguard Worker if [ "$STDIN_FILE" = "" ]; then 467*08b48e0bSAndroid Build Coastguard Worker 468*08b48e0bSAndroid Build Coastguard Worker cat $inputs | while read -r fn; do 469*08b48e0bSAndroid Build Coastguard Worker 470*08b48e0bSAndroid Build Coastguard Worker if [ -s "$IN_DIR/$fn" ]; then 471*08b48e0bSAndroid Build Coastguard Worker 472*08b48e0bSAndroid Build Coastguard Worker "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn" 473*08b48e0bSAndroid Build Coastguard Worker 474*08b48e0bSAndroid Build Coastguard Worker fi 475*08b48e0bSAndroid Build Coastguard Worker 476*08b48e0bSAndroid Build Coastguard Worker done 477*08b48e0bSAndroid Build Coastguard Worker 478*08b48e0bSAndroid Build Coastguard Worker else 479*08b48e0bSAndroid Build Coastguard Worker 480*08b48e0bSAndroid Build Coastguard Worker if [ -s "$IN_DIR/$fn" ]; then 481*08b48e0bSAndroid Build Coastguard Worker STDIN_FILE="$inputs.$$" 482*08b48e0bSAndroid Build Coastguard Worker cat $inputs | while read -r fn; do 483*08b48e0bSAndroid Build Coastguard Worker 484*08b48e0bSAndroid Build Coastguard Worker cp "$IN_DIR/$fn" "$STDIN_FILE" 485*08b48e0bSAndroid Build Coastguard Worker "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@" </dev/null 486*08b48e0bSAndroid Build Coastguard Worker 487*08b48e0bSAndroid Build Coastguard Worker done 488*08b48e0bSAndroid Build Coastguard Worker 489*08b48e0bSAndroid Build Coastguard Worker fi 490*08b48e0bSAndroid Build Coastguard Worker 491*08b48e0bSAndroid Build Coastguard Worker fi 492*08b48e0bSAndroid Build Coastguard Worker 493*08b48e0bSAndroid Build Coastguard Worker) & 494*08b48e0bSAndroid Build Coastguard Worker 495*08b48e0bSAndroid Build Coastguard Worker PIDS="$PIDS $!" 496*08b48e0bSAndroid Build Coastguard Worker done 497*08b48e0bSAndroid Build Coastguard Worker 498*08b48e0bSAndroid Build Coastguard Worker echo "[+] Waiting for running tasks IDs:$PIDS" 499*08b48e0bSAndroid Build Coastguard Worker wait 500*08b48e0bSAndroid Build Coastguard Worker echo "[+] all $THREADS running tasks completed." 501*08b48e0bSAndroid Build Coastguard Worker rm -f ${TMPFILE}* 502*08b48e0bSAndroid Build Coastguard Worker 503*08b48e0bSAndroid Build Coastguard Worker #echo trace dir files: $(ls $TRACE_DIR/*|wc -l) 504*08b48e0bSAndroid Build Coastguard Worker 505*08b48e0bSAndroid Build Coastguard Workerfi 506*08b48e0bSAndroid Build Coastguard Worker 507*08b48e0bSAndroid Build Coastguard Worker 508*08b48e0bSAndroid Build Coastguard Worker########################## 509*08b48e0bSAndroid Build Coastguard Worker# STEP 2: SORTING TUPLES # 510*08b48e0bSAndroid Build Coastguard Worker########################## 511*08b48e0bSAndroid Build Coastguard Worker 512*08b48e0bSAndroid Build Coastguard Worker# With this out of the way, we sort all tuples by popularity across all 513*08b48e0bSAndroid Build Coastguard Worker# datasets. The reasoning here is that we won't be able to avoid the files 514*08b48e0bSAndroid Build Coastguard Worker# that trigger unique tuples anyway, so we will want to start with them and 515*08b48e0bSAndroid Build Coastguard Worker# see what's left. 516*08b48e0bSAndroid Build Coastguard Worker 517*08b48e0bSAndroid Build Coastguard Workerecho "[*] Sorting trace sets (this may take a while)..." 518*08b48e0bSAndroid Build Coastguard Worker 519*08b48e0bSAndroid Build Coastguard Workerls "$IN_DIR" | sed "s#^#$TRACE_DIR/#" | tr '\n' '\0' | xargs -0 -n 1 cat | \ 520*08b48e0bSAndroid Build Coastguard Worker sort | uniq -c | sort -k 1,1 -n >"$TRACE_DIR/.all_uniq" 521*08b48e0bSAndroid Build Coastguard Worker 522*08b48e0bSAndroid Build Coastguard WorkerTUPLE_COUNT=$((`grep -c . "$TRACE_DIR/.all_uniq"`)) 523*08b48e0bSAndroid Build Coastguard Worker 524*08b48e0bSAndroid Build Coastguard Workerecho "[+] Found $TUPLE_COUNT unique tuples across $IN_COUNT files." 525*08b48e0bSAndroid Build Coastguard Worker 526*08b48e0bSAndroid Build Coastguard Worker##################################### 527*08b48e0bSAndroid Build Coastguard Worker# STEP 3: SELECTING CANDIDATE FILES # 528*08b48e0bSAndroid Build Coastguard Worker##################################### 529*08b48e0bSAndroid Build Coastguard Worker 530*08b48e0bSAndroid Build Coastguard Worker# The next step is to find the best candidate for each tuple. The "best" 531*08b48e0bSAndroid Build Coastguard Worker# part is understood simply as the smallest input that includes a particular 532*08b48e0bSAndroid Build Coastguard Worker# tuple in its trace. Empirical evidence suggests that this produces smaller 533*08b48e0bSAndroid Build Coastguard Worker# datasets than more involved algorithms that could be still pulled off in 534*08b48e0bSAndroid Build Coastguard Worker# a shell script. 535*08b48e0bSAndroid Build Coastguard Worker 536*08b48e0bSAndroid Build Coastguard Workerecho "[*] Finding best candidates for each tuple..." 537*08b48e0bSAndroid Build Coastguard Worker 538*08b48e0bSAndroid Build Coastguard WorkerCUR=0 539*08b48e0bSAndroid Build Coastguard Worker 540*08b48e0bSAndroid Build Coastguard Workerls -rS "$IN_DIR" | while read -r fn; do 541*08b48e0bSAndroid Build Coastguard Worker 542*08b48e0bSAndroid Build Coastguard Worker CUR=$((CUR+1)) 543*08b48e0bSAndroid Build Coastguard Worker printf "\\r Processing file $CUR/$IN_COUNT... " 544*08b48e0bSAndroid Build Coastguard Worker 545*08b48e0bSAndroid Build Coastguard Worker sed "s#\$# $fn#" "$TRACE_DIR/$fn" >>"$TRACE_DIR/.candidate_list" 546*08b48e0bSAndroid Build Coastguard Worker 547*08b48e0bSAndroid Build Coastguard Worker test -s "$TRACE_DIR/$fn" || echo Warning: $fn is ignored because of crashing the target 548*08b48e0bSAndroid Build Coastguard Worker 549*08b48e0bSAndroid Build Coastguard Workerdone 550*08b48e0bSAndroid Build Coastguard Worker 551*08b48e0bSAndroid Build Coastguard Workerecho 552*08b48e0bSAndroid Build Coastguard Worker 553*08b48e0bSAndroid Build Coastguard Worker############################## 554*08b48e0bSAndroid Build Coastguard Worker# STEP 4: LOADING CANDIDATES # 555*08b48e0bSAndroid Build Coastguard Worker############################## 556*08b48e0bSAndroid Build Coastguard Worker 557*08b48e0bSAndroid Build Coastguard Worker# At this point, we have a file of tuple-file pairs, sorted by file size 558*08b48e0bSAndroid Build Coastguard Worker# in ascending order (as a consequence of ls -rS). By doing sort keyed 559*08b48e0bSAndroid Build Coastguard Worker# only by tuple (-k 1,1) and configured to output only the first line for 560*08b48e0bSAndroid Build Coastguard Worker# every key (-s -u), we end up with the smallest file for each tuple. 561*08b48e0bSAndroid Build Coastguard Worker 562*08b48e0bSAndroid Build Coastguard Workerecho "[*] Sorting candidate list (be patient)..." 563*08b48e0bSAndroid Build Coastguard Worker 564*08b48e0bSAndroid Build Coastguard Workersort -k1,1 -s -u "$TRACE_DIR/.candidate_list" | \ 565*08b48e0bSAndroid Build Coastguard Worker sed 's/^/BEST_FILE[/;s/ /]="/;s/$/"/' >"$TRACE_DIR/.candidate_script" 566*08b48e0bSAndroid Build Coastguard Worker 567*08b48e0bSAndroid Build Coastguard Workerif [ ! -s "$TRACE_DIR/.candidate_script" ]; then 568*08b48e0bSAndroid Build Coastguard Worker echo "[-] Error: no traces obtained from test cases, check syntax!" 1>&2 569*08b48e0bSAndroid Build Coastguard Worker test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR" 570*08b48e0bSAndroid Build Coastguard Worker exit 1 571*08b48e0bSAndroid Build Coastguard Workerfi 572*08b48e0bSAndroid Build Coastguard Worker 573*08b48e0bSAndroid Build Coastguard Worker# The sed command converted the sorted list to a shell script that populates 574*08b48e0bSAndroid Build Coastguard Worker# BEST_FILE[tuple]="fname". Let's load that! 575*08b48e0bSAndroid Build Coastguard Worker 576*08b48e0bSAndroid Build Coastguard Worker. "$TRACE_DIR/.candidate_script" 577*08b48e0bSAndroid Build Coastguard Worker 578*08b48e0bSAndroid Build Coastguard Worker########################## 579*08b48e0bSAndroid Build Coastguard Worker# STEP 5: WRITING OUTPUT # 580*08b48e0bSAndroid Build Coastguard Worker########################## 581*08b48e0bSAndroid Build Coastguard Worker 582*08b48e0bSAndroid Build Coastguard Worker# The final trick is to grab the top pick for each tuple, unless said tuple is 583*08b48e0bSAndroid Build Coastguard Worker# already set due to the inclusion of an earlier candidate; and then put all 584*08b48e0bSAndroid Build Coastguard Worker# tuples associated with the newly-added file to the "already have" list. The 585*08b48e0bSAndroid Build Coastguard Worker# loop works from least popular tuples and toward the most common ones. 586*08b48e0bSAndroid Build Coastguard Worker 587*08b48e0bSAndroid Build Coastguard Workerecho "[*] Processing candidates and writing output files..." 588*08b48e0bSAndroid Build Coastguard Worker 589*08b48e0bSAndroid Build Coastguard WorkerCUR=0 590*08b48e0bSAndroid Build Coastguard Worker 591*08b48e0bSAndroid Build Coastguard Workertouch "$TRACE_DIR/.already_have" 592*08b48e0bSAndroid Build Coastguard Worker 593*08b48e0bSAndroid Build Coastguard Workerwhile read -r cnt tuple; do 594*08b48e0bSAndroid Build Coastguard Worker 595*08b48e0bSAndroid Build Coastguard Worker CUR=$((CUR+1)) 596*08b48e0bSAndroid Build Coastguard Worker printf "\\r Processing tuple $CUR/$TUPLE_COUNT with count $cnt... " 597*08b48e0bSAndroid Build Coastguard Worker 598*08b48e0bSAndroid Build Coastguard Worker # If we already have this tuple, skip it. 599*08b48e0bSAndroid Build Coastguard Worker 600*08b48e0bSAndroid Build Coastguard Worker grep -q "^$tuple\$" "$TRACE_DIR/.already_have" && continue 601*08b48e0bSAndroid Build Coastguard Worker 602*08b48e0bSAndroid Build Coastguard Worker FN=${BEST_FILE[tuple]} 603*08b48e0bSAndroid Build Coastguard Worker 604*08b48e0bSAndroid Build Coastguard Worker# echo "tuple nr $CUR ($tuple cnt=$cnt) -> $FN" >> "$TRACE_DIR/.log" 605*08b48e0bSAndroid Build Coastguard Worker $CP_TOOL "$IN_DIR/$FN" "$OUT_DIR/$FN" 606*08b48e0bSAndroid Build Coastguard Worker 607*08b48e0bSAndroid Build Coastguard Worker if [ "$((CUR % 5))" = "0" ]; then 608*08b48e0bSAndroid Build Coastguard Worker sort -u "$TRACE_DIR/$FN" "$TRACE_DIR/.already_have" >"$TRACE_DIR/.tmp" 609*08b48e0bSAndroid Build Coastguard Worker mv -f "$TRACE_DIR/.tmp" "$TRACE_DIR/.already_have" 610*08b48e0bSAndroid Build Coastguard Worker else 611*08b48e0bSAndroid Build Coastguard Worker cat "$TRACE_DIR/$FN" >>"$TRACE_DIR/.already_have" 612*08b48e0bSAndroid Build Coastguard Worker fi 613*08b48e0bSAndroid Build Coastguard Worker 614*08b48e0bSAndroid Build Coastguard Workerdone <"$TRACE_DIR/.all_uniq" 615*08b48e0bSAndroid Build Coastguard Worker 616*08b48e0bSAndroid Build Coastguard Workerecho 617*08b48e0bSAndroid Build Coastguard Worker 618*08b48e0bSAndroid Build Coastguard WorkerOUT_COUNT=`ls -- "$OUT_DIR" | wc -l` 619*08b48e0bSAndroid Build Coastguard Worker 620*08b48e0bSAndroid Build Coastguard Workerif [ "$OUT_COUNT" = "1" ]; then 621*08b48e0bSAndroid Build Coastguard Worker echo "[!] WARNING: All test cases had the same traces, check syntax!" 622*08b48e0bSAndroid Build Coastguard Workerfi 623*08b48e0bSAndroid Build Coastguard Worker 624*08b48e0bSAndroid Build Coastguard Workerecho "[+] Narrowed down to $OUT_COUNT files, saved in '$OUT_DIR'." 625*08b48e0bSAndroid Build Coastguard Workerecho 626*08b48e0bSAndroid Build Coastguard Worker 627*08b48e0bSAndroid Build Coastguard Workertest "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR" 628*08b48e0bSAndroid Build Coastguard Worker 629*08b48e0bSAndroid Build Coastguard Workerexit 0 630