about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--GNUmakefile2
-rwxr-xr-xafl-addseeds54
-rw-r--r--docs/Changelog.md1
-rw-r--r--instrumentation/afl-compiler-rt.o.c6
m---------nyx_mode/QEMU-Nyx0
-rw-r--r--src/afl-fuzz-stats.c33
-rw-r--r--src/afl-fuzz.c10
-rw-r--r--src/afl-performance.c21
-rw-r--r--unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py26
9 files changed, 106 insertions, 47 deletions
diff --git a/GNUmakefile b/GNUmakefile
index fadf20bd..5fd37147 100644
--- a/GNUmakefile
+++ b/GNUmakefile
@@ -32,7 +32,7 @@ VERSION     = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f
 # PROGS intentionally omit afl-as, which gets installed elsewhere.
 
 PROGS       = afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
-SH_PROGS    = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config afl-persistent-config afl-cc
+SH_PROGS    = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-addseeds afl-system-config afl-persistent-config afl-cc
 MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8
 ASAN_OPTIONS=detect_leaks=0
 
diff --git a/afl-addseeds b/afl-addseeds
new file mode 100755
index 00000000..bb2843a8
--- /dev/null
+++ b/afl-addseeds
@@ -0,0 +1,54 @@
+#!/bin/sh
+
+test -z "$1" -o "$1" = "-h" -o "$1" = "--help" && {
+  echo Syntax: afl-addseeds -o afl-out-dir [-i seed_file_or_dir] seed_file_or_seed_dir seed_file_or_seed_dir ...
+  echo
+  echo Options:
+  echo "  -o afl-out-dir       the output directory being used in the fuzzing campaign"
+  echo "  -i seed_file_or_dir  file or directory of files to add"
+  echo
+  echo Adds new seeds to an existing AFL++ fuzzing campaign.
+  exit 0
+}
+
+for TOOL in find ls; do
+  X=`which $TOOL`
+  test -n "$X" || { echo "Error: required tool '$TOOL' not found."; exit 1; }
+done
+
+TEST=`printf %06d 123 2>/dev/null`
+test "$TEST" = "000123" || { echo "Error: required tool 'printf' not found."; exit 1; }
+
+OUT=
+NEXT=
+for i in $*; do
+  test -n "$NEXT" && { OUT=$i ; NEXT=""; }
+  test "$i" = "-o" && { NEXT=1; }
+done
+
+test -d "$OUT" || { echo Error: $OUT is not an existing directory; exit 1; }
+OK=`ls $OUT/*/fuzzer_stats 2>/dev/null`
+test -n "$OK" || { echo "Error: $OUT is not an 'afl-fuzz -o ... ' output directory" ; exit 1; }
+
+OUTDIR=$OUT/addseeds/queue
+mkdir -p "$OUTDIR" 2>/dev/null
+test -d "$OUTDIR" || { echo Error: could not create $OUTDIR ; exit 1 ; }
+
+echo Adding seeds ...
+NEXTID=0
+for i in $*; do
+  test -z "$i" -o "$i" = "$OUT" -o "$i" = "-i" -o "$i" = "-o" || {
+    find "$i" -type f | while read FILE; do
+      N=xxx
+      while [ -n "$N" ]; do
+        ID=$NEXTID
+        N=`ls "$OUTDIR/id:$(printf %06d $ID),"* 2>/dev/null`
+        NEXTID=$(($NEXTID + 1))
+      done
+      FN=`echo "$FILE" | sed 's/.*\///'`
+      cp -v "$FILE" "$OUTDIR/id:$(printf %06d $ID),time:0,execs:0,orig:$FN"
+    done
+  }
+done
+
+echo Done.
diff --git a/docs/Changelog.md b/docs/Changelog.md
index dfbadea3..101d380b 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -19,6 +19,7 @@
     - fix for a few string compare transform functions for LAF
   - frida_mode:
     - fixes support for large map offsets
+  - added new tool afl-addseeds that adds new seeds to a running campaign
   - added benchmark/benchmark.sh if you want to see how good your fuzzing
     speed is in comparison to other setups.
 
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index dd9aae77..85ee9f71 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -666,8 +666,8 @@ static void __afl_map_shm(void) {
   }
 
   if (id_str) {
-
-    if ((__afl_dummy_fd[1] = open("/dev/null", O_WRONLY)) < 0) {
+    // /dev/null doesn't work so we use /dev/urandom
+    if ((__afl_dummy_fd[1] = open("/dev/urandom", O_WRONLY)) < 0) {
 
       if (pipe(__afl_dummy_fd) < 0) { __afl_dummy_fd[1] = 1; }
 
@@ -2294,7 +2294,7 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
   int len1 = strnlen(ptr1, len0);
   if (len1 < 31) len1 = area_is_valid(ptr1, len1 + 1);
   int len2 = strnlen(ptr2, len0);
-  if (len2 < 31) len2 = area_is_valid(ptr1, len2 + 1);
+  if (len2 < 31) len2 = area_is_valid(ptr2, len2 + 1);
   int l = MAX(len1, len2);
   if (l < 2) return;
 
diff --git a/nyx_mode/QEMU-Nyx b/nyx_mode/QEMU-Nyx
-Subproject 874fa033d117a3e9931245cb9e82836a4abc042
+Subproject 92ed7cefc1bd043a1230ca74b263b484825c265
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 3d0a9b9a..adf04420 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -778,10 +778,29 @@ void show_stats_normal(afl_state_t *afl) {
   if (unlikely(!banner[0])) {
 
     char *si = "";
+    char *fuzzer_name;
+
     if (afl->sync_id) { si = afl->sync_id; }
     memset(banner, 0, sizeof(banner));
-    banner_len = (afl->crash_mode ? 20 : 18) + strlen(VERSION) + strlen(si) +
-                 strlen(afl->power_name) + 4 + 6;
+
+    banner_len = strlen(VERSION) + strlen(si) + strlen(afl->power_name) + 4 + 6;
+
+    if (afl->crash_mode) {
+
+      fuzzer_name = "peruvian were-rabbit";
+
+    } else {
+
+      fuzzer_name = "american fuzzy lop";
+      if (banner_len + strlen(fuzzer_name) + strlen(afl->use_banner) > 75) {
+
+        fuzzer_name = "AFL";
+
+      }
+
+    }
+
+    banner_len += strlen(fuzzer_name);
 
     if (strlen(afl->use_banner) + banner_len > 75) {
 
@@ -798,18 +817,16 @@ void show_stats_normal(afl_state_t *afl) {
     if (afl->fsrv.nyx_mode) {
 
       snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
-               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
-               afl->crash_mode ? cPIN "peruvian were-rabbit"
-                               : cYEL "american fuzzy lop",
+               "%s%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s] - Nyx",
+               afl->crash_mode ? cPIN : cYEL, fuzzer_name,
                si, afl->use_banner, afl->power_name);
 
     } else {
 
 #endif
       snprintf(banner + banner_pad, sizeof(banner) - banner_pad,
-               "%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
-               afl->crash_mode ? cPIN "peruvian were-rabbit"
-                               : cYEL "american fuzzy lop",
+               "%s%s " cLCY VERSION cLBL " {%s} " cLGN "(%s) " cPIN "[%s]",
+               afl->crash_mode ? cPIN : cYEL, fuzzer_name,
                si, afl->use_banner, afl->power_name);
 
 #ifdef __linux__
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 86c05223..2538f4a4 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -1346,6 +1346,12 @@ int main(int argc, char **argv_orig, char **envp) {
 
   }
 
+  if (afl->sync_id && strcmp(afl->sync_id, "addseeds") == 0) {
+
+    FATAL("-M/-S name 'addseeds' is a reserved name, choose something else");
+
+  }
+
   if (afl->is_main_node == 1 && afl->schedule != FAST &&
       afl->schedule != EXPLORE) {
 
@@ -2826,7 +2832,9 @@ int main(int argc, char **argv_orig, char **envp) {
 
     if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0 &&
                !afl->non_instrumented_mode) &&
-        unlikely(cur_time > afl->last_find_time + afl->switch_fuzz_mode)) {
+        unlikely(cur_time > (likely(afl->last_find_time) ? afl->last_find_time
+                                                         : afl->start_time) +
+                                afl->switch_fuzz_mode)) {
 
       if (afl->afl_env.afl_no_ui) {
 
diff --git a/src/afl-performance.c b/src/afl-performance.c
index 04507410..07c1b527 100644
--- a/src/afl-performance.c
+++ b/src/afl-performance.c
@@ -1,24 +1,3 @@
-/*
-   Written in 2019 by David Blackman and Sebastiano Vigna (vigna@acm.org)
-
-   To the extent possible under law, the author has dedicated all copyright
-   and related and neighboring rights to this software to the public domain
-   worldwide. This software is distributed without any warranty.
-
-   See <https://creativecommons.org/publicdomain/zero/1.0/>.
-
-   This is xoshiro256++ 1.0, one of our all-purpose, rock-solid generators.
-   It has excellent (sub-ns) speed, a state (256 bits) that is large
-   enough for any parallel application, and it passes all tests we are
-   aware of.
-
-   For generating just floating-point numbers, xoshiro256+ is even faster.
-
-   The state must be seeded so that it is not everywhere zero. If you have
-   a 64-bit seed, we suggest to seed a splitmix64 generator and use its
-   output to fill s[].
-*/
-
 #include <stdint.h>
 #include "afl-fuzz.h"
 #include "types.h"
diff --git a/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py b/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py
index eccbc8bf..7e97f6a7 100644
--- a/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py
+++ b/unicorn_mode/helper_scripts/unicorn_dumper_pwndbg.py
@@ -40,10 +40,10 @@ import gdb
 pwndbg_loaded = False
 
 try:
-    import pwndbg.arch
-    import pwndbg.regs
-    import pwndbg.vmmap
-    import pwndbg.memory
+    import pwndbg.gdblib.arch
+    import pwndbg.gdblib.regs
+    import pwndbg.gdblib.vmmap
+    import pwndbg.gdblib.memory
 
     pwndbg_loaded = True
 
@@ -64,7 +64,7 @@ INDEX_FILE_NAME = "_index.json"
 
 
 def map_arch():
-    arch = pwndbg.arch.current  # from PWNDBG
+    arch = pwndbg.gdblib.arch.current  # from PWNDBG
     if "x86_64" in arch or "x86-64" in arch:
         return "x64"
     elif "x86" in arch or "i386" in arch:
@@ -74,9 +74,9 @@ def map_arch():
     elif "aarch64_be" in arch:
         return "arm64be"
     elif "arm" in arch:
-        cpsr = pwndbg.regs["cpsr"]
+        cpsr = pwndbg.gdblib.regs["cpsr"]
         # check endianess
-        if pwndbg.arch.endian == "big":
+        if pwndbg.gdblib.arch.endian == "big":
             # check for THUMB mode
             if cpsr & (1 << 5):
                 return "armbethumb"
@@ -89,7 +89,7 @@ def map_arch():
             else:
                 return "armle"
     elif "mips" in arch:
-        if pwndbg.arch.endian == "little":
+        if pwndbg.gdblib.arch.endian == "little":
             return "mipsel"
         else:
             return "mips"
@@ -109,8 +109,8 @@ def dump_arch_info():
 
 def dump_regs():
     reg_state = {}
-    for reg in pwndbg.regs.all:
-        reg_val = pwndbg.regs[reg]
+    for reg in pwndbg.gdblib.regs.all:
+        reg_val = pwndbg.gdblib.regs[reg]
         # current dumper script looks for register values to be hex strings
         #         reg_str = "0x{:08x}".format(reg_val)
         #         if "64" in get_arch():
@@ -125,7 +125,7 @@ def dump_process_memory(output_dir):
     final_segment_list = []
 
     # PWNDBG:
-    vmmap = pwndbg.vmmap.get()
+    vmmap = pwndbg.gdblib.vmmap.get()
 
     # Pointer to end of last dumped memory segment
     segment_last_addr = 0x0
@@ -165,7 +165,7 @@ def dump_process_memory(output_dir):
         if entry.read and not "(deleted)" in entry.objfile:
             try:
                 # Compress and dump the content to a file
-                seg_content = pwndbg.memory.read(start, end - start)
+                seg_content = pwndbg.gdblib.memory.read(start, end - start)
                 if seg_content == None:
                     print(
                         "Segment empty: @0x{0:016x} (size:UNKNOWN) {1}".format(
@@ -181,7 +181,7 @@ def dump_process_memory(output_dir):
                             repr(seg_info["permissions"]),
                         )
                     )
-                    compressed_seg_content = zlib.compress(str(seg_content))
+                    compressed_seg_content = zlib.compress(bytes(seg_content))
                     md5_sum = hashlib.md5(compressed_seg_content).hexdigest() + ".bin"
                     seg_info["content_file"] = md5_sum