diff options
author | Cory Barker <cobark@google.com> | 2023-06-13 01:48:23 +0000 |
---|---|---|
committer | Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com> | 2023-06-13 01:48:23 +0000 |
commit | 0bfdf29cdae30fc887a9ee3f31a0b8fe52f45df3 (patch) | |
tree | fc20f17f4053f3b858e31a4f08a252715784a9b0 /docs/custom_mutators.md | |
parent | b979ffa6e12911bad818db24ea11f98e3edf3c1e (diff) | |
parent | bdf032543e3b7bab910dd6849a9a00f34c5463df (diff) | |
download | AFLplusplus-0bfdf29cdae30fc887a9ee3f31a0b8fe52f45df3.tar.gz |
updating AFLpp repository am: c39bdae8bc am: e40f5ec2bd am: 675c292b99 am: 6c79891376 am: 3a355e79e8 am: bdf032543e
Original change: https://android-review.googlesource.com/c/platform/external/AFLplusplus/+/2617481
Change-Id: I5a48d3fa05ab26b816d20e4cce5f42cafd9a287a
Signed-off-by: Automerger Merge Worker <android-build-automerger-merge-worker@system.gserviceaccount.com>
Diffstat (limited to 'docs/custom_mutators.md')
-rw-r--r-- | docs/custom_mutators.md | 77 |
1 files changed, 71 insertions, 6 deletions
diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 7b4e0516..3f7e9e6e 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -38,11 +38,17 @@ performed with the custom mutator. ## 2) APIs +**IMPORTANT NOTE**: If you use our C/C++ API and you want to increase the size +of an **out_buf buffer, you have to use `afl_realloc()` for this, so include +`include/alloc-inl.h` - otherwise afl-fuzz will crash when trying to free +your buffers. + C/C++: ```c void *afl_custom_init(afl_state_t *afl, unsigned int seed); unsigned int afl_custom_fuzz_count(void *data, const unsigned char *buf, size_t buf_size); +void afl_custom_splice_optout(void *data); size_t afl_custom_fuzz(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf, unsigned char *add_buf, size_t add_buf_size, size_t max_size); const char *afl_custom_describe(void *data, size_t max_description_len); size_t afl_custom_post_process(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf); @@ -52,6 +58,7 @@ int afl_custom_post_trim(void *data, unsigned char success); size_t afl_custom_havoc_mutation(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf, size_t max_size); unsigned char afl_custom_havoc_mutation_probability(void *data); unsigned char afl_custom_queue_get(void *data, const unsigned char *filename); +void (*afl_custom_fuzz_send)(void *data, const u8 *buf, size_t buf_size); u8 afl_custom_queue_new_entry(void *data, const unsigned char *filename_new_queue, const unsigned int *filename_orig_queue); const char* afl_custom_introspection(my_mutator_t *data); void afl_custom_deinit(void *data); @@ -63,9 +70,12 @@ Python: def init(seed): pass -def fuzz_count(buf, add_buf, max_size): +def fuzz_count(buf): return cnt +def splice_optout() + pass + def fuzz(buf, add_buf, max_size): return mutated_out @@ -93,6 +103,9 @@ def havoc_mutation_probability(): def queue_get(filename): return True +def fuzz_send(buf): + pass + def queue_new_entry(filename_new_queue, filename_orig_queue): return False @@ -105,7 +118,7 @@ def deinit(): # optional for Python ### Custom Mutation -- `init`: +- `init` (optional in Python): This method is called when AFL++ starts up and is used to seed RNG and set up buffers and state. @@ -123,6 +136,13 @@ def deinit(): # optional for Python for a specific queue entry, use this function. This function is most useful if `AFL_CUSTOM_MUTATOR_ONLY` is **not** used. +- `splice_optout` (optional): + + If this function is present, no splicing target is passed to the `fuzz` + function. This saves time if splicing data is not needed by the custom + fuzzing function. + This function is never called, just needs to be present to activate. + - `fuzz` (optional): This method performs custom mutations on a given input. It also accepts an @@ -130,6 +150,7 @@ def deinit(): # optional for Python 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! + The returned output buffer is under **your** memory management! - `describe` (optional): @@ -159,6 +180,22 @@ def deinit(): # optional for Python This can return any python object that implements the buffer protocol and supports PyBUF_SIMPLE. These include bytes, bytearray, etc. + You can decide in the post_process mutator to not send the mutated data + to the target, e.g. if it is too short, too corrupted, etc. If so, + return a NULL buffer and zero length (or a 0 length string in Python). + + NOTE: Do not make any random changes to the data in this function! + + PERFORMANCE for C/C++: If possible make the changes in-place (so modify + the `*data` directly, and return it as `*outbuf = data`. + +- `fuzz_send` (optional): + + This method can be used if you want to send data to the target yourself, + e.g. via IPC. This replaces some usage of utils/afl_proxy but requires + that you start the target with afl-fuzz. + Example: [custom_mutators/examples/custom_send.c](custom_mutators/examples/custom_send.c) + - `queue_new_entry` (optional): This methods is called after adding a new test case to the queue. If the @@ -170,7 +207,7 @@ def deinit(): # optional for Python discovered if compiled with INTROSPECTION. The custom mutator can then return a string (const char *) that reports the exact mutations used. -- `deinit`: +- `deinit` (optional in Python): The last method to be called, deinitializing the state. @@ -260,13 +297,41 @@ sudo apt install python-dev ``` Then, AFL++ can be compiled with Python support. The AFL++ Makefile detects -Python 2 and 3 through `python-config` if it is in the PATH and compiles -`afl-fuzz` with the feature if available. +Python3 through `python-config`/`python3-config` if it is in the PATH and +compiles `afl-fuzz` with the feature if available. -Note: for some distributions, you might also need the package `python[23]-apt`. +Note: for some distributions, you might also need the package `python[3]-apt`. In case your setup is different, set the necessary variables like this: `PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`. +### Helpers + +For C/C++ custom mutators you get a pointer to `afl_state_t *afl` in the +`afl_custom_init()` which contains all information that you need. +Note that if you access it, you need to recompile your custom mutator if +you update AFL++ because the structure might have changed! + +For mutators written in Python, Rust, GO, etc. there are a few environment +variables set to help you to get started: + +`AFL_CUSTOM_INFO_PROGRAM` - the program name of the target that is executed. +If your custom mutator is used with modes like Qemu (`-Q`), this will still +contain the target program, not afl-qemu-trace. + +`AFL_CUSTOM_INFO_PROGRAM_INPUT` - if the `-f` parameter is used with afl-fuzz +then this value is found in this environment variable. + +`AFL_CUSTOM_INFO_PROGRAM_ARGV` - this contains the parameters given to the +target program and still has the `@@` identifier in there. + +Note: If `AFL_CUSTOM_INFO_PROGRAM_INPUT` is empty and `AFL_CUSTOM_INFO_PROGRAM_ARGV` +is either empty or does not contain `@@` then the target gets the input via +`stdin`. + +`AFL_CUSTOM_INFO_OUT` - This is the output directory for this fuzzer instance, +so if `afl-fuzz` was called with `-o out -S foobar`, then this will be set to +`out/foobar`. + ### Custom Mutator Preparation For C/C++ mutators, the source code must be compiled as a shared object: |