diff options
Diffstat (limited to 'afl-cmin')
-rwxr-xr-x | afl-cmin | 65 |
1 files changed, 54 insertions, 11 deletions
diff --git a/afl-cmin b/afl-cmin index 44a84735..9570bc93 100755 --- a/afl-cmin +++ b/afl-cmin @@ -287,7 +287,8 @@ BEGIN { system("rm -rf "trace_dir" 2>/dev/null"); system("rm "out_dir"/id[:_]* 2>/dev/null") - if (0 == system( "test -d "out_dir" -a -e "out_dir"/*" )) { + "ls "out_dir"/* 2>/dev/null | wc -l" | getline noofentries + 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 } @@ -318,7 +319,7 @@ BEGIN { print "[-] Error: can't find 'afl-showmap' - please set AFL_PATH." > "/dev/stderr" exit 1 } - + # get list of input filenames sorted by size i = 0 # yuck, gnu stat is option incompatible to bsd stat @@ -330,8 +331,10 @@ BEGIN { } else { stat_format = "-f '%z %N'" # *BSD, MacOS } - cmdline = "cd "in_dir" && find . \\( ! -name . -a -type d -prune \\) -o -type f -exec stat "stat_format" \\{\\} \\; | sort -n | cut -d' ' -f2-" + cmdline = "cd "in_dir" && find . \\( ! -name . -a -type d -prune \\) -o -type f -exec stat "stat_format" \\{\\} \\; | sort -k1n -k2r" + cmdline = "ls "in_dir" | (cd "in_dir" && xargs stat "stat_format") | sort -k1n -k2r" while (cmdline | getline) { + sub(/^[0-9]+ (\.\/)?/,"",$0) infilesSmallToBig[i++] = $0 } in_count = i @@ -390,10 +393,10 @@ BEGIN { cur = 0; if (!stdin_file) { - printf " Processing "in_count" files (forkserver mode)..." + print " Processing "in_count" files (forkserver mode)..." system( "AFL_CMIN_ALLOW_ANY=1 \""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string) } else { - printf " Processing "in_count" files (forkserver mode)..." + print " Processing "in_count" files (forkserver mode)..." system( "AFL_CMIN_ALLOW_ANY=1 \""showmap"\" -m "mem_limit" -t "timeout" -o \""trace_dir"\" -Z "extra_par" -i \""in_dir"\" -- \""target_bin"\" "prog_args_string" </dev/null") } @@ -410,6 +413,9 @@ BEGIN { out_count = 0 tuple_count = 0 + # from rare to frequent new tuples + # get the best (smallest) file for it + # and copy it while (cur < in_count) { fn = infilesSmallToBig[cur] ++cur @@ -426,17 +432,54 @@ BEGIN { if (! (key in best_file)) { # this is the best file for this key best_file[key] = fn - # copy file unless already done - if (! (fn in file_already_copied)) { - system(cp_tool" "in_dir"/"fn" "out_dir"/"fn) - file_already_copied[fn] = "" - ++out_count - } +#printf "BEST_FILE[%d]=\"%s\"\n",key,fn | "sort -t'[' -k2 > "trace_dir"/.candidate_script" } +#printf "%d %s\n",key,fn > trace_dir"/.candidate_list" } close(tracefile_path) } + print "" + + # sort keys + sortedKeys = trace_dir"/.all_uniq" + sortKeysCmd = "sort -k1n > "sortedKeys + for (key in key_count) { + printf "%7d %s\n",key_count[key],key | sortKeysCmd + } + close(sortKeysCmd) + + # iterate over keys from rare to frequent and + # copy best file + while ((getline < sortedKeys) > 0) { + + # split + nrFields = split($0, field, / +/) +#print nrFields" Felder: '"field[0]"', '"field[1]"', '"field[2]"', '"field[3]"'" + key = field[nrFields] + ++tcnt; + printf "\r Processing tuple "tcnt"/"tuple_count" with count "key_count[key]"..." + if (key in keyAlreadyKnown) { + continue + } + + fn = best_file[key] + # gather all tuples from the best file for this key + tracedfn = trace_dir"/"fn + while ((getline < tracedfn) > 0) { + keyAlreadyKnown[$0] = "" + } + close(tracedfn) + + # copy file unless already done + if (! (fn in file_already_copied)) { + system(cp_tool" "in_dir"/"fn" "out_dir"/"fn) + file_already_copied[fn] = "" + ++out_count + #printf "tuple nr %d (%d cnt=%d) -> %s\n",tcnt,key,key_count[key],fn > trace_dir"/.log" + } + } + close(sortedKeys) print "" print "[+] Found "tuple_count" unique tuples across "in_count" files." |