about summary refs log tree commit diff
path: root/custom_mutators
diff options
context:
space:
mode:
Diffstat (limited to 'custom_mutators')
-rw-r--r--custom_mutators/aflpp/aflpp.c2
-rw-r--r--custom_mutators/aflpp/standalone/Makefile2
-rw-r--r--custom_mutators/aflpp/standalone/README.md4
-rw-r--r--custom_mutators/aflpp/standalone/aflpp-standalone.c167
-rw-r--r--custom_mutators/atnwalk/README.md2
-rw-r--r--custom_mutators/atnwalk/atnwalk.c3
-rw-r--r--custom_mutators/autotokens/autotokens.cpp20
-rw-r--r--custom_mutators/autotokens/standalone/Makefile19
-rw-r--r--custom_mutators/autotokens/standalone/README.md12
-rw-r--r--custom_mutators/autotokens/standalone/autotokens-standalone.c192
-rw-r--r--custom_mutators/custom_send_tcp/Makefile7
-rw-r--r--custom_mutators/custom_send_tcp/README.md13
-rw-r--r--custom_mutators/custom_send_tcp/custom_send_tcp.c113
m---------custom_mutators/gramatron/json-c0
-rw-r--r--custom_mutators/grammar_mutator/GRAMMAR_VERSION2
m---------custom_mutators/grammar_mutator/grammar_mutator0
-rw-r--r--custom_mutators/radamsa/libradamsa.c2
17 files changed, 504 insertions, 56 deletions
diff --git a/custom_mutators/aflpp/aflpp.c b/custom_mutators/aflpp/aflpp.c
index 0b236f76..ea50751a 100644
--- a/custom_mutators/aflpp/aflpp.c
+++ b/custom_mutators/aflpp/aflpp.c
@@ -48,7 +48,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
 
     u8 *ptr = realloc(data->buf, max_size);
 
-    if (ptr) {
+    if (!ptr) {
 
       return 0;
 
diff --git a/custom_mutators/aflpp/standalone/Makefile b/custom_mutators/aflpp/standalone/Makefile
index f1e99445..d7bc840d 100644
--- a/custom_mutators/aflpp/standalone/Makefile
+++ b/custom_mutators/aflpp/standalone/Makefile
@@ -4,7 +4,7 @@ CFLAGS = -O3 -funroll-loops -fPIC
 all: aflpp-standalone
 
 aflpp-standalone:	aflpp-standalone.c
-	$(CC) $(CFLAGS) -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c
+	$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o aflpp-standalone aflpp-standalone.c ../../../src/afl-performance.c ../../../src/afl-fuzz-extras.c ../../../src/afl-common.c
 
 clean:
 	rm -f *.o *~ aflpp-standalone core
diff --git a/custom_mutators/aflpp/standalone/README.md b/custom_mutators/aflpp/standalone/README.md
index a1ffb5f9..3c26a29a 100644
--- a/custom_mutators/aflpp/standalone/README.md
+++ b/custom_mutators/aflpp/standalone/README.md
@@ -5,6 +5,6 @@ this is the AFL++ havoc mutator as a standalone mutator
 just type `make` to build.
 
 ```
-aflpp-standalone inputfile outputfile [splicefile]
+aflpp-standalone -h # to see all parameteres
+cat file | aflpp-standalone -m 4 -x foo.dict - outputfile splicefile # example
 ```
-
diff --git a/custom_mutators/aflpp/standalone/aflpp-standalone.c b/custom_mutators/aflpp/standalone/aflpp-standalone.c
index 3a2cbc2f..c059ce11 100644
--- a/custom_mutators/aflpp/standalone/aflpp-standalone.c
+++ b/custom_mutators/aflpp/standalone/aflpp-standalone.c
@@ -1,6 +1,12 @@
 #include "afl-fuzz.h"
 #include "afl-mutations.h"
 
+#include <unistd.h>
+#include <getopt.h>
+
+static int            max_havoc = 16, verbose;
+static unsigned char *dict;
+
 typedef struct my_mutator {
 
   afl_state_t *afl;
@@ -21,14 +27,14 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
   }
 
-  if ((data->buf = malloc(1024*1024)) == NULL) {
+  if ((data->buf = malloc(1024 * 1024)) == NULL) {
 
     perror("afl_custom_init alloc");
     return NULL;
 
   } else {
 
-    data->buf_size = 1024*1024;
+    data->buf_size = 1024 * 1024;
 
   }
 
@@ -36,9 +42,23 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
   data->afl = calloc(1, sizeof(afl_state_t));
   data->afl->queue_cycle = 1;
   data->afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
-  if (data->afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
+  if (data->afl->fsrv.dev_urandom_fd < 0) {
+
+    PFATAL("Unable to open /dev/urandom");
+
+  }
+
   rand_set_seed(data->afl, getpid());
 
+  if (dict) {
+
+    load_extras(data->afl, dict);
+    if (verbose)
+      fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict,
+              data->afl->extras_cnt);
+
+  }
+
   return data;
 
 }
@@ -53,7 +73,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
 
     u8 *ptr = realloc(data->buf, max_size);
 
-    if (ptr) {
+    if (!ptr) {
 
       return 0;
 
@@ -66,14 +86,20 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
 
   }
 
-  u32 havoc_steps = 1 + rand_below(data->afl, 16);
+  u32 havoc_steps = 1 + rand_below(data->afl, max_havoc);
+  if (verbose) fprintf(stderr, "Havoc steps: %u\n", havoc_steps);
 
   /* set everything up, costly ... :( */
   memcpy(data->buf, buf, buf_size);
 
   /* the mutation */
-  u32 out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps,
-                               false, true, add_buf, add_buf_size, max_size);
+  u32 out_buf_len;
+  do {
+
+    out_buf_len = afl_mutate(data->afl, data->buf, buf_size, havoc_steps, false,
+                             true, add_buf, add_buf_size, max_size);
+
+  } while (out_buf_len == buf_size && memcmp(buf, data->buf, buf_size) == 0);
 
   /* return size of mutated data */
   *out_buf = data->buf;
@@ -84,80 +110,143 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
 int main(int argc, char *argv[]) {
 
   if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
-    printf("Syntax: %s [-v] [inputfile [outputfile [splicefile]]]\n\n", argv[0]);
-    printf("Reads a testcase from stdin when no input file (or '-') is specified,\n");
-    printf("mutates according to AFL++'s mutation engine, and write to stdout when '-' or\n");
-    printf("no output filename is given. As an optional third parameter you can give a file\n");
+
+    printf(
+        "Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile "
+        "[splicefile]]]\n\n",
+        argv[0]);
+    printf(
+        "Reads a testcase from stdin when no input file (or '-') is "
+        "specified,\n");
+    printf(
+        "mutates according to AFL++'s mutation engine, and write to stdout "
+        "when '-' or\n");
+    printf(
+        "no output filename is given. As an optional third parameter you can "
+        "give a file\n");
     printf("for splicing. Maximum input and output length is 1MB.\n");
-    printf("The -v verbose option prints debug output to stderr.\n");
+    printf("Options:\n");
+    printf("  -v      verbose debug output to stderr.\n");
+    printf("  -m val  max mutations (1-val, val default is 16)\n");
+    printf("  -x file dictionary file (AFL++ format)\n");
     return 0;
+
   }
 
-  FILE *in = stdin, *out = stdout, *splice = NULL;
-  unsigned char *inbuf = malloc(1024 * 1024), *outbuf, *splicebuf = NULL;
-  int verbose = 0, splicelen = 0;
+  FILE          *in = stdin, *out = stdout, *splice = NULL;
+  unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL;
+  int            splicelen = 0, opt;
+
+  while ((opt = getopt(argc, argv, "vm:x:")) > 0) {
+
+    switch (opt) {
+
+      case 'm':
+        max_havoc = atoi(optarg);
+        break;
+      case 'v':
+        verbose = 1;
+        break;
+      case 'x':
+        dict = optarg;
+        break;
+      default:
+        fprintf(stderr, "Error: unknown parameter -%c\n", opt);
+        exit(-1);
+
+    }
+
+  }
+
+  if (max_havoc < 1) {
+
+    fprintf(stderr, "Error: illegal -m value\n");
+    exit(-1);
 
-  if (argc > 1 && strcmp(argv[1], "-v") == 0) {
-    verbose = 1;
-    argc--;
-    argv++;
-    fprintf(stderr, "Verbose active\n");
   }
 
   my_mutator_t *data = afl_custom_init(NULL, 0);
 
-  if (argc > 1 && strcmp(argv[1], "-") != 0) {
-    if ((in = fopen(argv[1], "r")) == NULL) {
+  if (argc > optind && strcmp(argv[optind], "-") != 0) {
+
+    if ((in = fopen(argv[optind], "r")) == NULL) {
+
       perror(argv[1]);
       return -1;
+
     }
-    if (verbose) fprintf(stderr, "Input: %s\n", argv[1]);
+
+    if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]);
+
   }
 
-  size_t inlen = fread(inbuf, 1, 1024*1024, in);
-  
+  size_t inlen = fread(inbuf, 1, 1024 * 1024, in);
+
   if (!inlen) {
-    fprintf(stderr, "Error: empty file %s\n", argv[1] ? argv[1] : "stdin");
+
+    fprintf(stderr, "Error: empty file %s\n",
+            argv[optind] ? argv[optind] : "stdin");
     return -1;
+
   }
 
-  if (argc > 2 && strcmp(argv[2], "-") != 0) {
-    if ((out = fopen(argv[2], "w")) == NULL) {
-      perror(argv[2]);
+  if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) {
+
+    if ((out = fopen(argv[optind + 1], "w")) == NULL) {
+
+      perror(argv[optind + 1]);
       return -1;
+
     }
-    if (verbose) fprintf(stderr, "Output: %s\n", argv[2]);
+
+    if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]);
+
   }
 
-  if (argc > 3) {
-    if ((splice = fopen(argv[3], "r")) == NULL) {
-      perror(argv[3]);
+  if (argc > optind + 2) {
+
+    if ((splice = fopen(argv[optind + 2], "r")) == NULL) {
+
+      perror(argv[optind + 2]);
       return -1;
+
     }
-    if (verbose) fprintf(stderr, "Splice: %s\n", argv[3]);
-    splicebuf = malloc(1024*1024);
-    size_t splicelen = fread(splicebuf, 1, 1024*1024, splice);
+
+    if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]);
+    splicebuf = malloc(1024 * 1024);
+    size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice);
     if (!splicelen) {
-      fprintf(stderr, "Error: empty file %s\n", argv[3]);
+
+      fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]);
       return -1;
+
     }
+
     if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
+
   }
 
   if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
-  unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf, splicelen, 1024*1024);
+  unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf,
+                                        splicelen, 1024 * 1024);
 
   if (outlen == 0 || !outbuf) {
+
     fprintf(stderr, "Error: no mutation data returned.\n");
     return -1;
+
   }
 
   if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
 
   if (fwrite(outbuf, 1, outlen, out) != outlen) {
+
     fprintf(stderr, "Warning: incomplete write.\n");
     return -1;
+
   }
-  
+
   return 0;
+
 }
+
diff --git a/custom_mutators/atnwalk/README.md b/custom_mutators/atnwalk/README.md
index 730349a3..7dbe8ee5 100644
--- a/custom_mutators/atnwalk/README.md
+++ b/custom_mutators/atnwalk/README.md
@@ -13,7 +13,7 @@ Just type `make` to build `atnwalk.so`.
 **NOTE:** The commands below just demonstrate an example how running ATNwalk looks like and require a working [testbed](https://github.com/atnwalk/testbed)
 
 ```bash
-# create the required a random seed first
+# create the required random seed first
 mkdir -p ~/campaign/example/seeds
 cd ~/campaign/example/seeds
 head -c1 /dev/urandom | ~/atnwalk/build/javascript/bin/decode -wb > seed.decoded 2> seed.encoded
diff --git a/custom_mutators/atnwalk/atnwalk.c b/custom_mutators/atnwalk/atnwalk.c
index c3a2cd95..45ccc181 100644
--- a/custom_mutators/atnwalk/atnwalk.c
+++ b/custom_mutators/atnwalk/atnwalk.c
@@ -180,7 +180,8 @@ size_t fail_fatal(int fd_socket, uint8_t **out_buf) {
 
   if (fd_socket != -1) { close(fd_socket); }
   *out_buf = NULL;
-  return 0;
+  fprintf(stderr, "atnwalk.socket not found in current directory!\n");
+  exit(-1);
 
 }
 
diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp
index 8135aba1..9bce3da7 100644
--- a/custom_mutators/autotokens/autotokens.cpp
+++ b/custom_mutators/autotokens/autotokens.cpp
@@ -39,6 +39,7 @@ extern "C" {
 #ifndef AFL_TXT_MAX_LEN
   #define AFL_TXT_MAX_LEN 65535
 #endif
+#define AUTOTOKENS_TXT_MIN_LEN 1
 
 #if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN
   #error SPLICE_MIN must be lower than SIZE_MIN
@@ -57,8 +58,9 @@ typedef struct my_mutator {
   if (unlikely(debug)) fprintf
 #define IFDEBUG if (unlikely(debug))
 
+int module_disabled = 0;
+
 static afl_state *afl_ptr;
-static int        module_disabled = 0;
 static int        auto_disable = AUTOTOKENS_AUTO_DISABLE;
 static int        debug = AUTOTOKENS_DEBUG;
 static int        only_fav = AUTOTOKENS_ONLY_FAV;
@@ -104,9 +106,9 @@ static void first_run(void *data) {
   if (afl_ptr->custom_only || !auto_disable) { return; }
 
   if (unlikely(afl_ptr->active_items == 1 &&
-               afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN)) {
+               afl_ptr->queue_cur->len < AUTOTOKENS_TXT_MIN_LEN)) {
 
-    if (afl_ptr->extras_cnt > 8) {
+    if (afl_ptr->extras_cnt) {
 
       u32 valid = 0;
 
@@ -237,7 +239,7 @@ extern "C" u32 afl_custom_fuzz_count(void *data, const u8 *buf,
 
 }
 
-extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size,
+extern "C" size_t afl_custom_fuzz(void *data, u8 *buf, size_t buf_size,
                                   u8 **out_buf, u8 *add_buf,
                                   size_t add_buf_size, size_t max_size) {
 
@@ -655,6 +657,7 @@ extern "C" unsigned char afl_custom_queue_get(void                *data,
     if (current_id > whitespace_ids + 6 && afl_ptr->active_items == 1 &&
         afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN) {
 
+    retry_thin_air:
       DEBUGF(stderr, "Creating an entry from thin air...\n");
       structure = new vector<u32>();
       u32 item, prev, cnt = current_id >> 1;
@@ -684,8 +687,6 @@ extern "C" unsigned char afl_custom_queue_get(void                *data,
 
     }
 
-    create_from_thin_air = 0;
-
   }
 
   if (entry == file_mapping.end()) {
@@ -693,7 +694,7 @@ extern "C" unsigned char afl_custom_queue_get(void                *data,
     // this input file was not analyzed for tokens yet, so let's do it!
     size_t len = afl_ptr->queue_cur->len;
 
-    if (len < AFL_TXT_MIN_LEN) {
+    if (len < AUTOTOKENS_TXT_MIN_LEN) {
 
       file_mapping[fn] = structure;  // NULL ptr so we don't read the file again
       s = NULL;
@@ -895,6 +896,7 @@ extern "C" unsigned char afl_custom_queue_get(void                *data,
 
     if (tokens.size() < AUTOTOKENS_SIZE_MIN) {
 
+      if (create_from_thin_air) { goto retry_thin_air; }
       file_mapping[fn] = NULL;
       s = NULL;
       DEBUGF(stderr, "too few tokens\n");
@@ -955,7 +957,7 @@ extern "C" unsigned char afl_custom_queue_get(void                *data,
 
 }
 
-extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) {
+extern "C" void *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
   (void)(seed);
   my_mutator_t *data = (my_mutator_t *)calloc(1, sizeof(my_mutator_t));
@@ -1070,7 +1072,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) {
   id_to_token[current_id] = "'";
   ++current_id;
 
-  return data;
+  return (void *)data;
 
 }
 
diff --git a/custom_mutators/autotokens/standalone/Makefile b/custom_mutators/autotokens/standalone/Makefile
new file mode 100644
index 00000000..8d5baf13
--- /dev/null
+++ b/custom_mutators/autotokens/standalone/Makefile
@@ -0,0 +1,19 @@
+
+CFLAGS = -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1 -Wno-implicit-function-declaration
+CXXFLAGS= -g -O3 -funroll-loops -fPIC -D_STANDALONE_MODULE=1
+
+all: autotokens-standalone
+
+autotokens.o:	../autotokens.cpp
+	$(CXX) $(CXXFLAGS) -I../../../include -I. -I../.. -c ../autotokens.cpp
+
+autotokens-standalone:	autotokens-standalone.c	autotokens.o
+	$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c autotokens-standalone.c
+	$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-performance.c
+	$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-extras.c
+	$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-fuzz-queue.c
+	$(CC) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -c ../../../src/afl-common.c
+	$(CXX) $(CFLAGS) -DBIN_PATH=\"foo\" -I../../../include -I. -o autotokens-standalone *.o
+
+clean:
+	rm -f *.o *~ autotokens-standalone core
diff --git a/custom_mutators/autotokens/standalone/README.md b/custom_mutators/autotokens/standalone/README.md
new file mode 100644
index 00000000..9e9babf7
--- /dev/null
+++ b/custom_mutators/autotokens/standalone/README.md
@@ -0,0 +1,12 @@
+# Autotokens standalone mutator
+
+this is a standalone version of the AFL++ autotokens custom mutator.
+
+just type `make` to build.
+
+You *MUST* use a dictionary file to have an effective grammarless grammar fuzzer!
+
+```
+autotokens-standalone -h # to see all parameteres
+autotokens-standalone -x foo.dict inputfile outputfile # example
+```
diff --git a/custom_mutators/autotokens/standalone/autotokens-standalone.c b/custom_mutators/autotokens/standalone/autotokens-standalone.c
new file mode 100644
index 00000000..e7a09cb3
--- /dev/null
+++ b/custom_mutators/autotokens/standalone/autotokens-standalone.c
@@ -0,0 +1,192 @@
+#include "afl-fuzz.h"
+#include "afl-mutations.h"
+
+#include <unistd.h>
+#include <getopt.h>
+
+static int            max_havoc = 16, verbose;
+static unsigned char *dict, *mh = "16";
+
+extern int module_disabled;
+
+void *afl_custom_init(afl_state_t *, unsigned int);
+
+int main(int argc, char *argv[]) {
+
+  if (argc > 1 && strncmp(argv[1], "-h", 2) == 0) {
+
+    printf(
+        "Syntax: %s [-v] [-m maxmutations] [-x dict] [inputfile [outputfile "
+        "[splicefile]]]\n\n",
+        argv[0]);
+    printf("Reads a testcase from a file (not stdin!),\n");
+    printf("writes to stdout when '-' or\n");
+    printf(
+        "no output filename is given. As an optional third parameter you can "
+        "give a file\n");
+    printf("for splicing. Maximum input and output length is 1MB.\n");
+    printf("Options:\n");
+    printf("  -v      verbose debug output to stderr.\n");
+    printf("  -m val  max mutations (1-val, val default is 16)\n");
+    printf("  -x file dictionary file (AFL++ format)\n");
+    printf("You can set the following environment variable parameters:\n");
+    printf("AUTOTOKENS_COMMENT` - what character or string starts a comment which will be\n");
+    printf("                      removed. Default: \"/* ... */\"\n");
+    return 0;
+
+  }
+
+  FILE          *in = stdin, *out = stdout, *splice = NULL;
+  unsigned char *inbuf = malloc(1024 * 1024), *outbuf = NULL, *splicebuf = NULL;
+  int            splicelen = 0, opt;
+
+  while ((opt = getopt(argc, argv, "vm:x:")) > 0) {
+
+    switch (opt) {
+
+      case 'm':
+        max_havoc = atoi(optarg);
+        mh = optarg;
+        break;
+      case 'v':
+        verbose = 1;
+        break;
+      case 'x':
+        dict = optarg;
+        break;
+      default:
+        fprintf(stderr, "Error: unknown parameter -%c\n", opt);
+        exit(-1);
+
+    }
+
+  }
+
+  if (max_havoc < 1) {
+
+    fprintf(stderr, "Error: illegal -m value\n");
+    exit(-1);
+
+  }
+
+  if (argc > optind && strcmp(argv[optind], "-") != 0) {
+
+    if ((in = fopen(argv[optind], "r")) == NULL) {
+
+      perror(argv[1]);
+      return -1;
+
+    }
+
+    if (verbose) fprintf(stderr, "Input: %s\n", argv[optind]);
+
+  }
+
+  size_t inlen = fread(inbuf, 1, 1024 * 1024, in);
+
+  if (!inlen) {
+
+    fprintf(stderr, "Error: empty file %s\n",
+            argv[optind] ? argv[optind] : "stdin");
+    return -1;
+
+  }
+
+  if (argc > optind + 1 && strcmp(argv[optind + 1], "-") != 0) {
+
+    if ((out = fopen(argv[optind + 1], "w")) == NULL) {
+
+      perror(argv[optind + 1]);
+      return -1;
+
+    }
+
+    if (verbose) fprintf(stderr, "Output: %s\n", argv[optind + 1]);
+
+  }
+
+  if (argc > optind + 2) {
+
+    if ((splice = fopen(argv[optind + 2], "r")) == NULL) {
+
+      perror(argv[optind + 2]);
+      return -1;
+
+    }
+
+    if (verbose) fprintf(stderr, "Splice: %s\n", argv[optind + 2]);
+    splicebuf = malloc(1024 * 1024);
+    size_t splicelen = fread(splicebuf, 1, 1024 * 1024, splice);
+    if (!splicelen) {
+
+      fprintf(stderr, "Error: empty file %s\n", argv[optind + 2]);
+      return -1;
+
+    }
+
+    if (verbose) fprintf(stderr, "Mutation splice length: %zu\n", splicelen);
+
+  }
+
+  /* configure autotokens */
+  setenv("AUTOTOKENS_LEARN_DICT", "1", 0);
+  setenv("AUTOTOKENS_CREATE_FROM_THIN_AIR", "1", 0);
+  setenv("AUTOTOKENS_CHANGE_MAX", mh, 0);
+
+  /* fake AFL++ state */
+  afl_state_t *afl = (afl_state_t *)calloc(1, sizeof(afl_state_t));
+  afl->queue_cycle = afl->havoc_div = afl->active_items = afl->queued_items = 1;
+  afl->shm.cmplog_mode = 0;
+  afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
+  if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
+
+  rand_set_seed(afl, getpid());
+
+  if (dict) {
+
+    load_extras(afl, dict);
+    if (verbose)
+      fprintf(stderr, "Loaded dictionary: %s (%u entries)\n", dict,
+              afl->extras_cnt);
+
+  }
+
+  // setup a fake queue entry
+  afl->queue_buf = malloc(64);
+  afl->queue_buf[0] = afl->queue_cur =
+      (struct queue_entry *)malloc(sizeof(struct queue_entry));
+  afl->queue_cur->testcase_buf = inbuf;
+  afl->queue_cur->fname = (u8 *)argv[optind];
+  afl->queue_cur->len = inlen;
+  afl->queue_cur->perf_score = 100;
+  afl->queue_cur->favored = afl->queue_cur->is_ascii = 1;
+  // afl->custom_only = 1;
+
+  void *data = (void *)afl_custom_init(afl, (u32)0);
+
+  u8 res = afl_custom_queue_get(inbuf, (u8 *)argv[optind]);
+
+  if (verbose) fprintf(stderr, "Mutation input length: %zu\n", inlen);
+  unsigned int outlen = afl_custom_fuzz(data, inbuf, inlen, &outbuf, splicebuf,
+                                        splicelen, 1024 * 1024);
+
+  if (outlen == 0 || !outbuf) {
+
+    fprintf(stderr, "Error: no mutation data returned.\n");
+    return -1;
+
+  }
+
+  if (verbose) fprintf(stderr, "Mutation output length: %u\n", outlen);
+
+  if (fwrite(outbuf, 1, outlen, out) != outlen) {
+
+    fprintf(stderr, "Warning: incomplete write.\n");
+    return -1;
+
+  }
+
+  return 0;
+
+}
+
diff --git a/custom_mutators/custom_send_tcp/Makefile b/custom_mutators/custom_send_tcp/Makefile
new file mode 100644
index 00000000..8549ccad
--- /dev/null
+++ b/custom_mutators/custom_send_tcp/Makefile
@@ -0,0 +1,7 @@
+all:	custom_send_tcp.so
+
+custom_send_tcp.so:
+	$(CC) -Wno-unused-result -g -O3 -shared -fPIC -o custom_send_tcp.so -I../../include custom_send_tcp.c
+
+clean:
+	rm -f custom_send_tcp.so *.o *~ core
diff --git a/custom_mutators/custom_send_tcp/README.md b/custom_mutators/custom_send_tcp/README.md
new file mode 100644
index 00000000..7b4bb869
--- /dev/null
+++ b/custom_mutators/custom_send_tcp/README.md
@@ -0,0 +1,13 @@
+# Send testcases via TCP custom mutator
+
+This custom mutator sends the fuzzing testcases via TCP.
+
+`AFL_CUSTOM_MUTATOR_LATE_SEND` - MUST be set!
+`CUSTOM_SEND_IP` - the IP address to send to (basically only 127.0.0.1 makes sense)
+`CUSTOM_SEND_PORT` - the TCP port to send to
+`CUSTOM_SEND_READ` - if the custom mutator should wait for a reply from the target
+
+Example:
+```
+CUSTOM_SEND_IP=127.0.0.1 CUSTOM_SEND_PORT=8000 CUSTOM_SEND_READ=1 AFL_CUSTOM_MUTATOR_LATE_SEND=1 AFL_CUSTOM_MUTATOR_LIBRARY=custom_send_tcp.so ./afl-fuzz ...
+```
diff --git a/custom_mutators/custom_send_tcp/custom_send_tcp.c b/custom_mutators/custom_send_tcp/custom_send_tcp.c
new file mode 100644
index 00000000..53689ced
--- /dev/null
+++ b/custom_mutators/custom_send_tcp/custom_send_tcp.c
@@ -0,0 +1,113 @@
+#include <time.h>
+#include <stdio.h>
+#include <stdint.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <fcntl.h>
+#include <arpa/inet.h>
+#include <sys/select.h>
+
+#include "afl-fuzz.h"
+
+static int my_debug = 0;
+static int my_read = 0;
+
+#define DEBUG(...) if (my_debug) printf(__VA_ARGS__)
+
+typedef struct tcp_send_mutator {
+    afl_state_t* afl;
+    struct sockaddr_in server_addr;
+} tcp_send_mutator_t;
+
+void *afl_custom_init(afl_state_t* afl, uint32_t seed) {
+    const char* ip = getenv("CUSTOM_SEND_IP");
+    const char* port = getenv("CUSTOM_SEND_PORT");
+
+    if (getenv("AFL_DEBUG")) my_debug = 1;
+    if (getenv("CUSTOM_SEND_READ")) my_read = 1;
+
+    if (!ip || !port) {
+       fprintf(stderr, "You forgot to set CUSTOM_SEND_IP and/or CUSTOM_SEND_PORT\n");
+       exit(1); 
+    }
+
+    tcp_send_mutator_t* mutator = calloc(1, sizeof(tcp_send_mutator_t));
+    if (!mutator) {
+       fprintf(stderr, "Failed to allocate mutator struct\n");
+       exit(1); 
+    }
+
+    mutator->afl = afl;
+
+    bzero(&mutator->server_addr, sizeof(mutator->server_addr));
+    mutator->server_addr.sin_family = AF_INET;
+    if (inet_pton(AF_INET, ip, &mutator->server_addr.sin_addr) <= 0) {
+        fprintf(stderr, "Could not convert target ip address!\n");
+        exit(1);
+    }
+    mutator->server_addr.sin_port = htons(atoi(port));
+    
+    printf("[+] Custom tcp send mutator setup ready to go!\n");
+
+    return mutator;
+}
+
+int try_connect(tcp_send_mutator_t *mutator, int sock, int max_attempts) {
+    while (max_attempts > 0) {
+        if (connect(sock, (struct sockaddr*)&mutator->server_addr, sizeof(mutator->server_addr)) == 0) {
+            return 0;
+        }
+
+        // Even with AFL_CUSTOM_LATE_SEND=1, there is a race between the
+        // application under test having started to listen for connections and
+        // afl_custom_fuzz_send being called. To address this race, we attempt
+        // to connect N times and sleep a short period of time in between
+        // connection attempts.
+        struct timespec t;
+        t.tv_sec = 0;
+        t.tv_nsec = 100;
+        nanosleep(&t, NULL);
+        --max_attempts;
+    }
+    return 1;
+}
+
+void afl_custom_fuzz_send(tcp_send_mutator_t *mutator, uint8_t *buf, size_t buf_size) {
+    int sock = socket(AF_INET, SOCK_STREAM, 0);
+
+    int written = 0;
+    if (sock >= 0 && try_connect(mutator, sock, 10000) == 0) {
+        DEBUG("connected, write()\n");
+        written = write(sock, buf, buf_size); 
+    } else {
+        DEBUG("socket() or connect() error: %d\n", errno);
+    }
+
+    if (written < 0) {
+        DEBUG("write() error: %d\n", errno);
+    } else if (my_read) {
+        struct timeval timeout;
+        timeout.tv_sec = 1;
+        timeout.tv_usec = 0;
+
+        fd_set set;
+        FD_ZERO(&set);
+        FD_SET(sock, &set);
+
+        int select_res = select(sock + 1, &set, NULL, NULL, &timeout);
+        if (select_res == -1) {
+            DEBUG("select() error: %d\n", errno);
+        } else if (select_res == 0) {
+            DEBUG("read() timeout!\n");
+        } else {
+            uint8_t buf[64];
+            (void)read(sock, buf, sizeof(buf));
+        }
+    }
+
+    close(sock);
+}
+
+void afl_custom_deinit(tcp_send_mutator_t* mutator) {
+    free(mutator);
+}
diff --git a/custom_mutators/gramatron/json-c b/custom_mutators/gramatron/json-c
-Subproject 11546bfd07a575c47416924cb98de3d33a4e642
+Subproject af8dd4a307e7b837f9fa2959549548ace4afe08
diff --git a/custom_mutators/grammar_mutator/GRAMMAR_VERSION b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
index 02119caf..eea76ba3 100644
--- a/custom_mutators/grammar_mutator/GRAMMAR_VERSION
+++ b/custom_mutators/grammar_mutator/GRAMMAR_VERSION
@@ -1 +1 @@
-95a6857
+05d8f53
diff --git a/custom_mutators/grammar_mutator/grammar_mutator b/custom_mutators/grammar_mutator/grammar_mutator
-Subproject 95a685773e571620cb6e2788dbbdba333e1b9bf
+Subproject 05d8f537f8d656f0754e7ad5dcc653c42cb4f8f
diff --git a/custom_mutators/radamsa/libradamsa.c b/custom_mutators/radamsa/libradamsa.c
index e6838752..1dcf91d8 100644
--- a/custom_mutators/radamsa/libradamsa.c
+++ b/custom_mutators/radamsa/libradamsa.c
@@ -3707,7 +3707,7 @@ typedef intptr_t     wdiff;
   1024 * 1024 * 8         /* static malloc'd heap size if used as a library */
 #define FBITS 24             /* bits in fixnum, on the way to 24 and beyond */
 #define FMAX                                                       \
-  ((1 << FBITS) - 1)  /* maximum fixnum (and most negative fixnum) \
+  ((1U << FBITS) - 1)  /* maximum fixnum (and most negative fixnum) \
                        */
 #define MAXOBJ 0xffff                /* max words in tuple including header */
 #define MAXPAYL                                                \