Lines Matching +full:- +full:qe
3 # american fuzzy lop++ - corpus minimization tool
4 # ---------------------------------------------
10 # Copyright 2019-2024 AFLplusplus
16 # https://www.apache.org/licenses/LICENSE-2.0
22 # - Screening large corpora of input files before using them as a seed for
23 # afl-fuzz. The tool will remove functionally redundant files and likely
26 # (In this case, you probably also want to consider running afl-tmin on
29 # - Minimizing the corpus generated organically by afl-fuzz, perhaps when
30 # planning to feed it to more resource-intensive tools. The tool achieves
35 # afl-tmin.
41 echo "corpus minimization tool for afl-fuzz"
48 # Process command-line options...
84 EXTRA_PAR="$EXTRA_PAR -e"
93 EXTRA_PAR="$EXTRA_PAR -O"
97 EXTRA_PAR="$EXTRA_PAR -Q"
101 EXTRA_PAR="$EXTRA_PAR -X"
105 EXTRA_PAR="$EXTRA_PAR -X"
109 EXTRA_PAR="$EXTRA_PAR -U"
123 shift $((OPTIND-1))
127 if [ "$TARGET_BIN" = "" -o "$IN_DIR" = "" -o "$OUT_DIR" = "" ]; then
130 Usage: $0 [ options ] -- /path/to/target_app [ ... ]
134 -i dir - input directory with the starting corpus
135 -o dir - output directory for minimized files
139 -T tasks - how many parallel processes to create (default=1, "all"=nproc)
140 -f file - location read by the fuzzed program (default: stdin)
141 -m megs - memory limit for child process (default=$MEM_LIMIT MB)
142 -t msec - run time limit for child process (default: 5000ms)
143 -O - use binary-only instrumentation (FRIDA mode)
144 -Q - use binary-only instrumentation (QEMU mode)
145 -U - use unicorn-based instrumentation (Unicorn mode)
146 -X - use Nyx mode
150 -A - allow crashing and timeout inputs
151 -C - keep crashing inputs, reject everything else
152 -e - solve for edge coverage only, ignore hit counts
159 AFL_PATH: last resort location to find the afl-showmap binary
172 echo "$IN_DIR" | grep -qE '^(/var)?/tmp/'
175 echo "$TARGET_BIN" | grep -qE '^(/var)?/tmp/'
178 echo "$OUT_DIR" | grep -qE '^(/var)?/tmp/'
181 echo "$STDIN_FILE" | grep -qE '^(/var)?/tmp/'
184 echo "$PWD" | grep -qE '^(/var)?/tmp/'
187 if [ "$T1" = "0" -o "$T2" = "0" -o "$T3" = "0" -o "$T4" = "0" -o "$T5" = "0" ]; then
188 echo "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." 1>&2
193 # If @@ is specified, but there's no -f, let's come up with a temporary input
200 if echo "$*" | grep -qF '@@'; then
208 if [ ! "$T_ARG" = "" -a -n "$F_ARG" -a ! "$NYX_MODE" == 1 ]; then
209 echo "[-] Error: -T and -f can not be used together." 1>&2
215 if [ "$MEM_LIMIT" -lt "5" ]; then
216 echo "[-] Error: dangerously low memory limit." 1>&2
224 if [ "$TIMEOUT" -lt "10" ]; then
225 echo "[-] Error: dangerously low timeout." 1>&2
232 if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then
236 if [ ! -f "$TNEW" -o ! -x "$TNEW" ]; then
237 echo "[-] Error: binary '$TARGET_BIN' not found or not executable." 1>&2
247 grep -aq AFL_DUMP_MAP_SIZE "$TARGET_BIN" && {
250 test -n "$MAPSIZE" && {
256 if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" …
258 if ! grep -qF "__AFL_SHM_ID" "$TARGET_BIN"; then
259 echo "[-] Error: binary '$TARGET_BIN' doesn't appear to be instrumented." 1>&2
265 if [ ! -d "$IN_DIR" ]; then
266 echo "[-] Error: directory '$IN_DIR' not found." 1>&2
270 test -d "$IN_DIR/default" && IN_DIR="$IN_DIR/default"
271 test -d "$IN_DIR/queue" && IN_DIR="$IN_DIR/queue"
273 find "$OUT_DIR" -name 'id[:_]*' -maxdepth 1 -exec rm -- {} \; 2>/dev/null
274 rm -rf "$TRACE_DIR" 2>/dev/null
278 if [ -d "$OUT_DIR" ]; then
279 echo "[-] Error: directory '$OUT_DIR' exists and is not empty - delete it first." 1>&2
283 mkdir -m 700 -p "$TRACE_DIR" || exit 1
286 rm -f "$STDIN_FILE" || exit 1
290 SHOWMAP=`command -v afl-showmap 2>/dev/null`
292 if [ -z "$SHOWMAP" ]; then
293 TMP="${0%/afl-cmin.bash}/afl-showmap"
294 if [ -x "$TMP" ]; then
299 if [ -z "$SHOWMAP" -a -x "./afl-showmap" ]; then
300 SHOWMAP="./afl-showmap"
302 if [ -n "$AFL_PATH" ]; then
303 SHOWMAP="$AFL_PATH/afl-showmap"
307 if [ ! -x "$SHOWMAP" ]; then
308 echo "[-] Error: can't find 'afl-showmap' - please set AFL_PATH." 1>&2
309 rm -rf "$TRACE_DIR"
318 if [ "$T_ARG" -gt 1 -a "$T_ARG" -le "$(nproc)" ]; then
321 echo "[-] Error: -T parameter must between 2 and $(nproc) or \"all\"." 1>&2
325 if [ -z "$F_ARG" ]; then
326 echo "[*] Are you aware of the '-T all' parallelize option that massively improves the speed?"
330 IN_COUNT=$((`ls -- "$IN_DIR" 2>/dev/null | wc -l`))
333 echo "[-] Hmm, no inputs in the target directory. Nothing to be done."
334 rm -rf "$TRACE_DIR"
338 echo "[*] Are you aware that afl-cmin is faster than this afl-cmin.bash script?"
341 if [ -n "$THREADS" ]; then
342 if [ "$IN_COUNT" -lt "$THREADS" ]; then
348 FIRST_FILE=`ls "$IN_DIR" | head -1`
352 if [ -d "$IN_DIR/$FIRST_FILE" ]; then
353 echo "[-] Error: The target directory contains subdirectories - please fix." 1>&2
354 rm -rf "$TRACE_DIR"
366 # Make sure that we can actually get anything out of afl-showmap before we
373 …AFL_CMIN_ALLOW_ANY=1 "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/.run_test" -Z $EXTRA_…
378 …AFL_CMIN_ALLOW_ANY=1 "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/.run_test" -Z $EXTRA_…
382 FIRST_COUNT=$((`grep -c . "$TRACE_DIR/.run_test"`))
384 if [ "$FIRST_COUNT" -gt "0" ]; then
390 echo "[-] Error: no instrumentation output detected (perhaps crash or timeout)." 1>&2
391 test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR"
398 ls -- "$IN_DIR" > $TMPFILE 2>/dev/null
399 IN_COUNT=$(cat $TMPFILE | wc -l)
401 if [ "$(($IN_COUNT % $THREADS))" -gt 0 ]; then
405 split -l $SPLIT $TMPFILE $TMPFILE.
423 ls "$IN_DIR" | while read -r fn; do
425 if [ -s "$IN_DIR/$fn" ]; then
430 … "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn"
438 ls "$IN_DIR" | while read -r fn; do
440 if [ -s "$IN_DIR/$fn" ]; then
446 …"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@…
468 cat $inputs | while read -r fn; do
470 if [ -s "$IN_DIR/$fn" ]; then
472 … "$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -- "$@" <"$IN_DIR/$fn"
480 if [ -s "$IN_DIR/$fn" ]; then
482 cat $inputs | while read -r fn; do
485 …"$SHOWMAP" -m "$MEM_LIMIT" -t "$TIMEOUT" -o "$TRACE_DIR/$fn" -Z $EXTRA_PAR -H "$STDIN_FILE" -- "$@…
501 rm -f ${TMPFILE}*
503 #echo trace dir files: $(ls $TRACE_DIR/*|wc -l)
519 ls "$IN_DIR" | sed "s#^#$TRACE_DIR/#" | tr '\n' '\0' | xargs -0 -n 1 cat | \
520 sort | uniq -c | sort -k 1,1 -n >"$TRACE_DIR/.all_uniq"
522 TUPLE_COUNT=$((`grep -c . "$TRACE_DIR/.all_uniq"`))
540 ls -rS "$IN_DIR" | while read -r fn; do
547 test -s "$TRACE_DIR/$fn" || echo Warning: $fn is ignored because of crashing the target
557 # At this point, we have a file of tuple-file pairs, sorted by file size
558 # in ascending order (as a consequence of ls -rS). By doing sort keyed
559 # only by tuple (-k 1,1) and configured to output only the first line for
560 # every key (-s -u), we end up with the smallest file for each tuple.
564 sort -k1,1 -s -u "$TRACE_DIR/.candidate_list" | \
567 if [ ! -s "$TRACE_DIR/.candidate_script" ]; then
568 echo "[-] Error: no traces obtained from test cases, check syntax!" 1>&2
569 test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR"
584 # tuples associated with the newly-added file to the "already have" list. The
593 while read -r cnt tuple; do
600 grep -q "^$tuple\$" "$TRACE_DIR/.already_have" && continue
604 # echo "tuple nr $CUR ($tuple cnt=$cnt) -> $FN" >> "$TRACE_DIR/.log"
608 sort -u "$TRACE_DIR/$FN" "$TRACE_DIR/.already_have" >"$TRACE_DIR/.tmp"
609 mv -f "$TRACE_DIR/.tmp" "$TRACE_DIR/.already_have"
618 OUT_COUNT=`ls -- "$OUT_DIR" | wc -l`
627 test "$AFL_KEEP_TRACES" = "" && rm -rf "$TRACE_DIR"