From 70da0c2e405102dc044cb4bed0f4f1e847c90d0b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 10 May 2023 16:09:18 +0200 Subject: better tritondse support --- docs/custom_mutators.md | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) (limited to 'docs/custom_mutators.md') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index a1de479e..3f7e9e6e 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -304,6 +304,34 @@ 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: -- cgit 1.4.1 From e71d422b3c9867249dcaac87e40b08010fc43497 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 8 Jun 2023 08:42:23 +0200 Subject: enhance custom mutator docs --- docs/custom_mutators.md | 15 +++++++++------ 1 file changed, 9 insertions(+), 6 deletions(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 3f7e9e6e..c5a64622 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -145,12 +145,15 @@ 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. - Note that a length > 0 *must* be returned! - The returned output buffer is under **your** memory management! + This method performs your custom mutations on a given input. + The add_buf is the contents of another queue item that can be used for + splicing - or anything else - and can also be ignored. If you are not + using this additional data then define `splice_optout` (see above). + This function is optional. + Returing a length of 0 is valid and is interpreted as skipping this + one mutation result. + For non-Python: the returned output buffer is under **your** memory + management! - `describe` (optional): -- cgit 1.4.1 From 6f8696c3149a08d93c9b61db97f7b23cc6578274 Mon Sep 17 00:00:00 2001 From: Manuel Carrasco Date: Thu, 9 Nov 2023 13:46:41 +0000 Subject: Fix possible doc inconsistency for custom mutator's queue_get function. --- docs/custom_mutators.md | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index c5a64622..1c4ab2cf 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -125,8 +125,9 @@ def deinit(): # optional for Python - `queue_get` (optional): - This method determines whether the custom fuzzer should fuzz the current - queue entry or not + This method determines whether AFL++ should fuzz the current + queue entry or not: all defined custom mutators as well as + all AFL++'s mutators. - `fuzz_count` (optional): -- cgit 1.4.1 From a9e6998b829e58eab670c79fca8913ba8c5f684d Mon Sep 17 00:00:00 2001 From: Xeonacid Date: Mon, 25 Dec 2023 13:50:32 +0800 Subject: Fix custom_send link Add a leading '/' to walk in the repo root instead of current dir. --- docs/custom_mutators.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 1c4ab2cf..71547f8b 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -198,7 +198,7 @@ def deinit(): # optional for Python 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) + Example: [custom_mutators/examples/custom_send.c](/custom_mutators/examples/custom_send.c) - `queue_new_entry` (optional): @@ -377,4 +377,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) \ No newline at end of file + - [A bug detected by AFL + XML-aware mutators](https://bugs.chromium.org/p/chromium/issues/detail?id=930663) -- cgit 1.4.1 From c3197dfeb736f3018124529eb184827eafe3a2d9 Mon Sep 17 00:00:00 2001 From: Xeonacid Date: Mon, 25 Dec 2023 18:30:46 +0800 Subject: Use ../ instead --- docs/custom_mutators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 71547f8b..ce0a42dc 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -198,7 +198,7 @@ def deinit(): # optional for Python 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) + Example: [custom_mutators/examples/custom_send.c](../custom_mutators/examples/custom_send.c) - `queue_new_entry` (optional): -- cgit 1.4.1 From f75778adfb0fbea570a94b43eff801eb6d996f79 Mon Sep 17 00:00:00 2001 From: Xeonacid Date: Thu, 11 Jan 2024 15:42:51 +0800 Subject: docs(custom_mutators): fix missing ':' (#1953) --- docs/custom_mutators.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index ce0a42dc..73e3c802 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -73,7 +73,7 @@ def init(seed): def fuzz_count(buf): return cnt -def splice_optout() +def splice_optout(): pass def fuzz(buf, add_buf, max_size): -- cgit 1.4.1 From b282ce999d2ab9428210deb0e838f45a6a534084 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 13 May 2024 13:42:58 +0200 Subject: post_process after trim --- docs/Changelog.md | 1 + docs/custom_mutators.md | 5 ++++ src/afl-fuzz-run.c | 62 +++++++++++++++++++++++++++++++++++++++++++++++++ test/test-llvm.sh | 5 ++-- 4 files changed, 71 insertions(+), 2 deletions(-) (limited to 'docs/custom_mutators.md') diff --git a/docs/Changelog.md b/docs/Changelog.md index 9a95e343..818010a7 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -7,6 +7,7 @@ * afl-fuzz - added AFL_DISABLE_REDUNDANT for huge queues - fix AFL_PERSISTENT_RECORD + - run custom_post_process after standard trimming - prevent filenames in the queue that have spaces - minor fix for FAST schedules - more frequent stats update when syncing (todo: check performance impact) diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 73e3c802..b7a7032f 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -266,6 +266,11 @@ trimmed input. Here's a quick API description: Omitting any of three trimming methods will cause the trimming to be disabled and trigger a fallback to the built-in default trimming routine. +**IMPORTANT** If you have a custom post process mutator that needs to be run +after trimming, you must call it yourself at the end of your successful +trimming! + + ### Environment Variables Optionally, the following environment variables are supported: diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ed7cb4ce..2a55da00 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -1028,6 +1028,68 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { if (needs_write) { + // run afl_custom_post_process + + if (unlikely(afl->custom_mutators_count) && + likely(!afl->afl_env.afl_post_process_keep_original)) { + + ssize_t new_size = q->len; + u8 *new_mem = in_buf; + u8 *new_buf = NULL; + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_post_process) { + + new_size = el->afl_custom_post_process(el->data, new_mem, new_size, + &new_buf); + + if (unlikely(!new_buf || new_size <= 0)) { + + new_size = 0; + new_buf = new_mem; + + } else { + + new_mem = new_buf; + + } + + } + + }); + + if (unlikely(!new_size)) { + + new_size = q->len; + new_mem = in_buf; + + } + + if (unlikely(new_size < afl->min_length)) { + + new_size = afl->min_length; + + } else if (unlikely(new_size > afl->max_length)) { + + new_size = afl->max_length; + + } + + q->len = new_size; + + if (new_mem != in_buf && new_mem != NULL) { + + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), new_size); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + memcpy(new_buf, new_mem, new_size); + + in_buf = new_buf; + + } + + } + s32 fd; if (unlikely(afl->no_unlink)) { diff --git a/test/test-llvm.sh b/test/test-llvm.sh index aef7a5e2..13e1bad1 100755 --- a/test/test-llvm.sh +++ b/test/test-llvm.sh @@ -197,7 +197,8 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { for I in char short int long "long long"; do for BITS in 8 16 32 64; do bin="$testcase-split-$I-$BITS.compcov" - AFL_LLVM_INSTRUMENT=AFL AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES_BITW=$BITS AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -fsigned-char -DINT_TYPE="$I" -o "$bin" "$testcase" > test.out 2>&1; + #AFL_LLVM_INSTRUMENT=AFL + AFL_DEBUG=1 AFL_LLVM_LAF_SPLIT_COMPARES_BITW=$BITS AFL_LLVM_LAF_SPLIT_COMPARES=1 ../afl-clang-fast -fsigned-char -DINT_TYPE="$I" -o "$bin" "$testcase" > test.out 2>&1; if ! test -e "$bin"; then cat test.out $ECHO "$RED[!] llvm_mode laf-intel/compcov integer splitting failed! ($testcase with type $I split to $BITS)!"; @@ -269,7 +270,7 @@ test -e ../afl-clang-fast -a -e ../split-switches-pass.so && { { mkdir -p in echo 00000000000000000000000000000000 > in/in - AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -l 3 -m none -V30 -i in -o out -c ./test-cmplog -- ./test-c >>errors 2>&1 + AFL_BENCH_UNTIL_CRASH=1 ../afl-fuzz -Z -l 3 -m none -V30 -i in -o out -c ./test-cmplog -- ./test-c >>errors 2>&1 } >>errors 2>&1 test -n "$( ls out/default/crashes/id:000000* out/default/hangs/id:000000* 2>/dev/null )" && { $ECHO "$GREEN[+] afl-fuzz is working correctly with llvm_mode cmplog" -- cgit 1.4.1