mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-15 19:38:09 +00:00
add afl-fuzz -y fuzz length support
This commit is contained in:
@ -11,6 +11,9 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
|
|||||||
### Version ++4.01a (dev)
|
### Version ++4.01a (dev)
|
||||||
- fix */build_...sh scripts to work outside of git
|
- fix */build_...sh scripts to work outside of git
|
||||||
- new custom_mutator: libafl with token fuzzing :)
|
- new custom_mutator: libafl with token fuzzing :)
|
||||||
|
- afl-fuzz:
|
||||||
|
- new commandline option -y to set min and max length of generated
|
||||||
|
fuzz inputs
|
||||||
- frida_mode:
|
- frida_mode:
|
||||||
- update to new frida release, handles now c++ throw/catch
|
- update to new frida release, handles now c++ throw/catch
|
||||||
|
|
||||||
|
@ -726,6 +726,9 @@ typedef struct afl_state {
|
|||||||
/* queue entries ready for splicing count (len > 4) */
|
/* queue entries ready for splicing count (len > 4) */
|
||||||
u32 ready_for_splicing_count;
|
u32 ready_for_splicing_count;
|
||||||
|
|
||||||
|
/* min/max length for generated fuzzing inputs */
|
||||||
|
u32 min_length, max_length;
|
||||||
|
|
||||||
/* This is the user specified maximum size to use for the testcase cache */
|
/* This is the user specified maximum size to use for the testcase cache */
|
||||||
u64 q_testcase_max_cache_size;
|
u64 q_testcase_max_cache_size;
|
||||||
|
|
||||||
@ -1090,12 +1093,12 @@ int statsd_format_metric(afl_state_t *afl, char *buff, size_t bufflen);
|
|||||||
|
|
||||||
/* Run */
|
/* Run */
|
||||||
|
|
||||||
fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
|
|
||||||
void write_to_testcase(afl_state_t *, void *, u32);
|
|
||||||
u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8);
|
|
||||||
void sync_fuzzers(afl_state_t *);
|
void sync_fuzzers(afl_state_t *);
|
||||||
|
u32 write_to_testcase(afl_state_t *, void *, u32, u32);
|
||||||
|
u8 calibrate_case(afl_state_t *, struct queue_entry *, u8 *, u32, u8);
|
||||||
u8 trim_case(afl_state_t *, struct queue_entry *, u8 *);
|
u8 trim_case(afl_state_t *, struct queue_entry *, u8 *);
|
||||||
u8 common_fuzz_stuff(afl_state_t *, u8 *, u32);
|
u8 common_fuzz_stuff(afl_state_t *, u8 *, u32);
|
||||||
|
fsrv_run_result_t fuzz_run_target(afl_state_t *, afl_forkserver_t *fsrv, u32);
|
||||||
|
|
||||||
/* Fuzz one */
|
/* Fuzz one */
|
||||||
|
|
||||||
|
@ -633,7 +633,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
if (afl->fsrv.exec_tmout < afl->hang_tmout) {
|
if (afl->fsrv.exec_tmout < afl->hang_tmout) {
|
||||||
|
|
||||||
u8 new_fault;
|
u8 new_fault;
|
||||||
write_to_testcase(afl, mem, len);
|
len = write_to_testcase(afl, mem, len, 0);
|
||||||
new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
|
new_fault = fuzz_run_target(afl, &afl->fsrv, afl->hang_tmout);
|
||||||
classify_counts(&afl->fsrv);
|
classify_counts(&afl->fsrv);
|
||||||
|
|
||||||
|
@ -49,7 +49,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
u8 fault;
|
u8 fault;
|
||||||
|
|
||||||
write_to_testcase(afl, out_buf, len);
|
len = write_to_testcase(afl, out_buf, len, 0);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
|
@ -617,11 +617,10 @@ void read_foreign_testcases(afl_state_t *afl, int first) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
write_to_testcase(afl, mem, st.st_size);
|
u32 len = write_to_testcase(afl, mem, st.st_size, 1);
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
afl->syncing_party = foreign_name;
|
afl->syncing_party = foreign_name;
|
||||||
afl->queued_imported +=
|
afl->queued_imported += save_if_interesting(afl, mem, len, fault);
|
||||||
save_if_interesting(afl, mem, st.st_size, fault);
|
|
||||||
afl->syncing_party = 0;
|
afl->syncing_party = 0;
|
||||||
munmap(mem, st.st_size);
|
munmap(mem, st.st_size);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
@ -428,7 +428,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf,
|
|||||||
|
|
||||||
if (likely(retlen)) {
|
if (likely(retlen)) {
|
||||||
|
|
||||||
write_to_testcase(afl, retbuf, retlen);
|
retlen = write_to_testcase(afl, retbuf, retlen, 0);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
++afl->trim_execs;
|
++afl->trim_execs;
|
||||||
|
@ -73,8 +73,8 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) {
|
|||||||
old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is
|
old file is unlinked and a new one is created. Otherwise, afl->fsrv.out_fd is
|
||||||
rewound and truncated. */
|
rewound and truncated. */
|
||||||
|
|
||||||
void __attribute__((hot))
|
u32 __attribute__((hot))
|
||||||
write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
|
write_to_testcase(afl_state_t *afl, void *mem, u32 len, u32 fix) {
|
||||||
|
|
||||||
#ifdef _AFL_DOCUMENT_MUTATIONS
|
#ifdef _AFL_DOCUMENT_MUTATIONS
|
||||||
s32 doc_fd;
|
s32 doc_fd;
|
||||||
@ -120,16 +120,39 @@ write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
|
|||||||
|
|
||||||
});
|
});
|
||||||
|
|
||||||
|
if (unlikely(new_size < afl->min_length && !fix)) {
|
||||||
|
|
||||||
|
new_size = afl->min_length;
|
||||||
|
|
||||||
|
} else if (unlikely(new_size > afl->max_length)) {
|
||||||
|
|
||||||
|
new_size = afl->max_length;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* everything as planned. use the potentially new data. */
|
/* everything as planned. use the potentially new data. */
|
||||||
afl_fsrv_write_to_testcase(&afl->fsrv, new_mem, new_size);
|
afl_fsrv_write_to_testcase(&afl->fsrv, new_mem, new_size);
|
||||||
|
len = new_size;
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
|
if (unlikely(len < afl->min_length && !fix)) {
|
||||||
|
|
||||||
|
len = afl->min_length;
|
||||||
|
|
||||||
|
} else if (unlikely(len > afl->max_length)) {
|
||||||
|
|
||||||
|
len = afl->max_length;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* boring uncustom. */
|
/* boring uncustom. */
|
||||||
afl_fsrv_write_to_testcase(&afl->fsrv, mem, len);
|
afl_fsrv_write_to_testcase(&afl->fsrv, mem, len);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return len;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The same, but with an adjustable gap. Used for trimming. */
|
/* The same, but with an adjustable gap. Used for trimming. */
|
||||||
@ -346,7 +369,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
/* we need a dummy run if this is LTO + cmplog */
|
/* we need a dummy run if this is LTO + cmplog */
|
||||||
if (unlikely(afl->shm.cmplog_mode)) {
|
if (unlikely(afl->shm.cmplog_mode)) {
|
||||||
|
|
||||||
write_to_testcase(afl, use_mem, q->len);
|
(void)write_to_testcase(afl, use_mem, q->len, 1);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
|
||||||
|
|
||||||
@ -389,7 +412,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
|
|
||||||
u64 cksum;
|
u64 cksum;
|
||||||
|
|
||||||
write_to_testcase(afl, use_mem, q->len);
|
(void)write_to_testcase(afl, use_mem, q->len, 1);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
|
||||||
|
|
||||||
@ -700,7 +723,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
/* See what happens. We rely on save_if_interesting() to catch major
|
/* See what happens. We rely on save_if_interesting() to catch major
|
||||||
errors and save the test case. */
|
errors and save the test case. */
|
||||||
|
|
||||||
write_to_testcase(afl, mem, st.st_size);
|
(void)write_to_testcase(afl, mem, st.st_size, 1);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
@ -943,7 +966,7 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
u8 fault;
|
u8 fault;
|
||||||
|
|
||||||
write_to_testcase(afl, out_buf, len);
|
len = write_to_testcase(afl, out_buf, len, 0);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
|
@ -102,6 +102,8 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
|
|||||||
afl->stats_avg_exec = 0;
|
afl->stats_avg_exec = 0;
|
||||||
afl->skip_deterministic = 1;
|
afl->skip_deterministic = 1;
|
||||||
afl->cmplog_lvl = 2;
|
afl->cmplog_lvl = 2;
|
||||||
|
afl->min_length = 1;
|
||||||
|
afl->max_length = MAX_FILE;
|
||||||
#ifndef NO_SPLICING
|
#ifndef NO_SPLICING
|
||||||
afl->use_splicing = 1;
|
afl->use_splicing = 1;
|
||||||
#endif
|
#endif
|
||||||
|
@ -155,6 +155,9 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
"\n"
|
"\n"
|
||||||
|
|
||||||
"Mutator settings:\n"
|
"Mutator settings:\n"
|
||||||
|
" -y [min-]max - set minimum and maximum length of generated fuzzing "
|
||||||
|
"input.\n"
|
||||||
|
" default: 1-%lu\n"
|
||||||
" -D - enable deterministic fuzzing (once per queue entry)\n"
|
" -D - enable deterministic fuzzing (once per queue entry)\n"
|
||||||
" -L minutes - use MOpt(imize) mode and set the time limit for "
|
" -L minutes - use MOpt(imize) mode and set the time limit for "
|
||||||
"entering the\n"
|
"entering the\n"
|
||||||
@ -204,7 +207,7 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
"(0-...)\n"
|
"(0-...)\n"
|
||||||
" -e ext - file extension for the fuzz test input file (if "
|
" -e ext - file extension for the fuzz test input file (if "
|
||||||
"needed)\n\n",
|
"needed)\n\n",
|
||||||
argv0, EXEC_TIMEOUT, MEM_LIMIT, FOREIGN_SYNCS_MAX);
|
argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX);
|
||||||
|
|
||||||
if (more_help > 1) {
|
if (more_help > 1) {
|
||||||
|
|
||||||
@ -529,11 +532,36 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
while ((opt = getopt(
|
while ((opt = getopt(
|
||||||
argc, argv,
|
argc, argv,
|
||||||
"+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOXYo:p:RQs:S:t:T:UV:Wx:Z")) >
|
"+Ab:B:c:CdDe:E:hi:I:f:F:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:Yy:Z")) >
|
||||||
0) {
|
0) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
|
case 'y': {
|
||||||
|
|
||||||
|
u8 *sep;
|
||||||
|
if (!(sep = strchr(optarg, '-')) && !(sep = strchr(optarg, ':'))) {
|
||||||
|
|
||||||
|
afl->max_length = atoi(optarg);
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
|
afl->min_length = atoi(optarg);
|
||||||
|
afl->max_length = atoi(sep + 1);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (afl->min_length < 1 || afl->max_length > MAX_FILE ||
|
||||||
|
afl->min_length > afl->max_length) {
|
||||||
|
|
||||||
|
FATAL("Illegal min/max length values: %s", optarg);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
case 'Z':
|
case 'Z':
|
||||||
afl->old_seed_selection = 1;
|
afl->old_seed_selection = 1;
|
||||||
break;
|
break;
|
||||||
@ -1622,6 +1650,16 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
OKF("Generating fuzz data with a a length of min=%u max=%u", afl->min_length,
|
||||||
|
afl->max_length);
|
||||||
|
u32 min_alloc = MAX(64U, afl->min_length);
|
||||||
|
afl_realloc(AFL_BUF_PARAM(in_scratch), min_alloc);
|
||||||
|
afl_realloc(AFL_BUF_PARAM(in), min_alloc);
|
||||||
|
afl_realloc(AFL_BUF_PARAM(out_scratch), min_alloc);
|
||||||
|
afl_realloc(AFL_BUF_PARAM(out), min_alloc);
|
||||||
|
afl_realloc(AFL_BUF_PARAM(eff), min_alloc);
|
||||||
|
afl_realloc(AFL_BUF_PARAM(ex), min_alloc);
|
||||||
|
|
||||||
afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
|
afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver;
|
||||||
|
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|
Reference in New Issue
Block a user