Skip to content

Commit 8cdc48f

Browse files
Merge pull request AFLplusplus#1579 from AFLplusplus/dev
push to stable
2 parents 2d64055 + e5c725c commit 8cdc48f

22 files changed

+425
-128
lines changed

GNUmakefile

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -381,6 +381,7 @@ help:
381381
@echo ASAN_BUILD - compiles AFL++ with memory sanitizer for debug purposes
382382
@echo UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for debug purposes
383383
@echo DEBUG - no optimization, -ggdb3, all warnings and -Werror
384+
@echo LLVM_DEBUG - shows llvm deprecation warnings
384385
@echo PROFILING - compile afl-fuzz with profiling information
385386
@echo INTROSPECTION - compile afl-fuzz with mutation introspection
386387
@echo NO_PYTHON - disable python support
@@ -425,7 +426,7 @@ test_python:
425426
@echo "[+] $(PYTHON_VERSION) support seems to be working."
426427
else
427428
test_python:
428-
@echo "[-] You seem to need to install the package python3-dev, python2-dev or python-dev (and perhaps python[23]-apt), but it is optional so we continue"
429+
@echo "[-] You seem to need to install the package python3-dev or python-dev (and perhaps python[3]-apt), but it is optional so we continue"
429430
endif
430431

431432
.PHONY: ready

GNUmakefile.llvm

Lines changed: 10 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -255,16 +255,19 @@ else
255255
endif
256256

257257
CFLAGS ?= -O3 -funroll-loops -fPIC -D_FORTIFY_SOURCE=2
258-
CFLAGS_SAFE := -Wall -g -Wno-cast-qual -Wno-variadic-macros -Wno-pointer-sign -I ./include/ -I ./instrumentation/ \
258+
CFLAGS_SAFE := -Wall -g -Wno-cast-qual -Wno-variadic-macros -Wno-pointer-sign \
259+
-I ./include/ -I ./instrumentation/ \
259260
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
260261
-DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\" \
261262
-DLLVM_LIBDIR=\"$(LLVM_LIBDIR)\" -DLLVM_VERSION=\"$(LLVMVER)\" \
262-
-Wno-deprecated -DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" \
263-
-DAFL_REAL_LD=\"$(AFL_REAL_LD)\" \
264-
-DAFL_CLANG_LDPATH=\"$(AFL_CLANG_LDPATH)\" \
265-
-DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
266-
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) -Wno-unused-function \
267-
$(AFL_CLANG_DEBUG_PREFIX)
263+
-DAFL_CLANG_FLTO=\"$(AFL_CLANG_FLTO)\" -DAFL_REAL_LD=\"$(AFL_REAL_LD)\" \
264+
-DAFL_CLANG_LDPATH=\"$(AFL_CLANG_LDPATH)\" -DAFL_CLANG_FUSELD=\"$(AFL_CLANG_FUSELD)\" \
265+
-DCLANG_BIN=\"$(CLANG_BIN)\" -DCLANGPP_BIN=\"$(CLANGPP_BIN)\" -DUSE_BINDIR=$(USE_BINDIR) \
266+
-Wno-unused-function $(AFL_CLANG_DEBUG_PREFIX)
267+
ifndef LLVM_DEBUG
268+
CFLAGS_SAFE += -Wno-deprecated
269+
endif
270+
268271
override CFLAGS += $(CFLAGS_SAFE)
269272

270273
ifdef AFL_TRACE_PC
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
// cc -O3 -fPIC -shared -g -o custom_send.so -I../../include custom_send.c
2+
// cd ../..
3+
// afl-cc -o test-instr test-instr.c
4+
// afl-fuzz -i in -o out -- ./test-instr -f /tmp/foo
5+
6+
#include "custom_mutator_helpers.h"
7+
8+
#include <stdio.h>
9+
#include <stdint.h>
10+
#include <stdlib.h>
11+
#include <unistd.h>
12+
#include <fcntl.h>
13+
14+
typedef struct my_mutator {
15+
16+
afl_t *afl;
17+
18+
} my_mutator_t;
19+
20+
my_mutator_t *afl_custom_init(afl_t *afl, unsigned int seed) {
21+
22+
my_mutator_t *data = calloc(1, sizeof(my_mutator_t));
23+
if (!data) {
24+
25+
perror("afl_custom_init alloc");
26+
return NULL;
27+
28+
}
29+
30+
data->afl = afl;
31+
32+
return data;
33+
34+
}
35+
36+
void afl_custom_fuzz_send(my_mutator_t *data, uint8_t *buf, size_t buf_size) {
37+
38+
int fd = open("/tmp/foo", O_CREAT | O_NOFOLLOW | O_TRUNC | O_RDWR, 0644);
39+
40+
if (fd >= 0) {
41+
42+
(void)write(fd, buf, buf_size);
43+
close(fd);
44+
45+
}
46+
47+
return;
48+
49+
}
50+
51+
void afl_custom_deinit(my_mutator_t *data) {
52+
53+
free(data);
54+
55+
}
56+

docs/Changelog.md

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,14 @@
44
release of the tool. See README.md for the general instruction manual.
55

66
### Version ++4.05a (dev)
7-
- your PR? :)
8-
7+
- afl-fuzz:
8+
- added afl_custom_fuzz_send custom mutator feature. Now your can
9+
send fuzz data to the target as you need, e.g. via IPC.
10+
- cmplog mode now has -l R option for random colorization, thanks
11+
to guyf2010 for the PR!
12+
- afl-showmap/afl-cmin
13+
- -t none now translates to -t 120000 (120 seconds)
14+
- unicorn_mode updated
915

1016
### Version ++4.04c (release)
1117
- fix gramatron and grammar_mutator build scripts

docs/INSTALL.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ These build options exist:
8383
* UBSAN_BUILD - compiles AFL++ tools with undefined behaviour sanitizer for
8484
debug purposes
8585
* DEBUG - no optimization, -ggdb3, all warnings and -Werror
86+
* LLVM_DEBUG - shows llvm deprecation warnings
8687
* PROFILING - compile afl-fuzz with profiling information
8788
* INTROSPECTION - compile afl-fuzz with mutation introspection
8889
* NO_PYTHON - disable python support

docs/custom_mutators.md

Lines changed: 14 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -57,6 +57,7 @@ int afl_custom_post_trim(void *data, unsigned char success);
5757
size_t afl_custom_havoc_mutation(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf, size_t max_size);
5858
unsigned char afl_custom_havoc_mutation_probability(void *data);
5959
unsigned char afl_custom_queue_get(void *data, const unsigned char *filename);
60+
void (*afl_custom_fuzz_send)(void *data, const u8 *buf, size_t buf_size);
6061
u8 afl_custom_queue_new_entry(void *data, const unsigned char *filename_new_queue, const unsigned int *filename_orig_queue);
6162
const char* afl_custom_introspection(my_mutator_t *data);
6263
void afl_custom_deinit(void *data);
@@ -98,6 +99,9 @@ def havoc_mutation_probability():
9899
def queue_get(filename):
99100
return True
100101
102+
def fuzz_send(buf):
103+
pass
104+
101105
def queue_new_entry(filename_new_queue, filename_orig_queue):
102106
return False
103107
@@ -168,6 +172,13 @@ def deinit(): # optional for Python
168172
to the target, e.g. if it is too short, too corrupted, etc. If so,
169173
return a NULL buffer and zero length (or a 0 length string in Python).
170174

175+
- `fuzz_send` (optional):
176+
177+
This method can be used if you want to send data to the target yourself,
178+
e.g. via IPC. This replaces some usage of utils/afl_proxy but requires
179+
that you start the target with afl-fuzz.
180+
Example: [custom_mutators/examples/custom_send.c](custom_mutators/examples/custom_send.c)
181+
171182
- `queue_new_entry` (optional):
172183

173184
This methods is called after adding a new test case to the queue. If the
@@ -269,10 +280,10 @@ sudo apt install python-dev
269280
```
270281

271282
Then, AFL++ can be compiled with Python support. The AFL++ Makefile detects
272-
Python 2 and 3 through `python-config` if it is in the PATH and compiles
273-
`afl-fuzz` with the feature if available.
283+
Python3 through `python-config`/`python3-config` if it is in the PATH and
284+
compiles `afl-fuzz` with the feature if available.
274285

275-
Note: for some distributions, you might also need the package `python[23]-apt`.
286+
Note: for some distributions, you might also need the package `python[3]-apt`.
276287
In case your setup is different, set the necessary variables like this:
277288
`PYTHON_INCLUDE=/path/to/python/include LDFLAGS=-L/path/to/python/lib make`.
278289

dynamic_list.txt

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,7 @@
88
"__afl_auto_first";
99
"__afl_auto_init";
1010
"__afl_auto_second";
11+
"__afl_connected";
1112
"__afl_coverage_discard";
1213
"__afl_coverage_interesting";
1314
"__afl_coverage_off";

include/afl-fuzz.h

Lines changed: 16 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -333,6 +333,7 @@ enum {
333333
/* 11 */ PY_FUNC_QUEUE_NEW_ENTRY,
334334
/* 12 */ PY_FUNC_INTROSPECTION,
335335
/* 13 */ PY_FUNC_DESCRIBE,
336+
/* 14 */ PY_FUNC_FUZZ_SEND,
336337
PY_FUNC_COUNT
337338

338339
};
@@ -656,7 +657,7 @@ typedef struct afl_state {
656657
u32 cmplog_max_filesize;
657658
u32 cmplog_lvl;
658659
u32 colorize_success;
659-
u8 cmplog_enable_arith, cmplog_enable_transform;
660+
u8 cmplog_enable_arith, cmplog_enable_transform, cmplog_random_colorization;
660661

661662
struct afl_pass_stat *pass_stats;
662663
struct cmp_map *orig_cmp_map;
@@ -968,6 +969,19 @@ struct custom_mutator {
968969
*/
969970
u8 (*afl_custom_queue_get)(void *data, const u8 *filename);
970971

972+
/**
973+
* This method can be used if you want to send data to the target yourself,
974+
* e.g. via IPC. This replaces some usage of utils/afl_proxy but requires
975+
* that you start the target with afl-fuzz.
976+
*
977+
* (Optional)
978+
*
979+
* @param data pointer returned in afl_custom_init by this custom mutator
980+
* @param buf Buffer containing the test case
981+
* @param buf_size Size of the test case
982+
*/
983+
void (*afl_custom_fuzz_send)(void *data, const u8 *buf, size_t buf_size);
984+
971985
/**
972986
* Allow for additional analysis (e.g. calling a different tool that does a
973987
* different kind of coverage and saves this for the custom mutator).
@@ -1022,6 +1036,7 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *, char *);
10221036
void finalize_py_module(void *);
10231037

10241038
u32 fuzz_count_py(void *, const u8 *, size_t);
1039+
void fuzz_send_py(void *, const u8 *, size_t);
10251040
size_t post_process_py(void *, u8 *, size_t, u8 **);
10261041
s32 init_trim_py(void *, u8 *, size_t);
10271042
s32 post_trim_py(void *, u8);

include/envs.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ static char *afl_environment_variables[] = {
4242
"AFL_DEBUG",
4343
"AFL_DEBUG_CHILD",
4444
"AFL_DEBUG_GDB",
45+
"AFL_DEBUG_UNICORN",
4546
"AFL_DISABLE_TRIM",
4647
"AFL_DISABLE_LLVM_INSTRUMENTATION",
4748
"AFL_DONT_OPTIMIZE",

instrumentation/README.lto.md

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -118,10 +118,11 @@ cmake \
118118
-DLLVM_LINK_LLVM_DYLIB="ON" \
119119
-DLLVM_TARGETS_TO_BUILD="host" \
120120
../llvm/
121+
# NOTE: for llvm 16 this needs to be changed to:
122+
# -DLLVM_ENABLE_PROJECTS='clang;compiler-rt;lld' \
123+
# -DLLVM_ENABLE_RUNTIMES='libcxx;libcxxabi' \
121124
cmake --build . -j4
122-
export PATH="$(pwd)/bin:$PATH"
123125
export LLVM_CONFIG="$(pwd)/bin/llvm-config"
124-
export LD_LIBRARY_PATH="$(llvm-config --libdir)${LD_LIBRARY_PATH:+:$LD_LIBRARY_PATH}"
125126
cd /path/to/AFLplusplus/
126127
make
127128
sudo make install

instrumentation/afl-compiler-rt.o.c

Lines changed: 20 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -105,6 +105,9 @@ u32 __afl_dictionary_len;
105105
u64 __afl_map_addr;
106106
u32 __afl_first_final_loc;
107107

108+
/* 1 if we are running in afl, and the forkserver was started, else 0 */
109+
u32 __afl_connected = 0;
110+
108111
// for the __AFL_COVERAGE_ON/__AFL_COVERAGE_OFF features to work:
109112
int __afl_selective_coverage __attribute__((weak));
110113
int __afl_selective_coverage_start_off __attribute__((weak));
@@ -1051,6 +1054,8 @@ static void __afl_start_forkserver(void) {
10511054

10521055
if (write(FORKSRV_FD + 1, tmp, 4) != 4) { return; }
10531056

1057+
__afl_connected = 1;
1058+
10541059
if (__afl_sharedmem_fuzzing || (__afl_dictionary_len && __afl_dictionary)) {
10551060

10561061
if (read(FORKSRV_FD, &was_killed, 4) != 4) _exit(1);
@@ -1261,48 +1266,38 @@ int __afl_persistent_loop(unsigned int max_cnt) {
12611266
iteration, it's our job to erase any trace of whatever happened
12621267
before the loop. */
12631268

1264-
if (is_persistent) {
1265-
1266-
memset(__afl_area_ptr, 0, __afl_map_size);
1267-
__afl_area_ptr[0] = 1;
1268-
memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
1269-
1270-
}
1269+
memset(__afl_area_ptr, 0, __afl_map_size);
1270+
__afl_area_ptr[0] = 1;
1271+
memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
12711272

12721273
cycle_cnt = max_cnt;
12731274
first_pass = 0;
12741275
__afl_selective_coverage_temp = 1;
12751276

12761277
return 1;
12771278

1278-
}
1279-
1280-
if (is_persistent) {
1281-
1282-
if (--cycle_cnt) {
1279+
} else if (--cycle_cnt) {
12831280

1284-
raise(SIGSTOP);
1281+
raise(SIGSTOP);
12851282

1286-
__afl_area_ptr[0] = 1;
1287-
memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
1288-
__afl_selective_coverage_temp = 1;
1283+
__afl_area_ptr[0] = 1;
1284+
memset(__afl_prev_loc, 0, NGRAM_SIZE_MAX * sizeof(PREV_LOC_T));
1285+
__afl_selective_coverage_temp = 1;
12891286

1290-
return 1;
1287+
return 1;
12911288

1292-
} else {
1289+
} else {
12931290

1294-
/* When exiting __AFL_LOOP(), make sure that the subsequent code that
1295-
follows the loop is not traced. We do that by pivoting back to the
1296-
dummy output region. */
1291+
/* When exiting __AFL_LOOP(), make sure that the subsequent code that
1292+
follows the loop is not traced. We do that by pivoting back to the
1293+
dummy output region. */
12971294

1298-
__afl_area_ptr = __afl_area_ptr_dummy;
1295+
__afl_area_ptr = __afl_area_ptr_dummy;
12991296

1300-
}
1297+
return 0;
13011298

13021299
}
13031300

1304-
return 0;
1305-
13061301
}
13071302

13081303
/* This one can be called from user code when deferred forkserver mode

0 commit comments

Comments
 (0)