add gramatron
MODIFY
.gitmodules
.gitmodules
[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

ADD
custom_mutators/gramatron/JSONC_VERSION
+af8dd4a307e7b837f9fa2959549548ace4afe08b

DELETE
custom_mutators/gramatron/Makefile
-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

MODIFY
custom_mutators/gramatron/README.md
custom_mutators/gramatron/README.md
# 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
```
-

ADD
custom_mutators/gramatron/build_gramatron_mutator.sh
+#!/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!"

MODIFY
custom_mutators/gramatron/gramfuzz-helpers.c
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

MODIFY
custom_mutators/gramatron/gramfuzz-mutators.c
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];

MODIFY
custom_mutators/gramatron/gramfuzz.c
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

MODIFY
custom_mutators/gramatron/gramfuzz.h
custom_mutators/gramatron/gramfuzz.h
3600 // Inputs that gave new coverage will be dumped every FLUSH_INTERVAL
// seconds
+afl_state_t *global_afl;
+
typedef struct trigger {
char * id;

ADD
custom_mutators/gramatron/json-c
+Subproject commit af8dd4a307e7b837f9fa2959549548ace4afe08b

MODIFY
docs/Changelog.md
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)

add gramatron