aboutsummaryrefslogtreecommitdiff
path: root/docs/custom_mutators.md
diff options
context:
space:
mode:
authorllzmb <46303940+llzmb@users.noreply.github.com>2021-12-04 20:38:00 +0100
committerllzmb <46303940+llzmb@users.noreply.github.com>2021-12-04 20:38:00 +0100
commitbcd81c377d22cf26812127881a8ac15ed9c022ad (patch)
treee39d9211b49416cf987ea8fbe80597deb9226ccb /docs/custom_mutators.md
parent13eedcd5e8128419ae1b3e04d56a775eeea6f471 (diff)
downloadafl++-bcd81c377d22cf26812127881a8ac15ed9c022ad.tar.gz
Fix line length and formatting
Diffstat (limited to 'docs/custom_mutators.md')
-rw-r--r--docs/custom_mutators.md80
1 files changed, 41 insertions, 39 deletions
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md
index 6bee5413..2a77db82 100644
--- a/docs/custom_mutators.md
+++ b/docs/custom_mutators.md
@@ -4,13 +4,13 @@ This file describes how you can implement custom mutations to be used in AFL.
For now, we support C/C++ library and Python module, collectivelly named as the
custom mutator.
-There is also experimental support for Rust in `custom_mutators/rust`.
-For documentation, refer to that directory.
-Run ```cargo doc -p custom_mutator --open``` in that directory to view the
-documentation in your web browser.
+There is also experimental support for Rust in `custom_mutators/rust`. For
+documentation, refer to that directory. Run `cargo doc -p custom_mutator --open`
+in that directory to view the documentation in your web browser.
Implemented by
-- C/C++ library (`*.so`): Khaled Yakdan from Code Intelligence (<yakdan@code-intelligence.de>)
+- C/C++ library (`*.so`): Khaled Yakdan from Code Intelligence
+ (<yakdan@code-intelligence.de>)
- Python module: Christian Holler from Mozilla (<choller@mozilla.com>)
## 1) Introduction
@@ -29,7 +29,8 @@ export AFL_CUSTOM_MUTATOR_LIBRARY="full/path/to/mutator_first.so;full/path/to/mu
For details, see [APIs](#2-apis) and [Usage](#3-usage).
-The custom mutation stage is set to be the first non-deterministic stage (right before the havoc stage).
+The custom mutation stage is set to be the first non-deterministic stage (right
+before the havoc stage).
Note: If `AFL_CUSTOM_MUTATOR_ONLY` is set, all mutations will solely be
performed with the custom mutator.
@@ -103,7 +104,8 @@ def deinit(): # optional for Python
- `init`:
- This method is called when AFL++ starts up and is used to seed RNG and set up buffers and state.
+ This method is called when AFL++ starts up and is used to seed RNG and set
+ up buffers and state.
- `queue_get` (optional):
@@ -121,18 +123,17 @@ def deinit(): # optional for Python
- `fuzz` (optional):
This method performs custom mutations on a given input. It also accepts an
- additional test case.
- Note that this function is optional - but it makes sense to use it.
- You would only skip this if `post_process` is used to fix checksums etc.
- so if you are using it, e.g., as a post processing library.
+ additional test case. Note that this function is optional - but it makes
+ sense to use it. You would only skip this if `post_process` is used to fix
+ checksums etc. so if you are using it, e.g., as a post processing library.
Note that a length > 0 *must* be returned!
- `describe` (optional):
When this function is called, it shall describe the current test case,
- generated by the last mutation. This will be called, for example,
- to name the written test case file after a crash occurred.
- Using it can help to reproduce crashing mutations.
+ generated by the last mutation. This will be called, for example, to name
+ the written test case file after a crash occurred. Using it can help to
+ reproduce crashing mutations.
- `havoc_mutation` and `havoc_mutation_probability` (optional):
@@ -144,21 +145,21 @@ def deinit(): # optional for Python
- `post_process` (optional):
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
- `post_process` function. This function is then transforming the data into the
- format expected by the API before executing the target.
+ 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 `post_process` function.
+ This function is then transforming the data into the format expected by the
+ API before executing the target.
This can return any python object that implements the buffer protocol and
supports PyBUF_SIMPLE. These include bytes, bytearray, etc.
- `queue_new_entry` (optional):
- This methods is called after adding a new test case to the queue.
- If the contents of the file was changed return True, False otherwise.
+ This methods is called after adding a new test case to the queue. If the
+ contents of the file was changed, return True, False otherwise.
- `introspection` (optional):
@@ -170,8 +171,8 @@ def deinit(): # optional for Python
The last method to be called, deinitializing the state.
-Note that there are also three functions for trimming as described in the
-next section.
+Note that there are also three functions for trimming as described in the next
+section.
### Trimming Support
@@ -179,8 +180,8 @@ The generic trimming routines implemented in AFL++ can easily destroy the
structure of complex formats, possibly leading to a point where you have a lot
of test cases in the queue that your Python module cannot process anymore but
your target application still accepts. This is especially the case when your
-target can process a part of the input (causing coverage) and then errors out
-on the remaining input.
+target can process a part of the input (causing coverage) and then errors out on
+the remaining input.
In such cases, it makes sense to implement a custom trimming routine. The API
consists of multiple methods because after each trimming step, we have to go
@@ -213,10 +214,10 @@ trimmed input. Here's a quick API description:
- `post_trim` (optional)
This method is called after each trim operation to inform you if your
- trimming step was successful or not (in terms of coverage). If you receive
- a failure here, you should reset your input to the last known good state.
- In any case, this method must return the next trim iteration index (from 0
- to the maximum amount of steps you returned in `init_trim`).
+ trimming step was successful or not (in terms of coverage). If you receive a
+ failure here, you should reset your input to the last known good state. In
+ any case, this method must return the next trim iteration index (from 0 to
+ the maximum amount of steps you returned in `init_trim`).
Omitting any of three trimming methods will cause the trimming to be disabled
and trigger a fallback to the built-in default trimming routine.
@@ -227,10 +228,10 @@ Optionally, the following environment variables are supported:
- `AFL_CUSTOM_MUTATOR_ONLY`
- Disable all other mutation stages. This can prevent broken test cases
- (those that your Python module can't work with anymore) to fill up your
- queue. Best combined with a custom trimming routine (see below) because
- trimming can cause the same test breakage like havoc and splice.
+ Disable all other mutation stages. This can prevent broken test cases (those
+ that your Python module can't work with anymore) to fill up your queue. Best
+ combined with a custom trimming routine (see below) because trimming can
+ cause the same test breakage like havoc and splice.
- `AFL_PYTHON_ONLY`
@@ -270,9 +271,10 @@ For C/C++ mutators, the source code must be compiled as a shared object:
```bash
gcc -shared -Wall -O3 example.c -o example.so
```
-Note that if you specify multiple custom mutators, the corresponding functions will
-be called in the order in which they are specified. e.g first `post_process` function of
-`example_first.so` will be called and then that of `example_second.so`.
+Note that if you specify multiple custom mutators, the corresponding functions
+will be called in the order in which they are specified. e.g first
+`post_process` function of `example_first.so` will be called and then that of
+`example_second.so`.
### Run
@@ -300,4 +302,4 @@ See [example.c](../custom_mutators/examples/example.c) and
- [bruce30262/libprotobuf-mutator_fuzzing_learning](https://github.com/bruce30262/libprotobuf-mutator_fuzzing_learning/tree/master/4_libprotobuf_aflpp_custom_mutator)
- [thebabush/afl-libprotobuf-mutator](https://github.com/thebabush/afl-libprotobuf-mutator)
- [XML Fuzzing@NullCon 2017](https://www.agarri.fr/docs/XML_Fuzzing-NullCon2017-PUBLIC.pdf)
- - [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663)
+ - [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663) \ No newline at end of file