about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--.gitmodules3
-rw-r--r--custom_mutators/gramatron/JSONC_VERSION1
-rw-r--r--custom_mutators/gramatron/Makefile7
-rw-r--r--custom_mutators/gramatron/README.md18
-rwxr-xr-xcustom_mutators/gramatron/build_gramatron_mutator.sh140
-rw-r--r--custom_mutators/gramatron/gramfuzz-helpers.c6
-rw-r--r--custom_mutators/gramatron/gramfuzz-mutators.c11
-rw-r--r--custom_mutators/gramatron/gramfuzz.c4
-rw-r--r--custom_mutators/gramatron/gramfuzz.h2
m---------custom_mutators/gramatron/json-c0
-rw-r--r--docs/Changelog.md2
11 files changed, 163 insertions, 31 deletions
diff --git a/.gitmodules b/.gitmodules
index c787ec0e..6edefd72 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -7,3 +7,6 @@
 [submodule "qemu_mode/qemuafl"]
 	path = qemu_mode/qemuafl
 	url = https://github.com/AFLplusplus/qemuafl
+[submodule "custom_mutators/gramatron/json-c"]
+	path = custom_mutators/gramatron/json-c
+	url = https://github.com/json-c/json-c
diff --git a/custom_mutators/gramatron/JSONC_VERSION b/custom_mutators/gramatron/JSONC_VERSION
new file mode 100644
index 00000000..7663833a
--- /dev/null
+++ b/custom_mutators/gramatron/JSONC_VERSION
@@ -0,0 +1 @@
+af8dd4a307e7b837f9fa2959549548ace4afe08b
diff --git a/custom_mutators/gramatron/Makefile b/custom_mutators/gramatron/Makefile
deleted file mode 100644
index d24f3dd4..00000000
--- a/custom_mutators/gramatron/Makefile
+++ /dev/null
@@ -1,7 +0,0 @@
-all:	gramatron.so
-
-gramatron.so:	gramfuzz.c gramfuzz.h gramfuzz-helpers.c gramfuzz-mutators.c gramfuzz-util.c hashmap.c hashmap.h test.c test.h utarray.h uthash.h
-	$(CC) -O3 -g -fPIC -Wno-unused-result -Wl,--allow-multiple-definition -I../../include -o gramatron.so -shared -I. -I/prg/dev/include gramfuzz.c gramfuzz-helpers.c gramfuzz-mutators.c gramfuzz-util.c hashmap.c test.c -ljson-c
-
-clean:
-	rm -f gramatron.so
diff --git a/custom_mutators/gramatron/README.md b/custom_mutators/gramatron/README.md
index 6659cb95..91f93355 100644
--- a/custom_mutators/gramatron/README.md
+++ b/custom_mutators/gramatron/README.md
@@ -1,20 +1,15 @@
 # GramaTron
 
 Gramatron is a coverage-guided fuzzer that uses grammar automatons to perform
-grammar-aware fuzzing.  Technical details about our framework are available in our
-[ISSTA'21 paper](https://nebelwelt.net/files/21ISSTA.pdf). The artifact to reproduce the
-experiments presented in our paper are present in `artifact/`. Instructions to run
-a sample campaign and incorporate new grammars is presented below: 
+grammar-aware fuzzing.  Technical details about our framework are available
+in the [ISSTA'21 paper](https://nebelwelt.net/files/21ISSTA.pdf).
+The artifact to reproduce the experiments presented in the paper are present
+in `artifact/`. Instructions to run a sample campaign and incorporate new
+grammars is presented below: 
 
 # Compiling
 
-- Install `json-c` 
-```
-git clone https://github.com/json-c/json-c.git
-cd json-c && git reset --hard af8dd4a307e7b837f9fa2959549548ace4afe08b && sh autogen.sh && ./configure && make && make install 
-```
-
-afterwards you can just `make` GrammaTron
+Simply execute `./build_gramatron_mutator.sh`
 
 # Running
 
@@ -48,4 +43,3 @@ Eg. ./preprocess/prep_automaton.sh ~/grammars/ruby/source.json PROGRAM
 
 Eg. ./test SanityCheck ~/grammars/ruby/source_automata.json
 ```
-
diff --git a/custom_mutators/gramatron/build_gramatron_mutator.sh b/custom_mutators/gramatron/build_gramatron_mutator.sh
new file mode 100755
index 00000000..c1cdf0e7
--- /dev/null
+++ b/custom_mutators/gramatron/build_gramatron_mutator.sh
@@ -0,0 +1,140 @@
+#!/bin/sh
+#
+# american fuzzy lop++ - gramatron build script
+# ------------------------------------------------
+#
+# Originally written by Nathan Voss <njvoss99@gmail.com>
+#
+# Adapted from code by Andrew Griffiths <agriffiths@google.com> and
+#                      Michal Zalewski
+#
+# Adapted for AFLplusplus by Dominik Maier <mail@dmnk.co>
+#
+# Copyright 2017 Battelle Memorial Institute. All rights reserved.
+# Copyright 2019-2020 AFLplusplus Project. All rights reserved.
+#
+# Licensed under the Apache License, Version 2.0 (the "License");
+# you may not use this file except in compliance with the License.
+# You may obtain a copy of the License at:
+#
+#   http://www.apache.org/licenses/LICENSE-2.0
+#
+# This script downloads, patches, and builds a version of Unicorn with
+# minor tweaks to allow Unicorn-emulated binaries to be run under
+# afl-fuzz.
+#
+# The modifications reside in patches/*. The standalone Unicorn library
+# will be written to /usr/lib/libunicornafl.so, and the Python bindings
+# will be installed system-wide.
+#
+# You must make sure that Unicorn Engine is not already installed before
+# running this script. If it is, please uninstall it first.
+
+JSONC_VERSION="$(cat ./JSONC_VERSION)"
+JSONC_REPO="https://github.com/json-c/json-c"
+
+echo "================================================="
+echo "Gramatron Mutator build script"
+echo "================================================="
+echo
+
+echo "[*] Performing basic sanity checks..."
+
+PLT=`uname -s`
+
+if [ ! -f "../../config.h" ]; then
+
+  echo "[-] Error: key files not found - wrong working directory?"
+  exit 1
+
+fi
+
+PYTHONBIN=`command -v python3 || command -v python || command -v python2 || echo python3`
+MAKECMD=make
+TARCMD=tar
+
+if [ "$PLT" = "Darwin" ]; then
+  CORES=`sysctl -n hw.ncpu`
+  TARCMD=tar
+fi
+
+if [ "$PLT" = "FreeBSD" ]; then
+  MAKECMD=gmake
+  CORES=`sysctl -n hw.ncpu`
+  TARCMD=gtar
+fi
+
+if [ "$PLT" = "NetBSD" ] || [ "$PLT" = "OpenBSD" ]; then
+  MAKECMD=gmake
+  CORES=`sysctl -n hw.ncpu`
+  TARCMD=gtar
+fi
+
+PREREQ_NOTFOUND=
+for i in git $MAKECMD $TARCMD; do
+
+  T=`command -v "$i" 2>/dev/null`
+
+  if [ "$T" = "" ]; then
+
+    echo "[-] Error: '$i' not found. Run 'sudo apt-get install $i' or similar."
+    PREREQ_NOTFOUND=1
+
+  fi
+
+done
+
+test -z "$CC" && export CC=cc
+
+if echo "$CC" | grep -qF /afl-; then
+
+  echo "[-] Error: do not use afl-gcc or afl-clang to compile this tool."
+  PREREQ_NOTFOUND=1
+
+fi
+
+if [ "$PREREQ_NOTFOUND" = "1" ]; then
+  exit 1
+fi
+
+echo "[+] All checks passed!"
+
+echo "[*] Making sure json-c is checked out"
+
+git status 1>/dev/null 2>/dev/null
+if [ $? -eq 0 ]; then
+  echo "[*] initializing json-c submodule"
+  git submodule init || exit 1
+  git submodule update ./json-c 2>/dev/null # ignore errors
+else
+  echo "[*] cloning json-c"
+  test -d json-c || {
+    CNT=1
+    while [ '!' -d json-c -a "$CNT" -lt 4 ]; do
+      echo "Trying to clone json-c (attempt $CNT/3)"
+      git clone "$JSONC_REPO" 
+      CNT=`expr "$CNT" + 1`
+    done
+  }
+fi
+
+test -d json-c || { echo "[-] not checked out, please install git or check your internet connection." ; exit 1 ; }
+echo "[+] Got json-c."
+
+cd "json-c" || exit 1
+echo "[*] Checking out $JSONC_VERSION"
+sh -c 'git stash && git stash drop' 1>/dev/null 2>/dev/null
+git checkout "$JSONC_VERSION" || exit 1
+sh autogen.sh || exit 1
+export CFLAGS=-fPIC
+./configure --disable-shared || exit 1
+make || exit 1
+cd ..
+
+echo
+echo
+echo "[+] Json-c successfully prepared!"
+echo "[+] Builing gramatron now."
+$CC -O3 -g -fPIC -Wno-unused-result -Wl,--allow-multiple-definition -I../../include -o gramatron.so -shared -I. -I/prg/dev/include gramfuzz.c gramfuzz-helpers.c gramfuzz-mutators.c gramfuzz-util.c hashmap.c json-c/.libs/libjson-c.a || exit 1
+echo
+echo "[+] gramatron successfully built!"
diff --git a/custom_mutators/gramatron/gramfuzz-helpers.c b/custom_mutators/gramatron/gramfuzz-helpers.c
index f894c850..378a3d90 100644
--- a/custom_mutators/gramatron/gramfuzz-helpers.c
+++ b/custom_mutators/gramatron/gramfuzz-helpers.c
@@ -73,7 +73,7 @@ void concatPrefixFeature(Array *prefix, Array *feature) {
   // the recursive feature. Might want to fix it to choose a random number upper
   // bounded by a static value instead.
   terminal *featureptr;
-  int       len = rand() % RECUR_THRESHOLD;
+  int       len = rand_below(global_afl, RECUR_THRESHOLD);
   for (int x = 0; x < len; x++) {
 
     for (int y = 0; y < feature->used; y++) {
@@ -149,7 +149,7 @@ Array *gen_input(state *pda, Array *input) {
     state_ptr = pda + curr_state;
 
     // Get a random trigger
-    randval = rand() % (state_ptr->trigger_len);
+    randval = rand_below(global_afl, state_ptr->trigger_len);
     trigger_ptr = (state_ptr->ptr) + randval;
 
     // Insert into the dynamic array
@@ -187,7 +187,7 @@ Array *gen_input_count(state *pda, Array *input, int *mut_count) {
     state_ptr = pda + curr_state;
 
     // Get a random trigger
-    randval = rand() % (state_ptr->trigger_len);
+    randval = rand_below(global_afl, state_ptr->trigger_len);
     trigger_ptr = (state_ptr->ptr) + randval;
 
     // Insert into the dynamic array
diff --git a/custom_mutators/gramatron/gramfuzz-mutators.c b/custom_mutators/gramatron/gramfuzz-mutators.c
index 0255e1d0..0fc9c307 100644
--- a/custom_mutators/gramatron/gramfuzz-mutators.c
+++ b/custom_mutators/gramatron/gramfuzz-mutators.c
@@ -13,7 +13,7 @@ Array *performRandomMutation(state *pda, Array *input) {
   Array *sliced;
 
   // Get offset at which to generate new input and slice it
-  int idx = rand() % input->used;
+  int idx = rand_below(global_afl, input->used);
   sliced = slice(input, idx);
   // print_repr(sliced, "Slice");
 
@@ -58,7 +58,7 @@ Array *performSpliceOne(Array *originput, IdxMap_new *statemap_orig,
     int length = utarray_len(stateptr);
     if (length) {
 
-      int *splice_idx = (int *)utarray_eltptr(stateptr, rand() % length);
+      int *splice_idx = (int *)utarray_eltptr(stateptr, rand_below(global_afl, length));
       ip.orig_idx = *splice_idx;
       ip.splice_idx = x;
       utarray_push_back(pairs, &ip);
@@ -69,7 +69,7 @@ Array *performSpliceOne(Array *originput, IdxMap_new *statemap_orig,
 
   // Pick a random pair
   int length = utarray_len(pairs);
-  cand = (intpair_t *)utarray_eltptr(pairs, rand() % length);
+  cand = (intpair_t *)utarray_eltptr(pairs, rand_below(global_afl, length));
   // printf("\n Orig_idx:%d Splice_idx:%d", cand->orig_idx, cand->splice_idx);
 
   // Perform the splicing
@@ -162,7 +162,7 @@ UT_array **get_dupes(Array *input, int *recur_len) {
 Array *doMult(Array *input, UT_array **recur, int recurlen) {
 
   int       offset = 0;
-  int       idx = rand() % (recurlen);
+  int       idx = rand_below(global_afl, recurlen);
   UT_array *recurMap = recur[idx];
   UT_array *recurPtr;
   Array *   prefix;
@@ -225,14 +225,13 @@ void getTwoIndices(UT_array *recur, int recurlen, int *firstIdx,
   for (int i = offset - 1; i > 0; i--) {
 
     // Pick a random index from 0 to i
-    int j = rand() % (i + 1);
+    int j = rand_below(global_afl, i + 1);
 
     // Swap arr[i] with the element at random index
     swap(&ArrayRecurIndices[i], &ArrayRecurIndices[j]);
 
   }
 
-  // Get the first two indices
   *firstIdx = ArrayRecurIndices[0];
   *secondIdx = ArrayRecurIndices[1];
 
diff --git a/custom_mutators/gramatron/gramfuzz.c b/custom_mutators/gramatron/gramfuzz.c
index fd126ec0..d64d2fa9 100644
--- a/custom_mutators/gramatron/gramfuzz.c
+++ b/custom_mutators/gramatron/gramfuzz.c
@@ -125,7 +125,6 @@ state *create_pda(u8 *automaton_file) {
 
 my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
 
-  srand(seed);
   my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
   if (!data) {
 
@@ -142,6 +141,7 @@ my_mutator_t *afl_custom_init(afl_state_t *afl, unsigned int seed) {
   }
 
   data->afl = afl;
+  global_afl = afl;  // dirty
   data->seed = seed;
 
   data->mut_alloced = 0;
@@ -211,7 +211,7 @@ size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
   } else if (data->mut_idx == 2) {  // Perform splice mutation
 
     // we cannot use the supplied splice data so choose a new random file
-    u32                 tid = rand() % data->afl->queued_paths;
+    u32                 tid = rand_below(global_afl, data->afl->queued_paths);
     struct queue_entry *q = data->afl->queue_buf[tid];
 
     // Read the input representation for the splice candidate
diff --git a/custom_mutators/gramatron/gramfuzz.h b/custom_mutators/gramatron/gramfuzz.h
index e6912074..1e599f0c 100644
--- a/custom_mutators/gramatron/gramfuzz.h
+++ b/custom_mutators/gramatron/gramfuzz.h
@@ -23,6 +23,8 @@
   3600  // Inputs that gave new coverage will be dumped every FLUSH_INTERVAL
         // seconds
 
+afl_state_t *global_afl;
+
 typedef struct trigger {
 
   char * id;
diff --git a/custom_mutators/gramatron/json-c b/custom_mutators/gramatron/json-c
new file mode 160000
+Subproject af8dd4a307e7b837f9fa2959549548ace4afe08
diff --git a/docs/Changelog.md b/docs/Changelog.md
index 3f3dc642..cb22c272 100644
--- a/docs/Changelog.md
+++ b/docs/Changelog.md
@@ -9,7 +9,7 @@ Want to stay in the loop on major new features? Join our mailing list by
 sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 ### Version ++3.15a (dev)
-  - ...
+  - added the very good grammar mutator "GramaTron" to the custom_mutators
 
 
 ### Version ++3.14c (release)