about summary refs log tree commit diff
path: root/afl-cmin
diff options
context:
space:
mode:
Diffstat (limited to 'afl-cmin')
-rwxr-xr-xafl-cmin88
1 files changed, 59 insertions, 29 deletions
diff --git a/afl-cmin b/afl-cmin
index ae723c1b..a88460a8 100755
--- a/afl-cmin
+++ b/afl-cmin
@@ -1,15 +1,19 @@
 #!/usr/bin/env sh
+SYS=$(uname -s)
+test "$SYS" = "Darwin" && {
+  echo Error: afl-cmin does not work on Apple currently. please use afl-cmin.bash instead.
+  exit 1
+}
 export AFL_QUIET=1
 export ASAN_OPTIONS=detect_leaks=0
 THISPATH=`dirname ${0}`
 export PATH="${THISPATH}:$PATH"
 awk -f - -- ${@+"$@"} <<'EOF'
 #!/usr/bin/awk -f
-
 # awk script to minimize a test corpus of input files
 #
 # based on afl-cmin bash script written by Michal Zalewski
-# rewritten by Heiko Eißfeldt (hexcoder-)
+# rewritten by Heiko Eissfeldt (hexcoder-)
 # tested with:
 #   gnu awk (x86 Linux)
 #   bsd awk (x86 *BSD)
@@ -104,7 +108,7 @@ function usage() {
 "\n" \
 "Execution control settings:\n" \
 "  -T tasks      - how many parallel tasks to run (default: 1, all=nproc)\n" \
-"  -f file       - location read by the fuzzed program (stdin)\n" \
+"  -f file       - location read by the fuzzed program (default: stdin)\n" \
 "  -m megs       - memory limit for child process ("mem_limit" MB)\n" \
 "  -t msec       - run time limit for child process (default: 5000)\n" \
 "  -O            - use binary-only instrumentation (FRIDA mode)\n" \
@@ -259,22 +263,20 @@ BEGIN {
   # Do a sanity check to discourage the use of /tmp, since we can't really
   # handle this safely from an awk script.
 
-  #if (!ENVIRON["AFL_ALLOW_TMP"]) {
-  #  dirlist[0] = in_dir
-  #  dirlist[1] = target_bin
-  #  dirlist[2] = out_dir
-  #  dirlist[3] = stdin_file
-  #  "pwd" | getline dirlist[4] # current directory
-  #  for (dirind in dirlist) {
-  #    dir = dirlist[dirind]
-  #
-  #      if (dir ~ /^(\/var)?\/tmp/) {
-  #        print "[-] Error: do not use this script in /tmp or /var/tmp." > "/dev/stderr"
-  #        exit 1
-  #      }
-  #    }
-  #  delete dirlist
-  #}
+  if (!ENVIRON["AFL_ALLOW_TMP"]) {
+    dirlist[0] = in_dir
+    dirlist[1] = target_bin
+    dirlist[2] = out_dir
+    dirlist[3] = stdin_file
+    "pwd" | getline dirlist[4] # current directory
+    for (dirind in dirlist) {
+      dir = dirlist[dirind]
+      if (dir ~ /^(\/var)?\/tmp/) {
+        print "[-] Warning: do not use this script in /tmp or /var/tmp for security reasons." > "/dev/stderr"
+      }
+    }
+    delete dirlist
+  }
 
   if (threads && stdin_file) {
     print "[-] Error: -T and -f cannot be used together." > "/dev/stderr"
@@ -318,7 +320,9 @@ BEGIN {
 
   if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) {
 
-    "command -v "target_bin" 2>/dev/null" | getline tnew
+    cmd = "command -v "target_bin" 2>/dev/null"
+    cmd | getline tnew
+    close(cmd)
     if (!tnew || !exists_and_is_executable(tnew)) {
       print "[-] Error: binary '"target_bin"' not found or not executable." > "/dev/stderr"
       exit 1
@@ -330,6 +334,7 @@ BEGIN {
     echo "[!] Trying to obtain the map size of the target ..."
     get_map_size = "AFL_DUMP_MAP_SIZE=1 " target_bin
     get_map_size | getline mapsize
+    close(get_map_size)
     if (mapsize && mapsize > 65535 && mapsize < 100000000) {
       AFL_MAP_SIZE = "AFL_MAP_SIZE="mapsize" "
       print "[+] Setting "AFL_MAP_SIZE
@@ -359,14 +364,18 @@ BEGIN {
   system("rm -rf "trace_dir" 2>/dev/null");
   system("rm "out_dir"/id[:_]* 2>/dev/null")
 
-  "ls "out_dir"/* 2>/dev/null | wc -l" | getline noofentries
+  cmd = "ls "out_dir"/* 2>/dev/null | wc -l"
+  cmd | getline noofentries
+  close(cmd)
   if (0 == system( "test -d "out_dir" -a "noofentries" -gt 0" )) {
     print "[-] Error: directory '"out_dir"' exists and is not empty - delete it first." > "/dev/stderr"
     exit 1
   }
 
   if (threads) {
-    "nproc" | getline nproc
+    cmd = "nproc"
+    cmd | getline nproc
+    close(cmd)
     if (threads == "all") {
       threads = nproc
     } else {
@@ -386,12 +395,14 @@ BEGIN {
   if (stdin_file) {
     # truncate input file
     printf "" > stdin_file
-    close( stdin_file )
+    close(stdin_file)
   }
 
   # First we look in PATH
   if (0 == system("command -v afl-showmap >/dev/null 2>&1")) {
-    "command -v afl-showmap 2>/dev/null" | getline showmap
+    cmd = "command -v afl-showmap 2>/dev/null"
+    cmd | getline showmap
+    close(cmd)
   } else {
     # then we look in the current directory
     if (0 == system("test -x ./afl-showmap")) {
@@ -413,13 +424,15 @@ BEGIN {
   # yuck, gnu stat is option incompatible to bsd stat
   # we use a heuristic to differentiate between
   # GNU stat and other stats
-  "stat --version 2>/dev/null" | getline statversion
-  if (statversion ~ /GNU coreutils/) {
+  cmd = "stat --version 2>/dev/null"
+  cmd | getline statversion
+  close(cmd)
+  if (statversion ~ /GNU coreutils/ || statversion ~ /BusyBox/) {
     stat_format = "-c '%s %n'" # GNU
   } else {
     stat_format = "-f '%z %N'" # *BSD, MacOS
   }
-  cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o -type f -exec stat "stat_format" \\{\\} + | sort -k1n -k2r)"
+  cmdline = "(cd "in_dir" && find . \\( ! -name \".*\" -a -type d \\) -o -type f -exec stat "stat_format" \\{\\} + | sort -k1n -k2r) | grep -Ev '^0'"
   #cmdline = "ls "in_dir" | (cd "in_dir" && xargs stat "stat_format" 2>/dev/null) | sort -k1n -k2r"
   #cmdline = "(cd "in_dir" && stat "stat_format" *) | sort -k1n -k2r"
   #cmdline = "(cd "in_dir" && ls | xargs stat "stat_format" ) | sort -k1n -k2r"
@@ -432,6 +445,7 @@ BEGIN {
     infilesSmallToBigFullMap[infilesSmallToBigFull[i]] = infilesSmallToBig[i]
     i++
   }
+  close(cmdline)
   in_count = i
 
   first_file = infilesSmallToBigFull[0]
@@ -468,6 +482,7 @@ BEGIN {
     while ((getline < runtest) > 0) {
       ++first_count
     }
+    close(runtest)
 
     if (first_count) {
       print "[+] OK, "first_count" tuples recorded."
@@ -480,6 +495,11 @@ BEGIN {
     }
   }
 
+  if (in_count < threads) {
+    threads = in_count
+    print "[!] WARNING: less inputs than threads, reducing threads to "threads" and likely the overhead of threading makes things slower..."
+  }
+
   # Let's roll!
 
   #############################
@@ -488,7 +508,7 @@ BEGIN {
 
   if (threads) {
 
-    inputsperfile = in_count / threads
+    inputsperfile = int(in_count / threads)
     if (in_count % threads) {
       inputsperfile++;
     }
@@ -513,7 +533,7 @@ BEGIN {
 
   if (threads > 1) {
 
-    print "[*] Creating " threads " parallel tasks with about " inputsperfile " each."
+    print "[*] Creating " threads " parallel tasks with about " inputsperfile " items each."
     for (i = 1; i <= threads; i++) {
 
       if (!stdin_file) {
@@ -582,6 +602,15 @@ BEGIN {
     else { print "    Processing file "cur"/"in_count }
     # create path for the trace file from afl-showmap
     tracefile_path = trace_dir"/"fn
+    # ensure the file size is not zero
+    cmd = "du -b \""tracefile_path"\""
+    # "ls -l \""tracefile_path"\""
+    cmd | getline output
+    close(cmd)
+    split(output, result, "\t")
+    if (result[1] == 0) {
+      print "[!] WARNING: file "fn" is crashing the target, ignoring..."
+    }
     # gather all keys, and count them
     while ((getline line < tracefile_path) > 0) {
         key = line
@@ -643,6 +672,7 @@ BEGIN {
     }
   }
   close(sortedKeys)
+  print ""
   print "[+] Found "tuple_count" unique tuples across "in_count" files."
 
   if (out_count == 1) {