about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--afl-fuzz.c17
-rw-r--r--custom_mutators/simple_mutator.c40
-rw-r--r--docs/custom_mutator.txt34
3 files changed, 91 insertions, 0 deletions
diff --git a/afl-fuzz.c b/afl-fuzz.c
index a1388a55..73efdfb1 100644
--- a/afl-fuzz.c
+++ b/afl-fuzz.c
@@ -369,7 +369,24 @@ static u32 a_extras_cnt;              /* Total number of tokens available */
 static u8* (*post_handler)(u8* buf, u32* len);
 
 /* hooks for the custom mutator function */
+/**
+ * Perform custom mutations on a given input
+ * @param data Input data to be mutated
+ * @param size Size of input data
+ * @param mutated_out Buffer to store the mutated input
+ * @param max_size Maximum size of the mutated output. The mutation must not produce data larger than max_size.
+ * @param seed Seed used for the mutation. The mutation should produce the same output given the same seed.
+ * @return Size of the mutated output.
+ */
 static size_t (*custom_mutator)(u8 *data, size_t size, u8* mutated_out, size_t max_size, unsigned int seed);
+/**
+ * A post-processing function to use right before AFL writes the test case to disk in order to execute the target.
+ * If this functionality is not needed, Simply don't define this function.
+ * @param data Buffer containing the test case to be executed.
+ * @param size Size of the test case.
+ * @param new_data Buffer to store the test case after processing
+ * @return Size of data after processing.
+ */
 static size_t (*pre_save_handler)(u8 *data, size_t size, u8 **new_data);
 
 
diff --git a/custom_mutators/simple_mutator.c b/custom_mutators/simple_mutator.c
new file mode 100644
index 00000000..5c40d462
--- /dev/null
+++ b/custom_mutators/simple_mutator.c
@@ -0,0 +1,40 @@
+/*
+  Simple Custom Mutator for AFL
+
+  Written by Khaled Yakdan <yakdan@code-intelligence.de>
+
+  This a simple mutator that assumes that the generates messages starting with one
+  of the three strings GET, PUT, or DEL followed by a payload. The mutator randomly
+  selects a commend and mutates the payload of the seed provided as input.
+*/
+
+#include <stdint.h>
+#include <stdlib.h>
+#include <string.h>
+
+static const char *commands[] = {
+  "GET",
+  "PUT",
+  "DEL",
+};
+
+static size_t data_size = 100;
+
+size_t afl_custom_mutator (uint8_t *data, size_t size, uint8_t* mutated_out, size_t max_size, unsigned int seed) {
+
+  // Seed the PRNG
+  srand(seed);
+
+  // Make sure that the packet size does not exceed the maximum size expected by the fuzzer
+  size_t mutated_size = data_size <= max_size ? data_size : max_size;
+
+  // Randomly select a command string to add as a header to the packet
+  memcpy(mutated_out, commands[rand() % 3], 3);
+
+  // Mutate the payload of the packet
+  for (int i = 3 ; i < mutated_size ; i++) {
+    mutated_out[i] = (data[i] + rand() % 10) & 0xff;
+  }
+
+  return mutated_size;
+}
diff --git a/docs/custom_mutator.txt b/docs/custom_mutator.txt
new file mode 100644
index 00000000..3b1b93b9
--- /dev/null
+++ b/docs/custom_mutator.txt
@@ -0,0 +1,34 @@
+==================================================
+Adding custom mutators to AFL using
+==================================================
+This file describes how you can implement custom mutations to be used in AFL.
+
+Implemented by Khaled Yakdan from Code Intelligence <yakdan@code-intelligence.de>
+
+
+1) Description
+--------------
+
+Custom mutator libraries can be passed to afl-fuzz to perform custom mutations
+on test cases beyond those available in AFL - for example, to enable structure-aware
+fuzzing by using libraries that perform mutations according to a given grammar.
+
+The custom mutator library is passed to afl-fuzz via the AFL_CUSTOM_MUTATOR_LIBRARY
+environment variable. The library must export the afl_custom_mutator() function and
+must be compiled as a shared object. For example:
+     $CC -shared -Wall -O3 <lib-name>.c -o <lib-name>.so
+
+AFL will call the afl_custom_mutator() function every time it needs to mutate
+a test case. For some cases, the format of the mutated data returned from
+the custom mutator is not suitable to directly execute the target with this input.
+For example, when using libprotobuf-mutator, the data returned is in a protobuf
+format which corresponds to a given grammar. In order to execute the target,
+the protobuf data must be converted to the plain-text format expected by the target.
+In such scenarios, the user can define the afl_pre_save_handler() function. This function
+is then transforms the data into the format expected by the API before executing the target.
+afl_pre_save_handler is optional and does not have to be implemented if its functionality
+is not needed.
+
+2) Example
+----------
+A simple example is provided in ../custom_mutators/
\ No newline at end of file