Skip to content

Commit 6177954

Browse files
committed
fix custom mutators and add real test cases
1 parent 7b40d7b commit 6177954

File tree

6 files changed

+107
-24
lines changed

6 files changed

+107
-24
lines changed

examples/custom_mutators/README.md

+3
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,9 @@ See [docs/custom_mutators.md](../docs/custom_mutators.md) for more information
66
Note that if you compile with python3.7 you must use python3 scripts, and if
77
you use python2.7 to compile python2 scripts!
88

9+
simple_example.c - most simplest example. generates a random sized buffer
10+
filled with 'A'
11+
912
example.c - this is a simple example written in C and should be compiled to a
1013
shared library. Use make to compile it and produce libexamplemutator.so
1114

examples/custom_mutators/example.py

+1
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
b"GET",
2222
b"PUT",
2323
b"DEL",
24+
b"AAAAAAAAAAAAAAAAA",
2425
]
2526

2627

+74
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,74 @@
1+
// This simple example just creates random buffer <= 100 filled with 'A'
2+
// needs -I /path/to/AFLplusplus/include
3+
#include "custom_mutator_helpers.h"
4+
5+
#include <stdint.h>
6+
#include <stdlib.h>
7+
#include <string.h>
8+
#include <stdio.h>
9+
10+
#ifndef _FIXED_CHAR
11+
#define 0x41
12+
#endif
13+
14+
typedef struct my_mutator {
15+
16+
afl_t *afl;
17+
18+
// Reused buffers:
19+
BUF_VAR(u8, fuzz);
20+
21+
} my_mutator_t;
22+
23+
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
24+
25+
srand(seed);
26+
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
27+
if (!data) {
28+
29+
perror("afl_custom_init alloc");
30+
return NULL;
31+
32+
}
33+
34+
data->afl = afl;
35+
36+
return data;
37+
38+
}
39+
40+
size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_size,
41+
u8 **out_buf, uint8_t *add_buf,
42+
size_t add_buf_size, // add_buf can be NULL
43+
size_t max_size) {
44+
45+
int size = (rand() % 100) + 1;
46+
if (size > max_size) size = max_size;
47+
u8 *mutated_out = maybe_grow(BUF_PARAMS(data, fuzz), size);
48+
if (!mutated_out) {
49+
50+
*out_buf = NULL;
51+
perror("custom mutator allocation (maybe_grow)");
52+
return 0; /* afl-fuzz will very likely error out after this. */
53+
54+
}
55+
56+
memset(mutated_out, _FIXED_CHAR, size);
57+
58+
*out_buf = mutated_out;
59+
return size;
60+
61+
}
62+
63+
/**
64+
* Deinitialize everything
65+
*
66+
* @param data The data ptr from afl_custom_init
67+
*/
68+
void afl_custom_deinit(my_mutator_t *data) {
69+
70+
free(data->fuzz_buf);
71+
free(data);
72+
73+
}
74+

src/afl-fuzz-mutators.c

+15-10
Original file line numberDiff line numberDiff line change
@@ -117,7 +117,7 @@ void destroy_custom_mutators(afl_state_t *afl) {
117117
LIST_FOREACH_CLEAR(&afl->custom_mutator_list, struct custom_mutator, {
118118

119119
if (!el->data) { FATAL("Deintializing NULL mutator"); }
120-
el->afl_custom_deinit(el->data);
120+
if (el->afl_custom_deinit) el->afl_custom_deinit(el->data);
121121
if (el->dh) dlclose(el->dh);
122122

123123
if (el->pre_save_buf) {
@@ -166,32 +166,37 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
166166

167167
}
168168

169+
/* "afl_custom_deinit", optional for backward compatibility */
170+
mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
171+
if (!mutator->afl_custom_deinit) WARNF("Symbol 'afl_custom_init' not found.");
172+
169173
/* "afl_custom_pre_save", optional */
170174
mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
171175
if (!mutator->afl_custom_pre_save)
172-
WARNF("Symbol 'afl_custom_pre_save' not found.");
176+
ACTF("optional symbol 'afl_custom_pre_save' not found.");
173177

174178
u8 notrim = 0;
175179
/* "afl_custom_init_trim", optional */
176180
mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
177181
if (!mutator->afl_custom_init_trim)
178-
WARNF("Symbol 'afl_custom_init_trim' not found.");
182+
ACTF("optional symbol 'afl_custom_init_trim' not found.");
179183

180184
/* "afl_custom_trim", optional */
181185
mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
182-
if (!mutator->afl_custom_trim) WARNF("Symbol 'afl_custom_trim' not found.");
186+
if (!mutator->afl_custom_trim)
187+
ACTF("optional symbol 'afl_custom_trim' not found.");
183188

184189
/* "afl_custom_post_trim", optional */
185190
mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
186191
if (!mutator->afl_custom_post_trim)
187-
WARNF("Symbol 'afl_custom_post_trim' not found.");
192+
ACTF("optional symbol 'afl_custom_post_trim' not found.");
188193

189194
if (notrim) {
190195

191196
mutator->afl_custom_init_trim = NULL;
192197
mutator->afl_custom_trim = NULL;
193198
mutator->afl_custom_post_trim = NULL;
194-
WARNF(
199+
ACTF(
195200
"Custom mutator does not implement all three trim APIs, standard "
196201
"trimming will be used.");
197202

@@ -200,23 +205,23 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) {
200205
/* "afl_custom_havoc_mutation", optional */
201206
mutator->afl_custom_havoc_mutation = dlsym(dh, "afl_custom_havoc_mutation");
202207
if (!mutator->afl_custom_havoc_mutation)
203-
WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
208+
ACTF("optional symbol 'afl_custom_havoc_mutation' not found.");
204209

205210
/* "afl_custom_havoc_mutation", optional */
206211
mutator->afl_custom_havoc_mutation_probability =
207212
dlsym(dh, "afl_custom_havoc_mutation_probability");
208213
if (!mutator->afl_custom_havoc_mutation_probability)
209-
WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found.");
214+
ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found.");
210215

211216
/* "afl_custom_queue_get", optional */
212217
mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
213218
if (!mutator->afl_custom_queue_get)
214-
WARNF("Symbol 'afl_custom_queue_get' not found.");
219+
ACTF("optional symbol 'afl_custom_queue_get' not found.");
215220

216221
/* "afl_custom_queue_new_entry", optional */
217222
mutator->afl_custom_queue_new_entry = dlsym(dh, "afl_custom_queue_new_entry");
218223
if (!mutator->afl_custom_queue_new_entry)
219-
WARNF("Symbol 'afl_custom_queue_new_entry' not found");
224+
ACTF("optional symbol 'afl_custom_queue_new_entry' not found");
220225

221226
OKF("Custom mutator '%s' installed successfully.", fn);
222227

test/test-multiple-mutators.c

+3-4
Original file line numberDiff line numberDiff line change
@@ -12,11 +12,10 @@
1212
int main(int argc, char **argv) {
1313

1414
int a = 0;
15-
char s[16];
16-
memset(s, 0, 16);
17-
read(0, s, 0xa0);
15+
char s[100];
16+
read(0, s, 100);
1817

19-
if (s[17] != '\x00') { abort(); }
18+
if (s[7] == 'B') { abort(); }
2019

2120
return 0;
2221

test/test.sh

+11-10
Original file line numberDiff line numberDiff line change
@@ -970,16 +970,17 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
970970
}
971971
}
972972
# Compile the custom mutator
973-
make -C ../examples/custom_mutators libexamplemutator.so > /dev/null 2>&1
974-
test -e test-custom-mutator -a -e ${CUSTOM_MUTATOR_PATH}/libexamplemutator.so && {
973+
cc -D_FIXED_CHAR=0x41 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator.so > /dev/null 2>&1
974+
cc -D_FIXED_CHAR=0x42 -g -fPIC -shared -I../include ../examples/custom_mutators/simple_example.c -o libexamplemutator2.so > /dev/null 2>&1
975+
test -e test-custom-mutator -a -e ./libexamplemutator.so && {
975976
# Create input directory
976977
mkdir -p in
977978
echo "00000" > in/in
978979

979980
# Run afl-fuzz w/ the C mutator
980-
$ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 10 seconds"
981+
$ECHO "$GREY[*] running afl-fuzz for the C mutator, this will take approx 5 seconds"
981982
{
982-
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
983+
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
983984
} >>errors 2>&1
984985

985986
# Check results
@@ -996,10 +997,10 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
996997
# Clean
997998
rm -rf out errors
998999

999-
#Run afl-fuzz w/ multiple C mutators
1000-
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 20 seconds"
1000+
# Run afl-fuzz w/ multiple C mutators
1001+
$ECHO "$GREY[*] running afl-fuzz with multiple custom C mutators, this will take approx 5 seconds"
10011002
{
1002-
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
1003+
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
10031004
} >>errors 2>&1
10041005

10051006
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 $?`" && {
10161017
rm -rf out errors
10171018

10181019
# Run afl-fuzz w/ the Python mutator
1019-
$ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 10 seconds"
1020+
$ECHO "$GREY[*] running afl-fuzz for the Python mutator, this will take approx 5 seconds"
10201021
{
10211022
export PYTHONPATH=${CUSTOM_MUTATOR_PATH}
10221023
export AFL_PYTHON_MODULE=example
1023-
../afl-fuzz -V10 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
1024+
AFL_CUSTOM_MUTATOR_ONLY=1 ../afl-fuzz -V5 -m ${MEM_LIMIT} -i in -o out -- ./test-custom-mutator >>errors 2>&1
10241025
unset PYTHONPATH
10251026
unset AFL_PYTHON_MODULE
10261027
} >>errors 2>&1
@@ -1039,7 +1040,7 @@ test "1" = "`../afl-fuzz | grep -i 'without python' >/dev/null; echo $?`" && {
10391040
# Clean
10401041
rm -rf in out errors
10411042
rm -rf ${CUSTOM_MUTATOR_PATH}/__pycache__/
1042-
rm -f test-multiple-mutators
1043+
rm -f test-multiple-mutators test-custom-mutator libexamplemutator.so libexamplemutator2.so
10431044
} || {
10441045
ls .
10451046
ls ${CUSTOM_MUTATOR_PATH}

0 commit comments

Comments
 (0)