mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-16 20:08:07 +00:00
fix custom mutators and add real test cases
This commit is contained in:
@ -6,6 +6,9 @@ See [docs/custom_mutators.md](../docs/custom_mutators.md) for more information
|
|||||||
Note that if you compile with python3.7 you must use python3 scripts, and if
|
Note that if you compile with python3.7 you must use python3 scripts, and if
|
||||||
you use python2.7 to compile python2 scripts!
|
you use python2.7 to compile python2 scripts!
|
||||||
|
|
||||||
|
simple_example.c - most simplest example. generates a random sized buffer
|
||||||
|
filled with 'A'
|
||||||
|
|
||||||
example.c - this is a simple example written in C and should be compiled to a
|
example.c - this is a simple example written in C and should be compiled to a
|
||||||
shared library. Use make to compile it and produce libexamplemutator.so
|
shared library. Use make to compile it and produce libexamplemutator.so
|
||||||
|
|
||||||
|
@ -21,6 +21,7 @@ COMMANDS = [
|
|||||||
b"GET",
|
b"GET",
|
||||||
b"PUT",
|
b"PUT",
|
||||||
b"DEL",
|
b"DEL",
|
||||||
|
b"AAAAAAAAAAAAAAAAA",
|
||||||
]
|
]
|
||||||
|
|
||||||
|
|
||||||
|
74
examples/custom_mutators/simple_example.c
Normal file
74
examples/custom_mutators/simple_example.c
Normal file
@ -0,0 +1,74 @@
|
|||||||
|
// This simple example just creates random buffer <= 100 filled with 'A'
|
||||||
|
// needs -I /path/to/AFLplusplus/include
|
||||||
|
#include "custom_mutator_helpers.h"
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
|
||||||
|
#ifndef _FIXED_CHAR
|
||||||
|
#define 0x41
|
||||||
|
#endif
|
||||||
|
|
||||||
|
typedef struct my_mutator {
|
||||||
|
|
||||||
|
afl_t *afl;
|
||||||
|
|
||||||
|
// Reused buffers:
|
||||||
|
BUF_VAR(u8, fuzz);
|
||||||
|
|
||||||
|
} my_mutator_t;
|
||||||
|
|
||||||
|
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
|
||||||
|
|
||||||
|
srand(seed);
|
||||||
|
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
|
||||||
|
if (!data) {
|
||||||
|
|
||||||
|
perror("afl_custom_init alloc");
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
data->afl = afl;
|
||||||
|
|
||||||
|
return data;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
|
||||||
|
u8 **out_buf, uint8_t *add_buf,
|
||||||
|
size_t add_buf_size, // add_buf can be NULL
|
||||||
|
size_t max_size) {
|
||||||
|
|
||||||
|
int size = (rand() % 100) + 1;
|
||||||
|
if (size > max_size) size = max_size;
|
||||||
|
u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), size);
|
||||||
|
if (!mutated_out) {
|
||||||
|
|
||||||
|
*out_buf = NULL;
|
||||||
|
perror("custom mutator allocation (maybe_grow)");
|
||||||
|
return 0; /* afl-fuzz will very likely error out after this. */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
memset(mutated_out, _FIXED_CHAR, size);
|
||||||
|
|
||||||
|
*out_buf = mutated_out;
|
||||||
|
return size;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Deinitialize everything
|
||||||
|
*
|
||||||
|
* @param data The data ptr from afl_custom_init
|
||||||
|
*/
|
||||||
|
void afl_custom_deinit(my_mutator_t *data) {
|
||||||
|
|
||||||
|
free(data->fuzz_buf);
|
||||||
|
free(data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
@ -117,7 +117,7 @@ void destroy_custom_mutators(afl_state_t *afl) {
|
|||||||
LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, {
|
LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, {
|
||||||
|
|
||||||
if (!el->data) { FATAL("Deintializing NULL mutator"); }
|
if (!el->data) { FATAL("Deintializing NULL mutator"); }
|
||||||
el->afl_custom_deinit(el->data);
|
if (el->afl_custom_deinit) el->afl_custom_deinit(el->data);
|
||||||
if (el->dh) dlclose(el->dh);
|
if (el->dh) dlclose(el->dh);
|
||||||
|
|
||||||
if (el->pre_save_buf) {
|
if (el->pre_save_buf) {
|
||||||
@ -166,32 +166,37 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* "afl_custom_deinit", optional for backward compatibility */
|
||||||
|
mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
|
||||||
|
if (!mutator->afl_custom_deinit) WARNF("Symbol 'afl_custom_init' not found.");
|
||||||
|
|
||||||
/* "afl_custom_pre_save", optional */
|
/* "afl_custom_pre_save", optional */
|
||||||
mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
|
mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
|
||||||
if (!mutator->afl_custom_pre_save)
|
if (!mutator->afl_custom_pre_save)
|
||||||
WARNF("Symbol 'afl_custom_pre_save' not found.");
|
ACTF("optional symbol 'afl_custom_pre_save' not found.");
|
||||||
|
|
||||||
u8 notrim = 0;
|
u8 notrim = 0;
|
||||||
/* "afl_custom_init_trim", optional */
|
/* "afl_custom_init_trim", optional */
|
||||||
mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
|
mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
|
||||||
if (!mutator->afl_custom_init_trim)
|
if (!mutator->afl_custom_init_trim)
|
||||||
WARNF("Symbol 'afl_custom_init_trim' not found.");
|
ACTF("optional symbol 'afl_custom_init_trim' not found.");
|
||||||
|
|
||||||
/* "afl_custom_trim", optional */
|
/* "afl_custom_trim", optional */
|
||||||
mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
|
mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
|
||||||
if (!mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found.");
|
if (!mutator->afl_custom_trim)
|
||||||
|
ACTF("optional symbol 'afl_custom_trim' not found.");
|
||||||
|
|
||||||
/* "afl_custom_post_trim", optional */
|
/* "afl_custom_post_trim", optional */
|
||||||
mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
|
mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
|
||||||
if (!mutator->afl_custom_post_trim)
|
if (!mutator->afl_custom_post_trim)
|
||||||
WARNF("Symbol 'afl_custom_post_trim' not found.");
|
ACTF("optional symbol 'afl_custom_post_trim' not found.");
|
||||||
|
|
||||||
if (notrim) {
|
if (notrim) {
|
||||||
|
|
||||||
mutator->afl_custom_init_trim = NULL;
|
mutator->afl_custom_init_trim = NULL;
|
||||||
mutator->afl_custom_trim = NULL;
|
mutator->afl_custom_trim = NULL;
|
||||||
mutator->afl_custom_post_trim = NULL;
|
mutator->afl_custom_post_trim = NULL;
|
||||||
WARNF(
|
ACTF(
|
||||||
"Custom mutator does not implement all three trim APIs, standard "
|
"Custom mutator does not implement all three trim APIs, standard "
|
||||||
"trimming will be used.");
|
"trimming will be used.");
|
||||||
|
|
||||||
@ -200,23 +205,23 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
/* "afl_custom_havoc_mutation", optional */
|
/* "afl_custom_havoc_mutation", optional */
|
||||||
mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation");
|
mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation");
|
||||||
if (!mutator->afl_custom_havoc_mutation)
|
if (!mutator->afl_custom_havoc_mutation)
|
||||||
WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
|
ACTF("optional symbol 'afl_custom_havoc_mutation' not found.");
|
||||||
|
|
||||||
/* "afl_custom_havoc_mutation", optional */
|
/* "afl_custom_havoc_mutation", optional */
|
||||||
mutator->afl_custom_havoc_mutation_probability =
|
mutator->afl_custom_havoc_mutation_probability =
|
||||||
dlsym(dh, "afl_custom_havoc_mutation_probability");
|
dlsym(dh, "afl_custom_havoc_mutation_probability");
|
||||||
if (!mutator->afl_custom_havoc_mutation_probability)
|
if (!mutator->afl_custom_havoc_mutation_probability)
|
||||||
WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found.");
|
ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found.");
|
||||||
|
|
||||||
/* "afl_custom_queue_get", optional */
|
/* "afl_custom_queue_get", optional */
|
||||||
mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
|
mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
|
||||||
if (!mutator->afl_custom_queue_get)
|
if (!mutator->afl_custom_queue_get)
|
||||||
WARNF("Symbol 'afl_custom_queue_get' not found.");
|
ACTF("optional symbol 'afl_custom_queue_get' not found.");
|
||||||
|
|
||||||
/* "afl_custom_queue_new_entry", optional */
|
/* "afl_custom_queue_new_entry", optional */
|
||||||
mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry");
|
mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry");
|
||||||
if (!mutator->afl_custom_queue_new_entry)
|
if (!mutator->afl_custom_queue_new_entry)
|
||||||
WARNF("Symbol 'afl_custom_queue_new_entry' not found");
|
ACTF("optional symbol 'afl_custom_queue_new_entry' not found");
|
||||||
|
|
||||||
OKF("Custom mutator '%s' installed successfully.", fn);
|
OKF("Custom mutator '%s' installed successfully.", fn);
|
||||||
|
|
||||||
|
@ -12,11 +12,10 @@
|
|||||||
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
||||||
|
|
||||||
int a = 0;
|
int a = 0;
|
||||||
char s[16];
|
char s[100];
|
||||||
memset(s, 0, 16);
|
read(0, s, 100);
|
||||||
read(0, s, 0xa0);
|
|
||||||
|
|
||||||
if (s[17] != '\x00') { abort(); }
|
if (s[7] == 'B') { abort(); }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
|
21
test/test.sh
21
test/test.sh
@ -970,16 +970,17 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
# Compile the custom mutator
|
# Compile the custom mutator
|
||||||
make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1
|
cc -D_FIXED_CHAR=0x41 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator.so > /dev/null 2>&1
|
||||||
test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && {
|
cc -D_FIXED_CHAR=0x42 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator2.so > /dev/null 2>&1
|
||||||
|
test -e test-custom-mutator -a -e ./libexamplemutator.so && {
|
||||||
# Create input directory
|
# Create input directory
|
||||||
mkdir -p in
|
mkdir -p in
|
||||||
echo "00000" > in/in
|
echo "00000" > in/in
|
||||||
|
|
||||||
# Run afl-fuzz w/ the C mutator
|
# Run afl-fuzz w/ the C mutator
|
||||||
$ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 10 seconds"
|
$ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 5 seconds"
|
||||||
{
|
{
|
||||||
AFL_CUSTOM_MUTATOR_LIBRARY=${CUSTOM_MUTATOR_PATH}/libexamplemutator.so ../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
|
AFL_CUSTOM_MUTATOR_LIBRARY=./libexamplemutator.so AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V1 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
|
||||||
} >>errors 2>&1
|
} >>errors 2>&1
|
||||||
|
|
||||||
# Check results
|
# Check results
|
||||||
@ -996,10 +997,10 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
# Clean
|
# Clean
|
||||||
rm -rf out errors
|
rm -rf out errors
|
||||||
|
|
||||||
#Run afl-fuzz w/ multiple C mutators
|
# Run afl-fuzz w/ multiple C mutators
|
||||||
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 20 seconds"
|
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 5 seconds"
|
||||||
{
|
{
|
||||||
AFL_CUSTOM_MUTATOR_LIBRARY="${CUSTOM_MUTATOR_PATH}/libexamplemutator.so;${CUSTOM_MUTATOR_PATH}/libexamplemutator.so" ../afl-fuzz -V20 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1
|
AFL_CUSTOM_MUTATOR_LIBRARY="./libexamplemutator.so;./libexamplemutator2.so" AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V1 -m ${MEM_LIMIT} -i in -o out -- ./test-multiple-mutators >>errors 2>&1
|
||||||
} >>errors 2>&1
|
} >>errors 2>&1
|
||||||
|
|
||||||
test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here
|
test -n "$( ls out/crashes/id:000000* 2>/dev/null )" && { # TODO: update here
|
||||||
@ -1016,11 +1017,11 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
rm -rf out errors
|
rm -rf out errors
|
||||||
|
|
||||||
# Run afl-fuzz w/ the Python mutator
|
# Run afl-fuzz w/ the Python mutator
|
||||||
$ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 10 seconds"
|
$ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 5 seconds"
|
||||||
{
|
{
|
||||||
export PYTHONPATH=${CUSTOM_MUTATOR_PATH}
|
export PYTHONPATH=${CUSTOM_MUTATOR_PATH}
|
||||||
export AFL_PYTHON_MODULE=example
|
export AFL_PYTHON_MODULE=example
|
||||||
../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
|
AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V5 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
|
||||||
unset PYTHONPATH
|
unset PYTHONPATH
|
||||||
unset AFL_PYTHON_MODULE
|
unset AFL_PYTHON_MODULE
|
||||||
} >>errors 2>&1
|
} >>errors 2>&1
|
||||||
@ -1039,7 +1040,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
|
|||||||
# Clean
|
# Clean
|
||||||
rm -rf in out errors
|
rm -rf in out errors
|
||||||
rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/
|
rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/
|
||||||
rm -f test-multiple-mutators
|
rm -f test-multiple-mutators test-custom-mutator libexamplemutator.so libexamplemutator2.so
|
||||||
} || {
|
} || {
|
||||||
ls .
|
ls .
|
||||||
ls ${CUSTOM_MUTATOR_PATH}
|
ls ${CUSTOM_MUTATOR_PATH}
|
||||||
|
Reference in New Issue
Block a user