From 26a5bd625ccbd8de4fbc9b5eea263d092bd405e5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 18 Nov 2022 12:23:18 +0100 Subject: write queue statistics --- include/afl-fuzz.h | 14 +++++++++++--- include/config.h | 3 ++- 2 files changed, 13 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 88646db3..f9dcbf8f 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -169,12 +169,18 @@ struct queue_entry { u32 bitmap_size, /* Number of bits set in bitmap */ fuzz_level, /* Number of fuzzing iterations */ - n_fuzz_entry; /* offset in n_fuzz */ + n_fuzz_entry, /* offset in n_fuzz */ + stats_selected, /* stats: how often selected */ + stats_skipped, /* stats: how often skipped */ + stats_finds, /* stats: # of saved finds */ + stats_crashes, /* stats: # of saved crashes */ + stats_tmouts; /* stats: # of saved timeouts */ u64 exec_us, /* Execution time (us) */ handicap, /* Number of queue cycles behind */ depth, /* Path depth */ - exec_cksum; /* Checksum of the execution trace */ + exec_cksum, /* Checksum of the execution trace */ + stats_mutated; /* stats: # of mutations performed */ u8 *trace_mini; /* Trace bytes, if kept */ u32 tc_ref; /* Trace bytes ref count */ @@ -686,7 +692,8 @@ typedef struct afl_state { u32 plot_prev_qp, plot_prev_pf, plot_prev_pnf, plot_prev_ce, plot_prev_md; u64 plot_prev_qc, plot_prev_uc, plot_prev_uh, plot_prev_ed; - u64 stats_last_stats_ms, stats_last_plot_ms, stats_last_ms, stats_last_execs; + u64 stats_last_stats_ms, stats_last_plot_ms, stats_last_queue_ms, + stats_last_ms, stats_last_execs; /* StatsD */ u64 statsd_last_send_ms; @@ -1101,6 +1108,7 @@ void load_stats_file(afl_state_t *); void write_setup_file(afl_state_t *, u32, char **); void write_stats_file(afl_state_t *, u32, double, double, double); void maybe_update_plot_file(afl_state_t *, u32, double, double); +void write_queue_stats(afl_state_t *); void show_stats(afl_state_t *); void show_stats_normal(afl_state_t *); void show_stats_pizza(afl_state_t *); diff --git a/include/config.h b/include/config.h index 22c1a162..b82ead47 100644 --- a/include/config.h +++ b/include/config.h @@ -290,10 +290,11 @@ #define UI_TARGET_HZ 5 -/* Fuzzer stats file and plot update intervals (sec): */ +/* Fuzzer stats file, queue stats and plot update intervals (sec): */ #define STATS_UPDATE_SEC 60 #define PLOT_UPDATE_SEC 5 +#define QUEUE_UPDATE_SEC 1800 /* Smoothing divisor for CPU load and exec speed stats (1 - no smoothing). */ -- cgit 1.4.1 From 85b44bb73025b41d9b9a8b0aaf742f073621a98b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 12 Dec 2022 18:35:05 +0100 Subject: add cmplog envs --- include/envs.h | 2 ++ 1 file changed, 2 insertions(+) (limited to 'include') diff --git a/include/envs.h b/include/envs.h index 68d83f8c..f4cdf390 100644 --- a/include/envs.h +++ b/include/envs.h @@ -124,7 +124,9 @@ static char *afl_environment_variables[] = { "AFL_LLVM_ALLOWLIST", "AFL_LLVM_DENYLIST", "AFL_LLVM_BLOCKLIST", + "AFL_CMPLOG", "AFL_LLVM_CMPLOG", + "AFL_GCC_CMPLOG", "AFL_LLVM_INSTRIM", "AFL_LLVM_CALLER", "AFL_LLVM_CTX", -- cgit 1.4.1 From 0165ca8c6c485e36fe8e5fc6182ebeba2100932b Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 20 Dec 2022 13:36:56 +0100 Subject: hide queue introspection behind define --- include/afl-fuzz.h | 8 ++++-- src/afl-fuzz-one.c | 74 ++++++++++++++++++++++++++++++++++++++++++++++++++++ src/afl-fuzz-stats.c | 7 +++++ src/afl-fuzz.c | 9 +++++-- 4 files changed, 94 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index f9dcbf8f..ea83aaca 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -169,12 +169,16 @@ struct queue_entry { u32 bitmap_size, /* Number of bits set in bitmap */ fuzz_level, /* Number of fuzzing iterations */ - n_fuzz_entry, /* offset in n_fuzz */ + n_fuzz_entry /* offset in n_fuzz */ +#ifdef INTROSPECTION + , stats_selected, /* stats: how often selected */ stats_skipped, /* stats: how often skipped */ stats_finds, /* stats: # of saved finds */ stats_crashes, /* stats: # of saved crashes */ - stats_tmouts; /* stats: # of saved timeouts */ + stats_tmouts /* stats: # of saved timeouts */ +#endif + ; u64 exec_us, /* Execution time (us) */ handicap, /* Number of queue cycles behind */ diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 253e78b6..9931820a 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -743,7 +743,9 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->stage_finds[STAGE_FLIP1] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP1] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Two walking bits. */ @@ -776,7 +778,9 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->stage_finds[STAGE_FLIP2] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP2] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Four walking bits. */ @@ -813,7 +817,9 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->stage_finds[STAGE_FLIP4] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP4] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Effector map setup. These macros calculate: @@ -922,7 +928,9 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->stage_finds[STAGE_FLIP8] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP8] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Two walking bytes. */ @@ -966,7 +974,9 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->stage_finds[STAGE_FLIP16] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP16] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif if (len < 4) { goto skip_bitflip; } @@ -1010,7 +1020,9 @@ u8 fuzz_one_original(afl_state_t *afl) { afl->stage_finds[STAGE_FLIP32] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP32] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_bitflip: @@ -1103,7 +1115,9 @@ skip_bitflip: afl->stage_finds[STAGE_ARITH8] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ARITH8] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* 16-bit arithmetics, both endians. */ @@ -1234,7 +1248,9 @@ skip_bitflip: afl->stage_finds[STAGE_ARITH16] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ARITH16] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* 32-bit arithmetics, both endians. */ @@ -1364,7 +1380,9 @@ skip_bitflip: afl->stage_finds[STAGE_ARITH32] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ARITH32] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_arith: @@ -1431,7 +1449,9 @@ skip_arith: afl->stage_finds[STAGE_INTEREST8] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_INTEREST8] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Setting 16-bit integers, both endians. */ @@ -1520,7 +1540,9 @@ skip_arith: afl->stage_finds[STAGE_INTEREST16] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_INTEREST16] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif if (len < 4) { goto skip_interest; } @@ -1610,7 +1632,9 @@ skip_arith: afl->stage_finds[STAGE_INTEREST32] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_INTEREST32] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_interest: @@ -1684,7 +1708,9 @@ skip_interest: afl->stage_finds[STAGE_EXTRAS_UO] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_UO] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Insertion of user-supplied extras. */ @@ -1741,7 +1767,9 @@ skip_interest: afl->stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_UI] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_user_extras: @@ -1800,7 +1828,9 @@ skip_user_extras: afl->stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_AO] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Insertion of auto extras. */ @@ -1857,7 +1887,9 @@ skip_user_extras: afl->stage_finds[STAGE_EXTRAS_AI] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_AI] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_extras: @@ -2004,7 +2036,9 @@ custom_mutator_stage: afl->stage_finds[STAGE_CUSTOM_MUTATOR] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_CUSTOM_MUTATOR] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif if (likely(afl->custom_only)) { @@ -2942,13 +2976,17 @@ havoc_stage: afl->stage_finds[STAGE_HAVOC] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_HAVOC] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif } else { afl->stage_finds[STAGE_SPLICE] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_SPLICE] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif } @@ -3430,7 +3468,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { afl->stage_finds[STAGE_FLIP1] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP1] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Two walking bits. */ @@ -3462,7 +3502,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { afl->stage_finds[STAGE_FLIP2] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP2] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Four walking bits. */ @@ -3498,7 +3540,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { afl->stage_finds[STAGE_FLIP4] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP4] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Effector map setup. These macros calculate: @@ -3606,7 +3650,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { afl->stage_finds[STAGE_FLIP8] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP8] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Two walking bytes. */ @@ -3649,7 +3695,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { afl->stage_finds[STAGE_FLIP16] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP16] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif if (len < 4) { goto skip_bitflip; } @@ -3692,7 +3740,9 @@ static u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) { afl->stage_finds[STAGE_FLIP32] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_FLIP32] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_bitflip: @@ -3783,7 +3833,9 @@ skip_bitflip: afl->stage_finds[STAGE_ARITH8] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ARITH8] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* 16-bit arithmetics, both endians. */ @@ -3910,7 +3962,9 @@ skip_bitflip: afl->stage_finds[STAGE_ARITH16] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ARITH16] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* 32-bit arithmetics, both endians. */ @@ -4036,7 +4090,9 @@ skip_bitflip: afl->stage_finds[STAGE_ARITH32] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_ARITH32] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_arith: @@ -4102,7 +4158,9 @@ skip_arith: afl->stage_finds[STAGE_INTEREST8] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_INTEREST8] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Setting 16-bit integers, both endians. */ @@ -4189,7 +4247,9 @@ skip_arith: afl->stage_finds[STAGE_INTEREST16] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_INTEREST16] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif if (len < 4) { goto skip_interest; } @@ -4277,7 +4337,9 @@ skip_arith: afl->stage_finds[STAGE_INTEREST32] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_INTEREST32] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_interest: @@ -4351,7 +4413,9 @@ skip_interest: afl->stage_finds[STAGE_EXTRAS_UO] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_UO] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Insertion of user-supplied extras. */ @@ -4408,7 +4472,9 @@ skip_interest: afl->stage_finds[STAGE_EXTRAS_UI] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_UI] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_user_extras: @@ -4468,7 +4534,9 @@ skip_user_extras: afl->stage_finds[STAGE_EXTRAS_AO] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_AO] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif /* Insertion of auto extras. */ @@ -4525,7 +4593,9 @@ skip_user_extras: afl->stage_finds[STAGE_EXTRAS_AI] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_EXTRAS_AI] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif skip_extras: @@ -5351,13 +5421,17 @@ pacemaker_fuzzing: afl->stage_finds[STAGE_HAVOC] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_HAVOC] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif } else { afl->stage_finds[STAGE_SPLICE] += new_hit_cnt - orig_hit_cnt; afl->stage_cycles[STAGE_SPLICE] += afl->stage_max; +#ifdef INTROSPECTION afl->queue_cur->stats_mutated += afl->stage_max; +#endif } diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index ac9ad4db..87e149de 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -365,6 +365,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, } +#ifdef INTROSPECTION void write_queue_stats(afl_state_t *afl) { FILE *f; @@ -395,6 +396,8 @@ void write_queue_stats(afl_state_t *afl) { } +#endif + /* Update the plot file if there is a reason to. */ void maybe_update_plot_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, @@ -649,7 +652,9 @@ void show_stats_normal(afl_state_t *afl) { cur_ms - afl->stats_last_queue_ms > QUEUE_UPDATE_SEC * 1000)) { afl->stats_last_queue_ms = cur_ms; +#ifdef INTROSPECTION write_queue_stats(afl); +#endif } @@ -1445,7 +1450,9 @@ void show_stats_pizza(afl_state_t *afl) { cur_ms - afl->stats_last_queue_ms > QUEUE_UPDATE_SEC * 1000)) { afl->stats_last_queue_ms = cur_ms; +#ifdef INTROSPECTION write_queue_stats(afl); +#endif } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 172b9d7a..efef5523 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2279,8 +2279,10 @@ int main(int argc, char **argv_orig, char **envp) { // real start time, we reset, so this works correctly with -V afl->start_time = get_cur_time(); - u32 runs_in_current_cycle = (u32)-1; - u32 prev_queued_items = 0, prev_saved_crashes = 0, prev_saved_tmouts = 0; + #ifdef INTROSPECTION + u32 prev_saved_crashes = 0, prev_saved_tmouts = 0; + #endif + u32 prev_queued_items = 0, runs_in_current_cycle = (u32)-1; u8 skipped_fuzz; #ifdef INTROSPECTION @@ -2542,6 +2544,7 @@ int main(int argc, char **argv_orig, char **envp) { } skipped_fuzz = fuzz_one(afl); + #ifdef INTROSPECTION ++afl->queue_cur->stats_selected; if (unlikely(skipped_fuzz)) { @@ -2573,6 +2576,8 @@ int main(int argc, char **argv_orig, char **envp) { } + #endif + if (unlikely(!afl->stop_soon && exit_1)) { afl->stop_soon = 2; } if (unlikely(afl->old_seed_selection)) { -- cgit 1.4.1 From 35f09e11a4373b0fb42c690d23127c144f72f73c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 3 Jan 2023 09:38:00 +0100 Subject: welcome 2023 --- .custom-format.py | 2 +- GNUmakefile.gcc_plugin | 2 +- afl-whatsup | 2 +- custom_mutators/gramatron/build_gramatron_mutator.sh | 2 +- custom_mutators/grammar_mutator/build_grammar_mutator.sh | 2 +- frida_mode/Scripting.md | 2 +- frida_mode/test/cmplog/cmplog.c | 2 +- frida_mode/test/deferred/testinstr.c | 2 +- frida_mode/test/dynamic/testinstr.c | 2 +- frida_mode/test/entry_point/testinstr.c | 2 +- frida_mode/test/exe/testinstr.c | 2 +- frida_mode/test/js/test.c | 2 +- frida_mode/test/js/test2.c | 2 +- frida_mode/test/output/testinstr.c | 2 +- frida_mode/test/perf/perf.c | 2 +- frida_mode/test/persistent_ret/testinstr.c | 2 +- frida_mode/test/testinstr/testinstr.c | 2 +- frida_mode/test/unstable/unstable.c | 2 +- include/afl-as.h | 2 +- include/afl-fuzz.h | 2 +- include/afl-prealloc.h | 2 +- include/alloc-inl.h | 2 +- include/cmplog.h | 2 +- include/common.h | 2 +- include/config.h | 2 +- include/debug.h | 2 +- include/forkserver.h | 2 +- include/hash.h | 2 +- include/list.h | 2 +- include/sharedmem.h | 2 +- include/snapshot-inl.h | 2 +- include/types.h | 2 +- include/xxhash.h | 2 +- instrumentation/afl-compiler-rt.o.c | 2 +- instrumentation/afl-gcc-cmplog-pass.so.cc | 2 +- instrumentation/afl-gcc-cmptrs-pass.so.cc | 2 +- instrumentation/afl-gcc-common.h | 2 +- instrumentation/afl-gcc-pass.so.cc | 2 +- instrumentation/afl-llvm-dict2file.so.cc | 2 +- instrumentation/afl-llvm-lto-instrumentlist.so.cc | 2 +- instrumentation/afl-llvm-pass.so.cc | 2 +- instrumentation/cmplog-instructions-pass.cc | 2 +- instrumentation/cmplog-routines-pass.cc | 2 +- instrumentation/cmplog-switches-pass.cc | 2 +- qemu_mode/build_qemu_support.sh | 2 +- qemu_mode/fastexit/Makefile | 2 +- qemu_mode/libcompcov/Makefile | 2 +- qemu_mode/libcompcov/compcovtest.cc | 2 +- qemu_mode/libcompcov/libcompcov.so.c | 2 +- qemu_mode/libqasan/Makefile | 2 +- qemu_mode/libqasan/hooks.c | 2 +- qemu_mode/libqasan/libqasan.c | 2 +- qemu_mode/libqasan/libqasan.h | 2 +- qemu_mode/libqasan/malloc.c | 2 +- qemu_mode/libqasan/patch.c | 2 +- qemu_mode/libqasan/string.c | 2 +- qemu_mode/libqasan/uninstrument.c | 2 +- qemu_mode/unsigaction/Makefile | 2 +- src/afl-analyze.c | 2 +- src/afl-as.c | 2 +- src/afl-cc.c | 2 +- src/afl-common.c | 2 +- src/afl-forkserver.c | 2 +- src/afl-fuzz-bitmap.c | 2 +- src/afl-fuzz-cmplog.c | 2 +- src/afl-fuzz-extras.c | 2 +- src/afl-fuzz-init.c | 2 +- src/afl-fuzz-mutators.c | 2 +- src/afl-fuzz-one.c | 2 +- src/afl-fuzz-python.c | 2 +- src/afl-fuzz-queue.c | 2 +- src/afl-fuzz-redqueen.c | 2 +- src/afl-fuzz-run.c | 2 +- src/afl-fuzz-state.c | 2 +- src/afl-fuzz-stats.c | 2 +- src/afl-fuzz.c | 2 +- src/afl-gotcpu.c | 2 +- src/afl-ld-lto.c | 2 +- src/afl-sharedmem.c | 2 +- src/afl-showmap.c | 2 +- src/afl-tmin.c | 2 +- test-instr.c | 2 +- unicorn_mode/build_unicorn_support.sh | 2 +- utils/afl_network_proxy/afl-network-client.c | 2 +- utils/afl_network_proxy/afl-network-server.c | 2 +- utils/afl_proxy/afl-proxy.c | 2 +- utils/afl_untracer/afl-untracer.c | 2 +- utils/afl_untracer/libtestinstr.c | 2 +- utils/argv_fuzzing/Makefile | 2 +- utils/argv_fuzzing/argvfuzz.c | 2 +- utils/distributed_fuzzing/sync_script.sh | 2 +- utils/libdislocator/libdislocator.so.c | 2 +- utils/libtokencap/libtokencap.so.c | 2 +- utils/persistent_mode/test-instr.c | 2 +- 94 files changed, 94 insertions(+), 94 deletions(-) (limited to 'include') diff --git a/.custom-format.py b/.custom-format.py index 95def5aa..d07c26df 100755 --- a/.custom-format.py +++ b/.custom-format.py @@ -6,7 +6,7 @@ # Written and maintained by Andrea Fioraldi # # Copyright 2015, 2016, 2017 Google Inc. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/GNUmakefile.gcc_plugin b/GNUmakefile.gcc_plugin index 28a1a828..4c4e10c4 100644 --- a/GNUmakefile.gcc_plugin +++ b/GNUmakefile.gcc_plugin @@ -11,7 +11,7 @@ # from Laszlo Szekeres. # # Copyright 2015 Google Inc. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/afl-whatsup b/afl-whatsup index 160a8c74..5546523a 100755 --- a/afl-whatsup +++ b/afl-whatsup @@ -6,7 +6,7 @@ # Originally written by Michal Zalewski # # Copyright 2015 Google Inc. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/custom_mutators/gramatron/build_gramatron_mutator.sh b/custom_mutators/gramatron/build_gramatron_mutator.sh index ff88ff26..c830329e 100755 --- a/custom_mutators/gramatron/build_gramatron_mutator.sh +++ b/custom_mutators/gramatron/build_gramatron_mutator.sh @@ -11,7 +11,7 @@ # Adapted for AFLplusplus by Dominik Maier # # Copyright 2017 Battelle Memorial Institute. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/custom_mutators/grammar_mutator/build_grammar_mutator.sh b/custom_mutators/grammar_mutator/build_grammar_mutator.sh index 74cae8aa..593cd2dc 100755 --- a/custom_mutators/grammar_mutator/build_grammar_mutator.sh +++ b/custom_mutators/grammar_mutator/build_grammar_mutator.sh @@ -14,7 +14,7 @@ # # # Copyright 2017 Battelle Memorial Institute. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/frida_mode/Scripting.md b/frida_mode/Scripting.md index 06d4212c..023e4a19 100644 --- a/frida_mode/Scripting.md +++ b/frida_mode/Scripting.md @@ -390,7 +390,7 @@ Consider the [following](test/js/test2.c) test code... -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/cmplog/cmplog.c b/frida_mode/test/cmplog/cmplog.c index 7c047ed6..2565b35c 100644 --- a/frida_mode/test/cmplog/cmplog.c +++ b/frida_mode/test/cmplog/cmplog.c @@ -2,7 +2,7 @@ // // Author: Mateusz Jurczyk (mjurczyk@google.com) // -// Copyright 2019-2022 Google LLC +// Copyright 2019-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/frida_mode/test/deferred/testinstr.c b/frida_mode/test/deferred/testinstr.c index 7e564a61..0ab44582 100644 --- a/frida_mode/test/deferred/testinstr.c +++ b/frida_mode/test/deferred/testinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/dynamic/testinstr.c b/frida_mode/test/dynamic/testinstr.c index ad26d060..8b285f6d 100644 --- a/frida_mode/test/dynamic/testinstr.c +++ b/frida_mode/test/dynamic/testinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/entry_point/testinstr.c b/frida_mode/test/entry_point/testinstr.c index 196b1d84..24d9a615 100644 --- a/frida_mode/test/entry_point/testinstr.c +++ b/frida_mode/test/entry_point/testinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/exe/testinstr.c b/frida_mode/test/exe/testinstr.c index 334f6518..d965502e 100644 --- a/frida_mode/test/exe/testinstr.c +++ b/frida_mode/test/exe/testinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/js/test.c b/frida_mode/test/js/test.c index f6778b6f..87c9cdf6 100644 --- a/frida_mode/test/js/test.c +++ b/frida_mode/test/js/test.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/js/test2.c b/frida_mode/test/js/test2.c index 9e9cdbb4..6b680a24 100644 --- a/frida_mode/test/js/test2.c +++ b/frida_mode/test/js/test2.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/output/testinstr.c b/frida_mode/test/output/testinstr.c index 334f6518..d965502e 100644 --- a/frida_mode/test/output/testinstr.c +++ b/frida_mode/test/output/testinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/perf/perf.c b/frida_mode/test/perf/perf.c index f6659b55..d9626974 100644 --- a/frida_mode/test/perf/perf.c +++ b/frida_mode/test/perf/perf.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/persistent_ret/testinstr.c b/frida_mode/test/persistent_ret/testinstr.c index b2bc19ef..12365ceb 100644 --- a/frida_mode/test/persistent_ret/testinstr.c +++ b/frida_mode/test/persistent_ret/testinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/testinstr/testinstr.c b/frida_mode/test/testinstr/testinstr.c index 334f6518..d965502e 100644 --- a/frida_mode/test/testinstr/testinstr.c +++ b/frida_mode/test/testinstr/testinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/frida_mode/test/unstable/unstable.c b/frida_mode/test/unstable/unstable.c index 7d16c26c..a87b6c74 100644 --- a/frida_mode/test/unstable/unstable.c +++ b/frida_mode/test/unstable/unstable.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/include/afl-as.h b/include/afl-as.h index bbbd5582..486314e2 100644 --- a/include/afl-as.h +++ b/include/afl-as.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index ea83aaca..edef9207 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/afl-prealloc.h b/include/afl-prealloc.h index bdf0d87f..d19a7b52 100644 --- a/include/afl-prealloc.h +++ b/include/afl-prealloc.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/alloc-inl.h b/include/alloc-inl.h index 6c2bafff..ae37028e 100644 --- a/include/alloc-inl.h +++ b/include/alloc-inl.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/cmplog.h b/include/cmplog.h index c6d2957e..6e16e6b0 100644 --- a/include/cmplog.h +++ b/include/cmplog.h @@ -12,7 +12,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/common.h b/include/common.h index 9d9a948c..b5dbc6de 100644 --- a/include/common.h +++ b/include/common.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/config.h b/include/config.h index b82ead47..b3310270 100644 --- a/include/config.h +++ b/include/config.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/debug.h b/include/debug.h index 566b1d00..cd621a72 100644 --- a/include/debug.h +++ b/include/debug.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/forkserver.h b/include/forkserver.h index a8a7e777..35bc1771 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -12,7 +12,7 @@ Dominik Maier > Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/hash.h b/include/hash.h index d8fef70c..0243c5b7 100644 --- a/include/hash.h +++ b/include/hash.h @@ -15,7 +15,7 @@ Other code written by Michal Zalewski Copyright 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/list.h b/include/list.h index 72bef749..283bf035 100644 --- a/include/list.h +++ b/include/list.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/sharedmem.h b/include/sharedmem.h index fbe68abe..d32bd845 100644 --- a/include/sharedmem.h +++ b/include/sharedmem.h @@ -12,7 +12,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/snapshot-inl.h b/include/snapshot-inl.h index 8d2f41ff..3864e473 100644 --- a/include/snapshot-inl.h +++ b/include/snapshot-inl.h @@ -12,7 +12,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/types.h b/include/types.h index 96ce78f8..d6476d82 100644 --- a/include/types.h +++ b/include/types.h @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/include/xxhash.h b/include/xxhash.h index 4cabc884..7bc0a14e 100644 --- a/include/xxhash.h +++ b/include/xxhash.h @@ -1,7 +1,7 @@ /* * xxHash - Extremely Fast Hash algorithm * Header File - * Copyright (C) 2012-2022 Yann Collet + * Copyright (C) 2012-2023 Yann Collet * * BSD 2-Clause License (https://www.opensource.org/licenses/bsd-license.php) * diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index fd5f2d4c..9c6345b6 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -3,7 +3,7 @@ ------------------------------------------------ Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/instrumentation/afl-gcc-cmplog-pass.so.cc b/instrumentation/afl-gcc-cmplog-pass.so.cc index 3c781fd7..b4e6fda9 100644 --- a/instrumentation/afl-gcc-cmplog-pass.so.cc +++ b/instrumentation/afl-gcc-cmplog-pass.so.cc @@ -3,7 +3,7 @@ Copyright 2014-2019 Free Software Foundation, Inc Copyright 2015, 2016 Google Inc. All rights reserved. Copyright 2019-2020 AFLplusplus Project. All rights reserved. - Copyright 2019-2022 AdaCore + Copyright 2019-2023 AdaCore Written by Alexandre Oliva , based on the AFL++ LLVM CmpLog pass by Andrea Fioraldi , and diff --git a/instrumentation/afl-gcc-cmptrs-pass.so.cc b/instrumentation/afl-gcc-cmptrs-pass.so.cc index 0ddbac15..dbb408b0 100644 --- a/instrumentation/afl-gcc-cmptrs-pass.so.cc +++ b/instrumentation/afl-gcc-cmptrs-pass.so.cc @@ -3,7 +3,7 @@ Copyright 2014-2019 Free Software Foundation, Inc Copyright 2015, 2016 Google Inc. All rights reserved. Copyright 2019-2020 AFLplusplus Project. All rights reserved. - Copyright 2019-2022 AdaCore + Copyright 2019-2023 AdaCore Written by Alexandre Oliva , based on the AFL++ LLVM CmpLog Routines pass by Andrea Fioraldi diff --git a/instrumentation/afl-gcc-common.h b/instrumentation/afl-gcc-common.h index cda3f9d8..1d5eb466 100644 --- a/instrumentation/afl-gcc-common.h +++ b/instrumentation/afl-gcc-common.h @@ -2,7 +2,7 @@ Copyright 2014-2019 Free Software Foundation, Inc Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AdaCore + Copyright 2019-2023 AdaCore Written by Alexandre Oliva , based on the AFL++ GCC plugin. diff --git a/instrumentation/afl-gcc-pass.so.cc b/instrumentation/afl-gcc-pass.so.cc index ea938a7f..4d7fd0ef 100644 --- a/instrumentation/afl-gcc-pass.so.cc +++ b/instrumentation/afl-gcc-pass.so.cc @@ -2,7 +2,7 @@ Copyright 2014-2019 Free Software Foundation, Inc Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AdaCore + Copyright 2019-2023 AdaCore Written by Alexandre Oliva , based on the AFL LLVM pass by Laszlo Szekeres and Michal diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index fd8baea2..bbbbe32c 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -4,7 +4,7 @@ Written by Marc Heuse - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/instrumentation/afl-llvm-lto-instrumentlist.so.cc b/instrumentation/afl-llvm-lto-instrumentlist.so.cc index 32b1798a..db5bd55e 100644 --- a/instrumentation/afl-llvm-lto-instrumentlist.so.cc +++ b/instrumentation/afl-llvm-lto-instrumentlist.so.cc @@ -9,7 +9,7 @@ from afl-as.c are Michal's fault. Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/instrumentation/afl-llvm-pass.so.cc b/instrumentation/afl-llvm-pass.so.cc index df1ccc4f..e8d0b1e5 100644 --- a/instrumentation/afl-llvm-pass.so.cc +++ b/instrumentation/afl-llvm-pass.so.cc @@ -12,7 +12,7 @@ NGRAM previous location coverage comes from Adrian Herrera. Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/instrumentation/cmplog-instructions-pass.cc b/instrumentation/cmplog-instructions-pass.cc index 084ad8c9..bca1f927 100644 --- a/instrumentation/cmplog-instructions-pass.cc +++ b/instrumentation/cmplog-instructions-pass.cc @@ -5,7 +5,7 @@ Written by Andrea Fioraldi Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/instrumentation/cmplog-routines-pass.cc b/instrumentation/cmplog-routines-pass.cc index 9733f86e..0498156d 100644 --- a/instrumentation/cmplog-routines-pass.cc +++ b/instrumentation/cmplog-routines-pass.cc @@ -5,7 +5,7 @@ Written by Andrea Fioraldi Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/instrumentation/cmplog-switches-pass.cc b/instrumentation/cmplog-switches-pass.cc index 563a4481..cd0ae76d 100644 --- a/instrumentation/cmplog-switches-pass.cc +++ b/instrumentation/cmplog-switches-pass.cc @@ -5,7 +5,7 @@ Written by Andrea Fioraldi Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/qemu_mode/build_qemu_support.sh b/qemu_mode/build_qemu_support.sh index f31f3cef..a064fe58 100755 --- a/qemu_mode/build_qemu_support.sh +++ b/qemu_mode/build_qemu_support.sh @@ -13,7 +13,7 @@ # counters by Andrea Fioraldi # # Copyright 2015, 2016, 2017 Google Inc. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/qemu_mode/fastexit/Makefile b/qemu_mode/fastexit/Makefile index 80a5ec48..c7b79277 100644 --- a/qemu_mode/fastexit/Makefile +++ b/qemu_mode/fastexit/Makefile @@ -4,7 +4,7 @@ # # Written by Andrea Fioraldi # -# Copyright 2019-2022 Andrea Fioraldi. All rights reserved. +# Copyright 2019-2023 Andrea Fioraldi. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/qemu_mode/libcompcov/Makefile b/qemu_mode/libcompcov/Makefile index cc591393..7260df87 100644 --- a/qemu_mode/libcompcov/Makefile +++ b/qemu_mode/libcompcov/Makefile @@ -4,7 +4,7 @@ # # Written by Andrea Fioraldi # -# Copyright 2019-2022 Andrea Fioraldi. All rights reserved. +# Copyright 2019-2023 Andrea Fioraldi. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/qemu_mode/libcompcov/compcovtest.cc b/qemu_mode/libcompcov/compcovtest.cc index b2d64f8d..23215013 100644 --- a/qemu_mode/libcompcov/compcovtest.cc +++ b/qemu_mode/libcompcov/compcovtest.cc @@ -2,7 +2,7 @@ // // Author: Mateusz Jurczyk (mjurczyk@google.com) // -// Copyright 2019-2022 Google LLC +// Copyright 2019-2023 Google LLC // // Licensed under the Apache License, Version 2.0 (the "License"); // you may not use this file except in compliance with the License. diff --git a/qemu_mode/libcompcov/libcompcov.so.c b/qemu_mode/libcompcov/libcompcov.so.c index c4107b8c..b6ee0019 100644 --- a/qemu_mode/libcompcov/libcompcov.so.c +++ b/qemu_mode/libcompcov/libcompcov.so.c @@ -5,7 +5,7 @@ Written and maintained by Andrea Fioraldi - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/qemu_mode/libqasan/Makefile b/qemu_mode/libqasan/Makefile index 79c3ab70..61782894 100644 --- a/qemu_mode/libqasan/Makefile +++ b/qemu_mode/libqasan/Makefile @@ -4,7 +4,7 @@ # # Written by Andrea Fioraldi # -# Copyright 2019-2022 Andrea Fioraldi. All rights reserved. +# Copyright 2019-2023 Andrea Fioraldi. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/qemu_mode/libqasan/hooks.c b/qemu_mode/libqasan/hooks.c index 7f20e848..a9fd0ce9 100644 --- a/qemu_mode/libqasan/hooks.c +++ b/qemu_mode/libqasan/hooks.c @@ -1,5 +1,5 @@ /******************************************************************************* -Copyright (c) 2019-2022, Andrea Fioraldi +Copyright (c) 2019-2023, Andrea Fioraldi Redistribution and use in source and binary forms, with or without diff --git a/qemu_mode/libqasan/libqasan.c b/qemu_mode/libqasan/libqasan.c index f4d590bd..12be7778 100644 --- a/qemu_mode/libqasan/libqasan.c +++ b/qemu_mode/libqasan/libqasan.c @@ -1,5 +1,5 @@ /******************************************************************************* -Copyright (c) 2019-2022, Andrea Fioraldi +Copyright (c) 2019-2023, Andrea Fioraldi Redistribution and use in source and binary forms, with or without diff --git a/qemu_mode/libqasan/libqasan.h b/qemu_mode/libqasan/libqasan.h index 676f34b0..a430c868 100644 --- a/qemu_mode/libqasan/libqasan.h +++ b/qemu_mode/libqasan/libqasan.h @@ -1,5 +1,5 @@ /******************************************************************************* -Copyright (c) 2019-2022, Andrea Fioraldi +Copyright (c) 2019-2023, Andrea Fioraldi Redistribution and use in source and binary forms, with or without diff --git a/qemu_mode/libqasan/malloc.c b/qemu_mode/libqasan/malloc.c index d81b15e9..d2db3856 100644 --- a/qemu_mode/libqasan/malloc.c +++ b/qemu_mode/libqasan/malloc.c @@ -1,5 +1,5 @@ /******************************************************************************* -Copyright (c) 2019-2022, Andrea Fioraldi +Copyright (c) 2019-2023, Andrea Fioraldi Redistribution and use in source and binary forms, with or without diff --git a/qemu_mode/libqasan/patch.c b/qemu_mode/libqasan/patch.c index 15c4df15..38e0903b 100644 --- a/qemu_mode/libqasan/patch.c +++ b/qemu_mode/libqasan/patch.c @@ -1,5 +1,5 @@ /******************************************************************************* -Copyright (c) 2019-2022, Andrea Fioraldi +Copyright (c) 2019-2023, Andrea Fioraldi Redistribution and use in source and binary forms, with or without diff --git a/qemu_mode/libqasan/string.c b/qemu_mode/libqasan/string.c index fc2de1f2..e17cff4b 100644 --- a/qemu_mode/libqasan/string.c +++ b/qemu_mode/libqasan/string.c @@ -1,5 +1,5 @@ /******************************************************************************* -Copyright (c) 2019-2022, Andrea Fioraldi +Copyright (c) 2019-2023, Andrea Fioraldi Redistribution and use in source and binary forms, with or without diff --git a/qemu_mode/libqasan/uninstrument.c b/qemu_mode/libqasan/uninstrument.c index 1686a015..e37a9b46 100644 --- a/qemu_mode/libqasan/uninstrument.c +++ b/qemu_mode/libqasan/uninstrument.c @@ -7,7 +7,7 @@ for some strange reason. */ /******************************************************************************* -Copyright (c) 2019-2022, Andrea Fioraldi +Copyright (c) 2019-2023, Andrea Fioraldi Redistribution and use in source and binary forms, with or without diff --git a/qemu_mode/unsigaction/Makefile b/qemu_mode/unsigaction/Makefile index f026a2b7..c1a7397f 100644 --- a/qemu_mode/unsigaction/Makefile +++ b/qemu_mode/unsigaction/Makefile @@ -4,7 +4,7 @@ # # Written by Andrea Fioraldi # -# Copyright 2019-2022 Andrea Fioraldi. All rights reserved. +# Copyright 2019-2023 Andrea Fioraldi. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/src/afl-analyze.c b/src/afl-analyze.c index a9b5b326..da1def3b 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-as.c b/src/afl-as.c index 1edc8cca..a0eb612f 100644 --- a/src/afl-as.c +++ b/src/afl-as.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-cc.c b/src/afl-cc.c index 1c3b5405..803e784e 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -5,7 +5,7 @@ Written by Michal Zalewski, Laszlo Szekeres and Marc Heuse Copyright 2015, 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-common.c b/src/afl-common.c index 31005804..211d5bf2 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index a241f2c6..9b8660ce 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -13,7 +13,7 @@ Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index b3a10bb7..485b82db 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index d0c829e2..8967d4bc 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -11,7 +11,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-extras.c b/src/afl-fuzz-extras.c index 884bb569..f6de11ae 100644 --- a/src/afl-fuzz-extras.c +++ b/src/afl-fuzz-extras.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index ed52ca00..adfc55ad 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index ef30b993..22e5262e 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 9931820a..97855607 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index d8aed8c6..b509b936 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 5017c37c..e3faa392 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 0dae26a3..8da1df13 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -11,7 +11,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 7f9c3bf3..7dd83150 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -10,7 +10,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 8bd465f0..896b5f71 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 87e149de..bfd30845 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index efef5523..138df26c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c index eee642fb..144ec9c9 100644 --- a/src/afl-gotcpu.c +++ b/src/afl-gotcpu.c @@ -9,7 +9,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-ld-lto.c b/src/afl-ld-lto.c index 5797def8..5438bd9f 100644 --- a/src/afl-ld-lto.c +++ b/src/afl-ld-lto.c @@ -9,7 +9,7 @@ Andrea Fioraldi Dominik Maier - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-sharedmem.c b/src/afl-sharedmem.c index b48c6fb3..a2c81586 100644 --- a/src/afl-sharedmem.c +++ b/src/afl-sharedmem.c @@ -11,7 +11,7 @@ Andrea Fioraldi Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-showmap.c b/src/afl-showmap.c index d85c28d9..da6880cc 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -12,7 +12,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/src/afl-tmin.c b/src/afl-tmin.c index d93b9a41..687bb0e7 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -12,7 +12,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/test-instr.c b/test-instr.c index f304e208..1d9f2e6e 100644 --- a/test-instr.c +++ b/test-instr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/unicorn_mode/build_unicorn_support.sh b/unicorn_mode/build_unicorn_support.sh index a3978d9d..222974cf 100755 --- a/unicorn_mode/build_unicorn_support.sh +++ b/unicorn_mode/build_unicorn_support.sh @@ -14,7 +14,7 @@ # # # Copyright 2017 Battelle Memorial Institute. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/utils/afl_network_proxy/afl-network-client.c b/utils/afl_network_proxy/afl-network-client.c index 89ca6c4e..0416f0f9 100644 --- a/utils/afl_network_proxy/afl-network-client.c +++ b/utils/afl_network_proxy/afl-network-client.c @@ -4,7 +4,7 @@ Written by Marc Heuse - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c index 8f0e9df9..2ae4c165 100644 --- a/utils/afl_network_proxy/afl-network-server.c +++ b/utils/afl_network_proxy/afl-network-server.c @@ -12,7 +12,7 @@ Dominik Maier Copyright 2016, 2017 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/utils/afl_proxy/afl-proxy.c b/utils/afl_proxy/afl-proxy.c index afd0e5d2..531a97a2 100644 --- a/utils/afl_proxy/afl-proxy.c +++ b/utils/afl_proxy/afl-proxy.c @@ -4,7 +4,7 @@ Written by Marc Heuse - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/utils/afl_untracer/afl-untracer.c b/utils/afl_untracer/afl-untracer.c index 6bee067c..ee40d252 100644 --- a/utils/afl_untracer/afl-untracer.c +++ b/utils/afl_untracer/afl-untracer.c @@ -4,7 +4,7 @@ Written by Marc Heuse - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/utils/afl_untracer/libtestinstr.c b/utils/afl_untracer/libtestinstr.c index a3f5acc8..b7afc325 100644 --- a/utils/afl_untracer/libtestinstr.c +++ b/utils/afl_untracer/libtestinstr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: diff --git a/utils/argv_fuzzing/Makefile b/utils/argv_fuzzing/Makefile index f016c5a7..3a4ce084 100644 --- a/utils/argv_fuzzing/Makefile +++ b/utils/argv_fuzzing/Makefile @@ -2,7 +2,7 @@ # american fuzzy lop++ - argvfuzz # -------------------------------- # -# Copyright 2019-2022 Kjell Braden +# Copyright 2019-2023 Kjell Braden # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/utils/argv_fuzzing/argvfuzz.c b/utils/argv_fuzzing/argvfuzz.c index e7cc6b72..41eead0c 100644 --- a/utils/argv_fuzzing/argvfuzz.c +++ b/utils/argv_fuzzing/argvfuzz.c @@ -2,7 +2,7 @@ american fuzzy lop++ - LD_PRELOAD for fuzzing argv in binaries ------------------------------------------------------------ - Copyright 2019-2022 Kjell Braden + Copyright 2019-2023 Kjell Braden Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/utils/distributed_fuzzing/sync_script.sh b/utils/distributed_fuzzing/sync_script.sh index 251ae4e6..b22816f1 100755 --- a/utils/distributed_fuzzing/sync_script.sh +++ b/utils/distributed_fuzzing/sync_script.sh @@ -6,7 +6,7 @@ # Originally written by Michal Zalewski # # Copyright 2014 Google Inc. All rights reserved. -# Copyright 2019-2022 AFLplusplus Project. All rights reserved. +# Copyright 2019-2023 AFLplusplus Project. All rights reserved. # # Licensed under the Apache License, Version 2.0 (the "License"); # you may not use this file except in compliance with the License. diff --git a/utils/libdislocator/libdislocator.so.c b/utils/libdislocator/libdislocator.so.c index c390d004..1cd7abc6 100644 --- a/utils/libdislocator/libdislocator.so.c +++ b/utils/libdislocator/libdislocator.so.c @@ -6,7 +6,7 @@ Originally written by Michal Zalewski Copyright 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/utils/libtokencap/libtokencap.so.c b/utils/libtokencap/libtokencap.so.c index 07d81d59..299056ab 100644 --- a/utils/libtokencap/libtokencap.so.c +++ b/utils/libtokencap/libtokencap.so.c @@ -6,7 +6,7 @@ Originally written by Michal Zalewski Copyright 2016 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. diff --git a/utils/persistent_mode/test-instr.c b/utils/persistent_mode/test-instr.c index 168aa429..4ead6577 100644 --- a/utils/persistent_mode/test-instr.c +++ b/utils/persistent_mode/test-instr.c @@ -3,7 +3,7 @@ -------------------------------------------------------- Originally written by Michal Zalewski Copyright 2014 Google Inc. All rights reserved. - Copyright 2019-2022 AFLplusplus Project. All rights reserved. + Copyright 2019-2023 AFLplusplus Project. All rights reserved. Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at: -- cgit 1.4.1 From 885a6fc106757b3968b86f9a4314f662bb04de43 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 5 Jan 2023 12:43:53 +0100 Subject: 4.05c release --- README.md | 4 ++-- docs/Changelog.md | 11 ++++++----- include/config.h | 2 +- 3 files changed, 9 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/README.md b/README.md index 4ff8c514..eeab7aa1 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ AFL++ logo -Release version: [4.04c](https://github.com/AFLplusplus/AFLplusplus/releases) +Release version: [4.05c](https://github.com/AFLplusplus/AFLplusplus/releases) -GitHub version: 4.05a +GitHub version: 4.06a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 6bfb314d..b9376711 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,7 +3,7 @@ This is the list of all noteworthy changes made in every public release of the tool. See README.md for the general instruction manual. -### Version ++4.05a (dev) +### Version ++4.05c (release) - MacOS: libdislocator, libtokencap etc. do not work with modern MacOS anymore, but could be patched to work, see this issue if you want to make the effort and send a PR: @@ -11,14 +11,15 @@ - afl-fuzz: - added afl_custom_fuzz_send custom mutator feature. Now your can send fuzz data to the target as you need, e.g. via IPC. - - cmplog mode now has -l R option for random colorization, thanks + - cmplog mode now has a -l R option for random colorization, thanks to guyf2010 for the PR! - queue statistics are written every 30 minutes to - out/NAME/queue_data - likely this will be moved to a debug flag - in the future. + out/NAME/queue_data if compiled with INTROSPECTION + - new env: AFL_FORK_SERVER_KILL_SIGNAL - afl-showmap/afl-cmin - - -t none now translates to -t 120000 (120 seconds) + - `-t none` now translates to `-t 120000` (120 seconds) - unicorn_mode updated + - several minor bugfixes ### Version ++4.04c (release) - fix gramatron and grammar_mutator build scripts diff --git a/include/config.h b/include/config.h index b3310270..67b9f932 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.05a" +#define VERSION "++4.05c" /****************************************************** * * -- cgit 1.4.1 From e4ff0ebd56d8076abd2413ebfaeb7b5e6c07bc3a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 5 Jan 2023 13:52:32 +0100 Subject: 4.06a init --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/config.h b/include/config.h index 67b9f932..a5a4c473 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.05c" +#define VERSION "++4.06a" /****************************************************** * * -- cgit 1.4.1 From 35801bed7a5feb8cc3a363bafbd577f256c467f6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 15 Jan 2023 13:47:31 +0100 Subject: dictionary support --- custom_mutators/autotokens/TODO | 15 +- custom_mutators/autotokens/autotokens.cpp | 248 +++++++++++++++++++++++------- include/config.h | 2 +- 3 files changed, 198 insertions(+), 67 deletions(-) (limited to 'include') diff --git a/custom_mutators/autotokens/TODO b/custom_mutators/autotokens/TODO index 700b3fa7..2e5e384f 100644 --- a/custom_mutators/autotokens/TODO +++ b/custom_mutators/autotokens/TODO @@ -1,13 +1,12 @@ whitespace belassen oder notieren? MAYBE 0=space 1=tab 2=linefeed -dictionary mitverwenden? JA aber nur ascii --> neue liste? -wie mache ich das bei honggfuzz? -ansonsten neuer custom mutator entrypoint? +cmplog: only add tokens that were found to fit? + +create from thin air if no good seed after a cycle and dict large enough? +(static u32 no_of_struct_inputs;) + +splice insert, splice overwrite +(linefeed, semicolon) -nur is_ascii wenn cmplog aktiv, ansonsten eigene implementierung -die aber dann dafür sorgt dass eine leere struktur da ist. -is is_ascii in afl-common.o ? -cmplog: only add tokens that were found to fit? diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index afde8c26..2fad8dd7 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -1,5 +1,7 @@ extern "C" { + #include "afl-fuzz.h" + } #include @@ -13,9 +15,7 @@ extern "C" { #include #define AUTOTOKENS_DEBUG 1 -#define AUTOTOKENS_LEN_MIN 12 -#define AUTOTOKENS_CHANGE_MIN_PERCENT 5 -#define AUTOTOKENS_CHANGE_MAX_PERCENT 10 +#define AUTOTOKENS_CHANGE_MIN 8 using namespace std; @@ -31,43 +31,55 @@ typedef struct my_mutator { static afl_state *afl_ptr; static int debug = AUTOTOKENS_DEBUG; static u32 current_id = 0; +static u32 valid_structures = 0; +static u32 extras_cnt = 0, a_extras_cnt = 0; static unordered_map *> file_mapping; static unordered_map token_to_id; static unordered_map id_to_token; -static regex regex_comment_slash("(//.*)([\r\n]?)", regex::optimize); -static regex regex_comment_star("/\\*(.|\n)*?\\*/", - regex::multiline | regex::optimize); -static regex regex_string("\"(.*?)\"|'(.*?')", regex::optimize); -static regex regex_word("[A-Za-z0-9_$]+", regex::optimize); -static regex regex_whitespace(R"([ \t]+)", regex::optimize); -static vector *s; +static regex regex_comment_slash("(//.*)([\r\n]?)", regex::optimize); +static regex regex_comment_star("/\\*(.|\n)*?\\*/", + regex::multiline | regex::optimize); +static regex regex_string("\"(.*?)\"|'(.*?')", regex::optimize); +static regex regex_word("[A-Za-z0-9_$]+", regex::optimize); +static regex regex_whitespace(R"([ \t]+)", regex::optimize); +static vector *s; // the structure of the currently selected input -extern "C" 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, size_t max_size) { +extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, + u8 **out_buf, u8 *add_buf, + size_t add_buf_size, size_t max_size) { - DEBUG(stderr, "MUT!\n"); + if (s == NULL) { + + *out_buf = NULL; + return 0; - if (s == NULL) { return 0; } + } - vector m = *s; - u32 i, m_size = (u32)m.size(); + vector m = *s; // copy of the structure we will modify + u32 i, m_size = (u32)m.size(); - u32 rounds = MAX(8, MIN(m_size >> 3, HAVOC_CYCLES * afl_ptr->queue_cur->perf_score * afl_ptr->havoc_div / 256)); - DEBUG(stderr, "structure size: %lu, rounds: %u \n", m.size(), rounds); + u32 rounds = + MAX(AUTOTOKENS_CHANGE_MIN, + MIN(m_size >> 3, HAVOC_CYCLES * afl_ptr->queue_cur->perf_score * + afl_ptr->havoc_div / 256)); + // DEBUG(stderr, "structure size: %lu, rounds: %u \n", m.size(), rounds); for (i = 0; i < rounds; ++i) { - + u32 item, new_item; - - switch(rand_below(afl_ptr, 4)) { + + switch (rand_below(afl_ptr, 4)) { + /* CHANGE */ - case 0: /* fall through */ + case 0: /* fall through */ case 1: item = rand_below(afl_ptr, m_size); do { + new_item = 1 + rand_below(afl_ptr, current_id); - } while(unlikely(new_item == m[item])); + + } while (unlikely(new_item == m[item])); + m[item] = new_item; break; /* INSERT (+1 so we insert also after last place) */ @@ -81,31 +93,32 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_s if (m_size > 8) { m.erase(m.begin() + rand_below(afl_ptr, m_size)); } --m_size; break; + // TODO: add full line insert splice, replace splace, delete + } - + } - + string output; - u32 m_size_1 = m_size - 1; + u32 m_size_1 = m_size - 1; + for (i = 0; i < m_size; ++i) { + output += id_to_token[m[i]]; if (likely(i < m_size_1)) { output += " "; } + } u32 mutated_size = output.size(); - u8 *mutated_out = (u8*)afl_realloc((void**)out_buf, mutated_size); + u8 *mutated_out = (u8 *)afl_realloc((void **)out_buf, mutated_size); if (unlikely(!mutated_out)) { - + *out_buf = NULL; return 0; - + } - /* - *out_buf = buf; - return buf_size; - */ memcpy(mutated_out, output.data(), mutated_size); *out_buf = mutated_out; DEBUG(stderr, "MUTATED to %u bytes:\n%s\n---\n", mutated_size, mutated_out); @@ -113,29 +126,106 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, uint8_t *buf, size_t buf_s } - /* We are not using afl_custom_queue_new_entry() because not every corpus entry will be necessarily fuzzed. so we use afl_custom_queue_get() instead */ extern "C" unsigned char afl_custom_queue_get(void *data, const unsigned char *filename) { - if (likely(!debug)) - if (!afl_ptr->queue_cur->is_ascii) { s = NULL; return 0; } + if (likely(!debug)) { + + if (afl_ptr->shm.cmplog_mode && !afl_ptr->queue_cur->is_ascii) { + + s = NULL; + return 0; + + } + + } + + // check if there are new dictionary entries and add them to the tokens + if (valid_structures) { + + while (extras_cnt < afl_ptr->extras_cnt) { + + u32 ok = 1, l = afl_ptr->extras[extras_cnt].len; + u8 *ptr = afl_ptr->extras[extras_cnt].data; + + for (u32 i = 0; i < l; ++i) { + + if (!isascii((int)ptr[i]) && !isprint((int)ptr[i])) { + + ok = 0; + break; + + } + + } + + if (ok) { + + ++current_id; + token_to_id[(char *)ptr] = current_id; + id_to_token[current_id] = (char *)ptr; + + } + + ++extras_cnt; + DEBUG(stderr, "Added from dictionary: \"%s\"\n", ptr); + + } + + while (a_extras_cnt < afl_ptr->a_extras_cnt) { + + u32 ok = 1, l = afl_ptr->a_extras[a_extras_cnt].len; + u8 *ptr = afl_ptr->a_extras[a_extras_cnt].data; + + for (u32 i = 0; i < l; ++i) { + + if (!isascii((int)ptr[i]) && !isprint((int)ptr[i])) { + + ok = 0; + break; + + } + + } + + if (ok) { + + ++current_id; + token_to_id[(char *)ptr] = current_id; + id_to_token[current_id] = (char *)ptr; + + } + + ++a_extras_cnt; + DEBUG(stderr, "Added from auto dictionary: \"%s\"\n", ptr); + + } + + } vector *structure = NULL; string fn = (char *)filename; + auto entry = file_mapping.find(fn); - auto entry = file_mapping.find(fn); if (entry == file_mapping.end()) { // this input file was not analyzed for tokens yet, so let's do it! FILE *fp = fopen((char *)filename, "rb"); - if (!fp) { s = NULL; return 0; } // should not happen + if (!fp) { + + s = NULL; + return 0; + + } // should not happen + fseek(fp, 0, SEEK_END); size_t len = (size_t)ftell(fp); - if (len < AUTOTOKENS_LEN_MIN) { + + if (len < AFL_TXT_MIN_LEN) { fclose(fp); file_mapping[fn] = structure; // NULL ptr so we don't read the file again @@ -151,6 +241,30 @@ extern "C" unsigned char afl_custom_queue_get(void *data, fread(input.data(), input.size(), 1, fp); fclose(fp); + if (!afl_ptr->shm.cmplog_mode) { + + // not running with CMPLOG? bad choice, but whatever ... + // we only want text inputs, so we have to check it ourselves. + + u32 valid_chars = 0; + for (u32 i = 0; i < len; ++i) { + + if (isascii((int)input[i]) || isprint((int)input[i])) { ++valid_chars; } + + } + + // we want at least 95% of text characters ... + if (((len * AFL_TXT_MIN_PERCENT) / 100) > valid_chars) { + + file_mapping[fn] = NULL; + DEBUG(stderr, "Not text (%lu) %s\n", len, filename); + s = NULL; + return 0; + + } + + } + // DEBUG(stderr, "Read %lu bytes for %s\nBefore comment trim:\n%s\n", // input.size(), filename, input.c_str()); @@ -175,7 +289,6 @@ extern "C" unsigned char afl_custom_queue_get(void *data, string::const_iterator cur = input.begin(), ende = input.end(), last = cur, found, prev; - DEBUG(stderr, "MATCHES:\n"); while (regex_search(cur, ende, match, regex_string)) { prev = cur; @@ -196,11 +309,12 @@ extern "C" unsigned char afl_custom_queue_get(void *data, DEBUG(stderr, "tokens: %lu input size: %lu\n", tokenized.size(), input.size()); - for (auto x : tokenized) { + if (unlikely(debug)) + for (auto x : tokenized) { - cerr << x << endl; + cerr << x << endl; - } + } for (auto token : tokenized) { @@ -232,8 +346,13 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (c < e) { - string foo(c, e); - DEBUG(stderr, "after string: \"%s\"\n", foo.c_str()); + if (unlikely(debug)) { + + string foo(c, e); + DEBUG(stderr, "after string: \"%s\"\n", foo.c_str()); + + } + tokens.push_back(std::string(c, e)); } @@ -248,8 +367,6 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (cur < ende) { - DEBUG(stderr, "REST!\n"); - sregex_token_iterator it{cur, ende, regex_whitespace, -1}; vector tokenized{it, {}}; tokenized.erase( @@ -260,11 +377,12 @@ extern "C" unsigned char afl_custom_queue_get(void *data, DEBUG(stderr, "tokens: %lu input size: %lu\n", tokenized.size(), input.size()); - for (auto x : tokenized) { + if (unlikely(debug)) + for (auto x : tokenized) { - cerr << x << endl; + cerr << x << endl; - } + } for (auto token : tokenized) { @@ -279,8 +397,13 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (p < f) { // there are items between search start and find - string foo(p, f); - DEBUG(stderr, "before string: \"%s\"\n", foo.c_str()); + if (unlikely(debug)) { + + string foo(p, f); + DEBUG(stderr, "before string: \"%s\"\n", foo.c_str()); + + } + tokens.push_back(std::string(p, f)); } @@ -296,8 +419,13 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (c < e) { - string foo(c, e); - DEBUG(stderr, "after string: \"%s\"\n", foo.c_str()); + if (unlikely(debug)) { + + string foo(c, e); + DEBUG(stderr, "after string: \"%s\"\n", foo.c_str()); + + } + tokens.push_back(std::string(c, e)); } @@ -306,15 +434,18 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - DEBUG(stderr, "DUMPING TOKENS:\n"); - if (unlikely(debug)) + if (unlikely(debug)) { + + DEBUG(stderr, "DUMPING TOKENS:\n"); for (u32 i = 0; i < tokens.size(); ++i) { DEBUG(stderr, "%s ", tokens[i].c_str()); } - DEBUG(stderr, "---------------------------\n"); + DEBUG(stderr, "---------------------------\n"); + + } /* Now we transform the tokens into an ID list and saved that */ @@ -342,6 +473,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, // save the token structure to the file mapping file_mapping[fn] = structure; s = structure; + ++valid_structures; // we are done! DEBUG(stderr, "DONE! We have %lu tokens in the structure\n", diff --git a/include/config.h b/include/config.h index a5a4c473..6cfaac11 100644 --- a/include/config.h +++ b/include/config.h @@ -494,7 +494,7 @@ /* What is the minimum percentage of ascii characters present to be classifed as "is_ascii"? */ -#define AFL_TXT_MIN_PERCENT 94 +#define AFL_TXT_MIN_PERCENT 95 /* How often to perform ASCII mutations 0 = disable, 1-8 are good values */ -- cgit 1.4.1 From 33f41e3974348d3b0b71b3a30a6483bb0418068c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 17 Jan 2023 09:52:35 +0100 Subject: autotokens: print stats at exit --- custom_mutators/autotokens/README | 7 ++++--- custom_mutators/autotokens/autotokens.cpp | 12 ++++++++++++ include/config.h | 4 ++-- 3 files changed, 18 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/custom_mutators/autotokens/README b/custom_mutators/autotokens/README index 6849279e..0dcc6a3e 100644 --- a/custom_mutators/autotokens/README +++ b/custom_mutators/autotokens/README @@ -1,6 +1,6 @@ # autotokens -This implements an improved autotoken idea presented in +This implements an improved autotoken grammar fuzzing idea presented in [Token-Level Fuzzing][https://www.usenix.org/system/files/sec21-salls.pdf]. It is a grammar fuzzer without actually knowing the grammar. @@ -8,5 +8,6 @@ It is recommended to run with together in an instance with `CMPLOG`. If you have a dictionary (`-x`) this improves this custom grammar mutator. -If **not** run with `CMPLOG`, it is possible to set `AFL_CUSTOM_MUTATOR_ONLY`, -to concentrate on grammar bug classes. +If **not** running with `CMPLOG`, it is possible to set +`AFL_CUSTOM_MUTATOR_ONLY` to concentrate on grammar bug classes. + diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index 850692a1..d6b269fd 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -35,6 +35,7 @@ static u32 valid_structures; static u32 whitespace_ids; static u32 extras_cnt, a_extras_cnt; static u64 all_spaces, all_tabs, all_lf, all_ws; +static u64 all_structure_items; static unordered_map *> file_mapping; static unordered_map token_to_id; static unordered_map id_to_token; @@ -519,6 +520,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, file_mapping[fn] = structure; s = structure; ++valid_structures; + all_structure_items += structure->size(); // we are done! DEBUG(stderr, "DONE! We have %lu tokens in the structure\n", @@ -586,6 +588,16 @@ extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) { extern "C" void afl_custom_deinit(my_mutator_t *data) { + /* we use this to print statistics at exit :-) + needs to be stderr as stdout is filtered */ + + fprintf(stderr, + "\n\nAutotoken mutator statistics:\n" + " Number of all seen tokens: %lu\n" + " Number of input structures: %lu\n" + " Number of all items in structures: %lu\n\n", + current_id - 1, valid_structures, all_structure_items); + free(data); } diff --git a/include/config.h b/include/config.h index 6cfaac11..f8a742f2 100644 --- a/include/config.h +++ b/include/config.h @@ -364,9 +364,9 @@ * * ***********************************************************/ -/* Call count interval between reseeding the libc PRNG from /dev/urandom: */ +/* Call count interval between reseeding the PRNG from /dev/urandom: */ -#define RESEED_RNG 100000 +#define RESEED_RNG 2500000 /* The default maximum testcase cache size in MB, 0 = disable. A value between 50 and 250 is a good default value. Note that the -- cgit 1.4.1 From 8fe5e29104fc514551bbc926c5142dac68562b43 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 18 Jan 2023 14:56:26 +0100 Subject: ignore timeout env option --- docs/env_variables.md | 3 +++ include/afl-fuzz.h | 2 +- include/envs.h | 1 + src/afl-fuzz-bitmap.c | 6 ++++++ src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz.c | 3 ++- 6 files changed, 20 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/docs/env_variables.md b/docs/env_variables.md index 22a5c386..0a57d190 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -354,6 +354,9 @@ checks or alter some of the more exotic semantics of the tool: - Setting `AFL_KEEP_TIMEOUTS` will keep longer running inputs if they reach new coverage + - On the contrary, if you are not interested in any timeouts, you can set + `AFL_IGNORE_TIMEOUTS` to get a bit of speed instead. + - `AFL_EXIT_ON_SEED_ISSUES` will restore the vanilla afl-fuzz behavior which does not allow crashes or timeout seeds in the initial -i corpus. diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index edef9207..69fea579 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -398,7 +398,7 @@ typedef struct afl_env_vars { afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme, - afl_no_startup_calibration; + afl_ignore_timeouts, afl_no_startup_calibration; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, diff --git a/include/envs.h b/include/envs.h index f4cdf390..0770f94d 100644 --- a/include/envs.h +++ b/include/envs.h @@ -103,6 +103,7 @@ static char *afl_environment_variables[] = { "AFL_HARDEN", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IGNORE_PROBLEMS", + "AFL_IGNORE_TIMEOUTS", "AFL_IGNORE_UNKNOWN_ENVS", "AFL_IMPORT_FIRST", "AFL_INPUT_LEN_MIN", diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 485b82db..b4e9537e 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -457,6 +457,12 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(len == 0)) { return 0; } + if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) { + + return 0; + + } + u8 fn[PATH_MAX]; u8 *queue_fn = ""; u8 new_bits = 0, keeping = 0, res, classified = 0, is_timeout = 0; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 896b5f71..104b1e4b 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -292,6 +292,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_ignore_problems = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_IGNORE_TIMEOUTS", + + afl_environment_variable_len)) { + + afl->afl_env.afl_ignore_timeouts = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", afl_environment_variable_len)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 5e0ecd1e..4db55b5e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -258,8 +258,9 @@ static void usage(u8 *argv0, int more_help) { "AFL_FORKSRV_INIT_TMOUT: time spent waiting for forkserver during startup (in ms)\n" "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" - "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n" + "AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n" + "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" "AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n" "AFL_PIZZA_MODE: 1 - enforce pizza mode, 0 - disable for April 1st\n" -- cgit 1.4.1 From 14d8eb9e40a6329abcb2f153174b543349c68c13 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 18 Jan 2023 22:17:14 +0100 Subject: autotoken: splicing; splice_optout --- custom_mutators/autotokens/Makefile | 6 +- custom_mutators/autotokens/autotokens.cpp | 103 +++++++++++++++++++++++++++--- docs/custom_mutators.md | 11 ++++ include/afl-fuzz.h | 14 ++++ src/afl-fuzz-mutators.c | 13 ++++ src/afl-fuzz-one.c | 3 +- src/afl-fuzz-python.c | 16 +++++ 7 files changed, 155 insertions(+), 11 deletions(-) (limited to 'include') diff --git a/custom_mutators/autotokens/Makefile b/custom_mutators/autotokens/Makefile index 8af63635..ab1da4b6 100644 --- a/custom_mutators/autotokens/Makefile +++ b/custom_mutators/autotokens/Makefile @@ -1,5 +1,9 @@ ifdef debug - CFLAGS += "-fsanitize=address -Wall" + CFLAGS += -fsanitize=address -Wall + CXX := clang++ +endif +ifdef DEBUG + CFLAGS += -fsanitize=address -Wall CXX := clang++ endif diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index 7aecb010..c9ec4352 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -19,6 +19,13 @@ extern "C" { #define AUTOTOKENS_ALTERNATIVE_TOKENIZE 0 #define AUTOTOKENS_CHANGE_MIN 8 #define AUTOTOKENS_WHITESPACE " " +#define AUTOTOKENS_SIZE_MIN 8 +#define AUTOTOKENS_SPLICE_MIN 4 +#define AUTOTOKENS_SPLICE_MAX 64 + +#if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN + #error SPLICE_MIN must be lower than SIZE_MIN +#endif using namespace std; @@ -42,6 +49,7 @@ static u32 extras_cnt, a_extras_cnt; static u64 all_spaces, all_tabs, all_lf, all_ws; static u64 all_structure_items; static unordered_map *> file_mapping; +static unordered_map *> id_mapping; static unordered_map token_to_id; static unordered_map id_to_token; static string whitespace = AUTOTOKENS_WHITESPACE; @@ -76,6 +84,8 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, u8 **out_buf, u8 *add_buf, size_t add_buf_size, size_t max_size) { + (void)(data); + if (s == NULL) { *out_buf = NULL; @@ -92,14 +102,14 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, afl_ptr->havoc_div / 256)); // DEBUG(stderr, "structure size: %lu, rounds: %u \n", m.size(), rounds); - u32 max_rand = 7; + u32 max_rand = 14; for (i = 0; i < rounds; ++i) { switch (rand_below(afl_ptr, max_rand)) { /* CHANGE */ - case 0 ... 3: /* fall through */ + case 0 ... 7: /* fall through */ { u32 pos = rand_below(afl_ptr, m_size); @@ -122,18 +132,19 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, } /* INSERT (m_size +1 so we insert also after last place) */ - case 4 ... 5: { + case 8 ... 9: { u32 new_item; do { new_item = rand_below(afl_ptr, current_id); - } while (!alternative_tokenize && new_item >= whitespace_ids); + } while (unlikely(!alternative_tokenize && new_item >= whitespace_ids)); u32 pos = rand_below(afl_ptr, m_size + 1); m.insert(m.begin() + pos, new_item); ++m_size; + DEBUG(stderr, "INS: %u at %u\n", new_item, pos); if (likely(!alternative_tokenize)) { @@ -168,8 +179,63 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, } + /* SPLICING */ + case 10 ... 11: { + + u32 strategy = rand_below(afl_ptr, 4), dst_off, n; + auto src = id_mapping[rand_below(afl_ptr, valid_structures)]; + u32 src_size = src->size(); + u32 src_off = rand_below(afl_ptr, src_size - AUTOTOKENS_SPLICE_MIN); + u32 rand_r = 1 + MAX(AUTOTOKENS_SPLICE_MIN, + MIN(AUTOTOKENS_SPLICE_MAX, src_size - src_off)); + + switch (strategy) { + + // insert + case 0: { + + dst_off = rand_below(afl_ptr, m_size); + n = AUTOTOKENS_SPLICE_MIN + + rand_below(afl_ptr, MIN(AUTOTOKENS_SPLICE_MAX, + rand_r - AUTOTOKENS_SPLICE_MIN)); + m.insert(m.begin() + dst_off, src->begin() + src_off, + src->begin() + src_off + n); + m_size += n; + DEBUG(stderr, "SPLICE-INS: %u at %u\n", n, dst_off); + break; + + } + + // overwrite + default: { + + dst_off = rand_below(afl_ptr, m_size - AUTOTOKENS_SPLICE_MIN); + n = AUTOTOKENS_SPLICE_MIN + + rand_below( + afl_ptr, + MIN(AUTOTOKENS_SPLICE_MAX - AUTOTOKENS_SPLICE_MIN, + MIN(m_size - dst_off - AUTOTOKENS_SPLICE_MIN, + src_size - src_off - AUTOTOKENS_SPLICE_MIN))); + + for (u32 i = 0; i < n; ++i) { + + m[dst_off + i] = (*src)[src_off + i]; + + } + + DEBUG(stderr, "SPLICE-MUT: %u at %u\n", n, dst_off); + break; + + } + + } + + break; + + } + /* ERASE - only if large enough */ - case 6: { + case 12 ... 13: { if (m_size > 8) { @@ -178,7 +244,7 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, } else { - max_rand = 6; + max_rand = 12; } @@ -236,12 +302,15 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, extern "C" unsigned char afl_custom_queue_get(void *data, const unsigned char *filename) { + (void)(data); + if (likely(!debug)) { if ((afl_ptr->shm.cmplog_mode && !afl_ptr->queue_cur->is_ascii) || (only_fav && !afl_ptr->queue_cur->favored)) { s = NULL; + DEBUG(stderr, "cmplog not ascii or only_fav and not favorite\n"); return 0; } @@ -334,8 +403,8 @@ extern "C" unsigned char afl_custom_queue_get(void *data, fclose(fp); file_mapping[fn] = structure; // NULL ptr so we don't read the file again - DEBUG(stderr, "Too short (%lu) %s\n", len, filename); s = NULL; + DEBUG(stderr, "Too short (%lu) %s\n", len, filename); return 0; } @@ -362,8 +431,8 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (((len * AFL_TXT_MIN_PERCENT) / 100) > valid_chars) { file_mapping[fn] = NULL; - DEBUG(stderr, "Not text (%lu) %s\n", len, filename); s = NULL; + DEBUG(stderr, "Not text (%lu) %s\n", len, filename); return 0; } @@ -766,6 +835,15 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } + if (tokens.size() < AUTOTOKENS_SIZE_MIN) { + + file_mapping[fn] = NULL; + s = NULL; + DEBUG(stderr, "too few tokens\n"); + return 0; + + } + /* Now we transform the tokens into an ID list and saved that */ structure = new vector(); @@ -791,8 +869,9 @@ extern "C" unsigned char afl_custom_queue_get(void *data, // save the token structure to the file mapping file_mapping[fn] = structure; - s = structure; + id_mapping[valid_structures] = structure; ++valid_structures; + s = structure; all_structure_items += structure->size(); // we are done! @@ -897,6 +976,12 @@ extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) { } +extern "C" void afl_custom_splice_optout(my_mutator_t *data) { + + (void)(data); + +} + extern "C" void afl_custom_deinit(my_mutator_t *data) { /* we use this to print statistics at exit :-) diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 4ffeda7a..322caa5b 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -48,6 +48,7 @@ C/C++: ```c void *afl_custom_init(afl_state_t *afl, unsigned int seed); unsigned int afl_custom_fuzz_count(void *data, const unsigned char *buf, size_t buf_size); +void afl_custom_splice_optout(void *data); size_t afl_custom_fuzz(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf, unsigned char *add_buf, size_t add_buf_size, size_t max_size); const char *afl_custom_describe(void *data, size_t max_description_len); size_t afl_custom_post_process(void *data, unsigned char *buf, size_t buf_size, unsigned char **out_buf); @@ -72,6 +73,9 @@ def init(seed): def fuzz_count(buf): return cnt +def splice_optout() + pass + def fuzz(buf, add_buf, max_size): return mutated_out @@ -132,6 +136,13 @@ def deinit(): # optional for Python for a specific queue entry, use this function. This function is most useful if `AFL_CUSTOM_MUTATOR_ONLY` is **not** used. +- `splice_optout` (optional): + + If this function is present, no splicing target is passed to the `fuzz` + function. This saves time if splicing data is not needed by the custom + fuzzing function. + This function is never called, just needs to be present to activate. + - `fuzz` (optional): This method performs custom mutations on a given input. It also accepts an diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 69fea579..1e8d085d 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -344,6 +344,7 @@ enum { /* 12 */ PY_FUNC_INTROSPECTION, /* 13 */ PY_FUNC_DESCRIBE, /* 14 */ PY_FUNC_FUZZ_SEND, + /* 15 */ PY_FUNC_SPLICE_OPTOUT, PY_FUNC_COUNT }; @@ -495,6 +496,7 @@ typedef struct afl_state { no_unlink, /* do not unlink cur_input */ debug, /* Debug mode */ custom_only, /* Custom mutator only mode */ + custom_splice_optout, /* Custom mutator no splice buffer */ is_main_node, /* if this is the main node */ is_secondary_node, /* if this is a secondary instance */ pizza_is_served; /* pizza mode */ @@ -828,6 +830,17 @@ struct custom_mutator { */ u32 (*afl_custom_fuzz_count)(void *data, const u8 *buf, size_t buf_size); + /** + * Opt-out of a splicing input for the fuzz mutator + * + * Empty dummy function. It's presence tells afl-fuzz not to pass a + * splice data pointer and len. + * + * @param data pointer returned in afl_custom_init by this custom mutator + * @noreturn + */ + void (*afl_custom_splice_optout)(void *data); + /** * Perform custom mutations on a given input * @@ -1057,6 +1070,7 @@ u8 havoc_mutation_probability_py(void *); u8 queue_get_py(void *, const u8 *); const char *introspection_py(void *); u8 queue_new_entry_py(void *, const u8 *, const u8 *); +void splice_optout(void *); void deinit_py(void *); #endif diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index 22e5262e..ce43064a 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -358,6 +358,19 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { } + /* "afl_custom_splice_optout", optional, never called */ + mutator->afl_custom_splice_optout = dlsym(dh, "afl_custom_splice_optout"); + if (!mutator->afl_custom_splice_optout) { + + ACTF("optional symbol 'afl_custom_splice_optout' not found."); + + } else { + + OKF("Found 'afl_custom_splice_optout'."); + afl->custom_splice_optout = 1; + + } + /* "afl_custom_fuzz_send", optional */ mutator->afl_custom_fuzz_send = dlsym(dh, "afl_custom_fuzz_send"); if (!mutator->afl_custom_fuzz_send) { diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index eaf65987..5e352dcb 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1954,7 +1954,8 @@ custom_mutator_stage: u32 target_len = 0; /* check if splicing makes sense yet (enough entries) */ - if (likely(afl->ready_for_splicing_count > 1)) { + if (likely(!afl->custom_splice_optout && + afl->ready_for_splicing_count > 1)) { /* Pick a random other queue entry for passing to external API that has the necessary length */ diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index b509b936..69c305f7 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -248,6 +248,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "queue_get"); py_functions[PY_FUNC_FUZZ_SEND] = PyObject_GetAttrString(py_module, "fuzz_send"); + py_functions[PY_FUNC_SPLICE_OPTOUT] = + PyObject_GetAttrString(py_module, "splice_optout"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); py_functions[PY_FUNC_INTROSPECTION] = @@ -394,6 +396,13 @@ void deinit_py(void *py_mutator) { } +void splice_optout_py(void *py_mutator) { + + // this is never called + (void)(py_mutator); + +} + struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, char *module_name) { @@ -474,6 +483,13 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, } + if (py_functions[PY_FUNC_SPLICE_OPTOUT]) { + + mutator->afl_custom_splice_optout = splice_optout_py; + afl->custom_splice_optout = 1; + + } + if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) { mutator->afl_custom_queue_new_entry = queue_new_entry_py; -- cgit 1.4.1 From eeca3a0b2939c605497e9b3a615ee4a466f4a3f2 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 19 Jan 2023 11:52:19 +0100 Subject: lots of fixes --- custom_mutators/autotokens/TODO | 2 +- custom_mutators/autotokens/autotokens.cpp | 424 +++++++++++++++++++----------- docs/custom_mutators.md | 1 + include/afl-fuzz.h | 11 +- src/afl-fuzz-one.c | 3 +- 5 files changed, 279 insertions(+), 162 deletions(-) (limited to 'include') diff --git a/custom_mutators/autotokens/TODO b/custom_mutators/autotokens/TODO index 95b79373..2e39511c 100644 --- a/custom_mutators/autotokens/TODO +++ b/custom_mutators/autotokens/TODO @@ -3,4 +3,4 @@ cmplog: only add tokens that were found to fit? create from thin air if no good seed after a cycle and dict large enough? (static u32 no_of_struct_inputs;) -splicing -> check if whitespace/token is needed \ No newline at end of file +splicing -> check if whitespace/token is needed diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index 4f3289c9..102bea0f 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -38,8 +38,10 @@ typedef struct my_mutator { } my_mutator_t; -#define DEBUG \ +#undef DEBUGF +#define DEBUGF \ if (unlikely(debug)) fprintf +#define IFDEBUG if (unlikely(debug)) static afl_state *afl_ptr; static int debug = AUTOTOKENS_DEBUG; @@ -57,12 +59,12 @@ static unordered_map *> id_mapping; static unordered_map token_to_id; static unordered_map id_to_token; static string whitespace = AUTOTOKENS_WHITESPACE; +static string output; static regex *regex_comment_custom; -static regex regex_comment_star("/\\*([:print:]|\n)*?\\*/", - regex::multiline | regex::optimize); -static regex regex_word("[A-Za-z0-9_$.-]+", regex::optimize); -static regex regex_whitespace(R"([ \t]+)", regex::optimize); -static regex regex_string("\"[[:print:]]*?\"|'[[:print:]]*?'", regex::optimize); +static regex regex_comment_star("/\\*([:print:]|\n)*?\\*/", + regex::multiline | regex::optimize); +static regex regex_word("[A-Za-z0-9_$.-]+", regex::optimize); +static regex regex_whitespace(R"([ \t]+)", regex::optimize); static vector *s; // the structure of the currently selected input u32 good_whitespace_or_singleval() { @@ -104,7 +106,7 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, MAX(AUTOTOKENS_CHANGE_MIN, MIN(m_size >> 3, HAVOC_CYCLES * afl_ptr->queue_cur->perf_score * afl_ptr->havoc_div / 256)); - // DEBUG(stderr, "structure size: %lu, rounds: %u \n", m.size(), rounds); + // DEBUGF(stderr, "structure size: %lu, rounds: %u \n", m.size(), rounds); #if AUTOTOKENS_SPLICE_DISABLE == 1 #define AUTOTOKENS_MUT_MAX 12 @@ -112,7 +114,7 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, #define AUTOTOKENS_MUT_MAX 14 #endif - u32 max_rand = AUTOTOKENS_MUT_MAX; + u32 max_rand = AUTOTOKENS_MUT_MAX, new_item, pos; for (i = 0; i < rounds; ++i) { @@ -122,8 +124,8 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, case 0 ... 7: /* fall through */ { - u32 pos = rand_below(afl_ptr, m_size); - u32 cur_item = m[pos], new_item; + pos = rand_below(afl_ptr, m_size); + u32 cur_item = m[pos]; do { new_item = rand_below(afl_ptr, current_id); @@ -135,7 +137,7 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, ((whitespace_ids < new_item && whitespace_ids >= cur_item) || (whitespace_ids >= new_item && whitespace_ids < cur_item))))); - DEBUG(stderr, "MUT: %u -> %u\n", cur_item, new_item); + DEBUGF(stderr, "MUT: %u -> %u\n", cur_item, new_item); m[pos] = new_item; break; @@ -144,7 +146,6 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, /* INSERT (m_size +1 so we insert also after last place) */ case 8 ... 9: { - u32 new_item; do { new_item = rand_below(afl_ptr, current_id); @@ -154,7 +155,7 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, u32 pos = rand_below(afl_ptr, m_size + 1); m.insert(m.begin() + pos, new_item); ++m_size; - DEBUG(stderr, "INS: %u at %u\n", new_item, pos); + DEBUGF(stderr, "INS: %u at %u\n", new_item, pos); if (likely(!alternative_tokenize)) { @@ -212,7 +213,8 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, m.insert(m.begin() + dst_off, src->begin() + src_off, src->begin() + src_off + n); m_size += n; - DEBUG(stderr, "SPLICE-INS: %u at %u\n", n, dst_off); + DEBUGF(stderr, "SPLICE-INS: %u at %u\n", n, dst_off); + break; } @@ -231,13 +233,36 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, copy(src->begin() + src_off, src->begin() + src_off + n, m.begin() + dst_off); - DEBUG(stderr, "SPLICE-MUT: %u at %u\n", n, dst_off); + DEBUGF(stderr, "SPLICE-MUT: %u at %u\n", n, dst_off); break; } } + if (likely(!alternative_tokenize)) { + + // do we need a whitespace/token at the beginning? + if (dst_off && id_to_token[m[dst_off - 1]].size() > 1 && + id_to_token[m[dst_off]].size() > 1) { + + m.insert(m.begin() + dst_off, good_whitespace_or_singleval()); + ++m_size; + + } + + // do we need a whitespace/token at the end? + if (dst_off + n < m_size && + id_to_token[m[dst_off + n - 1]].size() > 1 && + id_to_token[m[dst_off + n]].size() > 1) { + + m.insert(m.begin() + dst_off + n, good_whitespace_or_singleval()); + ++m_size; + + } + + } + break; } @@ -249,11 +274,32 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, if (m_size > 8) { - m.erase(m.begin() + rand_below(afl_ptr, m_size)); - --m_size; + do { + + pos = rand_below(afl_ptr, m_size); + + } while (unlikely(pos < whitespace_ids)); + + // if what we delete will result in a missing whitespace/token, + // instead of deleting we switch the item to a whitespace or token. + if (likely(!alternative_tokenize) && pos && pos < m_size && + id_to_token[m[pos - 1]].size() > 1 && + id_to_token[m[pos + 1]].size() > 1) { + + m[pos] = good_whitespace_or_singleval(); + + } else { + + m.erase(m.begin() + pos); + --m_size; + + } } else { + // if the data is already too small do not try to make it smaller + // again this run. + max_rand = AUTOTOKENS_MUT_MAX - 2; } @@ -262,14 +308,12 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, } - // TODO: add full line insert splice, replace splace, delete - } } - string output; - u32 m_size_1 = m_size - 1; + u32 m_size_1 = m_size - 1; + output = ""; for (i = 0; i < m_size; ++i) { @@ -282,31 +326,108 @@ extern "C" size_t afl_custom_fuzz(my_mutator_t *data, u8 *buf, size_t buf_size, } - u32 mutated_size = output.size(); - u8 *mutated_out = (u8 *)afl_realloc((void **)out_buf, mutated_size); + u32 mutated_size = (u32)output.size(); + u8 *mutated_out = (u8 *)output.data(); - if (unlikely(!mutated_out)) { + if (unlikely(mutated_size > max_size)) { mutated_size = max_size; } - *out_buf = NULL; - return 0; - - } - - if (unlikely(debug)) { + IFDEBUG { - DEBUG(stderr, "MUTATED to %u bytes:\n", mutated_size); + DEBUGF(stderr, "MUTATED to %u bytes:\n", mutated_size); fwrite(output.data(), 1, mutated_size, stderr); - DEBUG(stderr, "\n---\n"); + DEBUGF(stderr, "\n---\n"); } - memcpy(mutated_out, output.data(), mutated_size); *out_buf = mutated_out; ++fuzz_count; return mutated_size; } +/* I get f*cking stack overflow using C++ regex with a regex of + "\"[[:print:]]*?\"" if this matches a long string even with regex::optimize + enabled :-( */ +u8 my_search_string(string::const_iterator cur, string::const_iterator ende, + string::const_iterator *match_begin, + string::const_iterator *match_end) { + + string::const_iterator start = cur, found_begin; + u8 quote_type = 0; + + while (cur < ende) { + + switch (*cur) { + + case '"': { + + if (cur == start || *(cur - 1) != '\\') { + + if (!quote_type) { + + found_begin = cur; + quote_type = 1; + + } else if (quote_type == 1) { + + *match_begin = found_begin; + *match_end = cur + 1; + return 1; + + } + + } + + break; + + } + + case '\'': { + + if (cur == start || *(cur - 1) != '\\') { + + if (!quote_type) { + + found_begin = cur; + quote_type = 2; + + } else if (quote_type == 2) { + + *match_begin = found_begin; + *match_end = cur + 1; + return 1; + + } + + } + + break; + + } + + case '\n': + case '\r': + case 0: { + + quote_type = 0; + break; + + } + + default: + if (unlikely(quote_type && !isprint(*cur))) { quote_type = 0; } + break; + + } + + ++cur; + + } + + return 0; + +} + /* We are not using afl_custom_queue_new_entry() because not every corpus entry will be necessarily fuzzed. so we use afl_custom_queue_get() instead */ @@ -321,7 +442,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, (only_fav && !afl_ptr->queue_cur->favored)) { s = NULL; - DEBUG(stderr, "cmplog not ascii or only_fav and not favorite\n"); + DEBUGF(stderr, "cmplog not ascii or only_fav and not favorite\n"); return 0; } @@ -356,7 +477,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } ++extras_cnt; - DEBUG(stderr, "Added from dictionary: \"%s\"\n", ptr); + DEBUGF(stderr, "Added from dictionary: \"%s\"\n", ptr); } @@ -385,7 +506,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } ++a_extras_cnt; - DEBUG(stderr, "Added from auto dictionary: \"%s\"\n", ptr); + DEBUGF(stderr, "Added from auto dictionary: \"%s\"\n", ptr); } @@ -415,7 +536,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, fclose(fp); file_mapping[fn] = structure; // NULL ptr so we don't read the file again s = NULL; - DEBUG(stderr, "Too short (%lu) %s\n", len, filename); + DEBUGF(stderr, "Too short (%lu) %s\n", len, filename); return 0; } @@ -443,14 +564,14 @@ extern "C" unsigned char afl_custom_queue_get(void *data, file_mapping[fn] = NULL; s = NULL; - DEBUG(stderr, "Not text (%lu) %s\n", len, filename); + DEBUGF(stderr, "Not text (%lu) %s\n", len, filename); return 0; } } - // DEBUG(stderr, "Read %lu bytes for %s\nBefore comment trim:\n%s\n", + // DEBUGF(stderr, "Read %lu bytes for %s\nBefore comment trim:\n%s\n", // input.size(), filename, input.c_str()); if (regex_comment_custom) { @@ -463,15 +584,15 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - DEBUG(stderr, "After replace %lu bytes for %s\n%s\n", input.size(), - filename, input.c_str()); + DEBUGF(stderr, "After replace %lu bytes for %s\n%s\n", input.size(), + filename, input.c_str()); u32 spaces = count(input.begin(), input.end(), ' '); u32 tabs = count(input.begin(), input.end(), '\t'); u32 linefeeds = count(input.begin(), input.end(), '\n'); bool ends_with_linefeed = input[input.length() - 1] == '\n'; - DEBUG(stderr, "spaces=%u tabs=%u linefeeds=%u ends=%u\n", spaces, tabs, - linefeeds, ends_with_linefeed); + DEBUGF(stderr, "spaces=%u tabs=%u linefeeds=%u ends=%u\n", spaces, tabs, + linefeeds, ends_with_linefeed); all_spaces += spaces; all_tabs += tabs; all_lf += linefeeds; @@ -479,25 +600,28 @@ extern "C" unsigned char afl_custom_queue_get(void *data, // now extract all tokens vector tokens; - smatch match; - string::const_iterator cur = input.begin(), ende = input.end(), found, prev; + string::const_iterator cur = input.begin(), ende = input.end(), found, prev, + match_begin, match_end; - DEBUG(stderr, "START!\n"); + DEBUGF(stderr, "START!\n"); if (likely(!alternative_tokenize)) { - while (regex_search(cur, ende, match, regex_string, - regex_constants::match_any | - regex_constants::match_not_null | - regex_constants::match_continuous)) { + while (my_search_string(cur, ende, &match_begin, &match_end)) { prev = cur; - found = match[0].first; - cur = match[0].second; - DEBUG(stderr, - "string %s found at start %lu offset %lu continue at %lu\n", - match[0].str().c_str(), prev - input.begin(), match.position(), - cur - input.begin()); + found = match_begin; + cur = match_end; + + IFDEBUG { + + string foo(match_begin, match_end); + DEBUGF(stderr, + "string %s found at start %lu offset %lu continue at %lu\n", + foo.c_str(), prev - input.begin(), found - prev, + cur - input.begin()); + + } if (prev < found) { // there are items between search start and find while (prev < found) { @@ -512,8 +636,8 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } tokens.push_back(std::string(start, prev)); - DEBUG(stderr, "WHITESPACE %ld \"%s\"\n", prev - start, - tokens[tokens.size() - 1].c_str()); + DEBUGF(stderr, "WHITESPACE %ld \"%s\"\n", prev - start, + tokens[tokens.size() - 1].c_str()); } else if (isalnum(*prev) || *prev == '$' || *prev == '_') { @@ -525,14 +649,14 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - tokens.push_back(std::string(start, prev)); - DEBUG(stderr, "IDENTIFIER %ld \"%s\"\n", prev - start, - tokens[tokens.size() - 1].c_str()); + tokens.push_back(string(start, prev)); + DEBUGF(stderr, "IDENTIFIER %ld \"%s\"\n", prev - start, + tokens[tokens.size() - 1].c_str()); } else { - tokens.push_back(std::string(prev, prev + 1)); - DEBUG(stderr, "OTHER \"%c\"\n", *prev); + tokens.push_back(string(prev, prev + 1)); + DEBUGF(stderr, "OTHER \"%c\"\n", *prev); ++prev; } @@ -541,11 +665,12 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - if (match[0].length() > 0) { tokens.push_back(match[0]); } + tokens.push_back(string(match_begin, match_end)); + DEBUGF(stderr, "TOK: %s\n", tokens[tokens.size() - 1].c_str()); } - DEBUG(stderr, "AFTER all strings\n"); + DEBUGF(stderr, "AFTER all strings\n"); if (cur < ende) { @@ -561,8 +686,8 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } tokens.push_back(std::string(start, cur)); - DEBUG(stderr, "WHITESPACE %ld \"%s\"\n", cur - start, - tokens[tokens.size() - 1].c_str()); + DEBUGF(stderr, "WHITESPACE %ld \"%s\"\n", cur - start, + tokens[tokens.size() - 1].c_str()); } else if (isalnum(*cur) || *cur == '$' || *cur == '_') { @@ -575,13 +700,13 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } tokens.push_back(std::string(start, cur)); - DEBUG(stderr, "IDENTIFIER %ld \"%s\"\n", cur - start, - tokens[tokens.size() - 1].c_str()); + DEBUGF(stderr, "IDENTIFIER %ld \"%s\"\n", cur - start, + tokens[tokens.size() - 1].c_str()); } else { tokens.push_back(std::string(cur, cur + 1)); - DEBUG(stderr, "OTHER \"%c\"\n", *cur); + DEBUGF(stderr, "OTHER \"%c\"\n", *cur); ++cur; } @@ -593,19 +718,21 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } else { // alternative tokenize - - while (regex_search(cur, ende, match, regex_string, - regex_constants::match_any | - regex_constants::match_not_null | - regex_constants::match_continuous)) { + while (my_search_string(cur, ende, &match_begin, &match_end)) { prev = cur; - found = match[0].first; - cur = match[0].second; - DEBUG(stderr, - "string %s found at start %lu offset %lu continue at %lu\n", - match[0].str().c_str(), prev - input.begin(), match.position(), - cur - input.begin()); + found = match_begin; + cur = match_end; + IFDEBUG { + + string foo(match_begin, match_end); + DEBUGF(stderr, + "string %s found at start %lu offset %lu continue at %lu\n", + foo.c_str(), prev - input.begin(), found - prev, + cur - input.begin()); + + } + if (prev < found) { // there are items between search start and find sregex_token_iterator it{prev, found, regex_whitespace, -1}; vector tokenized{it, {}}; @@ -619,10 +746,10 @@ extern "C" unsigned char afl_custom_queue_get(void *data, tokenized.end()); tokens.reserve(tokens.size() + tokenized.size() * 2 + 1); - if (unlikely(debug)) { + IFDEBUG { - DEBUG(stderr, "tokens: %lu input size: %lu\n", tokenized.size(), - input.size()); + DEBUGF(stderr, "tokens1: %lu input size: %lu\n", tokenized.size(), + input.size()); for (auto x : tokenized) { cerr << x << endl; @@ -636,10 +763,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, string::const_iterator c = token.begin(), e = token.end(), f, p; smatch m; - while (regex_search(c, e, m, regex_word, - regex_constants::match_any | - regex_constants::match_not_null | - regex_constants::match_continuous)) { + while (regex_search(c, e, m, regex_word)) { p = c; f = m[0].first; @@ -649,10 +773,10 @@ extern "C" unsigned char afl_custom_queue_get(void *data, // there are items between search start and find while (p < f) { - if (unlikely(debug)) { + IFDEBUG { string foo(p, p + 1); - DEBUG(stderr, "before string: \"%s\"\n", foo.c_str()); + DEBUGF(stderr, "before string: \"%s\"\n", foo.c_str()); } @@ -661,20 +785,21 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - /* - string foo(p, f); - DEBUG(stderr, "before string: \"%s\"\n", - foo.c_str()); tokens.push_back(std::string(p, f)); - */ + IFDEBUG { + + string foo(p, f); + DEBUGF(stderr, "before string: \"%s\"\n", foo.c_str()); + tokens.push_back(std::string(p, f)); + + } } - DEBUG( - stderr, - "SUBstring \"%s\" found at start %lu offset %lu continue at " - "%lu\n", - m[0].str().c_str(), p - input.begin(), m.position(), - c - token.begin()); + DEBUGF(stderr, + "SUBstring \"%s\" found at start %lu offset %lu continue " + "at %lu\n", + m[0].str().c_str(), p - input.begin(), m.position(), + c - token.begin()); tokens.push_back(m[0].str()); } @@ -683,10 +808,10 @@ extern "C" unsigned char afl_custom_queue_get(void *data, while (c < e) { - if (unlikely(debug)) { + IFDEBUG { string foo(c, c + 1); - DEBUG(stderr, "after string: \"%s\"\n", foo.c_str()); + DEBUGF(stderr, "after string: \"%s\"\n", foo.c_str()); } @@ -695,17 +820,14 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - /* - if (unlikely(debug)) { + IFDEBUG { - string foo(c, e); - DEBUG(stderr, "after string: \"%s\"\n", - foo.c_str()); + string foo(c, e); + DEBUGF(stderr, "after string: \"%s\"\n", foo.c_str()); - } + } - tokens.push_back(std::string(c, e)); - */ + tokens.push_back(std::string(c, e)); } @@ -713,7 +835,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - if (match[0].length() > 0) { tokens.push_back(match[0]); } + tokens.push_back(string(match_begin, match_end)); } @@ -727,10 +849,10 @@ extern "C" unsigned char afl_custom_queue_get(void *data, tokenized.end()); tokens.reserve(tokens.size() + tokenized.size() * 2 + 1); - if (unlikely(debug)) { + IFDEBUG { - DEBUG(stderr, "tokens: %lu input size: %lu\n", tokenized.size(), - input.size()); + DEBUGF(stderr, "tokens2: %lu input size: %lu\n", tokenized.size(), + input.size()); for (auto x : tokenized) { cerr << x << endl; @@ -744,10 +866,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, string::const_iterator c = token.begin(), e = token.end(), f, p; smatch m; - while (regex_search(c, e, m, regex_word, - regex_constants::match_any | - regex_constants::match_not_null | - regex_constants::match_continuous)) { + while (regex_search(c, e, m, regex_word)) { p = c; f = m[0].first; @@ -757,10 +876,10 @@ extern "C" unsigned char afl_custom_queue_get(void *data, // there are items between search start and find while (p < f) { - if (unlikely(debug)) { + IFDEBUG { string foo(p, p + 1); - DEBUG(stderr, "before string: \"%s\"\n", foo.c_str()); + DEBUGF(stderr, "before string: \"%s\"\n", foo.c_str()); } @@ -769,25 +888,22 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - /* - if (unlikely(debug)) { + IFDEBUG { - string foo(p, f); - DEBUG(stderr, "before string: \"%s\"\n", - foo.c_str()); + string foo(p, f); + DEBUGF(stderr, "before string: \"%s\"\n", foo.c_str()); - } + } - tokens.push_back(std::string(p, f)); - */ + tokens.push_back(std::string(p, f)); } - DEBUG(stderr, - "SUB2string \"%s\" found at start %lu offset %lu continue at " - "%lu\n", - m[0].str().c_str(), p - input.begin(), m.position(), - c - token.begin()); + DEBUGF(stderr, + "SUB2string \"%s\" found at start %lu offset %lu continue " + "at %lu\n", + m[0].str().c_str(), p - input.begin(), m.position(), + c - token.begin()); tokens.push_back(m[0].str()); } @@ -796,10 +912,10 @@ extern "C" unsigned char afl_custom_queue_get(void *data, while (c < e) { - if (unlikely(debug)) { + IFDEBUG { string foo(c, c + 1); - DEBUG(stderr, "after string: \"%s\"\n", foo.c_str()); + DEBUGF(stderr, "after string: \"%s\"\n", foo.c_str()); } @@ -808,16 +924,14 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - /* - if (unlikely(debug)) { + IFDEBUG { - string foo(c, e); - DEBUG(stderr, "after string: \"%s\"\n", foo.c_str()); + string foo(c, e); + DEBUGF(stderr, "after string: \"%s\"\n", foo.c_str()); - } + } - tokens.push_back(std::string(c, e)); - */ + tokens.push_back(std::string(c, e)); } @@ -827,22 +941,22 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - if (unlikely(debug)) { + IFDEBUG { - DEBUG(stderr, "DUMPING TOKENS:\n"); + DEBUGF(stderr, "DUMPING TOKENS:\n"); u32 size_1 = tokens.size() - 1; for (u32 i = 0; i < tokens.size(); ++i) { - DEBUG(stderr, "%s", tokens[i].c_str()); + DEBUGF(stderr, "%s", tokens[i].c_str()); if (unlikely(alternative_tokenize && i < size_1)) { - DEBUG(stderr, "%s", whitespace.c_str()); + DEBUGF(stderr, "%s", whitespace.c_str()); } } - DEBUG(stderr, "---------------------------\n"); + DEBUGF(stderr, "---------------------------\n"); } @@ -850,7 +964,7 @@ extern "C" unsigned char afl_custom_queue_get(void *data, file_mapping[fn] = NULL; s = NULL; - DEBUG(stderr, "too few tokens\n"); + DEBUGF(stderr, "too few tokens\n"); return 0; } @@ -886,21 +1000,23 @@ extern "C" unsigned char afl_custom_queue_get(void *data, all_structure_items += structure->size(); // we are done! - DEBUG(stderr, "DONE! We have %lu tokens in the structure\n", - structure->size()); + DEBUGF(stderr, "DONE! We have %lu tokens in the structure\n", + structure->size()); + + } - } else { + else { if (entry->second == NULL) { - DEBUG(stderr, "Skipping %s\n", filename); + DEBUGF(stderr, "Skipping %s\n", filename); s = NULL; return 0; } s = entry->second; - DEBUG(stderr, "OK %s\n", filename); + DEBUGF(stderr, "OK %s\n", filename); } diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 322caa5b..82131c92 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -150,6 +150,7 @@ def deinit(): # optional for Python 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! - `describe` (optional): diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 1e8d085d..229bc025 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -844,15 +844,16 @@ struct custom_mutator { /** * Perform custom mutations on a given input * - * (Optional for now. Required in the future) + * (Optional) * - * @param data pointer returned in afl_custom_init by this custom mutator + * Getting an add_buf can be skipped by using afl_custom_splice_optout(). + * + * @param[in] data Pointer returned in afl_custom_init by this custom mutator * @param[in] buf Pointer to the input data to be mutated and the mutated * output * @param[in] buf_size Size of the input/output data - * @param[out] out_buf the new buffer. We may reuse *buf if large enough. - * *out_buf = NULL is treated as FATAL. - * @param[in] add_buf Buffer containing the additional test case + * @param[out] out_buf The new buffer, under your memory mgmt. + * @param[in] add_buf Buffer containing an additional test case (splicing) * @param[in] add_buf_size Size of the additional test case * @param[in] max_size Maximum size of the mutated output. The mutation must * not produce data larger than max_size. diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 5e352dcb..bd482562 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -564,8 +564,7 @@ u8 fuzz_one_original(afl_state_t *afl) { if (afl->cmplog_lvl == 3 || (afl->cmplog_lvl == 2 && afl->queue_cur->tc_ref) || afl->queue_cur->favored || - !(afl->fsrv.total_execs % afl->queued_items) || - get_cur_time() - afl->last_find_time > 300000) { // 300 seconds + get_cur_time() - afl->last_find_time > 600000) { // 600 seconds if (input_to_state_stage(afl, in_buf, out_buf, len)) { -- cgit 1.4.1 From f4a13585a1a205798093291fd04659a4158b4d50 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 26 Jan 2023 12:21:47 +0100 Subject: better asan defaults everwhere --- docs/Changelog.md | 1 + include/common.h | 1 + src/afl-analyze.c | 84 +--------------------------- src/afl-common.c | 57 +++++++++++++++++++ src/afl-forkserver.c | 54 +----------------- src/afl-showmap.c | 45 +-------------- src/afl-tmin.c | 83 +-------------------------- utils/afl_network_proxy/afl-network-server.c | 17 +----- 8 files changed, 68 insertions(+), 274 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index fb573c73..434bc101 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -24,6 +24,7 @@ - `-t none` now translates to `-t 120000` (120 seconds) - unicorn_mode updated - updated rust custom mutator dependencies and LibAFL custom mutator + - overall better sanitizer default setting handling - several minor bugfixes ### Version ++4.04c (release) diff --git a/include/common.h b/include/common.h index b5dbc6de..c5a32cdb 100644 --- a/include/common.h +++ b/include/common.h @@ -43,6 +43,7 @@ u32 check_binary_signatures(u8 *fn); void detect_file_args(char **argv, u8 *prog_in, bool *use_stdin); void print_suggested_envs(char *mispelled_env); void check_environment_vars(char **env); +void set_sanitizer_defaults(); char **argv_cpy_dup(int argc, char **argv); void argv_cpy_free(char **argv); diff --git a/src/afl-analyze.c b/src/afl-analyze.c index da1def3b..d4a9aa91 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -656,28 +656,6 @@ static void set_up_environment(char **argv) { if (fsrv.out_fd < 0) { PFATAL("Unable to create '%s'", fsrv.out_file); } /* Set sane defaults... */ - - x = get_afl_env("ASAN_OPTIONS"); - - if (x) { - - if (!strstr(x, "abort_on_error=1")) { - - FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!"); - - } - -#ifndef ASAN_BUILD - if (!getenv("AFL_DEBUG") && !strstr(x, "symbolize=0")) { - - FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); - - } - -#endif - - } - x = get_afl_env("MSAN_OPTIONS"); if (x) { @@ -689,69 +667,9 @@ static void set_up_environment(char **argv) { } - if (!strstr(x, "symbolize=0")) { - - FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!"); - - } - - } - - x = get_afl_env("LSAN_OPTIONS"); - - if (x) { - - if (!strstr(x, "symbolize=0")) { - - FATAL("Custom LSAN_OPTIONS set without symbolize=0 - please fix!"); - - } - } - setenv("ASAN_OPTIONS", - "abort_on_error=1:" - "detect_leaks=0:" - "allocator_may_return_null=1:" - "detect_odr_violation=0:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); - - setenv("UBSAN_OPTIONS", - "halt_on_error=1:" - "abort_on_error=1:" - "malloc_context_size=0:" - "allocator_may_return_null=1:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); - - setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "abort_on_error=1:" - "msan_track_origins=0" - "allocator_may_return_null=1:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", 0); - - setenv("LSAN_OPTIONS", - "exitcode=" STRINGIFY(LSAN_ERROR) ":" - "fast_unwind_on_malloc=0:" - "symbolize=0:" - "print_suppressions=0", - 0); + set_sanitizer_defaults(); if (get_afl_env("AFL_PRELOAD")) { diff --git a/src/afl-common.c b/src/afl-common.c index 211d5bf2..d83130b4 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -58,6 +58,63 @@ u8 last_intr = 0; #define AFL_PATH "/usr/local/lib/afl/" #endif +void set_sanitizer_defaults() { + + /* Set sane defaults for ASAN if nothing else is specified. */ + u8 *have_asan_options = getenv("ASAN_OPTIONS"); + u8 *have_ubsan_options = getenv("UBSAN_OPTIONS"); + u8 *have_msan_options = getenv("MSAN_OPTIONS"); + u8 *have_lsan_options = getenv("LSAN_OPTIONS"); + u8 have_san_options = 0; + if (have_asan_options || have_ubsan_options || have_msan_options || + have_lsan_options) + have_san_options = 1; + u8 default_options[1024] = + "detect_odr_violation=0:abort_on_error=1:symbolize=0:malloc_context_" + "size=0:allocator_may_return_null=1:handle_segv=0:handle_sigbus=0:" + "handle_abort=0:handle_sigfpe=0:handle_sigill=0:"; + + if (!have_lsan_options) strcat(default_options, "detect_leaks=0:"); + + /* Set sane defaults for ASAN if nothing else is specified. */ + + if (!have_san_options) setenv("ASAN_OPTIONS", default_options, 1); + + /* Set sane defaults for UBSAN if nothing else is specified. */ + + if (!have_san_options) setenv("UBSAN_OPTIONS", default_options, 1); + + /* MSAN is tricky, because it doesn't support abort_on_error=1 at this + point. So, we do this in a very hacky way. */ + + if (!have_msan_options) { + + u8 buf[2048] = ""; + if (!have_san_options) strcpy(buf, default_options); + strcat(buf, "exit_code=" STRINGIFY(MSAN_ERROR) ":msan_track_origins=0:"); + setenv("MSAN_OPTIONS", buf, 1); + + } + + /* LSAN, too, does not support abort_on_error=1. (is this still true??) */ + + if (!have_lsan_options) { + + u8 buf[2048] = ""; + if (!have_san_options) strcpy(buf, default_options); + strcat(buf, + "exitcode=" STRINGIFY( + LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:"); + setenv("LSAN_OPTIONS", buf, 1); + + } + + /* Envs for QASan */ + setenv("QASAN_MAX_CALL_STACK", "0", 0); + setenv("QASAN_SYMBOLIZE", "0", 0); + +} + u32 check_binary_signatures(u8 *fn) { int ret = 0, fd = open(fn, O_RDONLY); diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index ef2fa904..89d01460 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -688,58 +688,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 1); } - /* Set sane defaults for ASAN if nothing else is specified. */ - u8 *have_asan_options = getenv("ASAN_OPTIONS"); - u8 *have_ubsan_options = getenv("UBSAN_OPTIONS"); - u8 *have_msan_options = getenv("MSAN_OPTIONS"); - u8 *have_lsan_options = getenv("LSAN_OPTIONS"); - u8 have_san_options = 0; - if (have_asan_options || have_ubsan_options || have_msan_options || - have_lsan_options) - have_san_options = 1; - u8 default_options[1024] = - "detect_odr_violation=0:abort_on_error=1:symbolize=0:malloc_context_" - "size=0:allocator_may_return_null=1:handle_segv=0:handle_sigbus=0:" - "handle_abort=0:handle_sigfpe=0:handle_sigill=0:"; - - if (!have_lsan_options) strcat(default_options, "detect_leaks=0:"); - - /* Set sane defaults for ASAN if nothing else is specified. */ - - if (!have_san_options) setenv("ASAN_OPTIONS", default_options, 1); - - /* Set sane defaults for UBSAN if nothing else is specified. */ - - if (!have_san_options) setenv("UBSAN_OPTIONS", default_options, 1); - - /* MSAN is tricky, because it doesn't support abort_on_error=1 at this - point. So, we do this in a very hacky way. */ - - if (!have_msan_options) { - - u8 buf[2048] = ""; - if (!have_san_options) strcpy(buf, default_options); - strcat(buf, "exit_code=" STRINGIFY(MSAN_ERROR) ":msan_track_origins=0:"); - setenv("MSAN_OPTIONS", buf, 1); - - } - - /* LSAN, too, does not support abort_on_error=1. (is this still true??) */ - - if (!have_lsan_options) { - - u8 buf[2048] = ""; - if (!have_san_options) strcpy(buf, default_options); - strcat(buf, - "exitcode=" STRINGIFY( - LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:"); - setenv("LSAN_OPTIONS", buf, 1); - - } - - /* Envs for QASan */ - setenv("QASAN_MAX_CALL_STACK", "0", 0); - setenv("QASAN_SYMBOLIZE", "0", 0); + /* Set sane defaults for sanitizers */ + set_sanitizer_defaults(); fsrv->init_child_func(fsrv, argv); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 4e019794..1e281d08 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -597,49 +597,8 @@ static void set_up_environment(afl_forkserver_t *fsrv, char **argv) { char *afl_preload; char *frida_afl_preload = NULL; - setenv("ASAN_OPTIONS", - "abort_on_error=1:" - "detect_leaks=0:" - "allocator_may_return_null=1:" - "symbolize=0:" - "detect_odr_violation=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); - - setenv("LSAN_OPTIONS", - "exitcode=" STRINGIFY(LSAN_ERROR) ":" - "fast_unwind_on_malloc=0:" - "symbolize=0:" - "print_suppressions=0", - 0); - - setenv("UBSAN_OPTIONS", - "halt_on_error=1:" - "abort_on_error=1:" - "malloc_context_size=0:" - "allocator_may_return_null=1:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); - - setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "abort_on_error=1:" - "msan_track_origins=0" - "allocator_may_return_null=1:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", 0); + + set_sanitizer_defaults(); if (get_afl_env("AFL_PRELOAD")) { diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 687bb0e7..12c5e0c9 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -674,27 +674,6 @@ static void set_up_environment(afl_forkserver_t *fsrv, char **argv) { /* Set sane defaults... */ - x = get_afl_env("ASAN_OPTIONS"); - - if (x) { - - if (!strstr(x, "abort_on_error=1")) { - - FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!"); - - } - -#ifndef ASAN_BUILD - if (!getenv("AFL_DEBUG") && !strstr(x, "symbolize=0")) { - - FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); - - } - -#endif - - } - x = get_afl_env("MSAN_OPTIONS"); if (x) { @@ -706,69 +685,9 @@ static void set_up_environment(afl_forkserver_t *fsrv, char **argv) { } - if (!strstr(x, "symbolize=0")) { - - FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!"); - - } - - } - - x = get_afl_env("LSAN_OPTIONS"); - - if (x) { - - if (!strstr(x, "symbolize=0")) { - - FATAL("Custom LSAN_OPTIONS set without symbolize=0 - please fix!"); - - } - } - setenv("ASAN_OPTIONS", - "abort_on_error=1:" - "detect_leaks=0:" - "allocator_may_return_null=1:" - "symbolize=0:" - "detect_odr_violation=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); - - setenv("UBSAN_OPTIONS", - "halt_on_error=1:" - "abort_on_error=1:" - "malloc_context_size=0:" - "allocator_may_return_null=1:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", - 0); - - setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "abort_on_error=1:" - "msan_track_origins=0" - "allocator_may_return_null=1:" - "symbolize=0:" - "handle_segv=0:" - "handle_sigbus=0:" - "handle_abort=0:" - "handle_sigfpe=0:" - "handle_sigill=0", 0); - - setenv("LSAN_OPTIONS", - "exitcode=" STRINGIFY(LSAN_ERROR) ":" - "fast_unwind_on_malloc=0:" - "symbolize=0:" - "print_suppressions=0", - 0); + set_sanitizer_defaults(); if (get_afl_env("AFL_PRELOAD")) { diff --git a/utils/afl_network_proxy/afl-network-server.c b/utils/afl_network_proxy/afl-network-server.c index 2ae4c165..04309ada 100644 --- a/utils/afl_network_proxy/afl-network-server.c +++ b/utils/afl_network_proxy/afl-network-server.c @@ -194,7 +194,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { } - if (!strstr(x, "symbolize=0")) { + if (!getenv("AFL_DEBUG") && !strstr(x, "symbolize=0")) { FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!"); @@ -213,7 +213,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { } - if (!strstr(x, "symbolize=0")) { + if (!getenv("AFL_DEBUG") && !strstr(x, "symbolize=0")) { FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!"); @@ -221,18 +221,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) { } - setenv("ASAN_OPTIONS", - "abort_on_error=1:" - "detect_leaks=0:" - "symbolize=0:" - "allocator_may_return_null=1", - 0); - - setenv("MSAN_OPTIONS", "exit_code=" STRINGIFY(MSAN_ERROR) ":" - "symbolize=0:" - "abort_on_error=1:" - "allocator_may_return_null=1:" - "msan_track_origins=0", 0); + set_sanitizer_defaults(); if (get_afl_env("AFL_PRELOAD")) { -- cgit 1.4.1 From 0d55feb11db1f79ee92db5f44ed04277388c933d Mon Sep 17 00:00:00 2001 From: Your Date: Tue, 31 Jan 2023 06:49:32 +0000 Subject: Add support for disabling branch suppression --- frida_mode/README.md | 7 + frida_mode/frida.map | 1 + frida_mode/include/instrument.h | 1 + frida_mode/src/instrument/instrument.c | 5 + frida_mode/src/instrument/instrument_arm64.c | 22 +- frida_mode/src/instrument/instrument_x64.c | 10 +- frida_mode/src/instrument/instrument_x86.c | 12 +- frida_mode/src/js/api.js | 7 + frida_mode/src/js/js_api.c | 7 + frida_mode/test/png/GNUmakefile | 2 +- frida_mode/ts/lib/afl.ts | 12 + frida_mode/ts/package-lock.json | 432 ++++++++++++++++++++++++++- include/envs.h | 1 + 13 files changed, 502 insertions(+), 17 deletions(-) (limited to 'include') diff --git a/frida_mode/README.md b/frida_mode/README.md index 055bb3ee..aac13153 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -193,6 +193,13 @@ instrumented address block translations. backpatching information. By default, the child will report applied backpatches to the parent so that they can be applied and then be inherited by the next child on fork. +* `AFL_FRIDA_INST_NO_SUPPRESS` - Disable deterministic branch suppression. + Deterministic branch suppression skips the preamble which generates coverage + information at the start of each block, if the block is reached by a + deterministic branch. This reduces map polution, and may improve performance + when all the executing blocks have been prefetched and backpatching applied. + However, in the event that backpatching is incomplete, this may incur a + performance penatly as branch instructions are disassembled on each branch. * `AFL_FRIDA_INST_SEED` - Sets the initial seed for the hash function used to generate block (and hence edge) IDs. Setting this to a constant value may be useful for debugging purposes, e.g., investigating unstable edges. diff --git a/frida_mode/frida.map b/frida_mode/frida.map index 73fff686..baf067ab 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -22,6 +22,7 @@ js_api_set_instrument_no_optimize; js_api_set_instrument_regs_file; js_api_set_instrument_seed; + js_api_set_instrument_suppress_disable; js_api_set_instrument_trace; js_api_set_instrument_trace_unique; js_api_set_instrument_unstable_coverage_file; diff --git a/frida_mode/include/instrument.h b/frida_mode/include/instrument.h index 8c93d881..1825e331 100644 --- a/frida_mode/include/instrument.h +++ b/frida_mode/include/instrument.h @@ -15,6 +15,7 @@ extern guint64 instrument_hash_zero; extern char *instrument_coverage_unstable_filename; extern gboolean instrument_coverage_insn; extern char *instrument_regs_filename; +extern gboolean instrument_suppress; extern gboolean instrument_use_fixed_seed; extern guint64 instrument_fixed_seed; diff --git a/frida_mode/src/instrument/instrument.c b/frida_mode/src/instrument/instrument.c index e1e4ac22..a6aac666 100644 --- a/frida_mode/src/instrument/instrument.c +++ b/frida_mode/src/instrument/instrument.c @@ -27,6 +27,7 @@ gboolean instrument_optimize = false; gboolean instrument_unique = false; guint64 instrument_hash_zero = 0; guint64 instrument_hash_seed = 0; +gboolean instrument_suppress = false; gboolean instrument_use_fixed_seed = FALSE; guint64 instrument_fixed_seed = 0; @@ -290,6 +291,7 @@ void instrument_config(void) { (getenv("AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE")); instrument_coverage_insn = (getenv("AFL_FRIDA_INST_INSN") != NULL); instrument_regs_filename = getenv("AFL_FRIDA_INST_REGS_FILE"); + instrument_suppress = (getenv("AFL_FRIDA_INST_NO_SUPPRESS") == NULL); instrument_debug_config(); instrument_coverage_config(); @@ -321,6 +323,9 @@ void instrument_init(void) { FOKF(cBLU "Instrumentation" cRST " - " cGRN "instructions:" cYEL " [%c]", instrument_coverage_insn ? 'X' : ' '); + FOKF(cBLU "Instrumentation" cRST " - " cGRN "suppression:" cYEL " [%c]", + instrument_suppress ? 'X' : ' '); + if (instrument_tracing && instrument_optimize) { WARNF("AFL_FRIDA_INST_TRACE implies AFL_FRIDA_INST_NO_OPTIMIZE"); diff --git a/frida_mode/src/instrument/instrument_arm64.c b/frida_mode/src/instrument/instrument_arm64.c index 77aa8c1d..4372861d 100644 --- a/frida_mode/src/instrument/instrument_arm64.c +++ b/frida_mode/src/instrument/instrument_arm64.c @@ -313,7 +313,7 @@ void instrument_coverage_optimize(const cs_insn *instr, // gum_arm64_writer_put_brk_imm(cw, 0x0); - instrument_coverage_suppress_init(); + if (instrument_suppress) { instrument_coverage_suppress_init(); } code_addr = cw->pc; @@ -333,9 +333,13 @@ void instrument_coverage_optimize(const cs_insn *instr, block_start = GSIZE_TO_POINTER(GUM_ADDRESS(cw->code) - GUM_RESTORATION_PROLOG_SIZE); - if (!g_hash_table_add(coverage_blocks, block_start)) { + if (instrument_suppress) { - FATAL("Failed - g_hash_table_add"); + if (!g_hash_table_add(coverage_blocks, block_start)) { + + FATAL("Failed - g_hash_table_add"); + + } } @@ -371,7 +375,17 @@ void instrument_coverage_optimize(const cs_insn *instr, code.code.mov_x1_curr_loc_shr_1 |= (area_offset_ror << 5); - gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); + if (instrument_suppress) { + + gum_arm64_writer_put_bytes(cw, code.bytes, sizeof(afl_log_code)); + + } else { + + size_t offset = offsetof(afl_log_code, code.stp_x0_x1); + gum_arm64_writer_put_bytes(cw, &code.bytes[offset], + sizeof(afl_log_code) - offset); + + } } diff --git a/frida_mode/src/instrument/instrument_x64.c b/frida_mode/src/instrument/instrument_x64.c index f7b7d6c5..8338f8e7 100644 --- a/frida_mode/src/instrument/instrument_x64.c +++ b/frida_mode/src/instrument/instrument_x64.c @@ -380,11 +380,15 @@ void instrument_coverage_optimize(const cs_insn *instr, } - instrument_coverage_suppress_init(); + if (instrument_suppress) { - if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { + instrument_coverage_suppress_init(); - FATAL("Failed - g_hash_table_add"); + if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { + + FATAL("Failed - g_hash_table_add"); + + } } diff --git a/frida_mode/src/instrument/instrument_x86.c b/frida_mode/src/instrument/instrument_x86.c index f15893cb..4667ea29 100644 --- a/frida_mode/src/instrument/instrument_x86.c +++ b/frida_mode/src/instrument/instrument_x86.c @@ -203,13 +203,17 @@ void instrument_coverage_optimize(const cs_insn *instr, code.code = template; - instrument_coverage_suppress_init(); + if (instrument_suppress) { - // gum_x86_writer_put_breakpoint(cw); + instrument_coverage_suppress_init(); - if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { + // gum_x86_writer_put_breakpoint(cw); - FATAL("Failed - g_hash_table_add"); + if (!g_hash_table_add(coverage_blocks, GSIZE_TO_POINTER(cw->code))) { + + FATAL("Failed - g_hash_table_add"); + + } } diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index fce7a5d7..f9ea1ffb 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -170,6 +170,12 @@ class Afl { static setInstrumentSeed(seed) { Afl.jsApiSetInstrumentSeed(seed); } + /* + * See `AFL_FRIDA_INST_NO_SUPPRESS` + */ + static setInstrumentSuppressDisable() { + Afl.jsApiSetInstrumentSuppressDisable(); + } /** * See `AFL_FRIDA_INST_TRACE_UNIQUE`. */ @@ -339,6 +345,7 @@ Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_li Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); Afl.jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction("js_api_set_instrument_regs_file", "void", ["pointer"]); Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]); +Afl.jsApiSetInstrumentSuppressDisable = Afl.jsApiGetFunction("js_api_set_instrument_suppress_disable", "void", []); Afl.jsApiSetInstrumentTrace = Afl.jsApiGetFunction("js_api_set_instrument_trace", "void", []); Afl.jsApiSetInstrumentTraceUnique = Afl.jsApiGetFunction("js_api_set_instrument_trace_unique", "void", []); Afl.jsApiSetInstrumentUnstableCoverageFile = Afl.jsApiGetFunction("js_api_set_instrument_unstable_coverage_file", "void", ["pointer"]); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 01bba4ff..2e996c1c 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -289,6 +289,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_cache_size( } +__attribute__((visibility("default"))) void +js_api_set_instrument_suppress_disable(void) { + + instrument_suppress = false; + +} + __attribute__((visibility("default"))) void js_api_set_js_main_hook( const js_main_hook_t hook) { diff --git a/frida_mode/test/png/GNUmakefile b/frida_mode/test/png/GNUmakefile index 86fd1483..408b7dcb 100644 --- a/frida_mode/test/png/GNUmakefile +++ b/frida_mode/test/png/GNUmakefile @@ -25,7 +25,7 @@ HARNESS_URL:="https://raw.githubusercontent.com/llvm/llvm-project/main/compiler- PNGTEST_FILE:=$(PNGTEST_BUILD_DIR)target.cc PNGTEST_OBJ:=$(PNGTEST_BUILD_DIR)target.o -PNGTEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/master/benchmarks/libpng-1.2.56/target.cc" +PNGTEST_URL:="https://raw.githubusercontent.com/google/fuzzbench/e0c4a994b6999bae46e8dec5bcea9a73251b8dba/benchmarks/libpng-1.2.56/target.cc" TEST_BIN:=$(BUILD_DIR)test ifeq "$(shell uname)" "Darwin" diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index 7a83c0fb..6a2350e7 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -201,6 +201,13 @@ class Afl { Afl.jsApiSetInstrumentSeed(seed); } + /* + * See `AFL_FRIDA_INST_NO_SUPPRESS` + */ + public static setInstrumentSuppressDisable(): void{ + Afl.jsApiSetInstrumentSuppressDisable(); + } + /** * See `AFL_FRIDA_INST_TRACE_UNIQUE`. */ @@ -451,6 +458,11 @@ class Afl { "void", ["uint64"]); + private static readonly jsApiSetInstrumentSuppressDisable = Afl.jsApiGetFunction( + "js_api_set_instrument_suppress_disable", + "void", + []); + private static readonly jsApiSetInstrumentTrace = Afl.jsApiGetFunction( "js_api_set_instrument_trace", "void", diff --git a/frida_mode/ts/package-lock.json b/frida_mode/ts/package-lock.json index e766c2c2..670d7a83 100644 --- a/frida_mode/ts/package-lock.json +++ b/frida_mode/ts/package-lock.json @@ -1,11 +1,433 @@ { - "requires": true, + "name": "@worksbutnottested/aflplusplus-frida", + "version": "1.0.1", "lockfileVersion": 1, + "requires": true, "dependencies": { - "tsc": { - "version": "2.0.3", - "resolved": "https://registry.npmjs.org/tsc/-/tsc-2.0.3.tgz", - "integrity": "sha512-SN+9zBUtrpUcOpaUO7GjkEHgWtf22c7FKbKCA4e858eEM7Qz86rRDpgOU2lBIDf0fLCsEg65ms899UMUIB2+Ow==", + "@babel/code-frame": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.18.6.tgz", + "integrity": "sha512-TDCmlK5eOvH+eH7cdAFlNXeVJqWIQ7gW9tY1GJIpUtFb6CmjVyq2VM3u71bOyR8CRihcCgMUYoDNyLXao3+70Q==", + "dev": true, + "requires": { + "@babel/highlight": "^7.18.6" + } + }, + "@babel/helper-validator-identifier": { + "version": "7.19.1", + "resolved": "https://registry.npmjs.org/@babel/helper-validator-identifier/-/helper-validator-identifier-7.19.1.tgz", + "integrity": "sha512-awrNfaMtnHUr653GgGEs++LlAvW6w+DcPrOliSMXWCKo597CwL5Acf/wWdNkf/tfEQE3mjkeD1YOVZOUV/od1w==", + "dev": true + }, + "@babel/highlight": { + "version": "7.18.6", + "resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.18.6.tgz", + "integrity": "sha512-u7stbOuYjaPezCuLj29hNW1v64M2Md2qupEKP1fHc7WdOA3DgLh37suiSrZYY7haUB7iBeQZ9P1uiRF359do3g==", + "dev": true, + "requires": { + "@babel/helper-validator-identifier": "^7.18.6", + "chalk": "^2.0.0", + "js-tokens": "^4.0.0" + } + }, + "@types/frida-gum": { + "version": "16.5.1", + "resolved": "https://registry.npmjs.org/@types/frida-gum/-/frida-gum-16.5.1.tgz", + "integrity": "sha512-t+2HZG6iBO2cEKtb2KvtP33m/7TGmzSd42YqznToA34+TkS97NttsFZ9OY2s0hPyDQOg+hZTjR1QggRkEL/Ovg==" + }, + "@types/node": { + "version": "14.18.36", + "resolved": "https://registry.npmjs.org/@types/node/-/node-14.18.36.tgz", + "integrity": "sha512-FXKWbsJ6a1hIrRxv+FoukuHnGTgEzKYGi7kilfMae96AL9UNkPFNWJEEYWzdRI9ooIkbr4AKldyuSTLql06vLQ==", + "dev": true + }, + "ansi-styles": { + "version": "3.2.1", + "resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz", + "integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==", + "dev": true, + "requires": { + "color-convert": "^1.9.0" + } + }, + "argparse": { + "version": "1.0.10", + "resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz", + "integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==", + "dev": true, + "requires": { + "sprintf-js": "~1.0.2" + } + }, + "balanced-match": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz", + "integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==", + "dev": true + }, + "brace-expansion": { + "version": "1.1.11", + "resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz", + "integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==", + "dev": true, + "requires": { + "balanced-match": "^1.0.0", + "concat-map": "0.0.1" + } + }, + "builtin-modules": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz", + "integrity": "sha512-wxXCdllwGhI2kCC0MnvTGYTMvnVZTvqgypkiTI8Pa5tcz2i6VqsqwYGgqwXji+4RgCzms6EajE4IxiUH6HH8nQ==", + "dev": true + }, + "chalk": { + "version": "2.4.2", + "resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz", + "integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==", + "dev": true, + "requires": { + "ansi-styles": "^3.2.1", + "escape-string-regexp": "^1.0.5", + "supports-color": "^5.3.0" + } + }, + "color-convert": { + "version": "1.9.3", + "resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz", + "integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==", + "dev": true, + "requires": { + "color-name": "1.1.3" + } + }, + "color-name": { + "version": "1.1.3", + "resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz", + "integrity": "sha512-72fSenhMw2HZMTVHeCA9KCmpEIbzWiQsjN+BHcBbS9vr1mtt+vJjPdksIBNUmKAW8TFUDPJK5SUU3QhE9NEXDw==", + "dev": true + }, + "commander": { + "version": "2.20.3", + "resolved": "https://registry.npmjs.org/commander/-/commander-2.20.3.tgz", + "integrity": "sha512-GpVkmM8vF2vQUkj2LvZmD35JxeJOLCwJ9cUkugyk2nuhbv3+mJvpLYYt+0+USMxE+oj+ey/lJEnhZw75x/OMcQ==", + "dev": true + }, + "concat-map": { + "version": "0.0.1", + "resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz", + "integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==", + "dev": true + }, + "diff": { + "version": "4.0.2", + "resolved": "https://registry.npmjs.org/diff/-/diff-4.0.2.tgz", + "integrity": "sha512-58lmxKSA4BNyLz+HHMUzlOEpg09FV+ev6ZMe3vJihgdxzgcwZ8VoEEPmALCZG9LmqfVoNMMKpttIYTVG6uDY7A==", + "dev": true + }, + "escape-string-regexp": { + "version": "1.0.5", + "resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz", + "integrity": "sha512-vbRorB5FUQWvla16U8R/qgaFIya2qGzwDrNmCZuYKrbdSUMG6I1ZCGQRefkRVhuOkIGVne7BQ35DSfo1qvJqFg==", + "dev": true + }, + "esprima": { + "version": "4.0.1", + "resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz", + "integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==", + "dev": true + }, + "fs.realpath": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz", + "integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==", + "dev": true + }, + "function-bind": { + "version": "1.1.1", + "resolved": "https://registry.npmjs.org/function-bind/-/function-bind-1.1.1.tgz", + "integrity": "sha512-yIovAzMX49sF8Yl58fSCWJ5svSLuaibPxXQJFLmBObTuCr0Mf1KiPopGM9NiFjiYBCbfaa2Fh6breQ6ANVTI0A==", + "dev": true + }, + "get-caller-file": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/get-caller-file/-/get-caller-file-1.0.3.tgz", + "integrity": "sha512-3t6rVToeoZfYSGd8YoLFR2DJkiQrIiUrGcjvFX2mDw3bn6k2OtwHN0TNCLbBO+w8qTvimhDkv+LSscbJY1vE6w==", + "dev": true + }, + "glob": { + "version": "7.2.3", + "resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz", + "integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==", + "dev": true, + "requires": { + "fs.realpath": "^1.0.0", + "inflight": "^1.0.4", + "inherits": "2", + "minimatch": "^3.1.1", + "once": "^1.3.0", + "path-is-absolute": "^1.0.0" + } + }, + "has": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/has/-/has-1.0.3.tgz", + "integrity": "sha512-f2dvO0VU6Oej7RkWJGrehjbzMAjFp5/VKPp5tTpWIV4JHHZK1/BxbFRtf/siA2SWTe09caDmVtYYzWEIbBS4zw==", + "dev": true, + "requires": { + "function-bind": "^1.1.1" + } + }, + "has-flag": { + "version": "3.0.0", + "resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz", + "integrity": "sha512-sKJf1+ceQBr4SMkvQnBDNDtf4TXpVhVGateu0t918bl30FnbE2m4vNLX+VWe/dpjlb+HugGYzW7uQXH98HPEYw==", + "dev": true + }, + "inflight": { + "version": "1.0.6", + "resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz", + "integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==", + "dev": true, + "requires": { + "once": "^1.3.0", + "wrappy": "1" + } + }, + "inherits": { + "version": "2.0.4", + "resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz", + "integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==", + "dev": true + }, + "is-core-module": { + "version": "2.11.0", + "resolved": "https://registry.npmjs.org/is-core-module/-/is-core-module-2.11.0.tgz", + "integrity": "sha512-RRjxlvLDkD1YJwDbroBHMb+cukurkDWNyHx7D3oNB5x9rb5ogcksMC5wHCadcXoo67gVr/+3GFySh3134zi6rw==", + "dev": true, + "requires": { + "has": "^1.0.3" + } + }, + "js-tokens": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz", + "integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==", + "dev": true + }, + "js-yaml": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.14.1.tgz", + "integrity": "sha512-okMH7OXXJ7YrN9Ok3/SXrnu4iX9yOk+25nqX4imS2npuvTYDmo/QEZoqwZkYaIDk3jVvBOTOIEgEhaLOynBS9g==", + "dev": true, + "requires": { + "argparse": "^1.0.7", + "esprima": "^4.0.0" + } + }, + "minimatch": { + "version": "3.1.2", + "resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz", + "integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==", + "dev": true, + "requires": { + "brace-expansion": "^1.1.7" + } + }, + "minimist": { + "version": "1.2.7", + "resolved": "https://registry.npmjs.org/minimist/-/minimist-1.2.7.tgz", + "integrity": "sha512-bzfL1YUZsP41gmu/qjrEk0Q6i2ix/cVeAhbCbqH9u3zYutS1cLg00qhrD0M2MVdCcx4Sc0UpP2eBWo9rotpq6g==", + "dev": true + }, + "mkdirp": { + "version": "0.5.6", + "resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.6.tgz", + "integrity": "sha512-FP+p8RB8OWpF3YZBCrP5gtADmtXApB5AMLn+vdyA+PyxCjrCs00mjyUozssO33cwDeT3wNGdLxJ5M//YqtHAJw==", + "dev": true, + "requires": { + "minimist": "^1.2.6" + } + }, + "mock-require": { + "version": "3.0.3", + "resolved": "https://registry.npmjs.org/mock-require/-/mock-require-3.0.3.tgz", + "integrity": "sha512-lLzfLHcyc10MKQnNUCv7dMcoY/2Qxd6wJfbqCcVk3LDb8An4hF6ohk5AztrvgKhJCqj36uyzi/p5se+tvyD+Wg==", + "dev": true, + "requires": { + "get-caller-file": "^1.0.2", + "normalize-path": "^2.1.1" + } + }, + "normalize-path": { + "version": "2.1.1", + "resolved": "https://registry.npmjs.org/normalize-path/-/normalize-path-2.1.1.tgz", + "integrity": "sha512-3pKJwH184Xo/lnH6oyP1q2pMd7HcypqqmRs91/6/i2CGtWwIKGCkOOMTm/zXbgTEWHw1uNpNi/igc3ePOYHb6w==", + "dev": true, + "requires": { + "remove-trailing-separator": "^1.0.1" + } + }, + "once": { + "version": "1.4.0", + "resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz", + "integrity": "sha512-lNaJgI+2Q5URQBkccEKHTQOPaXdUxnZZElQTZY0MFUAuaEqe1E+Nyvgdz/aIyNi6Z9MzO5dv1H8n58/GELp3+w==", + "dev": true, + "requires": { + "wrappy": "1" + } + }, + "path-is-absolute": { + "version": "1.0.1", + "resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz", + "integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==", + "dev": true + }, + "path-parse": { + "version": "1.0.7", + "resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.7.tgz", + "integrity": "sha512-LDJzPVEEEPR+y48z93A0Ed0yXb8pAByGWo/k5YYdYgpY2/2EsOsksJrq7lOHxryrVOn1ejG6oAp8ahvOIQD8sw==", + "dev": true + }, + "remove-trailing-separator": { + "version": "1.1.0", + "resolved": "https://registry.npmjs.org/remove-trailing-separator/-/remove-trailing-separator-1.1.0.tgz", + "integrity": "sha512-/hS+Y0u3aOfIETiaiirUFwDBDzmXPvO+jAfKTitUngIPzdKc6Z0LoFjM/CK5PL4C+eKwHohlHAb6H0VFfmmUsw==", + "dev": true + }, + "resolve": { + "version": "1.22.1", + "resolved": "https://registry.npmjs.org/resolve/-/resolve-1.22.1.tgz", + "integrity": "sha512-nBpuuYuY5jFsli/JIs1oldw6fOQCBioohqWZg/2hiaOybXOft4lonv85uDOKXdf8rhyK159cxU5cDcK/NKk8zw==", + "dev": true, + "requires": { + "is-core-module": "^2.9.0", + "path-parse": "^1.0.7", + "supports-preserve-symlinks-flag": "^1.0.0" + } + }, + "semver": { + "version": "5.7.1", + "resolved": "https://registry.npmjs.org/semver/-/semver-5.7.1.tgz", + "integrity": "sha512-sauaDf/PZdVgrLTNYHRtpXa1iRiKcaebiKQ1BJdpQlWH2lCvexQdX55snPFyK7QzpudqbCI0qXFfOasHdyNDGQ==", + "dev": true + }, + "sprintf-js": { + "version": "1.0.3", + "resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz", + "integrity": "sha512-D9cPgkvLlV3t3IzL0D0YLvGA9Ahk4PcvVwUbN0dSGr1aP0Nrt4AEnTUbuGvquEC0mA64Gqt1fzirlRs5ibXx8g==", + "dev": true + }, + "supports-color": { + "version": "5.5.0", + "resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz", + "integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==", + "dev": true, + "requires": { + "has-flag": "^3.0.0" + } + }, + "supports-preserve-symlinks-flag": { + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/supports-preserve-symlinks-flag/-/supports-preserve-symlinks-flag-1.0.0.tgz", + "integrity": "sha512-ot0WnXS9fgdkgIcePe6RHNk1WA8+muPa6cSjeR3V8K27q9BB1rTE3R1p7Hv0z1ZyAc8s6Vvv8DIyWf681MAt0w==", + "dev": true + }, + "tslib": { + "version": "1.14.1", + "resolved": "https://registry.npmjs.org/tslib/-/tslib-1.14.1.tgz", + "integrity": "sha512-Xni35NKzjgMrwevysHTCArtLDpPvye8zV/0E4EyYn43P7/7qvQwPh9BGkHewbMulVntbigmcT7rdX3BNo9wRJg==", + "dev": true + }, + "tslint": { + "version": "6.1.3", + "resolved": "https://registry.npmjs.org/tslint/-/tslint-6.1.3.tgz", + "integrity": "sha512-IbR4nkT96EQOvKE2PW/djGz8iGNeJ4rF2mBfiYaR/nvUWYKJhLwimoJKgjIFEIDibBtOevj7BqCRL4oHeWWUCg==", + "dev": true, + "requires": { + "@babel/code-frame": "^7.0.0", + "builtin-modules": "^1.1.1", + "chalk": "^2.3.0", + "commander": "^2.12.1", + "diff": "^4.0.1", + "glob": "^7.1.1", + "js-yaml": "^3.13.1", + "minimatch": "^3.0.4", + "mkdirp": "^0.5.3", + "resolve": "^1.3.2", + "semver": "^5.3.0", + "tslib": "^1.13.0", + "tsutils": "^2.29.0" + } + }, + "tsutils": { + "version": "2.29.0", + "resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz", + "integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==", + "dev": true, + "requires": { + "tslib": "^1.8.1" + } + }, + "typescript": { + "version": "4.9.5", + "resolved": "https://registry.npmjs.org/typescript/-/typescript-4.9.5.tgz", + "integrity": "sha512-1FXk9E2Hm+QzZQ7z+McJiHL4NW1F2EzMu9Nq9i3zAaGqibafqYwCVU6WyWAuyQRRzOlxou8xZSyXLEN8oKj24g==", + "dev": true + }, + "typescript-tslint-plugin": { + "version": "0.5.5", + "resolved": "https://registry.npmjs.org/typescript-tslint-plugin/-/typescript-tslint-plugin-0.5.5.tgz", + "integrity": "sha512-tR5igNQP+6FhxaPJYRlUBVsEl0n5cSuXRbg7L1y80mL4B1jUHb8uiIcbQBJ9zWyypJEdFYFUccpXxvMwZR8+AA==", + "dev": true, + "requires": { + "minimatch": "^3.0.4", + "mock-require": "^3.0.3", + "vscode-languageserver": "^5.2.1" + } + }, + "vscode-jsonrpc": { + "version": "4.0.0", + "resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz", + "integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg==", + "dev": true + }, + "vscode-languageserver": { + "version": "5.2.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz", + "integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==", + "dev": true, + "requires": { + "vscode-languageserver-protocol": "3.14.1", + "vscode-uri": "^1.0.6" + } + }, + "vscode-languageserver-protocol": { + "version": "3.14.1", + "resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz", + "integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==", + "dev": true, + "requires": { + "vscode-jsonrpc": "^4.0.0", + "vscode-languageserver-types": "3.14.0" + } + }, + "vscode-languageserver-types": { + "version": "3.14.0", + "resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz", + "integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A==", + "dev": true + }, + "vscode-uri": { + "version": "1.0.8", + "resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz", + "integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ==", + "dev": true + }, + "wrappy": { + "version": "1.0.2", + "resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz", + "integrity": "sha512-l4Sp/DRseor9wL6EvV2+TuQn63dMkPjZ/sp9XkghTEbV9KlPS1xUsZ3u7/IQO4wxtcFB4bgpQPRcR3QCvezPcQ==", "dev": true } } diff --git a/include/envs.h b/include/envs.h index f4cdf390..46fc796b 100644 --- a/include/envs.h +++ b/include/envs.h @@ -68,6 +68,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", + "AFL_FRIDA_INST_NO_SUPPRESS" "AFL_FRIDA_INST_RANGES", "AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", -- cgit 1.4.1 From 90f61552f794fc0fae5dc2585f81f31d32db1e89 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 4 Feb 2023 15:39:03 +0100 Subject: changes --- custom_mutators/autotokens/TODO | 9 ++++----- custom_mutators/autotokens/autotokens.cpp | 12 ++++++++++++ include/config.h | 4 ++-- 3 files changed, 18 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/custom_mutators/autotokens/TODO b/custom_mutators/autotokens/TODO index 3cae3060..528dff1f 100644 --- a/custom_mutators/autotokens/TODO +++ b/custom_mutators/autotokens/TODO @@ -1,5 +1,3 @@ -cmplog: only add tokens that were found to fit? - create from thin air if no good seed after a cycle and dict large enough? (static u32 no_of_struct_inputs;) @@ -16,8 +14,9 @@ corpus analyse: - libpcap min len, max len, % wenn 95/98/99/100 ascii -funktion und env für menge an mutationen - env für menge an per mutation run -only add inital dictionary, not furher finds, e.g. cmplog +AFL_TXT_MAX_LEN 65535 +AFL_TXT_MIN_LEN 16 +AFL_TXT_MIN_PERCENT=99 + diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index a0125851..46a347f8 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -34,6 +34,9 @@ extern "C" { #ifndef AUTOTOKENS_SPLICE_DISABLE #define AUTOTOKENS_SPLICE_DISABLE 0 #endif +#ifndef AFL_TXT_MAX_LEN + #define AFL_TXT_MAX_LEN 65535 +#endif #if AUTOTOKENS_SPLICE_MIN >= AUTOTOKENS_SIZE_MIN #error SPLICE_MIN must be lower than SIZE_MIN @@ -571,6 +574,15 @@ extern "C" unsigned char afl_custom_queue_get(void *data, DEBUGF(stderr, "Too short (%lu) %s\n", len, filename); return 1; + } else + if (len > AFL_TXT_MAX_LEN) { + + fclose(fp); + file_mapping[fn] = structure; // NULL ptr so we don't read the file again + s = NULL; + DEBUGF(stderr, "Too long (%lu) %s\n", len, filename); + return 1; + } string input; diff --git a/include/config.h b/include/config.h index f8a742f2..ed8b844c 100644 --- a/include/config.h +++ b/include/config.h @@ -489,12 +489,12 @@ /* Minimum length of a queue input to be evaluated for "is_ascii"? */ -#define AFL_TXT_MIN_LEN 12 +#define AFL_TXT_MIN_LEN 16 /* What is the minimum percentage of ascii characters present to be classifed as "is_ascii"? */ -#define AFL_TXT_MIN_PERCENT 95 +#define AFL_TXT_MIN_PERCENT 98 /* How often to perform ASCII mutations 0 = disable, 1-8 are good values */ -- cgit 1.4.1 From ca063c92d20f4dee6ae9fd1d48dc531768b14ca5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 6 Feb 2023 08:52:12 +0100 Subject: more options --- include/config.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/config.h b/include/config.h index ed8b844c..49d09174 100644 --- a/include/config.h +++ b/include/config.h @@ -494,7 +494,7 @@ /* What is the minimum percentage of ascii characters present to be classifed as "is_ascii"? */ -#define AFL_TXT_MIN_PERCENT 98 +#define AFL_TXT_MIN_PERCENT 99 /* How often to perform ASCII mutations 0 = disable, 1-8 are good values */ -- cgit 1.4.1 From c86d06849b46865f126a522b7b4c8eb0f72c6ba1 Mon Sep 17 00:00:00 2001 From: Marcello Maugeri Date: Wed, 8 Feb 2023 15:54:27 +0100 Subject: Update forkserver.h Fix typo --- include/forkserver.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'include') diff --git a/include/forkserver.h b/include/forkserver.h index 35bc1771..50898a08 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -43,7 +43,7 @@ typedef enum NyxReturnValue { Normal, Crash, Asan, - Timout, + Timeout, InvalidWriteToPayload, Error, IoError, -- cgit 1.4.1 From 54fa78d32ce6779117a656c72f5c630713e7033f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 13 Feb 2023 09:52:57 +0100 Subject: autodisable and better performance --- custom_mutators/autotokens/Makefile | 12 ++- custom_mutators/autotokens/TODO | 21 ----- custom_mutators/autotokens/autotokens.cpp | 143 +++++++++++++++++++++++------- include/config.h | 4 + src/afl-fuzz-queue.c | 89 ++++++++++++------- 5 files changed, 179 insertions(+), 90 deletions(-) (limited to 'include') diff --git a/custom_mutators/autotokens/Makefile b/custom_mutators/autotokens/Makefile index ab1da4b6..6ee7d324 100644 --- a/custom_mutators/autotokens/Makefile +++ b/custom_mutators/autotokens/Makefile @@ -1,16 +1,22 @@ ifdef debug - CFLAGS += -fsanitize=address -Wall + CPPLAGS += -fsanitize=address + CXXFLAGS += -Wall + CC := clang CXX := clang++ endif ifdef DEBUG - CFLAGS += -fsanitize=address -Wall + CPPFLAGS += -fsanitize=address + CXXFLAGS += -Wall + CC := clang CXX := clang++ endif all: autotokens.so autotokens.so: autotokens.cpp - $(CXX) -g -O3 $(CFLAGS) -shared -fPIC -o autotokens.so -I../../include autotokens.cpp ../../src/afl-performance.o + $(CC) -D_STANDALONE_MODULE=1 -I../../include -g -O3 $(CPPFLAGS) -fPIC -c -o ./afl-fuzz-queue.o ../../src/afl-fuzz-queue.c + $(CC) -I../../include -g -O3 $(CPPFLAGS) -DBIN_PATH=\"dummy\" -Wno-pointer-sign -fPIC -c -o ./afl-common.o ../../src/afl-common.c + $(CXX) -Wno-deprecated -g -O3 $(CXXFLAGS) $(CPPFLAGS) -shared -fPIC -o autotokens.so -I../../include autotokens.cpp ./afl-fuzz-queue.o ../../src/afl-performance.o ./afl-common.o clean: rm -f autotokens.so *~ core diff --git a/custom_mutators/autotokens/TODO b/custom_mutators/autotokens/TODO index 496bfd45..2e99e147 100644 --- a/custom_mutators/autotokens/TODO +++ b/custom_mutators/autotokens/TODO @@ -1,24 +1,3 @@ -create from thin air if no good seed after a cycle and dict large enough? -(static u32 no_of_struct_inputs;) - -splicing -> check if whitespace/token is needed - -whitespace/token check only AFTER mutation - -analyse welche einen DICT haben, und welche davon rein ascii - -corpus analyse: - + libxml - - sqlite - - libpcap -min len, max len, % wenn 95/98/99/100 ascii - env für menge an per mutation run -AFL_TXT_MAX_LEN 65535 -AFL_TXT_MIN_LEN 16 -AFL_TXT_MIN_PERCENT=99 - --> KEIN FAV! - change_min/_max werte diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index 10afa2c2..cda90a38 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -25,10 +25,12 @@ extern "C" { #define AUTOTOKENS_CHANGE_MIN 8 #define AUTOTOKENS_CHANGE_MAX 64 #define AUTOTOKENS_SIZE_MIN 8 +#define AUTOTOKENS_SIZE_MAX 65535 #define AUTOTOKENS_SPLICE_MIN 4 #define AUTOTOKENS_SPLICE_MAX 64 #define AUTOTOKENS_CREATE_FROM_THIN_AIR 0 #define AUTOTOKENS_FUZZ_COUNT_SHIFT 0 +#define AUTOTOKENS_AUTO_DISABLE 0 // 0 = no learning, 1 only from -x dict/autodict, 2 also from cmplog #define AUTOTOKENS_LEARN_DICT 1 #ifndef AUTOTOKENS_SPLICE_DISABLE @@ -56,6 +58,8 @@ typedef struct my_mutator { #define IFDEBUG if (unlikely(debug)) static afl_state *afl_ptr; +static int module_disabled = 0; +static int auto_disable = AUTOTOKENS_AUTO_DISABLE; static int debug = AUTOTOKENS_DEBUG; static int only_fav = AUTOTOKENS_ONLY_FAV; static int learn_dictionary_tokens = AUTOTOKENS_LEARN_DICT; @@ -93,6 +97,99 @@ static void first_run(void *data) { (void)(data); + /* For auto-loading this module we check here if we can analyze from the + input if the inputs look like text inputs and disable the module if + not. */ + + if (afl_ptr->custom_only || !auto_disable) { return; } + + if (unlikely(afl_ptr->active_items == 1 && + afl_ptr->queue_cur->len < AFL_TXT_MIN_LEN)) { + + if (afl_ptr->extras_cnt > 8) { + + u32 valid = 0; + + while (extras_cnt < afl_ptr->extras_cnt) { + + u32 ok = 1, l = afl_ptr->extras[extras_cnt].len; + u8 *buf, *ptr = afl_ptr->extras[extras_cnt].data; + + for (u32 i = 0; i < l; ++i) { + + if (!isascii((int)ptr[i]) && !isprint((int)ptr[i])) { + + ok = 0; + break; + + } + + } + + if (ok) { + + buf = (u8 *)malloc(afl_ptr->extras[extras_cnt].len + 1); + memcpy(buf, afl_ptr->extras[extras_cnt].data, + afl_ptr->extras[extras_cnt].len); + buf[afl_ptr->extras[extras_cnt].len] = 0; + token_to_id[(char *)buf] = current_id; + id_to_token[current_id] = (char *)buf; + ++current_id; + ++valid; + + } + + ++extras_cnt; + + } + + if ((valid * 100) / afl_ptr->extras_cnt < 95) { module_disabled = 1; } + + } else { + + module_disabled = 1; + + } + + return; + + } + + u32 is_ascii = 0, valid = 0; + + for (u32 i = 0; i < afl_ptr->queued_items; ++i) { + + struct queue_entry *q; + + q = afl_ptr->queue_buf[i]; + + if (!q->disabled && q->len >= AUTOTOKENS_SIZE_MIN && + q->len <= AFL_TXT_MAX_LEN) { + + ++valid; + u8 *input = queue_testcase_get(afl_ptr, q); + + u32 valid_chars = 0; + for (u32 i = 0; i < q->len; ++i) { + + if (isascii((int)input[i]) || isprint((int)input[i])) { ++valid_chars; } + + } + + // we want at least 99% of text characters ... + if (((q->len * AFL_TXT_MIN_PERCENT) / 100) <= valid_chars) { + + ++is_ascii; + q->is_ascii = 1; + + } + + } + + } + + if ((is_ascii * 100) / valid < 70) { module_disabled = 1; } + } static u32 good_whitespace_or_singleval() { @@ -441,21 +538,25 @@ extern "C" unsigned char afl_custom_queue_get(void *data, is_first_run = 0; first_run(data); + if (module_disabled) { WARNF("Autotokens custom module is disabled."); } + } - if (unlikely(!afl_ptr->custom_only) && !create_from_thin_air && - ((afl_ptr->shm.cmplog_mode && !afl_ptr->queue_cur->is_ascii) || - (only_fav && !afl_ptr->queue_cur->favored))) { + if (likely(module_disabled) || + (unlikely(!afl_ptr->custom_only) && !create_from_thin_air && + ((afl_ptr->shm.cmplog_mode && !afl_ptr->queue_cur->is_ascii) || + (only_fav && !afl_ptr->queue_cur->favored)))) { s = NULL; - DEBUGF(stderr, "cmplog not ascii or only_fav and not favorite\n"); + DEBUGF(stderr, + "cmplog not ascii or only_fav and not favorite or disabled\n"); return 1; } // check if there are new dictionary entries and add them to the tokens - if (likely(valid_structures || create_from_thin_air) && - learn_state < learn_dictionary_tokens) { + if (unlikely(learn_state < learn_dictionary_tokens) && + likely(valid_structures || create_from_thin_air)) { if (unlikely(!learn_state)) { learn_state = 1; } @@ -569,21 +670,10 @@ extern "C" unsigned char afl_custom_queue_get(void *data, if (entry == file_mapping.end()) { // this input file was not analyzed for tokens yet, so let's do it! - - FILE *fp = fopen((char *)filename, "rb"); - if (!fp) { - - s = NULL; - return 1; - - } // should not happen - - fseek(fp, 0, SEEK_END); - size_t len = (size_t)ftell(fp); + size_t len = afl_ptr->queue_cur->len; if (len < AFL_TXT_MIN_LEN) { - fclose(fp); file_mapping[fn] = structure; // NULL ptr so we don't read the file again s = NULL; DEBUGF(stderr, "Too short (%lu) %s\n", len, filename); @@ -591,7 +681,6 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } else if (len > AFL_TXT_MAX_LEN) { - fclose(fp); file_mapping[fn] = structure; // NULL ptr so we don't read the file again s = NULL; DEBUGF(stderr, "Too long (%lu) %s\n", len, filename); @@ -599,19 +688,8 @@ extern "C" unsigned char afl_custom_queue_get(void *data, } - string input; - input.resize(len); - rewind(fp); - - if (fread((void *)input.data(), 1, len, fp) != len) { - - s = NULL; - DEBUGF(stderr, "Too short read %s\n", filename); - return 1; - - } - - fclose(fp); + u8 *input_buf = queue_testcase_get(afl_ptr, afl_ptr->queue_cur); + string input((char *)input_buf, afl_ptr->queue_cur->len); if (!afl_ptr->shm.cmplog_mode) { @@ -866,6 +944,7 @@ extern "C" my_mutator_t *afl_custom_init(afl_state *afl, unsigned int seed) { } if (getenv("AUTOTOKENS_DEBUG")) { debug = 1; } + if (getenv("AUTOTOKENS_AUTO_DISABLE")) { auto_disable = 1; } if (getenv("AUTOTOKENS_ONLY_FAV")) { only_fav = 1; } if (getenv("AUTOTOKENS_CREATE_FROM_THIN_AIR")) { create_from_thin_air = 1; } diff --git a/include/config.h b/include/config.h index 49d09174..ad8b76a8 100644 --- a/include/config.h +++ b/include/config.h @@ -491,6 +491,10 @@ #define AFL_TXT_MIN_LEN 16 +/* Maximum length of a queue input to be evaluated for "is_ascii"? */ + +#define AFL_TXT_MAX_LEN 65535 + /* What is the minimum percentage of ascii characters present to be classifed as "is_ascii"? */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index e3faa392..3c8a3e46 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -27,6 +27,22 @@ #include #include +#ifdef _STANDALONE_MODULE +void minimize_bits(afl_state_t *afl, u8 *dst, u8 *src) { + + return; + +} + +void run_afl_custom_queue_new_entry(afl_state_t *afl, struct queue_entry *q, + u8 *a, u8 *b) { + + return; + +} + +#endif + /* select next queue entry based on alias algo - fast! */ inline u32 select_next_queue_entry(afl_state_t *afl) { @@ -78,8 +94,8 @@ void create_alias_table(afl_state_t *afl) { afl->alias_probability = (double *)afl_realloc( (void **)&afl->alias_probability, n * sizeof(double)); double *P = (double *)afl_realloc(AFL_BUF_PARAM(out), n * sizeof(double)); - int *S = (u32 *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); - int *L = (u32 *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); + int *S = (int *)afl_realloc(AFL_BUF_PARAM(out_scratch), n * sizeof(u32)); + int *L = (int *)afl_realloc(AFL_BUF_PARAM(in_scratch), n * sizeof(u32)); if (!P || !S || !L || !afl->alias_table || !afl->alias_probability) { @@ -247,11 +263,11 @@ void create_alias_table(afl_state_t *afl) { void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) { - u8 fn[PATH_MAX]; - s32 fd; + char fn[PATH_MAX]; + s32 fd; snprintf(fn, PATH_MAX, "%s/queue/.state/deterministic_done/%s", afl->out_dir, - strrchr(q->fname, '/') + 1); + strrchr((char *)q->fname, '/') + 1); fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); if (fd < 0) { PFATAL("Unable to create '%s'", fn); } @@ -266,10 +282,10 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) { void mark_as_variable(afl_state_t *afl, struct queue_entry *q) { - u8 fn[PATH_MAX]; - u8 ldest[PATH_MAX]; + char fn[PATH_MAX]; + char ldest[PATH_MAX]; - u8 *fn_name = strrchr(q->fname, '/') + 1; + char *fn_name = strrchr((char *)q->fname, '/') + 1; sprintf(ldest, "../../%s", fn_name); sprintf(fn, "%s/queue/.state/variable_behavior/%s", afl->out_dir, fn_name); @@ -293,12 +309,12 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { if (likely(state == q->fs_redundant)) { return; } - u8 fn[PATH_MAX]; + char fn[PATH_MAX]; q->fs_redundant = state; sprintf(fn, "%s/queue/.state/redundant_edges/%s", afl->out_dir, - strrchr(q->fname, '/') + 1); + strrchr((char *)q->fname, '/') + 1); if (state) { @@ -409,7 +425,7 @@ u8 check_if_text_buf(u8 *buf, u32 len) { static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) { - if (q->len < AFL_TXT_MIN_LEN) return 0; + if (q->len < AFL_TXT_MIN_LEN || q->len < AFL_TXT_MAX_LEN) return 0; u8 *buf; int fd; @@ -417,8 +433,8 @@ static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) { ssize_t comp; if (len >= MAX_FILE) len = MAX_FILE - 1; - if ((fd = open(q->fname, O_RDONLY)) < 0) return 0; - buf = afl_realloc(AFL_BUF_PARAM(in_scratch), len + 1); + if ((fd = open((char *)q->fname, O_RDONLY)) < 0) return 0; + buf = (u8 *)afl_realloc(AFL_BUF_PARAM(in_scratch), len + 1); comp = read(fd, buf, len); close(fd); if (comp != (ssize_t)len) return 0; @@ -520,7 +536,8 @@ static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) { void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { - struct queue_entry *q = ck_alloc(sizeof(struct queue_entry)); + struct queue_entry *q = + (struct queue_entry *)ck_alloc(sizeof(struct queue_entry)); q->fname = fname; q->len = len; @@ -554,7 +571,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { afl->cycles_wo_finds = 0; - struct queue_entry **queue_buf = afl_realloc( + struct queue_entry **queue_buf = (struct queue_entry **)afl_realloc( AFL_BUF_PARAM(queue), afl->queued_items * sizeof(struct queue_entry *)); if (unlikely(!queue_buf)) { PFATAL("alloc"); } queue_buf[afl->queued_items - 1] = q; @@ -574,7 +591,11 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { } /* only redqueen currently uses is_ascii */ - if (afl->shm.cmplog_mode) q->is_ascii = check_if_text(afl, q); + if (unlikely(afl->shm.cmplog_mode && !q->is_ascii)) { + + q->is_ascii = check_if_text(afl, q); + + } } @@ -704,7 +725,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { if (!q->trace_mini) { u32 len = (afl->fsrv.map_size >> 3); - q->trace_mini = ck_alloc(len); + q->trace_mini = (u8 *)ck_alloc(len); minimize_bits(afl, q->trace_mini, afl->fsrv.trace_bits); } @@ -1090,19 +1111,19 @@ inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q, if (len != old_len) { afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len; - q->testcase_buf = realloc(q->testcase_buf, len); + q->testcase_buf = (u8 *)realloc(q->testcase_buf, len); if (unlikely(!q->testcase_buf)) { - PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len); } } - int fd = open(q->fname, O_RDONLY); + int fd = open((char *)q->fname, O_RDONLY); - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", (char *)q->fname); } ck_read(fd, q->testcase_buf, len, q->fname); close(fd); @@ -1122,7 +1143,7 @@ inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q, if (likely(len != old_len)) { - u8 *ptr = realloc(q->testcase_buf, len); + u8 *ptr = (u8 *)realloc(q->testcase_buf, len); if (likely(ptr)) { @@ -1154,23 +1175,23 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { if (unlikely(q == afl->queue_cur)) { - buf = afl_realloc((void **)&afl->testcase_buf, len); + buf = (u8 *)afl_realloc((void **)&afl->testcase_buf, len); } else { - buf = afl_realloc((void **)&afl->splicecase_buf, len); + buf = (u8 *)afl_realloc((void **)&afl->splicecase_buf, len); } if (unlikely(!buf)) { - PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len); } - int fd = open(q->fname, O_RDONLY); + int fd = open((char *)q->fname, O_RDONLY); - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", (char *)q->fname); } ck_read(fd, buf, len, q->fname); close(fd); @@ -1214,7 +1235,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { do_once = 1; // release unneeded memory - afl->q_testcase_cache = ck_realloc( + afl->q_testcase_cache = (struct queue_entry **)ck_realloc( afl->q_testcase_cache, (afl->q_testcase_max_cache_entries + 1) * sizeof(size_t)); @@ -1261,15 +1282,15 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) { /* Map the test case into memory. */ - int fd = open(q->fname, O_RDONLY); + int fd = open((char *)q->fname, O_RDONLY); - if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", q->fname); } + if (unlikely(fd < 0)) { PFATAL("Unable to open '%s'", (char *)q->fname); } - q->testcase_buf = malloc(len); + q->testcase_buf = (u8 *)malloc(len); if (unlikely(!q->testcase_buf)) { - PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len); } @@ -1332,11 +1353,11 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q, /* Map the test case into memory. */ - q->testcase_buf = malloc(len); + q->testcase_buf = (u8 *)malloc(len); if (unlikely(!q->testcase_buf)) { - PFATAL("Unable to malloc '%s' with len %u", q->fname, len); + PFATAL("Unable to malloc '%s' with len %u", (char *)q->fname, len); } -- cgit 1.4.1 From 80eabd6e8a30c2ffc0f084ab34df8b9d582419c3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 13 Feb 2023 11:34:14 +0100 Subject: AFL_LLVM_DICT2FILE_NO_MAIN support --- TODO.md | 3 +-- docs/Changelog.md | 1 + docs/env_variables.md | 3 +++ docs/fuzzing_in_depth.md | 4 +++- include/envs.h | 1 + instrumentation/README.llvm.md | 4 ++++ instrumentation/SanitizerCoverageLTO.so.cc | 11 ++++++++++- instrumentation/afl-llvm-dict2file.so.cc | 17 ++++++++++++++--- src/afl-cc.c | 5 ++++- 9 files changed, 41 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/TODO.md b/TODO.md index 862224f0..187fa191 100644 --- a/TODO.md +++ b/TODO.md @@ -9,13 +9,12 @@ - afl-plot to support multiple plot_data - parallel builds for source-only targets - get rid of check_binary, replace with more forkserver communication - - first fuzzer should be a main automatically + - first fuzzer should be a main automatically? not sure. ## Maybe - forkserver tells afl-fuzz if cmplog is supported and if so enable it by default, with AFL_CMPLOG_NO=1 (?) set to skip? - - afl_custom_fuzz_splice_optin() - afl_custom_splice() - cmdline option from-to range for mutations diff --git a/docs/Changelog.md b/docs/Changelog.md index eee88a51..89c37912 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,6 +10,7 @@ - add CFI sanitizer variant to gcc targets - llvm 16 support (thanks to @devnexen!) - support llvm 15 native pcguard changes + - LTO autoken and llvm_mode: added AFL_LLVM_DICT2FILE_NO_MAIN support - better sanitizer default options support for all tools - unicorn_mode: updated and minor issues fixed - frida_mode: fix issue on MacOS diff --git a/docs/env_variables.md b/docs/env_variables.md index 0a57d190..61fb1e2b 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -129,6 +129,9 @@ subset of the settings discussed in section 1, with the exception of: write all constant string comparisons to this file to be used later with afl-fuzz' `-x` option. + - An option to `AFL_LLVM_DICT2FILE` is `AFL_LLVM_DICT2FILE_NO_MAIN=1` which + skill not parse `main()`. + - `TMPDIR` and `AFL_KEEP_ASSEMBLY`, since no temporary assembly files are created. diff --git a/docs/fuzzing_in_depth.md b/docs/fuzzing_in_depth.md index 87f31a58..efab0633 100644 --- a/docs/fuzzing_in_depth.md +++ b/docs/fuzzing_in_depth.md @@ -534,6 +534,8 @@ dictionaries/FORMAT.dict`. * With `afl-clang-fast`, you can set `AFL_LLVM_DICT2FILE=/full/path/to/new/file.dic` to automatically generate a dictionary during target compilation. + Adding `AFL_LLVM_DICT2FILE_NO_MAIN=1` to not parse main (usually command line + parameter parsing) is often a good idea too. * You also have the option to generate a dictionary yourself during an independent run of the target, see [utils/libtokencap/README.md](../utils/libtokencap/README.md). @@ -935,7 +937,7 @@ phase and start fuzzing at once. 3. Also randomize the afl-fuzz runtime options, e.g.: * 65% for `AFL_DISABLE_TRIM` * 50% for `AFL_KEEP_TIMEOUTS` - * 50% use a dictionary generated by `AFL_LLVM_DICT2FILE` + * 50% use a dictionary generated by `AFL_LLVM_DICT2FILE` + `AFL_LLVM_DICT2FILE_NO_MAIN=1` * 40% use MOpt (`-L 0`) * 40% for `AFL_EXPAND_HAVOC_NOW` * 20% for old queue processing (`-Z`) diff --git a/include/envs.h b/include/envs.h index 0770f94d..5018b0f8 100644 --- a/include/envs.h +++ b/include/envs.h @@ -133,6 +133,7 @@ static char *afl_environment_variables[] = { "AFL_LLVM_CTX", "AFL_LLVM_CTX_K", "AFL_LLVM_DICT2FILE", + "AFL_LLVM_DICT2FILE_NO_MAIN", "AFL_LLVM_DOCUMENT_IDS", "AFL_LLVM_INSTRIM_LOOPHEAD", "AFL_LLVM_INSTRUMENT", diff --git a/instrumentation/README.llvm.md b/instrumentation/README.llvm.md index 9da1b0f6..c0677474 100644 --- a/instrumentation/README.llvm.md +++ b/instrumentation/README.llvm.md @@ -167,6 +167,10 @@ Just specify `AFL_LLVM_DICT2FILE=/absolute/path/file.txt` and during compilation all constant string compare parameters will be written to this file to be used with afl-fuzz' `-x` option. +Adding `AFL_LLVM_DICT2FILE_NO_MAIN=1` will skip parsing `main()` which often +does command line parsing which has string comparisons that are not helpful +for fuzzing. + ## 6) AFL++ Context Sensitive Branch Coverage ### What is this? diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 231151f5..f82224ed 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -236,6 +236,7 @@ class ModuleSanitizerCoverageLTO // const SpecialCaseList * Allowlist; // const SpecialCaseList * Blocklist; uint32_t autodictionary = 1; + uint32_t autodictionary_no_main = 0; uint32_t inst = 0; uint32_t afl_global_id = 0; uint32_t unhandled = 0; @@ -411,7 +412,8 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( /* Show a banner */ setvbuf(stdout, NULL, _IONBF, 0); - if (getenv("AFL_DEBUG")) debug = 1; + if (getenv("AFL_DEBUG")) { debug = 1; } + if (getenv("AFL_LLVM_DICT2FILE_NO_MAIN")) { autodictionary_no_main = 1; } if ((isatty(2) && !getenv("AFL_QUIET")) || debug) { @@ -503,6 +505,13 @@ bool ModuleSanitizerCoverageLTO::instrumentModule( if (!isInInstrumentList(&F, MNAME) || !F.size()) { continue; } + if (autodictionary_no_main && + (!F.getName().compare("main") || !F.getName().compare("_main"))) { + + continue; + + } + for (auto &BB : F) { for (auto &IN : BB) { diff --git a/instrumentation/afl-llvm-dict2file.so.cc b/instrumentation/afl-llvm-dict2file.so.cc index bbbbe32c..97f1d47f 100644 --- a/instrumentation/afl-llvm-dict2file.so.cc +++ b/instrumentation/afl-llvm-dict2file.so.cc @@ -182,7 +182,7 @@ bool AFLdict2filePass::runOnModule(Module &M) { DenseMap valueMap; char *ptr; - int found = 0; + int found = 0, handle_main = 1; /* Show a banner */ setvbuf(stdout, NULL, _IONBF, 0); @@ -192,10 +192,14 @@ bool AFLdict2filePass::runOnModule(Module &M) { SAYF(cCYA "afl-llvm-dict2file" VERSION cRST " by Marc \"vanHauser\" Heuse \n"); - } else + } else { be_quiet = 1; + } + + if (getenv("AFL_LLVM_DICT2FILE_NO_MAIN")) { handle_main = 0; } + scanForDangerousFunctions(&M); ptr = getenv("AFL_LLVM_DICT2FILE"); @@ -210,7 +214,14 @@ bool AFLdict2filePass::runOnModule(Module &M) { for (auto &F : M) { - if (isIgnoreFunction(&F)) continue; + if (!handle_main && + (!F.getName().compare("main") || !F.getName().compare("_main"))) { + + continue; + + } + + if (isIgnoreFunction(&F)) { continue; } if (!isInInstrumentList(&F, MNAME) || !F.size()) { continue; } /* Some implementation notes. diff --git a/src/afl-cc.c b/src/afl-cc.c index 7c3682fb..7b059d40 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -2041,6 +2041,8 @@ int main(int argc, char **argv, char **envp) { " AFL_LLVM_DICT2FILE: generate an afl dictionary based on found " "comparisons\n" + " AFL_LLVM_DICT2FILE_NO_MAIN: skip parsing main() for the " + "dictionary\n" " AFL_LLVM_LAF_ALL: enables all LAF splits/transforms\n" " AFL_LLVM_LAF_SPLIT_COMPARES: enable cascaded comparisons\n" " AFL_LLVM_LAF_SPLIT_COMPARES_BITW: size limit (default 8)\n" @@ -2128,7 +2130,8 @@ int main(int argc, char **argv, char **envp) { "defaults.\n" "Recommended is afl-clang-lto with AFL_LLVM_CMPLOG or afl-clang-fast " "with\n" - "AFL_LLVM_CMPLOG and AFL_LLVM_DICT2FILE.\n\n"); + "AFL_LLVM_CMPLOG and " + "AFL_LLVM_DICT2FILE+AFL_LLVM_DICT2FILE_NO_MAIN.\n\n"); exit(1); -- cgit 1.4.1 From 668f5e1fa9c126bb8c751a6e4ef038ae60a442fa Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 15 Feb 2023 09:32:32 +0100 Subject: debug output --- custom_mutators/autotokens/Makefile | 8 ++++++-- custom_mutators/autotokens/autotokens.cpp | 17 ++++++++++++++++- docs/Changelog.md | 1 + docs/env_variables.md | 2 ++ include/afl-fuzz.h | 2 +- include/envs.h | 1 + src/afl-fuzz-init.c | 2 +- src/afl-fuzz-one.c | 2 +- src/afl-fuzz-run.c | 2 +- src/afl-fuzz-state.c | 7 +++++++ 10 files changed, 37 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/custom_mutators/autotokens/Makefile b/custom_mutators/autotokens/Makefile index 6ee7d324..0daba17d 100644 --- a/custom_mutators/autotokens/Makefile +++ b/custom_mutators/autotokens/Makefile @@ -13,10 +13,14 @@ endif all: autotokens.so -autotokens.so: autotokens.cpp +afl-fuzz-queue.o: ../../src/afl-fuzz-queue.c $(CC) -D_STANDALONE_MODULE=1 -I../../include -g -O3 $(CPPFLAGS) -fPIC -c -o ./afl-fuzz-queue.o ../../src/afl-fuzz-queue.c + +afl-common.o: ../../src/afl-common.c $(CC) -I../../include -g -O3 $(CPPFLAGS) -DBIN_PATH=\"dummy\" -Wno-pointer-sign -fPIC -c -o ./afl-common.o ../../src/afl-common.c + +autotokens.so: afl-fuzz-queue.o afl-common.o autotokens.cpp $(CXX) -Wno-deprecated -g -O3 $(CXXFLAGS) $(CPPFLAGS) -shared -fPIC -o autotokens.so -I../../include autotokens.cpp ./afl-fuzz-queue.o ../../src/afl-performance.o ./afl-common.o clean: - rm -f autotokens.so *~ core + rm -f autotokens.so *.o *~ core diff --git a/custom_mutators/autotokens/autotokens.cpp b/custom_mutators/autotokens/autotokens.cpp index cda90a38..043d9588 100644 --- a/custom_mutators/autotokens/autotokens.cpp +++ b/custom_mutators/autotokens/autotokens.cpp @@ -145,6 +145,9 @@ static void first_run(void *data) { if ((valid * 100) / afl_ptr->extras_cnt < 95) { module_disabled = 1; } + DEBUGF(stderr, "DICT: valid %u, total %u, %u < 95 == disable\n", valid, + afl_ptr->extras_cnt, (u32)((valid * 100) / afl_ptr->extras_cnt)); + } else { module_disabled = 1; @@ -190,6 +193,10 @@ static void first_run(void *data) { if ((is_ascii * 100) / valid < 70) { module_disabled = 1; } + DEBUGF(stderr, "seeds: total %u, valid %u, ascii %u, %u < 70 == disabled\n", + afl_ptr->active_items, valid, is_ascii, + (u32)((is_ascii * 100) / valid)); + } static u32 good_whitespace_or_singleval() { @@ -538,7 +545,15 @@ extern "C" unsigned char afl_custom_queue_get(void *data, is_first_run = 0; first_run(data); - if (module_disabled) { WARNF("Autotokens custom module is disabled."); } + if (module_disabled) { + + WARNF("Autotokens custom module is disabled."); + + } else if (auto_disable) { + + OKF("Autotokens custom module is enabled."); + + } } diff --git a/docs/Changelog.md b/docs/Changelog.md index 89c37912..5f253064 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -6,6 +6,7 @@ ### Version ++4.06a (dev) - afl-fuzz: - ensure temporary file descriptor is closed when not used + - added `AFL_NO_WARN_INSTABILITY` - afl-cc: - add CFI sanitizer variant to gcc targets - llvm 16 support (thanks to @devnexen!) diff --git a/docs/env_variables.md b/docs/env_variables.md index 61fb1e2b..7a574e59 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -482,6 +482,8 @@ checks or alter some of the more exotic semantics of the tool: - Setting `AFL_NO_STARTUP_CALIBRATION` will skip the initial calibration of all starting seeds, and start fuzzing at once. + - Setting `AFL_NO_WARN_INSTABILITY` will suppress instability warnings. + - In QEMU mode (-Q) and FRIDA mode (-O), `AFL_PATH` will be searched for afl-qemu-trace and afl-frida-trace.so. diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 229bc025..9bf91faf 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -399,7 +399,7 @@ typedef struct afl_env_vars { afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme, - afl_ignore_timeouts, afl_no_startup_calibration; + afl_ignore_timeouts, afl_no_startup_calibration, afl_no_warn_instability; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, diff --git a/include/envs.h b/include/envs.h index 5018b0f8..56675eda 100644 --- a/include/envs.h +++ b/include/envs.h @@ -172,6 +172,7 @@ static char *afl_environment_variables[] = { "AFL_NO_UI", "AFL_NO_PYTHON", "AFL_NO_STARTUP_CALIBRATION", + "AFL_NO_WARN_INSTABILITY", "AFL_UNTRACER_FILE", "AFL_LLVM_USE_TRACE_PC", "AFL_MAP_SIZE", diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 1182bd41..c20965b4 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1120,7 +1120,7 @@ void perform_dry_run(afl_state_t *afl) { } - if (q->var_behavior) { + if (unlikely(q->var_behavior && !afl->afl_env.afl_no_warn_instability)) { WARNF("Instrumentation output varies across runs."); diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 2f016217..e97db273 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -1988,7 +1988,7 @@ custom_mutator_stage: if (unlikely(!mutated_buf)) { - //FATAL("Error in custom_fuzz. Size returned: %zu", mutated_size); + // FATAL("Error in custom_fuzz. Size returned: %zu", mutated_size); break; } diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 7dd83150..f5425011 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -523,7 +523,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } - if (unlikely(!var_detected)) { + if (unlikely(!var_detected && !afl->afl_env.afl_no_warn_instability)) { // note: from_queue seems to only be set during initialization if (afl->afl_env.afl_no_ui || from_queue) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 104b1e4b..6d8c8758 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -204,6 +204,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_no_affinity = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_NO_WARN_INSTABILITY", + + afl_environment_variable_len)) { + + afl->afl_env.afl_no_warn_instability = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_TRY_AFFINITY", afl_environment_variable_len)) { -- cgit 1.4.1 From 0c0a6c3bfabf0facaed33fae1aa5ad54a6a11b32 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 23 Feb 2023 11:22:40 +0100 Subject: regression fix --- include/config.h | 2 +- src/afl-forkserver.c | 2 +- src/afl-fuzz-cmplog.c | 8 ++++++-- src/afl-fuzz.c | 3 ++- src/afl-gotcpu.c | 4 ++-- 5 files changed, 12 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/include/config.h b/include/config.h index ad8b76a8..e46f515a 100644 --- a/include/config.h +++ b/include/config.h @@ -489,7 +489,7 @@ /* Minimum length of a queue input to be evaluated for "is_ascii"? */ -#define AFL_TXT_MIN_LEN 16 +#define AFL_TXT_MIN_LEN 12 /* Maximum length of a queue input to be evaluated for "is_ascii"? */ diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 5aa4c2ff..50dc7a26 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -59,7 +59,7 @@ static list_t fsrv_list = {.element_prealloc_count = 0}; static void fsrv_exec_child(afl_forkserver_t *fsrv, char **argv) { - if (fsrv->qemu_mode || fsrv->cs_mode) { + if (fsrv->qemu_mode || fsrv->frida_mode || fsrv->cs_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); diff --git a/src/afl-fuzz-cmplog.c b/src/afl-fuzz-cmplog.c index 2bf26d19..229aef09 100644 --- a/src/afl-fuzz-cmplog.c +++ b/src/afl-fuzz-cmplog.c @@ -33,11 +33,15 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) { setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1); - if (fsrv->qemu_mode) { setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); } + if (fsrv->qemu_mode || fsrv->frida_mode || fsrv->cs_mode) { + + setenv("AFL_DISABLE_LLVM_INSTRUMENTATION", "1", 0); + + } if (!fsrv->qemu_mode && !fsrv->frida_mode && argv[0] != fsrv->cmplog_binary) { - argv[0] = fsrv->cmplog_binary; + fsrv->target_path = argv[0] = fsrv->cmplog_binary; } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ea467401..4914ce0b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1298,7 +1298,8 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->is_main_node == 1 && afl->schedule != FAST && afl->schedule != EXPLORE) { + if (afl->is_main_node == 1 && afl->schedule != FAST && + afl->schedule != EXPLORE) { FATAL("-M is compatible only with fast and explore -p power schedules"); diff --git a/src/afl-gotcpu.c b/src/afl-gotcpu.c index 8988fd54..4f851099 100644 --- a/src/afl-gotcpu.c +++ b/src/afl-gotcpu.c @@ -92,7 +92,7 @@ static u32 measure_preemption(u32 target_ms) { volatile u32 v1, v2 = 0; u64 st_t, en_t, st_c, en_c, real_delta, slice_delta; - //s32 loop_repeats = 0; + // s32 loop_repeats = 0; st_t = get_cur_time_us(); st_c = get_cpu_usage_us(); @@ -113,7 +113,7 @@ repeat_loop: if (en_t - st_t < target_ms * 1000) { - //loop_repeats++; + // loop_repeats++; goto repeat_loop; } -- cgit 1.4.1 From 07cf27cddc6f0189ee9b21f888595c84549b5b93 Mon Sep 17 00:00:00 2001 From: Amit Elkabetz <12958411+amitelka@users.noreply.github.com> Date: Sun, 5 Mar 2023 18:16:21 +0200 Subject: Added flag -u to allow custom interval to update fuzzer_stats file --- include/afl-fuzz.h | 1 + src/afl-fuzz-state.c | 1 + src/afl-fuzz-stats.c | 2 +- src/afl-fuzz.c | 17 ++++++++++++++--- 4 files changed, 17 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 9bf91faf..62d71968 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -693,6 +693,7 @@ typedef struct afl_state { /* statistics file */ double last_bitmap_cvg, last_stability, last_eps; + u64 stats_file_update_freq_msecs; /* Stats update frequency (msecs) */ /* plot file saves from last run */ u32 plot_prev_qp, plot_prev_pf, plot_prev_pnf, plot_prev_ce, plot_prev_md; diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 6d8c8758..e319c512 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -100,6 +100,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) { afl->hang_tmout = EXEC_TIMEOUT; afl->exit_on_time = 0; afl->stats_update_freq = 1; + afl->stats_file_update_freq_msecs = STATS_UPDATE_SEC * 1000; afl->stats_avg_exec = 0; afl->skip_deterministic = 1; afl->sync_time = SYNC_TIME; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index bfd30845..0e36227f 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -613,7 +613,7 @@ void show_stats_normal(afl_state_t *afl) { if (unlikely(!afl->non_instrumented_mode && (afl->force_ui_update || - cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000))) { + cur_ms - afl->stats_last_stats_ms > afl->stats_file_update_freq_msecs))) { afl->stats_last_stats_ms = cur_ms; write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio, diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 4914ce0b..efbab289 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -210,7 +210,10 @@ static void usage(u8 *argv0, int more_help) { " -b cpu_id - bind the fuzzing process to the specified CPU core " "(0-...)\n" " -e ext - file extension for the fuzz test input file (if " - "needed)\n\n", + "needed)\n" + " -u - interval to update fuzzer_stats file in seconds, " + "defaults to 60 sec\n" + "\n", argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX); if (more_help > 1) { @@ -501,7 +504,7 @@ fail: int main(int argc, char **argv_orig, char **envp) { s32 opt, auto_sync = 0 /*, user_set_cache = 0*/; - u64 prev_queued = 0; + u64 prev_queued = 0, stats_update_freq_sec = 0; u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, default_output = 1, map_size = get_map_size(); u8 *extras_dir[4]; @@ -553,7 +556,7 @@ int main(int argc, char **argv_orig, char **envp) { while ( (opt = getopt( argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > + "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:u:UV:WXx:YZ")) > 0) { switch (opt) { @@ -665,6 +668,14 @@ int main(int argc, char **argv_orig, char **envp) { break; + case 'u': + if (sscanf(optarg, "%llu", &stats_update_freq_sec) < 1) { + FATAL("Bad syntax used for -u"); + } + + afl->stats_file_update_freq_msecs = stats_update_freq_sec * 1000; + break; + case 'i': /* input dir */ if (afl->in_dir) { FATAL("Multiple -i options not supported"); } -- cgit 1.4.1 From 403d95d2d2c7a9bd72eca5ea91743f8d835845ef Mon Sep 17 00:00:00 2001 From: Amit Elkabetz <12958411+amitelka@users.noreply.github.com> Date: Sun, 5 Mar 2023 18:21:35 +0200 Subject: auto code format fixes --- include/afl-fuzz.h | 2 +- src/afl-fuzz-stats.c | 7 ++++--- src/afl-fuzz.c | 10 +++++----- 3 files changed, 10 insertions(+), 9 deletions(-) (limited to 'include') diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 62d71968..6a8e8b5d 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -693,7 +693,7 @@ typedef struct afl_state { /* statistics file */ double last_bitmap_cvg, last_stability, last_eps; - u64 stats_file_update_freq_msecs; /* Stats update frequency (msecs) */ + u64 stats_file_update_freq_msecs; /* Stats update frequency (msecs) */ /* plot file saves from last run */ u32 plot_prev_qp, plot_prev_pf, plot_prev_pnf, plot_prev_ce, plot_prev_md; diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 0e36227f..db4bf24e 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -611,9 +611,10 @@ void show_stats_normal(afl_state_t *afl) { /* Roughly every minute, update fuzzer stats and save auto tokens. */ - if (unlikely(!afl->non_instrumented_mode && - (afl->force_ui_update || - cur_ms - afl->stats_last_stats_ms > afl->stats_file_update_freq_msecs))) { + if (unlikely( + !afl->non_instrumented_mode && + (afl->force_ui_update || cur_ms - afl->stats_last_stats_ms > + afl->stats_file_update_freq_msecs))) { afl->stats_last_stats_ms = cur_ms; write_stats_file(afl, t_bytes, t_byte_ratio, stab_ratio, diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index efbab289..9ca88b5b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -553,11 +553,9 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - while ( - (opt = getopt( - argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:u:UV:WXx:YZ")) > - 0) { + while ((opt = getopt(argc, argv, + "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:u:" + "UV:WXx:YZ")) > 0) { switch (opt) { @@ -670,7 +668,9 @@ int main(int argc, char **argv_orig, char **envp) { case 'u': if (sscanf(optarg, "%llu", &stats_update_freq_sec) < 1) { + FATAL("Bad syntax used for -u"); + } afl->stats_file_update_freq_msecs = stats_update_freq_sec * 1000; -- cgit 1.4.1 From e9e440d7f33a61793c63f90f9555ff3c0f45b3b4 Mon Sep 17 00:00:00 2001 From: Amit Elkabetz <12958411+amitelka@users.noreply.github.com> Date: Sun, 5 Mar 2023 20:25:39 +0200 Subject: Fixed according to PR comment, moved cli flag to an env variable --- docs/env_variables.md | 6 ++++++ include/envs.h | 1 + src/afl-fuzz-state.c | 20 ++++++++++++++++++++ src/afl-fuzz.c | 26 ++++++++------------------ 4 files changed, 35 insertions(+), 18 deletions(-) (limited to 'include') diff --git a/docs/env_variables.md b/docs/env_variables.md index 6cd4104b..c9dc1bbd 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -584,6 +584,12 @@ checks or alter some of the more exotic semantics of the tool: - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to 0 to disable although it is 1st of April. + - If you need a specific interval to update fuzzer_stats file, you can + set `AFL_FUZZER_STATS_UPDATE_INTERVAL` to the interval in seconds you'd + the file to be updated. + Note that will not be exact and with slow targets it can take seconds + until there is a slice for the time test. + ## 5) Settings for afl-qemu-trace The QEMU wrapper used to instrument binary-only code supports several settings: diff --git a/include/envs.h b/include/envs.h index cf069a00..066921b9 100644 --- a/include/envs.h +++ b/include/envs.h @@ -91,6 +91,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_TRACEABLE", "AFL_FRIDA_VERBOSE", "AFL_FUZZER_ARGS", // oss-fuzz + "AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST", "AFL_GCC_DENYLIST", diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index e319c512..8964f38e 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -24,6 +24,7 @@ */ #include +#include #include "afl-fuzz.h" #include "envs.h" @@ -566,6 +567,25 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } + } else if (!strncmp(env, "AFL_FUZZER_STATS_UPDATE_INTERVAL", + + afl_environment_variable_len)) { + + u64 stats_update_freq_sec = + strtoull(get_afl_env(afl_environment_variables[i]), NULL, 0); + if (ULLONG_MAX == stats_update_freq_sec || + 0 == stats_update_freq_sec) { + + WARNF( + "Incorrect value given to AFL_FUZZER_STATS_UPDATE_INTERVAL, " + "using default of 60 seconds\n"); + + } else { + + afl->stats_file_update_freq_msecs = stats_update_freq_sec * 1000; + + } + } } else { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 78d9da71..d7708fdf 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -211,8 +211,6 @@ static void usage(u8 *argv0, int more_help) { "(0-...)\n" " -e ext - file extension for the fuzz test input file (if " "needed)\n" - " -u - interval to update fuzzer_stats file in seconds, " - "defaults to 60 sec, minimum interval: 1 sec\n" "\n", argv0, EXEC_TIMEOUT, MEM_LIMIT, MAX_FILE, FOREIGN_SYNCS_MAX); @@ -315,6 +313,8 @@ static void usage(u8 *argv0, int more_help) { " afl-clang-lto/afl-gcc-fast target\n" "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n" "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so)\n" + "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in seconds, " + "(default: 60, minimum: 1)\n" "\n" ); @@ -504,7 +504,7 @@ fail: int main(int argc, char **argv_orig, char **envp) { s32 opt, auto_sync = 0 /*, user_set_cache = 0*/; - u64 prev_queued = 0, stats_update_freq_sec = 0; + u64 prev_queued = 0; u32 sync_interval_cnt = 0, seek_to = 0, show_help = 0, default_output = 1, map_size = get_map_size(); u8 *extras_dir[4]; @@ -553,9 +553,11 @@ int main(int argc, char **argv_orig, char **envp) { afl->shmem_testcase_mode = 1; // we always try to perform shmem fuzzing - while ((opt = getopt(argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:u:" - "UV:WXx:YZ")) > 0) { + while ( + (opt = getopt( + argc, argv, + "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > + 0) { switch (opt) { @@ -666,18 +668,6 @@ int main(int argc, char **argv_orig, char **envp) { break; - case 'u': - if (sscanf(optarg, "%llu", &stats_update_freq_sec) < 1) { - - FATAL("Bad syntax used for -u"); - - } - - if (stats_update_freq_sec < 1) { FATAL("-u interval must be >= 1"); } - - afl->stats_file_update_freq_msecs = stats_update_freq_sec * 1000; - break; - case 'i': /* input dir */ if (afl->in_dir) { FATAL("Multiple -i options not supported"); } -- cgit 1.4.1 From 5221938945cc5ff15af04b727c6a7e0085005044 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 9 Mar 2023 17:36:13 +0100 Subject: various fixes --- docs/Changelog.md | 2 +- include/common.h | 3 +++ instrumentation/afl-compiler-rt.o.c | 18 ++++++++++++------ src/afl-analyze.c | 4 ++++ src/afl-common.c | 37 ++++++++++++++++++++++++++++++------- src/afl-fuzz-init.c | 19 ++++++++++++------- src/afl-fuzz-stats.c | 2 +- src/afl-showmap.c | 4 ++++ src/afl-tmin.c | 4 ++++ 9 files changed, 71 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 5287d038..25c1f6bc 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -20,7 +20,7 @@ - better sanitizer default options support for all tools - unicorn_mode: updated and minor issues fixed - frida_mode: fix issue on MacOS - - more minor fixes + - more minor fixes and cross-platform support ### Version ++4.05c (release) - MacOS: libdislocator, libtokencap etc. do not work with modern diff --git a/include/common.h b/include/common.h index c5a32cdb..5d198468 100644 --- a/include/common.h +++ b/include/common.h @@ -143,5 +143,8 @@ FILE *create_ffile(u8 *fn); /* create a file */ s32 create_file(u8 *fn); +/* memmem implementation as not all platforms support this */ +void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); + #endif diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 94022a65..a88396d4 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1622,17 +1622,23 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { } - if (__afl_already_initialized_shm && __afl_final_loc > __afl_map_size) { + if (__afl_already_initialized_shm) { - if (__afl_debug) { + if (__afl_final_loc > __afl_map_size) { + + if (__afl_debug) { + + fprintf(stderr, "Reinit shm necessary (+%u)\n", + __afl_final_loc - __afl_map_size); + + } - fprintf(stderr, "Reinit shm necessary (+%u)\n", - __afl_final_loc - __afl_map_size); + __afl_unmap_shm(); + __afl_map_shm(); } - __afl_unmap_shm(); - __afl_map_shm(); + __afl_map_size = __afl_final_loc + 1; } diff --git a/src/afl-analyze.c b/src/afl-analyze.c index d4a9aa91..9734f75c 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -725,7 +725,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; + #ifdef SA_RESTART sa.sa_flags = SA_RESTART; + #else + sa.sa_flags = 0; + #endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-common.c b/src/afl-common.c index b0df1994..86226c9f 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -58,6 +58,25 @@ u8 last_intr = 0; #define AFL_PATH "/usr/local/lib/afl/" #endif +void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, + size_t needlelen) { + + if (unlikely(needlelen > haystacklen)) { return NULL; } + + for (u32 i = 0; i <= haystacklen - needlelen; ++i) { + + if (unlikely(memcmp(haystack + i, needle, needlelen) == 0)) { + + return (void *)(haystack + i); + + } + + } + + return (void *)NULL; + +} + void set_sanitizer_defaults() { /* Set sane defaults for ASAN if nothing else is specified. */ @@ -67,9 +86,9 @@ void set_sanitizer_defaults() { u8 *have_lsan_options = getenv("LSAN_OPTIONS"); u8 have_san_options = 0; u8 default_options[1024] = - "detect_odr_violation=0:abort_on_error=1:symbolize=0:malloc_context_" - "size=0:allocator_may_return_null=1:handle_segv=0:handle_sigbus=0:" - "handle_abort=0:handle_sigfpe=0:handle_sigill=0:"; + "detect_odr_violation=0:abort_on_error=1:symbolize=0:allocator_may_" + "return_null=1:handle_segv=0:handle_sigbus=0:handle_abort=0:handle_" + "sigfpe=0:handle_sigill=0:"; if (have_asan_options || have_ubsan_options || have_msan_options || have_lsan_options) { @@ -84,14 +103,18 @@ void set_sanitizer_defaults() { u8 buf[2048] = ""; if (!have_san_options) { strcpy(buf, default_options); } - strcat(buf, "exitcode=" STRINGIFY(LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:detect_leaks=1:"); + strcat(buf, "exitcode=" STRINGIFY(LSAN_ERROR) ":fast_unwind_on_malloc=0:print_suppressions=0:detect_leaks=1:malloc_context_size=30:"); setenv("LSAN_OPTIONS", buf, 1); } /* for everything not LSAN we disable detect_leaks */ - if (!have_lsan_options) { strcat(default_options, "detect_leaks=0:"); } + if (!have_lsan_options) { + + strcat(default_options, "detect_leaks=0:malloc_context_size=0:"); + + } /* Set sane defaults for ASAN if nothing else is specified. */ @@ -130,7 +153,7 @@ u32 check_binary_signatures(u8 *fn) { if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); } close(fd); - if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { + if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { if (!be_quiet) { OKF(cPIN "Persistent mode binary detected."); } setenv(PERSIST_ENV_VAR, "1", 1); @@ -155,7 +178,7 @@ u32 check_binary_signatures(u8 *fn) { } - if (memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { + if (afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { if (!be_quiet) { OKF(cPIN "Deferred forkserver binary detected."); } setenv(DEFER_ENV_VAR, "1", 1); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index c20965b4..3b441eee 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -24,7 +24,9 @@ */ #include "afl-fuzz.h" +#include "common.h" #include +#include #include "cmplog.h" #ifdef HAVE_AFFINITY @@ -2786,7 +2788,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { !afl->fsrv.nyx_mode && #endif !afl->fsrv.cs_mode && !afl->non_instrumented_mode && - !memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { + !afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { SAYF("\n" cLRD "[-] " cRST "Looks like the target binary is not instrumented! The fuzzer depends " @@ -2817,7 +2819,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } if ((afl->fsrv.cs_mode || afl->fsrv.qemu_mode || afl->fsrv.frida_mode) && - memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { + afl_memmem(f_data, f_len, SHM_ENV_VAR, strlen(SHM_ENV_VAR) + 1)) { SAYF("\n" cLRD "[-] " cRST "This program appears to be instrumented with afl-gcc, but is being " @@ -2830,9 +2832,9 @@ void check_binary(afl_state_t *afl, u8 *fname) { } - if (memmem(f_data, f_len, "__asan_init", 11) || - memmem(f_data, f_len, "__msan_init", 11) || - memmem(f_data, f_len, "__lsan_init", 11)) { + if (afl_memmem(f_data, f_len, "__asan_init", 11) || + afl_memmem(f_data, f_len, "__msan_init", 11) || + afl_memmem(f_data, f_len, "__lsan_init", 11)) { afl->fsrv.uses_asan = 1; @@ -2840,7 +2842,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { /* Detect persistent & deferred init signatures in the binary. */ - if (memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { + if (afl_memmem(f_data, f_len, PERSIST_SIG, strlen(PERSIST_SIG) + 1)) { OKF(cPIN "Persistent mode binary detected."); setenv(PERSIST_ENV_VAR, "1", 1); @@ -2867,7 +2869,7 @@ void check_binary(afl_state_t *afl, u8 *fname) { } if (afl->fsrv.frida_mode || - memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { + afl_memmem(f_data, f_len, DEFER_SIG, strlen(DEFER_SIG) + 1)) { OKF(cPIN "Deferred forkserver binary detected."); setenv(DEFER_ENV_VAR, "1", 1); @@ -2923,8 +2925,11 @@ void setup_signal_handlers(void) { struct sigaction sa; + memset((void*)&sa, 0, sizeof(sa)); sa.sa_handler = NULL; +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 65caf5ee..f53fd610 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -62,7 +62,7 @@ void write_setup_file(afl_state_t *afl, u32 argc, char **argv) { if (memchr(argv[i], '\'', strlen(argv[i]))) { #else - if (index(argv[i], '\'')) { + if (strchr(argv[i], '\'')) { #endif diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 1e281d08..32dd1c20 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -654,7 +654,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; + #ifdef SA_RESTART sa.sa_flags = SA_RESTART; + #else + sa.sa_flags = 0; + #endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 12c5e0c9..530578d9 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -743,7 +743,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; + #ifdef SA_RESTART sa.sa_flags = SA_RESTART; + #else + sa.sa_flags = 0; + #endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); -- cgit 1.4.1 From 30483919eb65f6301dbbba7762e28a6d21972571 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 9 Mar 2023 17:37:29 +0100 Subject: code format --- include/common.h | 3 ++- src/afl-analyze.c | 8 ++++---- src/afl-fuzz-init.c | 2 +- src/afl-showmap.c | 8 ++++---- src/afl-tmin.c | 8 ++++---- 5 files changed, 15 insertions(+), 14 deletions(-) (limited to 'include') diff --git a/include/common.h b/include/common.h index 5d198468..0958b035 100644 --- a/include/common.h +++ b/include/common.h @@ -144,7 +144,8 @@ FILE *create_ffile(u8 *fn); s32 create_file(u8 *fn); /* memmem implementation as not all platforms support this */ -void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); +void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, + size_t needlelen); #endif diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 9734f75c..548956d8 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -725,11 +725,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; - #ifdef SA_RESTART +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; - #else - sa.sa_flags = 0; - #endif +#else + sa.sa_flags = 0; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 3b441eee..01d1e82e 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -2925,7 +2925,7 @@ void setup_signal_handlers(void) { struct sigaction sa; - memset((void*)&sa, 0, sizeof(sa)); + memset((void *)&sa, 0, sizeof(sa)); sa.sa_handler = NULL; #ifdef SA_RESTART sa.sa_flags = SA_RESTART; diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 32dd1c20..29abeb13 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -654,11 +654,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; - #ifdef SA_RESTART +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; - #else - sa.sa_flags = 0; - #endif +#else + sa.sa_flags = 0; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 530578d9..c0087f5f 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -743,11 +743,11 @@ static void setup_signal_handlers(void) { struct sigaction sa; sa.sa_handler = NULL; - #ifdef SA_RESTART +#ifdef SA_RESTART sa.sa_flags = SA_RESTART; - #else - sa.sa_flags = 0; - #endif +#else + sa.sa_flags = 0; +#endif sa.sa_sigaction = NULL; sigemptyset(&sa.sa_mask); -- cgit 1.4.1 From b1bfc1ae76bacbf48b81c81480a9f32e0c8919f6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 27 Mar 2023 17:51:53 +0200 Subject: time_wo_finds in fuzzer_stats --- docs/Changelog.md | 1 + docs/afl-fuzz_approach.md | 1 + include/afl-fuzz.h | 1 + src/afl-fuzz-queue.c | 19 ++++++++++++++++++- src/afl-fuzz-stats.c | 6 ++++++ 5 files changed, 27 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 25c1f6bc..3c06a785 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -8,6 +8,7 @@ - ensure temporary file descriptor is closed when not used - added `AFL_NO_WARN_INSTABILITY` - added `AFL_FRIDA_STATS_INTERVAL` + - added time_wo_finds to fuzzer_stats - afl-cc: - add CFI sanitizer variant to gcc targets - llvm 16 support (thanks to @devnexen!) diff --git a/docs/afl-fuzz_approach.md b/docs/afl-fuzz_approach.md index 6af39769..cb173f10 100644 --- a/docs/afl-fuzz_approach.md +++ b/docs/afl-fuzz_approach.md @@ -483,6 +483,7 @@ directory. This includes: - `fuzzer_pid` - PID of the fuzzer process - `cycles_done` - queue cycles completed so far - `cycles_wo_finds` - number of cycles without any new paths found +- `time_wo_finds` - longest time in seconds no new path was found - `execs_done` - number of execve() calls attempted - `execs_per_sec` - overall number of execs per second - `corpus_count` - total number of entries in the queue diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 6a8e8b5d..58d02af5 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -591,6 +591,7 @@ typedef struct afl_state { last_find_time, /* Time for most recent path (ms) */ last_crash_time, /* Time for most recent crash (ms) */ last_hang_time, /* Time for most recent hang (ms) */ + longest_find_time, /* Longest time taken for a find */ exit_on_time, /* Delay to exit if no new paths */ sync_time; /* Sync time (ms) */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 4eb55bb3..40184645 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -577,7 +577,24 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { queue_buf[afl->queued_items - 1] = q; q->id = afl->queued_items - 1; - afl->last_find_time = get_cur_time(); + u64 cur_time = get_cur_time(); + + if (likely(afl->start_time) && + unlikely(afl->longest_find_time < cur_time - afl->last_find_time)) { + + if (unlikely(!afl->last_find_time)) { + + afl->longest_find_time = cur_time - afl->start_time; + + } else { + + afl->longest_find_time = cur_time - afl->last_find_time; + + } + + } + + afl->last_find_time = cur_time; if (afl->custom_mutators_count) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index f53fd610..25ebe987 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -251,6 +251,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, "fuzzer_pid : %u\n" "cycles_done : %llu\n" "cycles_wo_finds : %llu\n" + "time_wo_finds : %llu\n" "execs_done : %llu\n" "execs_per_sec : %0.02f\n" "execs_ps_last_min : %0.02f\n" @@ -291,6 +292,11 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, (afl->start_time - afl->prev_run_time) / 1000, cur_time / 1000, (afl->prev_run_time + cur_time - afl->start_time) / 1000, (u32)getpid(), afl->queue_cycle ? (afl->queue_cycle - 1) : 0, afl->cycles_wo_finds, + afl->longest_find_time > cur_time - afl->last_find_time + ? afl->longest_find_time / 1000 + : ((afl->start_time == 0 || afl->last_find_time == 0) + ? 0 + : (cur_time - afl->last_find_time) / 1000), afl->fsrv.total_execs, afl->fsrv.total_execs / ((double)(afl->prev_run_time + get_cur_time() - afl->start_time) / -- cgit 1.4.1 From e46e0bce44f0799731f5e7724ba3dfacafd4c41a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 2 Apr 2023 12:03:45 +0200 Subject: allow pizza mode to be disabled --- docs/Changelog.md | 3 +++ docs/env_variables.md | 2 +- include/afl-fuzz.h | 6 ++++-- src/afl-fuzz-state.c | 10 +++++++++- 4 files changed, 17 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 3c06a785..fbf50137 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,9 @@ - added `AFL_NO_WARN_INSTABILITY` - added `AFL_FRIDA_STATS_INTERVAL` - added time_wo_finds to fuzzer_stats + - fixed a crash in pizza (1st april easter egg) mode. Sorry for + everyone who was affected! + - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1 - afl-cc: - add CFI sanitizer variant to gcc targets - llvm 16 support (thanks to @devnexen!) diff --git a/docs/env_variables.md b/docs/env_variables.md index c9dc1bbd..a6a0ae44 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -581,7 +581,7 @@ checks or alter some of the more exotic semantics of the tool: constructors in your target, you can set `AFL_EARLY_FORKSERVER`. Note that this is not a compile time option but a runtime option :-) - - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to 0 + - Set `AFL_PIZZA_MODE` to 1 to enable the April 1st stats menu, set to -1 to disable although it is 1st of April. - If you need a specific interval to update fuzzer_stats file, you can diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 58d02af5..5fd393dd 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -398,8 +398,8 @@ typedef struct afl_env_vars { afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, - afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme, - afl_ignore_timeouts, afl_no_startup_calibration, afl_no_warn_instability; + afl_keep_timeouts, afl_no_crash_readme, afl_ignore_timeouts, + afl_no_startup_calibration, afl_no_warn_instability; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, @@ -408,6 +408,8 @@ typedef struct afl_env_vars { *afl_testcache_entries, *afl_child_kill_signal, *afl_fsrv_kill_signal, *afl_target_env, *afl_persistent_record, *afl_exit_on_time; + s32 afl_pizza_mode; + } afl_env_vars_t; struct afl_pass_stat { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index f9aa5cfe..46b67def 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -648,7 +648,15 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } - if (afl->afl_env.afl_pizza_mode) { afl->pizza_is_served = 1; } + if (afl->afl_env.afl_pizza_mode > 0) { + + afl->pizza_is_served = 1; + + } else if (afl->afl_env.afl_pizza_mode < 0) { + + OKF("Pizza easter egg mode is now disabled."); + + } if (issue_detected) { sleep(2); } -- cgit 1.4.1 From 36127fb1970746f53fec44f9394061f57a4e94c3 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 5 Apr 2023 12:59:20 +0200 Subject: add -z switch --- docs/Changelog.md | 1 + include/afl-fuzz.h | 3 ++- src/afl-fuzz-queue.c | 7 ++++++- src/afl-fuzz.c | 5 +++++ 4 files changed, 14 insertions(+), 2 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index fbf50137..8127e594 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,6 +12,7 @@ - fixed a crash in pizza (1st april easter egg) mode. Sorry for everyone who was affected! - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1 + - add -z switch to prefer new coverage findings in seed selection - afl-cc: - add CFI sanitizer variant to gcc targets - llvm 16 support (thanks to @devnexen!) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 5fd393dd..7ff3315b 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -501,7 +501,8 @@ typedef struct afl_state { custom_splice_optout, /* Custom mutator no splice buffer */ is_main_node, /* if this is the main node */ is_secondary_node, /* if this is a secondary instance */ - pizza_is_served; /* pizza mode */ + pizza_is_served, /* pizza mode */ + prefer_new; /* prefer new queue entries */ u32 stats_update_freq; /* Stats update frequency (execs) */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 40184645..1cdc8b54 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -74,9 +74,14 @@ double compute_weight(afl_state_t *afl, struct queue_entry *q, if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); } weight *= (log(q->bitmap_size) / avg_bitmap_size); weight *= (1 + (q->tc_ref / avg_top_size)); - if (unlikely(weight < 1.0)) { weight = 1.0; } + if (unlikely(weight < 0.1)) { weight = 0.1; } if (unlikely(q->favored)) { weight *= 5; } if (unlikely(!q->was_fuzzed)) { weight *= 2; } + if (unlikely(afl->prefer_new)) { + + weight *= (2.0 * (q->id / (afl->queued_items - 1))); + + } return weight; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 3380fd90..0f01360e 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -132,6 +132,7 @@ static void usage(u8 *argv0, int more_help) { " fast(default), explore, exploit, seek, rare, mmopt, " "coe, lin\n" " quad -- see docs/FAQ.md for more information\n" + " -z - prefer new coverage findings when fuzzing\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" " -t msec - timeout for each run (auto-scaled, default %u ms). " @@ -569,6 +570,10 @@ int main(int argc, char **argv_orig, char **envp) { afl->max_length = atoi(optarg); break; + case 'z': + afl->prefer_new = 1; + break; + case 'Z': afl->old_seed_selection = 1; break; -- cgit 1.4.1 From 6cc8d607fb24e060591ece4b42d83fc06de68fc6 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 13 Apr 2023 11:44:39 +0200 Subject: remove -z option, use -p mmopt instead --- GNUmakefile | 2 +- docs/Changelog.md | 2 +- include/afl-fuzz.h | 3 +-- instrumentation/SanitizerCoverageLTO.so.cc | 2 +- instrumentation/SanitizerCoveragePCGUARD.so.cc | 2 +- src/afl-fuzz-queue.c | 14 ++++---------- src/afl-fuzz.c | 7 +------ 7 files changed, 10 insertions(+), 22 deletions(-) (limited to 'include') diff --git a/GNUmakefile b/GNUmakefile index 208e965b..85f164f5 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -546,7 +546,7 @@ ifndef AFL_NO_X86 test_build: afl-cc afl-gcc afl-as afl-showmap @echo "[*] Testing the CC wrapper afl-cc and its instrumentation output..." @unset AFL_MAP_SIZE AFL_USE_UBSAN AFL_USE_CFISAN AFL_USE_LSAN AFL_USE_ASAN AFL_USE_MSAN; ASAN_OPTIONS=detect_leaks=0 AFL_INST_RATIO=100 AFL_PATH=. ./afl-cc test-instr.c $(LDFLAGS) -o test-instr 2>&1 || (echo "Oops, afl-cc failed"; exit 1 ) - - ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -o .test-instr0 ./test-instr < /dev/null + -ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -q -m none -o .test-instr0 ./test-instr < /dev/null -echo 1 | ASAN_OPTIONS=detect_leaks=0 ./afl-showmap -m none -q -o .test-instr1 ./test-instr @rm -f test-instr @cmp -s .test-instr0 .test-instr1; DR="$$?"; rm -f .test-instr0 .test-instr1; if [ "$$DR" = "0" ]; then echo; echo "Oops, the instrumentation of afl-cc does not seem to be behaving correctly!"; echo; echo "Please post to https://github.com/AFLplusplus/AFLplusplus/issues to troubleshoot the issue."; echo; exit 1; fi diff --git a/docs/Changelog.md b/docs/Changelog.md index 736deb30..501300b1 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -12,7 +12,7 @@ - fixed a crash in pizza (1st april easter egg) mode. Sorry for everyone who was affected! - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1 - - add -z switch to prefer new coverage findings in seed selection + - option `-p mmopt` now also selects new queue items more often - print name of custom mutator in UI - afl-cc: - add CFI sanitizer variant to gcc targets diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 7ff3315b..5fd393dd 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -501,8 +501,7 @@ typedef struct afl_state { custom_splice_optout, /* Custom mutator no splice buffer */ is_main_node, /* if this is the main node */ is_secondary_node, /* if this is a secondary instance */ - pizza_is_served, /* pizza mode */ - prefer_new; /* prefer new queue entries */ + pizza_is_served; /* pizza mode */ u32 stats_update_freq; /* Stats update frequency (execs) */ diff --git a/instrumentation/SanitizerCoverageLTO.so.cc b/instrumentation/SanitizerCoverageLTO.so.cc index 5603c455..e41f19b6 100644 --- a/instrumentation/SanitizerCoverageLTO.so.cc +++ b/instrumentation/SanitizerCoverageLTO.so.cc @@ -18,7 +18,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #if LLVM_VERSION_MAJOR < 17 -#include "llvm/ADT/Triple.h" + #include "llvm/ADT/Triple.h" #endif #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" diff --git a/instrumentation/SanitizerCoveragePCGUARD.so.cc b/instrumentation/SanitizerCoveragePCGUARD.so.cc index 5f23698b..85b1ddd5 100644 --- a/instrumentation/SanitizerCoveragePCGUARD.so.cc +++ b/instrumentation/SanitizerCoveragePCGUARD.so.cc @@ -14,7 +14,7 @@ #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" #if LLVM_VERSION_MAJOR < 17 -#include "llvm/ADT/Triple.h" + #include "llvm/ADT/Triple.h" #endif #include "llvm/Analysis/EHPersonalities.h" #include "llvm/Analysis/PostDominators.h" diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 6fc3c743..8ad7cd97 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -149,21 +149,15 @@ void create_alias_table(afl_state_t *afl) { } - if (unlikely(afl->prefer_new) && afl->queued_discovered) { + if (unlikely(afl->schedule == MMOPT) && afl->queued_discovered) { - double avg_weight = sum / active; + u32 cnt = afl->queued_discovered >= 5 ? 5 : afl->queued_discovered; - for (i = n - afl->queued_discovered; i < n; i++) { + for (i = n - cnt; i < n; i++) { struct queue_entry *q = afl->queue_buf[i]; - if (likely(!q->disabled) && q->weight > avg_weight) { - - double prev_weight = q->weight; - q->weight *= (2.0 * (i / n)); - sum += (q->weight - prev_weight); - - } + if (likely(!q->disabled)) { q->weight *= 2.0; } } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a0c322da..5ba54d0b 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -132,7 +132,6 @@ static void usage(u8 *argv0, int more_help) { " fast(default), explore, exploit, seek, rare, mmopt, " "coe, lin\n" " quad -- see docs/FAQ.md for more information\n" - " -z - prefer new coverage findings when fuzzing\n" " -f file - location read by the fuzzed program (default: stdin " "or @@)\n" " -t msec - timeout for each run (auto-scaled, default %u ms). " @@ -556,7 +555,7 @@ int main(int argc, char **argv_orig, char **envp) { while ( (opt = getopt( argc, argv, - "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YzZ")) > + "+Ab:B:c:CdDe:E:hi:I:f:F:g:G:l:L:m:M:nNOo:p:RQs:S:t:T:UV:WXx:YZ")) > 0) { switch (opt) { @@ -569,10 +568,6 @@ int main(int argc, char **argv_orig, char **envp) { afl->max_length = atoi(optarg); break; - case 'z': - afl->prefer_new = 1; - break; - case 'Z': afl->old_seed_selection = 1; break; -- cgit 1.4.1 From f756734ad2782c3ed56feadb4b7b23fc82a7a968 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 13 Apr 2023 12:07:27 +0200 Subject: fix attempt at post_process implementation --- docs/Changelog.md | 1 + docs/custom_mutators.md | 9 +++++++-- include/afl-fuzz.h | 9 +++++++-- src/afl-fuzz-python.c | 49 +++++++++---------------------------------------- src/afl-fuzz-run.c | 7 ++++++- 5 files changed, 30 insertions(+), 45 deletions(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 501300b1..9436fc9f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -13,6 +13,7 @@ everyone who was affected! - allow pizza mode to be disabled when AFL_PIZZA_MODE is set to -1 - option `-p mmopt` now also selects new queue items more often + - fix bug in post_process custom mutator implementation - print name of custom mutator in UI - afl-cc: - add CFI sanitizer variant to gcc targets diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index 82131c92..a1de479e 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -118,7 +118,7 @@ def deinit(): # optional for Python ### Custom Mutation -- `init`: +- `init` (optional in Python): This method is called when AFL++ starts up and is used to seed RNG and set up buffers and state. @@ -184,6 +184,11 @@ def deinit(): # optional for Python to the target, e.g. if it is too short, too corrupted, etc. If so, return a NULL buffer and zero length (or a 0 length string in Python). + NOTE: Do not make any random changes to the data in this function! + + PERFORMANCE for C/C++: If possible make the changes in-place (so modify + the `*data` directly, and return it as `*outbuf = data`. + - `fuzz_send` (optional): This method can be used if you want to send data to the target yourself, @@ -202,7 +207,7 @@ def deinit(): # optional for Python discovered if compiled with INTROSPECTION. The custom mutator can then return a string (const char *) that reports the exact mutations used. -- `deinit`: +- `deinit` (optional in Python): The last method to be called, deinitializing the state. diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 5fd393dd..8b6502b4 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -885,14 +885,19 @@ struct custom_mutator { * A post-processing function to use right before AFL writes the test case to * disk in order to execute the target. * - * (Optional) If this functionality is not needed, simply don't define this + * NOTE: Do not do any random changes to the data in this function! + * + * PERFORMANCE: If you can modify the data in-place you will have a better + * performance. Modify *data and set `*out_buf = data`. + * + * (Optional) If this functionality is not needed, simply do not define this * function. * * @param[in] data pointer returned in afl_custom_init by this custom mutator * @param[in] buf Buffer containing the test case to be executed * @param[in] buf_size Size of the test case * @param[out] out_buf Pointer to the buffer storing the test case after - * processing. External library should allocate memory for out_buf. + * processing. The external library should allocate memory for out_buf. * It can chose to alter buf in-place, if the space is large enough. * @return Size of the output buffer. */ diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index 673e5a6c..7dad0770 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -219,11 +219,14 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (py_module != NULL) { - u8 py_notrim = 0, py_idx; - /* init, required */ + u8 py_notrim = 0; py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init"); - if (!py_functions[PY_FUNC_INIT]) - FATAL("init function not found in python module"); + if (!py_functions[PY_FUNC_INIT]) { + + WARNF("init function not found in python module"); + + } + py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); if (!py_functions[PY_FUNC_FUZZ]) py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "mutate"); @@ -231,12 +234,6 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "describe"); py_functions[PY_FUNC_FUZZ_COUNT] = PyObject_GetAttrString(py_module, "fuzz_count"); - if (!py_functions[PY_FUNC_FUZZ]) { - - WARNF("fuzz function not found in python module"); - - } - py_functions[PY_FUNC_POST_PROCESS] = PyObject_GetAttrString(py_module, "post_process"); py_functions[PY_FUNC_INIT_TRIM] = @@ -263,36 +260,6 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { if (!py_functions[PY_FUNC_DEINIT]) WARNF("deinit function not found in python module"); - for (py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) { - - if (!py_functions[py_idx] || !PyCallable_Check(py_functions[py_idx])) { - - if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) { - - // Implementing the trim API is optional for now - if (PyErr_Occurred()) { PyErr_Print(); } - py_notrim = 1; - - } else if (py_idx >= PY_OPTIONAL) { - - // Only _init and _deinit are not optional currently - - if (PyErr_Occurred()) { PyErr_Print(); } - - } else { - - fprintf(stderr, - "Cannot find/call function with index %d in external " - "Python module.\n", - py_idx); - return NULL; - - } - - } - - } - if (py_notrim) { py_functions[PY_FUNC_INIT_TRIM] = NULL; @@ -345,6 +312,8 @@ static void init_py(afl_state_t *afl, py_mutator_t *py_mutator, (void)afl; + if (py_mutator->py_functions[PY_FUNC_INIT] == NULL) { return; } + PyObject *py_args, *py_value; /* Provide the init function a seed for the Python RNG */ diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index f5425011..26e8549d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -133,7 +133,12 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { } - if (new_mem != *mem) { *mem = new_mem; } + if (new_mem != *mem && new_mem != NULL && new_size > 0) { + + *mem = afl_realloc((void **)mem, new_size); + memmove(*mem, new_mem, new_size); + + } if (unlikely(afl->custom_mutators_count)) { -- cgit 1.4.1 From eefd98f3741b5feca32c75b34a8d7b33e34044d0 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Fri, 14 Apr 2023 02:25:33 +0200 Subject: add Nyx support in various tools (like afl-cmin) --- afl-cmin | 14 ++++++-- include/common.h | 6 ++++ include/forkserver.h | 3 ++ src/afl-analyze.c | 64 ++++++++++++++++++++++++++++++--- src/afl-common.c | 31 ++++++++++++++++ src/afl-forkserver.c | 65 ++++++++++++++++++++++++++++++++++ src/afl-fuzz.c | 63 --------------------------------- src/afl-showmap.c | 99 ++++++++++++++++++++++++++++++++++++++++++++++++++-- src/afl-tmin.c | 59 ++++++++++++++++++++++++++++++- 9 files changed, 330 insertions(+), 74 deletions(-) (limited to 'include') diff --git a/afl-cmin b/afl-cmin index 15b61f89..12791584 100755 --- a/afl-cmin +++ b/afl-cmin @@ -109,6 +109,7 @@ function usage() { " -O - use binary-only instrumentation (FRIDA mode)\n" \ " -Q - use binary-only instrumentation (QEMU mode)\n" \ " -U - use unicorn-based instrumentation (unicorn mode)\n" \ +" -X - use Nyx mode\n" \ "\n" \ "Minimization settings:\n" \ " -A - allow crashes and timeouts (not recommended)\n" \ @@ -156,7 +157,7 @@ BEGIN { # process options Opterr = 1 # default is to diagnose Optind = 1 # skip ARGV[0] - while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQU?")) != -1) { + while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUX?")) != -1) { if (_go_c == "i") { if (!Optarg) usage() if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} @@ -217,6 +218,12 @@ BEGIN { extra_par = extra_par " -U" unicorn_mode = 1 continue + } else + if (_go_c == "X") { + if (nyx_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} + extra_par = extra_par " -X" + nyx_mode = 1 + continue } else if (_go_c == "?") { exit 1 @@ -291,7 +298,8 @@ BEGIN { exit 1 } - if (target_bin && !exists_and_is_executable(target_bin)) { + + if (!nyx_mode && target_bin && !exists_and_is_executable(target_bin)) { "command -v "target_bin" 2>/dev/null" | getline tnew if (!tnew || !exists_and_is_executable(tnew)) { @@ -311,7 +319,7 @@ BEGIN { } } - if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode) { + if (!ENVIRON["AFL_SKIP_BIN_CHECK"] && !qemu_mode && !frida_mode && !unicorn_mode && !nyx_mode) { if (0 != system( "grep -q __AFL_SHM_ID "target_bin )) { print "[-] Error: binary '"target_bin"' doesn't appear to be instrumented." > "/dev/stderr" exit 1 diff --git a/include/common.h b/include/common.h index 0958b035..279a5f47 100644 --- a/include/common.h +++ b/include/common.h @@ -147,5 +147,11 @@ s32 create_file(u8 *fn); void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, size_t needlelen); +#ifdef __linux__ +/* Nyx helper functions to create and remove tmp workdirs */ +char* create_nyx_tmp_workdir(void); +void remove_nyx_tmp_workdir(char* nyx_out_dir_path); +#endif + #endif diff --git a/include/forkserver.h b/include/forkserver.h index 50898a08..273a9255 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -75,6 +75,9 @@ typedef struct { } nyx_plugin_handler_t; +/* Imports helper functions to enable Nyx mode (Linux only )*/ +nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary); + #endif typedef struct afl_forkserver { diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 548956d8..0bdadfdc 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -121,9 +121,9 @@ static void kill_child() { } -static void classify_counts(u8 *mem) { +static void classify_counts(u8 *mem, u32 mem_size) { - u32 i = map_size; + u32 i = mem_size; if (edges_only) { @@ -222,7 +222,7 @@ static u64 analyze_run_target(u8 *mem, u32 len, u8 first_run) { } - classify_counts(fsrv.trace_bits); + classify_counts(fsrv.trace_bits, fsrv.map_size); total_execs++; if (stop_soon) { @@ -768,6 +768,7 @@ static void usage(u8 *argv0) { " -U - use unicorn-based instrumentation (Unicorn mode)\n" " -W - use qemu-based instrumentation with Wine (Wine " "mode)\n" + " -X - use Nyx mode\n" #endif "\n" @@ -814,7 +815,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_init(&fsrv); - while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWh")) > 0) { + while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWXh")) > 0) { switch (opt) { @@ -965,6 +966,22 @@ int main(int argc, char **argv_orig, char **envp) { fsrv.mem_limit = mem_limit; break; + + #ifdef __linux__ + case 'X': /* NYX mode */ + + if (fsrv.nyx_mode) { FATAL("Multiple -X options not supported"); } + + fsrv.nyx_mode = 1; + fsrv.nyx_parent = true; + fsrv.nyx_standalone = true; + + break; + #else + case 'X': + FATAL("Nyx mode is only availabe on linux..."); + break; + #endif case 'h': usage(argv[0]); @@ -997,7 +1014,17 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(argv); +#ifdef __linux__ + if(!fsrv.nyx_mode){ + fsrv.target_path = find_binary(argv[optind]); + } + else{ + fsrv.target_path = ck_strdup(argv[optind]); + } +#else fsrv.target_path = find_binary(argv[optind]); +#endif + fsrv.trace_bits = afl_shm_init(&shm, map_size, 0); detect_file_args(argv + optind, fsrv.out_file, &use_stdin); signal(SIGALRM, kill_child); @@ -1020,6 +1047,23 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &target_path, argc - optind, argv + optind); +#ifdef __linux__ + } else if (fsrv.nyx_mode) { + + fsrv.nyx_id = 0; + + u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); + fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); + if (fsrv.nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } + + fsrv.out_dir_path = create_nyx_tmp_workdir(); + fsrv.nyx_bind_cpu_id = 0; + + use_argv = argv + optind; +#endif + } else { use_argv = argv + optind; @@ -1045,7 +1089,13 @@ int main(int argc, char **argv_orig, char **envp) { &fsrv, NULL, NULL, (fsrv.qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM); read_initial_file(); +#ifdef __linux__ + if(!fsrv.nyx_mode){ + (void)check_binary_signatures(fsrv.target_path); + } +#else (void)check_binary_signatures(fsrv.target_path); +#endif ACTF("Performing dry run (mem limit = %llu MB, timeout = %u ms%s)...", mem_limit, exec_tmout, edges_only ? ", edges only" : ""); @@ -1069,6 +1119,12 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); +#ifdef __linux__ + if (fsrv.nyx_mode) { + remove_nyx_tmp_workdir(fsrv.out_dir_path); + } +#endif + afl_shm_deinit(&shm); afl_fsrv_deinit(&fsrv); if (fsrv.target_path) { ck_free(fsrv.target_path); } diff --git a/src/afl-common.c b/src/afl-common.c index 86226c9f..7dbf7129 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1359,3 +1359,34 @@ s32 create_file(u8 *fn) { } +#ifdef __linux__ + +/* Nyx requires a tmp workdir to access specific files (such as mmapped files, + * etc.). This helper function basically creates both a path to a tmp workdir + * and the workdir itself. If the environment variable TMPDIR is set, we use + * that as the base directory, otherwise we use /tmp. */ +char* create_nyx_tmp_workdir(void) { + + char *tmpdir = getenv("TMPDIR"); + + if (!tmpdir) { tmpdir = "/tmp"; } + + char* nyx_out_dir_path = alloc_printf("%s/.nyx_tmp_%d/", tmpdir, (u32)getpid()); + + if (mkdir(nyx_out_dir_path, 0700)) { + PFATAL("Unable to create nyx workdir"); + } + + return nyx_out_dir_path; +} + +/* Vice versa, we remove the tmp workdir for nyx with this helper function. */ +void remove_nyx_tmp_workdir(char* nyx_out_dir_path) { + /* Fix me: This is not recursive, so it will always fail. Use a libnyx helper function instead + * to remove the workdir safely (and not risking to wipe the whole filesystem accidentally). */ + //if (rmdir(nyx_out_dir_path)) { + // PFATAL("Unable to remove nyx workdir"); + //} + free(nyx_out_dir_path); +} +#endif diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 5aa4c2ff..95328aa2 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -49,6 +49,71 @@ #include #include +#ifdef __linux__ +#include + +/* function to load nyx_helper function from libnyx.so */ + +nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { + + void *handle; + nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t)); + + ACTF("Trying to load libnyx.so plugin..."); + handle = dlopen((char *)libnyx_binary, RTLD_NOW); + if (!handle) { goto fail; } + + plugin->nyx_new = dlsym(handle, "nyx_new"); + if (plugin->nyx_new == NULL) { goto fail; } + + plugin->nyx_new_parent = dlsym(handle, "nyx_new_parent"); + if (plugin->nyx_new_parent == NULL) { goto fail; } + + plugin->nyx_new_child = dlsym(handle, "nyx_new_child"); + if (plugin->nyx_new_child == NULL) { goto fail; } + + plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown"); + if (plugin->nyx_shutdown == NULL) { goto fail; } + + plugin->nyx_option_set_reload_mode = + dlsym(handle, "nyx_option_set_reload_mode"); + if (plugin->nyx_option_set_reload_mode == NULL) { goto fail; } + + plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout"); + if (plugin->nyx_option_set_timeout == NULL) { goto fail; } + + plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply"); + if (plugin->nyx_option_apply == NULL) { goto fail; } + + plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input"); + if (plugin->nyx_set_afl_input == NULL) { goto fail; } + + plugin->nyx_exec = dlsym(handle, "nyx_exec"); + if (plugin->nyx_exec == NULL) { goto fail; } + + plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer"); + if (plugin->nyx_get_bitmap_buffer == NULL) { goto fail; } + + plugin->nyx_get_bitmap_buffer_size = + dlsym(handle, "nyx_get_bitmap_buffer_size"); + if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; } + + plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string"); + if (plugin->nyx_get_aux_string == NULL) { goto fail; } + + OKF("libnyx plugin is ready!"); + return plugin; + +fail: + + FATAL("failed to load libnyx: %s\n", dlerror()); + free(plugin); + return NULL; + +} + +#endif + /** * The correct fds for reading and writing pipes */ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index a0c322da..8b4fe1e5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -436,69 +436,6 @@ static void fasan_check_afl_preload(char *afl_preload) { } - #ifdef __linux__ - #include - -nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { - - void *handle; - nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t)); - - ACTF("Trying to load libnyx.so plugin..."); - handle = dlopen((char *)libnyx_binary, RTLD_NOW); - if (!handle) { goto fail; } - - plugin->nyx_new = dlsym(handle, "nyx_new"); - if (plugin->nyx_new == NULL) { goto fail; } - - plugin->nyx_new_parent = dlsym(handle, "nyx_new_parent"); - if (plugin->nyx_new_parent == NULL) { goto fail; } - - plugin->nyx_new_child = dlsym(handle, "nyx_new_child"); - if (plugin->nyx_new_child == NULL) { goto fail; } - - plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown"); - if (plugin->nyx_shutdown == NULL) { goto fail; } - - plugin->nyx_option_set_reload_mode = - dlsym(handle, "nyx_option_set_reload_mode"); - if (plugin->nyx_option_set_reload_mode == NULL) { goto fail; } - - plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout"); - if (plugin->nyx_option_set_timeout == NULL) { goto fail; } - - plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply"); - if (plugin->nyx_option_apply == NULL) { goto fail; } - - plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input"); - if (plugin->nyx_set_afl_input == NULL) { goto fail; } - - plugin->nyx_exec = dlsym(handle, "nyx_exec"); - if (plugin->nyx_exec == NULL) { goto fail; } - - plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer"); - if (plugin->nyx_get_bitmap_buffer == NULL) { goto fail; } - - plugin->nyx_get_bitmap_buffer_size = - dlsym(handle, "nyx_get_bitmap_buffer_size"); - if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; } - - plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string"); - if (plugin->nyx_get_aux_string == NULL) { goto fail; } - - OKF("libnyx plugin is ready!"); - return plugin; - -fail: - - FATAL("failed to load libnyx: %s\n", dlerror()); - free(plugin); - return NULL; - -} - - #endif - /* Main entry point */ int main(int argc, char **argv_orig, char **envp) { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 29abeb13..3ddebaad 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -434,6 +434,20 @@ static u32 read_file(u8 *in_file) { } +#ifdef __linux__ +/* Execute the target application with an empty input (in Nyx mode). */ +static void showmap_run_target_nyx_mode(afl_forkserver_t *fsrv) { + + afl_fsrv_write_to_testcase(fsrv, NULL, 0); + + if (afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon) == + FSRV_RUN_ERROR) { + + FATAL("Error running target in Nyx mode"); + } +} +#endif + /* Execute target application. */ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) { @@ -797,6 +811,7 @@ static void usage(u8 *argv0) { " -W - use qemu-based instrumentation with Wine (Wine mode)\n" " (Not necessary, here for consistency with other afl-* " "tools)\n" + " -X - use Nyx mode\n" #endif "\n" "Other settings:\n" @@ -875,7 +890,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = true; } - while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrsh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshX")) > 0) { switch (opt) { @@ -1063,6 +1078,22 @@ int main(int argc, char **argv_orig, char **envp) { break; + #ifdef __linux__ + case 'X': /* NYX mode */ + + if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } + + fsrv->nyx_mode = 1; + fsrv->nyx_parent = true; + fsrv->nyx_standalone = true; + + break; + #else + case 'X': + FATAL("Nyx mode is only availabe on linux..."); + break; + #endif + case 'b': /* Secret undocumented mode. Writes output in raw binary format @@ -1134,7 +1165,17 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); +#ifdef __linux__ + if(!fsrv->nyx_mode){ + fsrv->target_path = find_binary(argv[optind]); + } + else{ + fsrv->target_path = ck_strdup(argv[optind]); + } +#else fsrv->target_path = find_binary(argv[optind]); +#endif + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); if (!quiet_mode) { @@ -1190,6 +1231,26 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); +#ifdef __linux__ + } else if (fsrv->nyx_mode) { + + use_argv = ck_alloc(sizeof(char *) * (1)); + use_argv[0] = argv[0]; + + fsrv->nyx_id = 0; + + u8 *libnyx_binary = find_afl_binary(use_argv[0], "libnyx.so"); + fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); + if (fsrv->nyx_handlers == NULL) { + + FATAL("failed to initialize libnyx.so..."); + + } + + fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_bind_cpu_id = 0; +#endif + } else { use_argv = argv + optind; @@ -1226,7 +1287,13 @@ int main(int argc, char **argv_orig, char **envp) { } +#ifdef __linux__ + if(!fsrv->nyx_mode && in_dir){ + (void)check_binary_signatures(fsrv->target_path); + } +#else if (in_dir) { (void)check_binary_signatures(fsrv->target_path); } +#endif shm_fuzz = ck_alloc(sizeof(sharedmem_t)); @@ -1247,7 +1314,13 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz = map + sizeof(u32); configure_afl_kill_signals( - fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode) ? SIGKILL : SIGTERM); + fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode + #ifdef __linux__ + || fsrv->nyx_mode + #endif + ) + ? SIGKILL + : SIGTERM); if (!fsrv->cs_mode && !fsrv->qemu_mode && !unicorn_mode) { @@ -1370,6 +1443,12 @@ int main(int argc, char **argv_orig, char **envp) { if (execute_testcases(in_dir) == 0) { +#ifdef __linux__ + if (fsrv->nyx_mode) { + remove_nyx_tmp_workdir(fsrv->out_dir_path); + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } +#endif FATAL("could not read input testcases from %s", in_dir); } @@ -1390,7 +1469,15 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->support_shmem_fuzz && !fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); - showmap_run_target(fsrv, use_argv); +#ifdef __linux__ + if(!fsrv->nyx_mode){ +#endif + showmap_run_target(fsrv, use_argv); +#ifdef __linux__ + } else { + showmap_run_target_nyx_mode(fsrv); + } +#endif tcnt = write_results_to_file(fsrv, out_file); if (!quiet_mode) { @@ -1441,6 +1528,12 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->target_path) { ck_free(fsrv->target_path); } +#ifdef __linux__ + if (fsrv->nyx_mode) { + remove_nyx_tmp_workdir(fsrv->out_dir_path); + } +#endif + afl_fsrv_deinit(fsrv); if (stdin_file) { ck_free(stdin_file); } diff --git a/src/afl-tmin.c b/src/afl-tmin.c index c0087f5f..942525d4 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -789,6 +789,7 @@ static void usage(u8 *argv0) { "mode)\n" " (Not necessary, here for consistency with other afl-* " "tools)\n" + " -X - use Nyx mode\n" #endif "\n" @@ -845,7 +846,7 @@ int main(int argc, char **argv_orig, char **envp) { SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); - while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWHh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXHh")) > 0) { switch (opt) { @@ -1003,6 +1004,22 @@ int main(int argc, char **argv_orig, char **envp) { break; + #ifdef __linux__ + case 'X': /* NYX mode */ + + if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } + + fsrv->nyx_mode = 1; + fsrv->nyx_parent = true; + fsrv->nyx_standalone = true; + + break; + #else + case 'X': + FATAL("Nyx mode is only availabe on linux..."); + break; + #endif + case 'H': /* Hang Mode */ /* Minimizes a testcase to the minimum that still times out */ @@ -1068,7 +1085,17 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); +#ifdef __linux__ + if(!fsrv->nyx_mode){ + fsrv->target_path = find_binary(argv[optind]); + } + else{ + fsrv->target_path = ck_strdup(argv[optind]); + } +#else fsrv->target_path = find_binary(argv[optind]); +#endif + fsrv->trace_bits = afl_shm_init(&shm, map_size, 0); detect_file_args(argv + optind, out_file, &fsrv->use_stdin); signal(SIGALRM, kill_child); @@ -1092,6 +1119,23 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); +#ifdef __linux__ + } else if (fsrv->nyx_mode) { + + fsrv->nyx_id = 0; + + u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); + fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); + if (fsrv->nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } + + fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_bind_cpu_id = 0; + + use_argv = argv + optind; +#endif + } else { use_argv = argv + optind; @@ -1161,7 +1205,14 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz = map + sizeof(u32); read_initial_file(); + +#ifdef __linux__ + if(!fsrv->nyx_mode){ + (void)check_binary_signatures(fsrv->target_path); + } +#else (void)check_binary_signatures(fsrv->target_path); +#endif if (!fsrv->qemu_mode && !unicorn_mode) { @@ -1265,6 +1316,12 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); +#ifdef __linux__ + if (fsrv->nyx_mode) { + remove_nyx_tmp_workdir(fsrv->out_dir_path); + } +#endif + remove_shm = 0; afl_shm_deinit(&shm); if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); -- cgit 1.4.1 From a96cdc649fbdf2ae6f40d4e966812c46083032a2 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Fri, 14 Apr 2023 05:59:12 +0200 Subject: switch to latest libnyx API --- include/forkserver.h | 25 ++++++++++++++++-------- src/afl-forkserver.c | 54 ++++++++++++++++++++++++++++++++++------------------ 2 files changed, 52 insertions(+), 27 deletions(-) (limited to 'include') diff --git a/include/forkserver.h b/include/forkserver.h index 273a9255..7cbad8c8 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -51,16 +51,23 @@ typedef enum NyxReturnValue { } NyxReturnValue; +typedef enum NyxProcessRole { + StandAlone, + Parent, + Child, +} NyxProcessRole; + typedef struct { - void *(*nyx_new)(const char *sharedir, const char *workdir, uint32_t cpu_id, - uint32_t input_buffer_size, - bool input_buffer_write_protection); - void *(*nyx_new_parent)(const char *sharedir, const char *workdir, - uint32_t cpu_id, uint32_t input_buffer_size, - bool input_buffer_write_protection); - void *(*nyx_new_child)(const char *sharedir, const char *workdir, - uint32_t cpu_id, uint32_t worker_id); + void *(*nyx_config_load)(const char *sharedir); + void (*nyx_config_set_workdir_path)(void *config, const char *workdir); + void (*nyx_config_set_input_buffer_size)(void *config, uint32_t input_buffer_size); + void (*nyx_config_set_input_buffer_write_protection)(void *config, bool input_buffer_write_protection); + void (*nyx_config_set_hprintf_fd)(void *config, int32_t hprintf_fd); + void (*nyx_config_set_process_role)(void *config, enum NyxProcessRole role); + void (*nyx_config_set_reuse_snapshot_path)(void *config, const char *reuse_snapshot_path); + + void *(*nyx_new)(void *config, uint32_t worker_id); void (*nyx_shutdown)(void *qemu_process); void (*nyx_option_set_reload_mode)(void *qemu_process, bool enable); void (*nyx_option_set_timeout)(void *qemu_process, uint8_t timeout_sec, @@ -73,6 +80,8 @@ typedef struct { uint32_t (*nyx_get_aux_string)(void *nyx_process, uint8_t *buffer, uint32_t size); + bool (*nyx_remove_work_dir)(const char *workdir); + } nyx_plugin_handler_t; /* Imports helper functions to enable Nyx mode (Linux only )*/ diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 95328aa2..33c46b8c 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -63,14 +63,29 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { handle = dlopen((char *)libnyx_binary, RTLD_NOW); if (!handle) { goto fail; } - plugin->nyx_new = dlsym(handle, "nyx_new"); - if (plugin->nyx_new == NULL) { goto fail; } + plugin->nyx_config_load = dlsym(handle, "nyx_config_load"); + if (plugin->nyx_config_load == NULL) { goto fail; } + + plugin->nyx_config_set_workdir_path = dlsym(handle, "nyx_config_set_workdir_path"); + if (plugin->nyx_config_set_workdir_path == NULL) { goto fail; } + + plugin->nyx_config_set_input_buffer_size = dlsym(handle, "nyx_config_set_input_buffer_size"); + if (plugin->nyx_config_set_input_buffer_size == NULL) { goto fail; } + + plugin->nyx_config_set_input_buffer_write_protection = dlsym(handle, "nyx_config_set_input_buffer_write_protection"); + if (plugin->nyx_config_set_input_buffer_write_protection == NULL) { goto fail; } - plugin->nyx_new_parent = dlsym(handle, "nyx_new_parent"); - if (plugin->nyx_new_parent == NULL) { goto fail; } + plugin->nyx_config_set_hprintf_fd = dlsym(handle, "nyx_config_set_hprintf_fd"); + if (plugin->nyx_config_set_hprintf_fd == NULL) { goto fail; } - plugin->nyx_new_child = dlsym(handle, "nyx_new_child"); - if (plugin->nyx_new_child == NULL) { goto fail; } + plugin->nyx_config_set_process_role = dlsym(handle, "nyx_config_set_process_role"); + if (plugin->nyx_config_set_process_role == NULL) { goto fail; } + + plugin->nyx_config_set_reuse_snapshot_path = dlsym(handle, "nyx_config_set_reuse_snapshot_path"); + if (plugin->nyx_config_set_reuse_snapshot_path == NULL) { goto fail; } + + plugin->nyx_new = dlsym(handle, "nyx_new"); + if (plugin->nyx_new == NULL) { goto fail; } plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown"); if (plugin->nyx_shutdown == NULL) { goto fail; } @@ -101,6 +116,10 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string"); if (plugin->nyx_get_aux_string == NULL) { goto fail; } + plugin->nyx_remove_work_dir = dlsym(handle, "nyx_remove_work_dir"); + if (plugin->nyx_remove_work_dir == NULL) { goto fail; } + + OKF("libnyx plugin is ready!"); return plugin; @@ -474,27 +493,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if (fsrv->nyx_standalone) { + void* nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new( - fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true); + fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, x); + fsrv->nyx_handlers->nyx_config_set_input_buffer_size(nyx_config, MAX_FILE); + fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); + if (fsrv->nyx_standalone) { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, StandAlone); } else { - if (fsrv->nyx_parent) { - - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_parent( - fsrv->target_path, x, fsrv->nyx_bind_cpu_id, MAX_FILE, true); - + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, Parent); } else { - - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new_child( - fsrv->target_path, x, fsrv->nyx_bind_cpu_id, fsrv->nyx_id); - + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, Child); } - } + fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); + ck_free(x); if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); } -- cgit 1.4.1 From 47833bcf9e4b642e090f7cc0da25d1ed99688e5e Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Sun, 16 Apr 2023 04:28:19 +0200 Subject: fix remove_nyx_tmp_workdir function --- include/common.h | 2 +- src/afl-common.c | 24 +++++++++++++++++------- 2 files changed, 18 insertions(+), 8 deletions(-) (limited to 'include') diff --git a/include/common.h b/include/common.h index 279a5f47..e03566de 100644 --- a/include/common.h +++ b/include/common.h @@ -150,7 +150,7 @@ void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, #ifdef __linux__ /* Nyx helper functions to create and remove tmp workdirs */ char* create_nyx_tmp_workdir(void); -void remove_nyx_tmp_workdir(char* nyx_out_dir_path); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path); #endif #endif diff --git a/src/afl-common.c b/src/afl-common.c index 7dbf7129..fe0db94d 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1381,12 +1381,22 @@ char* create_nyx_tmp_workdir(void) { } /* Vice versa, we remove the tmp workdir for nyx with this helper function. */ -void remove_nyx_tmp_workdir(char* nyx_out_dir_path) { - /* Fix me: This is not recursive, so it will always fail. Use a libnyx helper function instead - * to remove the workdir safely (and not risking to wipe the whole filesystem accidentally). */ - //if (rmdir(nyx_out_dir_path)) { - // PFATAL("Unable to remove nyx workdir"); - //} - free(nyx_out_dir_path); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path) { + char* workdir_path = alloc_printf("%s/workdir", nyx_out_dir_path); + + if (access(workdir_path, R_OK) == 0) { + if(fsrv->nyx_handlers->nyx_remove_work_dir(workdir_path) != true) { + WARNF("Unable to remove nyx workdir (%s)", workdir_path); + } + } + + if (access(nyx_out_dir_path, R_OK) == 0) { + if (rmdir(nyx_out_dir_path)) { + WARNF("Unable to remove nyx workdir (%s)", nyx_out_dir_path); + } + } + + ck_free(workdir_path); + ck_free(nyx_out_dir_path); } #endif -- cgit 1.4.1 From 059d470e8dd0a5339daefe0842f4ad5014717838 Mon Sep 17 00:00:00 2001 From: Sergej Schumilo Date: Sun, 16 Apr 2023 04:42:09 +0200 Subject: improved Nyx tmp dir handling (additional sanity checks) --- include/forkserver.h | 2 ++ src/afl-analyze.c | 7 +--- src/afl-forkserver.c | 97 +++++++++++++++++++++++++++++++++++----------------- src/afl-fuzz.c | 8 ----- src/afl-showmap.c | 13 +------ src/afl-tmin.c | 7 +--- 6 files changed, 71 insertions(+), 63 deletions(-) (limited to 'include') diff --git a/include/forkserver.h b/include/forkserver.h index 7cbad8c8..ba280d38 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -190,6 +190,8 @@ typedef struct afl_forkserver { u32 nyx_id; /* nyx runner id (0 -> master) */ u32 nyx_bind_cpu_id; /* nyx runner cpu id */ char *nyx_aux_string; + bool nyx_use_tmp_workdir; + char *nyx_tmp_workdir_path; #endif } afl_forkserver_t; diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 0bdadfdc..0a4e7fb5 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -1058,7 +1058,7 @@ int main(int argc, char **argv_orig, char **envp) { FATAL("failed to initialize libnyx.so..."); } - fsrv.out_dir_path = create_nyx_tmp_workdir(); + fsrv.nyx_use_tmp_workdir = true; fsrv.nyx_bind_cpu_id = 0; use_argv = argv + optind; @@ -1119,11 +1119,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); -#ifdef __linux__ - if (fsrv.nyx_mode) { - remove_nyx_tmp_workdir(fsrv.out_dir_path); - } -#endif afl_shm_deinit(&shm); afl_fsrv_deinit(&fsrv); diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index ae2adc3d..0e705c63 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -126,11 +126,39 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { fail: FATAL("failed to load libnyx: %s\n", dlerror()); - free(plugin); + ck_free(plugin); return NULL; } +void afl_nyx_runner_kill(afl_forkserver_t *fsrv){ + if (fsrv->nyx_mode) { + + if (fsrv->nyx_aux_string){ + ck_free(fsrv->nyx_aux_string); + } + + /* check if we actually got a valid nyx runner */ + if (fsrv->nyx_runner) { + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } + + /* if we have use a tmp work dir we need to remove it */ + if (fsrv->nyx_use_tmp_workdir && fsrv->nyx_tmp_workdir_path) { + remove_nyx_tmp_workdir(fsrv, fsrv->nyx_tmp_workdir_path); + } + } +} + +/* Wrapper for FATAL() that kills the nyx runner (and removes all created tmp + * files) before exiting. Used before "afl_fsrv_killall()" is registered as + * an atexit() handler. */ +#define NYX_PRE_FATAL(fsrv, x...) \ + do { \ + afl_nyx_runner_kill(fsrv); \ + FATAL(x); \ + } while (0) + #endif /** @@ -168,6 +196,8 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->nyx_runner = NULL; fsrv->nyx_id = 0xFFFFFFFF; fsrv->nyx_bind_cpu_id = 0xFFFFFFFF; + fsrv->nyx_use_tmp_workdir = false; + fsrv->nyx_tmp_workdir_path = NULL; #endif // this structure needs default so we initialize it if this was not done @@ -481,21 +511,24 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!be_quiet) { ACTF("Spinning up the NYX backend..."); } - if (fsrv->out_dir_path == NULL) { FATAL("Nyx workdir path not found..."); } + if (fsrv->nyx_use_tmp_workdir){ + fsrv->nyx_tmp_workdir_path = create_nyx_tmp_workdir(); + fsrv->out_dir_path = fsrv->nyx_tmp_workdir_path; + } else { + if (fsrv->out_dir_path == NULL) { NYX_PRE_FATAL(fsrv, "Nyx workdir path not found..."); } + } - char *x = alloc_printf("%s/workdir", fsrv->out_dir_path); + char *workdir_path = alloc_printf("%s/workdir", fsrv->out_dir_path); - if (fsrv->nyx_id == 0xFFFFFFFF) { FATAL("Nyx ID is not set..."); } + if (fsrv->nyx_id == 0xFFFFFFFF) {NYX_PRE_FATAL(fsrv, "Nyx ID is not set..."); } if (fsrv->nyx_bind_cpu_id == 0xFFFFFFFF) { - - FATAL("Nyx CPU ID is not set..."); - + NYX_PRE_FATAL(fsrv, "Nyx CPU ID is not set..."); } void* nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); - fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, x); + fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, workdir_path); fsrv->nyx_handlers->nyx_config_set_input_buffer_size(nyx_config, MAX_FILE); fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); @@ -512,22 +545,36 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (getenv("NYX_REUSE_SNAPSHOT") != NULL){ if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) { - FATAL("NYX_REUSE_SNAPSHOT path does not exist"); + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not exist"); } /* stupid sanity check to avoid passing an empty or invalid snapshot directory */ char* snapshot_file_path = alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT")); if (access(snapshot_file_path, R_OK) == -1) { - FATAL("NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); } - free(snapshot_file_path); + ck_free(snapshot_file_path); + + /* another sanity check to avoid passing a snapshot directory that is + * located in the current workdir (the workdir will be wiped by libnyx on startup) */ + char* outdir_path_real = realpath(fsrv->out_dir_path, NULL); + char* workdir_snapshot_path = alloc_printf("%s/workdir/snapshot", outdir_path_real); + char* reuse_snapshot_path_real = realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL); + + if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0){ + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path is located in current workdir (use another output directory)"); + } + + ck_free(reuse_snapshot_path_real); + ck_free(workdir_snapshot_path); + ck_free(outdir_path_real); fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path(nyx_config, getenv("NYX_REUSE_SNAPSHOT")); } fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); - ck_free(x); + ck_free(workdir_path); if (fsrv->nyx_runner == NULL) { FATAL("Something went wrong ..."); } @@ -555,13 +602,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, switch (fsrv->nyx_handlers->nyx_exec(fsrv->nyx_runner)) { case Abort: - FATAL("Error: Nyx abort occured..."); + NYX_PRE_FATAL(fsrv, "Error: Nyx abort occured..."); break; case IoError: - FATAL("Error: QEMU-Nyx has died..."); + NYX_PRE_FATAL(fsrv, "Error: QEMU-Nyx has died..."); break; case Error: - FATAL("Error: Nyx runtime error has occured..."); + NYX_PRE_FATAL(fsrv, "Error: Nyx runtime error has occured..."); break; default: break; @@ -571,7 +618,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* autodict in Nyx mode */ if (!ignore_autodict) { - x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); + char* x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); int nyx_autodict_fd = open(x, O_RDONLY); ck_free(x); @@ -584,7 +631,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, u8 *dict = ck_alloc(f_len); if (dict == NULL) { - FATAL("Could not allocate %u bytes of autodictionary memory", + NYX_PRE_FATAL(fsrv, "Could not allocate %u bytes of autodictionary memory", f_len); } @@ -602,7 +649,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } else { - FATAL( + NYX_PRE_FATAL(fsrv, "Reading autodictionary fail at position %u with %u bytes " "left.", offset, len); @@ -1289,19 +1336,7 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) { fsrv->child_pid = -1; #ifdef __linux__ - if (fsrv->nyx_mode) { - - if (fsrv->nyx_aux_string){ - free(fsrv->nyx_aux_string); - } - - /* check if we actually got a valid nyx runner */ - if (fsrv->nyx_runner) { - fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); - } - - } - + afl_nyx_runner_kill(fsrv); #endif } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 8b4fe1e5..0e380f73 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2191,14 +2191,6 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->pending_not_fuzzed || !valid_seeds) { - #ifdef __linux__ - if (afl->fsrv.nyx_mode) { - - afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner); - - } - - #endif FATAL("We need at least one valid input seed that does not crash!"); } diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 3ddebaad..832730fd 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1247,7 +1247,7 @@ int main(int argc, char **argv_orig, char **envp) { } - fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_use_tmp_workdir = true; fsrv->nyx_bind_cpu_id = 0; #endif @@ -1443,12 +1443,6 @@ int main(int argc, char **argv_orig, char **envp) { if (execute_testcases(in_dir) == 0) { -#ifdef __linux__ - if (fsrv->nyx_mode) { - remove_nyx_tmp_workdir(fsrv->out_dir_path); - fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); - } -#endif FATAL("could not read input testcases from %s", in_dir); } @@ -1528,11 +1522,6 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->target_path) { ck_free(fsrv->target_path); } -#ifdef __linux__ - if (fsrv->nyx_mode) { - remove_nyx_tmp_workdir(fsrv->out_dir_path); - } -#endif afl_fsrv_deinit(fsrv); diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 942525d4..98403049 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -1130,7 +1130,7 @@ int main(int argc, char **argv_orig, char **envp) { FATAL("failed to initialize libnyx.so..."); } - fsrv->out_dir_path = create_nyx_tmp_workdir(); + fsrv->nyx_use_tmp_workdir = true; fsrv->nyx_bind_cpu_id = 0; use_argv = argv + optind; @@ -1316,11 +1316,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); -#ifdef __linux__ - if (fsrv->nyx_mode) { - remove_nyx_tmp_workdir(fsrv->out_dir_path); - } -#endif remove_shm = 0; afl_shm_deinit(&shm); -- cgit 1.4.1 From 56f7e3aa088e715b054f10c01b6b5a7e5acf8931 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sun, 16 Apr 2023 12:42:32 +0200 Subject: hidden -Y option for nyx, code format --- afl-cmin | 10 +-- afl-cmin.bash | 30 +++++--- include/common.h | 4 +- include/forkserver.h | 13 +++- src/afl-analyze.c | 29 +++++--- src/afl-common.c | 26 +++++-- src/afl-forkserver.c | 151 +++++++++++++++++++++++++++----------- src/afl-showmap.c | 54 +++++++++----- src/afl-tmin.c | 27 ++++--- utils/aflpp_driver/aflpp_driver.c | 23 +++--- 10 files changed, 243 insertions(+), 124 deletions(-) (limited to 'include') diff --git a/afl-cmin b/afl-cmin index 12791584..c5e64410 100755 --- a/afl-cmin +++ b/afl-cmin @@ -124,9 +124,9 @@ function usage() { "AFL_FORKSRV_INIT_TMOUT: time the fuzzer waits for the forkserver to come up\n" \ "AFL_KEEP_TRACES: leave the temporary /.traces directory\n" \ "AFL_KILL_SIGNAL: Signal delivered to child processes on timeout (default: SIGKILL)\n" \ -"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on termination\n" \ -" (default: SIGTERM). If this is not set and AFL_KILL_SIGNAL is set,\n" \ -" this will be set to the same value as AFL_KILL_SIGNAL.\n" \ +"AFL_FORK_SERVER_KILL_SIGNAL: Signal delivered to fork server processes on\n" \ +" termination (default: SIGTERM). If this is not set and AFL_KILL_SIGNAL is\n" \ +" set, this will be set to the same value as AFL_KILL_SIGNAL.\n" \ "AFL_NO_FORKSRV: run target via execve instead of using the forkserver\n" \ "AFL_CMIN_ALLOW_ANY: write tuples for crashing inputs also\n" \ "AFL_PATH: path for the afl-showmap binary if not found anywhere in PATH\n" \ @@ -157,7 +157,7 @@ BEGIN { # process options Opterr = 1 # default is to diagnose Optind = 1 # skip ARGV[0] - while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUX?")) != -1) { + while ((_go_c = getopt(ARGC, ARGV, "hi:o:f:m:t:eACOQUXY?")) != -1) { if (_go_c == "i") { if (!Optarg) usage() if (in_dir) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} @@ -219,7 +219,7 @@ BEGIN { unicorn_mode = 1 continue } else - if (_go_c == "X") { + if (_go_c == "X" || _go_c == "Y") { if (nyx_mode) { print "Option "_go_c" is only allowed once" > "/dev/stderr"} extra_par = extra_par " -X" nyx_mode = 1 diff --git a/afl-cmin.bash b/afl-cmin.bash index 10c9477a..bcf62eba 100755 --- a/afl-cmin.bash +++ b/afl-cmin.bash @@ -53,7 +53,7 @@ unset IN_DIR OUT_DIR STDIN_FILE EXTRA_PAR MEM_LIMIT_GIVEN \ export AFL_QUIET=1 -while getopts "+i:o:f:m:t:eOQUACh" opt; do +while getopts "+i:o:f:m:t:eOQUAChXY" opt; do case "$opt" in @@ -94,6 +94,14 @@ while getopts "+i:o:f:m:t:eOQUACh" opt; do EXTRA_PAR="$EXTRA_PAR -Q" QEMU_MODE=1 ;; + "Y") + EXTRA_PAR="$EXTRA_PAR -X" + NYX_MODE=1 + ;; + "X") + EXTRA_PAR="$EXTRA_PAR -X" + NYX_MODE=1 + ;; "U") EXTRA_PAR="$EXTRA_PAR -U" UNICORN_MODE=1 @@ -128,6 +136,7 @@ Execution control settings: -O - use binary-only instrumentation (FRIDA mode) -Q - use binary-only instrumentation (QEMU mode) -U - use unicorn-based instrumentation (Unicorn mode) + -X - use Nyx mode Minimization settings: @@ -206,16 +215,19 @@ if [ ! "$TIMEOUT" = "none" ]; then fi -if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then +if [ "$NYX_MODE" = "" ]; then + if [ ! -f "$TARGET_BIN" -o ! -x "$TARGET_BIN" ]; then - TNEW="`which "$TARGET_BIN" 2>/dev/null`" + TNEW="`which "$TARGET_BIN" 2>/dev/null`" - if [ ! -f "$TNEW" -o ! -x "$TNEW" ]; then - echo "[-] Error: binary '$TARGET_BIN' not found or not executable." 1>&2 - exit 1 - fi + if [ ! -f "$TNEW" -o ! -x "$TNEW" ]; then + echo "[-] Error: binary '$TARGET_BIN' not found or not executable." 1>&2 + exit 1 + fi + + TARGET_BIN="$TNEW" - TARGET_BIN="$TNEW" + fi fi @@ -228,7 +240,7 @@ grep -aq AFL_DUMP_MAP_SIZE "./$TARGET_BIN" && { } } -if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" ]; then +if [ "$AFL_SKIP_BIN_CHECK" = "" -a "$QEMU_MODE" = "" -a "$FRIDA_MODE" = "" -a "$UNICORN_MODE" = "" -a "$NYX_MODE" = "" ]; then if ! grep -qF "__AFL_SHM_ID" "$TARGET_BIN"; then echo "[-] Error: binary '$TARGET_BIN' doesn't appear to be instrumented." 1>&2 diff --git a/include/common.h b/include/common.h index e03566de..8d85d201 100644 --- a/include/common.h +++ b/include/common.h @@ -149,8 +149,8 @@ void *afl_memmem(const void *haystack, size_t haystacklen, const void *needle, #ifdef __linux__ /* Nyx helper functions to create and remove tmp workdirs */ -char* create_nyx_tmp_workdir(void); -void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path); +char *create_nyx_tmp_workdir(void); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char *nyx_out_dir_path); #endif #endif diff --git a/include/forkserver.h b/include/forkserver.h index ba280d38..f5069ce2 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -52,20 +52,25 @@ typedef enum NyxReturnValue { } NyxReturnValue; typedef enum NyxProcessRole { + StandAlone, Parent, Child, + } NyxProcessRole; typedef struct { void *(*nyx_config_load)(const char *sharedir); void (*nyx_config_set_workdir_path)(void *config, const char *workdir); - void (*nyx_config_set_input_buffer_size)(void *config, uint32_t input_buffer_size); - void (*nyx_config_set_input_buffer_write_protection)(void *config, bool input_buffer_write_protection); + void (*nyx_config_set_input_buffer_size)(void *config, + uint32_t input_buffer_size); + void (*nyx_config_set_input_buffer_write_protection)( + void *config, bool input_buffer_write_protection); void (*nyx_config_set_hprintf_fd)(void *config, int32_t hprintf_fd); void (*nyx_config_set_process_role)(void *config, enum NyxProcessRole role); - void (*nyx_config_set_reuse_snapshot_path)(void *config, const char *reuse_snapshot_path); + void (*nyx_config_set_reuse_snapshot_path)(void *config, + const char *reuse_snapshot_path); void *(*nyx_new)(void *config, uint32_t worker_id); void (*nyx_shutdown)(void *qemu_process); @@ -191,7 +196,7 @@ typedef struct afl_forkserver { u32 nyx_bind_cpu_id; /* nyx runner cpu id */ char *nyx_aux_string; bool nyx_use_tmp_workdir; - char *nyx_tmp_workdir_path; + char *nyx_tmp_workdir_path; #endif } afl_forkserver_t; diff --git a/src/afl-analyze.c b/src/afl-analyze.c index 0a4e7fb5..5b122741 100644 --- a/src/afl-analyze.c +++ b/src/afl-analyze.c @@ -815,7 +815,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_fsrv_init(&fsrv); - while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWXh")) > 0) { + while ((opt = getopt(argc, argv, "+i:f:m:t:eAOQUWXYh")) > 0) { switch (opt) { @@ -966,8 +966,9 @@ int main(int argc, char **argv_orig, char **envp) { fsrv.mem_limit = mem_limit; break; - - #ifdef __linux__ + + case 'Y': // fallthough +#ifdef __linux__ case 'X': /* NYX mode */ if (fsrv.nyx_mode) { FATAL("Multiple -X options not supported"); } @@ -977,11 +978,11 @@ int main(int argc, char **argv_orig, char **envp) { fsrv.nyx_standalone = true; break; - #else +#else case 'X': FATAL("Nyx mode is only availabe on linux..."); break; - #endif +#endif case 'h': usage(argv[0]); @@ -1015,12 +1016,16 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(argv); #ifdef __linux__ - if(!fsrv.nyx_mode){ + if (!fsrv.nyx_mode) { + fsrv.target_path = find_binary(argv[optind]); - } - else{ + + } else { + fsrv.target_path = ck_strdup(argv[optind]); + } + #else fsrv.target_path = find_binary(argv[optind]); #endif @@ -1048,6 +1053,7 @@ int main(int argc, char **argv_orig, char **envp) { use_argv = get_cs_argv(argv[0], &target_path, argc - optind, argv + optind); #ifdef __linux__ + } else if (fsrv.nyx_mode) { fsrv.nyx_id = 0; @@ -1055,7 +1061,9 @@ int main(int argc, char **argv_orig, char **envp) { u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); fsrv.nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); if (fsrv.nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } fsrv.nyx_use_tmp_workdir = true; @@ -1090,9 +1098,7 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); #ifdef __linux__ - if(!fsrv.nyx_mode){ - (void)check_binary_signatures(fsrv.target_path); - } + if (!fsrv.nyx_mode) { (void)check_binary_signatures(fsrv.target_path); } #else (void)check_binary_signatures(fsrv.target_path); #endif @@ -1119,7 +1125,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); - afl_shm_deinit(&shm); afl_fsrv_deinit(&fsrv); if (fsrv.target_path) { ck_free(fsrv.target_path); } diff --git a/src/afl-common.c b/src/afl-common.c index 5692e277..a5c48e80 100644 --- a/src/afl-common.c +++ b/src/afl-common.c @@ -1365,36 +1365,46 @@ s32 create_file(u8 *fn) { * etc.). This helper function basically creates both a path to a tmp workdir * and the workdir itself. If the environment variable TMPDIR is set, we use * that as the base directory, otherwise we use /tmp. */ -char* create_nyx_tmp_workdir(void) { +char *create_nyx_tmp_workdir(void) { char *tmpdir = getenv("TMPDIR"); if (!tmpdir) { tmpdir = "/tmp"; } - char* nyx_out_dir_path = alloc_printf("%s/.nyx_tmp_%d/", tmpdir, (u32)getpid()); + char *nyx_out_dir_path = + alloc_printf("%s/.nyx_tmp_%d/", tmpdir, (u32)getpid()); - if (mkdir(nyx_out_dir_path, 0700)) { - PFATAL("Unable to create nyx workdir"); - } + if (mkdir(nyx_out_dir_path, 0700)) { PFATAL("Unable to create nyx workdir"); } return nyx_out_dir_path; + } /* Vice versa, we remove the tmp workdir for nyx with this helper function. */ -void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char* nyx_out_dir_path) { - char* workdir_path = alloc_printf("%s/workdir", nyx_out_dir_path); +void remove_nyx_tmp_workdir(afl_forkserver_t *fsrv, char *nyx_out_dir_path) { + + char *workdir_path = alloc_printf("%s/workdir", nyx_out_dir_path); if (access(workdir_path, R_OK) == 0) { - if(fsrv->nyx_handlers->nyx_remove_work_dir(workdir_path) != true) { + + if (fsrv->nyx_handlers->nyx_remove_work_dir(workdir_path) != true) { + WARNF("Unable to remove nyx workdir (%s)", workdir_path); + } + } if (rmdir(nyx_out_dir_path)) { + WARNF("Unable to remove nyx workdir (%s)", nyx_out_dir_path); + } ck_free(workdir_path); ck_free(nyx_out_dir_path); + } + #endif + diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index fd4e213d..aa8c8622 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -50,7 +50,7 @@ #include #ifdef __linux__ -#include + #include /* function to load nyx_helper function from libnyx.so */ @@ -66,22 +66,32 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { plugin->nyx_config_load = dlsym(handle, "nyx_config_load"); if (plugin->nyx_config_load == NULL) { goto fail; } - plugin->nyx_config_set_workdir_path = dlsym(handle, "nyx_config_set_workdir_path"); + plugin->nyx_config_set_workdir_path = + dlsym(handle, "nyx_config_set_workdir_path"); if (plugin->nyx_config_set_workdir_path == NULL) { goto fail; } - plugin->nyx_config_set_input_buffer_size = dlsym(handle, "nyx_config_set_input_buffer_size"); + plugin->nyx_config_set_input_buffer_size = + dlsym(handle, "nyx_config_set_input_buffer_size"); if (plugin->nyx_config_set_input_buffer_size == NULL) { goto fail; } - plugin->nyx_config_set_input_buffer_write_protection = dlsym(handle, "nyx_config_set_input_buffer_write_protection"); - if (plugin->nyx_config_set_input_buffer_write_protection == NULL) { goto fail; } + plugin->nyx_config_set_input_buffer_write_protection = + dlsym(handle, "nyx_config_set_input_buffer_write_protection"); + if (plugin->nyx_config_set_input_buffer_write_protection == NULL) { - plugin->nyx_config_set_hprintf_fd = dlsym(handle, "nyx_config_set_hprintf_fd"); + goto fail; + + } + + plugin->nyx_config_set_hprintf_fd = + dlsym(handle, "nyx_config_set_hprintf_fd"); if (plugin->nyx_config_set_hprintf_fd == NULL) { goto fail; } - plugin->nyx_config_set_process_role = dlsym(handle, "nyx_config_set_process_role"); + plugin->nyx_config_set_process_role = + dlsym(handle, "nyx_config_set_process_role"); if (plugin->nyx_config_set_process_role == NULL) { goto fail; } - plugin->nyx_config_set_reuse_snapshot_path = dlsym(handle, "nyx_config_set_reuse_snapshot_path"); + plugin->nyx_config_set_reuse_snapshot_path = + dlsym(handle, "nyx_config_set_reuse_snapshot_path"); if (plugin->nyx_config_set_reuse_snapshot_path == NULL) { goto fail; } plugin->nyx_new = dlsym(handle, "nyx_new"); @@ -119,7 +129,6 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) { plugin->nyx_remove_work_dir = dlsym(handle, "nyx_remove_work_dir"); if (plugin->nyx_remove_work_dir == NULL) { goto fail; } - OKF("libnyx plugin is ready!"); return plugin; @@ -131,33 +140,40 @@ fail: } -void afl_nyx_runner_kill(afl_forkserver_t *fsrv){ +void afl_nyx_runner_kill(afl_forkserver_t *fsrv) { + if (fsrv->nyx_mode) { - if (fsrv->nyx_aux_string){ - ck_free(fsrv->nyx_aux_string); - } + if (fsrv->nyx_aux_string) { ck_free(fsrv->nyx_aux_string); } /* check if we actually got a valid nyx runner */ if (fsrv->nyx_runner) { + fsrv->nyx_handlers->nyx_shutdown(fsrv->nyx_runner); + } /* if we have use a tmp work dir we need to remove it */ if (fsrv->nyx_use_tmp_workdir && fsrv->nyx_tmp_workdir_path) { + remove_nyx_tmp_workdir(fsrv, fsrv->nyx_tmp_workdir_path); + } + } + } -/* Wrapper for FATAL() that kills the nyx runner (and removes all created tmp - * files) before exiting. Used before "afl_fsrv_killall()" is registered as - * an atexit() handler. */ -#define NYX_PRE_FATAL(fsrv, x...) \ - do { \ - afl_nyx_runner_kill(fsrv); \ - FATAL(x); \ - } while (0) + /* Wrapper for FATAL() that kills the nyx runner (and removes all created tmp + * files) before exiting. Used before "afl_fsrv_killall()" is registered as + * an atexit() handler. */ + #define NYX_PRE_FATAL(fsrv, x...) \ + do { \ + \ + afl_nyx_runner_kill(fsrv); \ + FATAL(x); \ + \ + } while (0) #endif @@ -511,70 +527,116 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!be_quiet) { ACTF("Spinning up the NYX backend..."); } - if (fsrv->nyx_use_tmp_workdir){ + if (fsrv->nyx_use_tmp_workdir) { + fsrv->nyx_tmp_workdir_path = create_nyx_tmp_workdir(); fsrv->out_dir_path = fsrv->nyx_tmp_workdir_path; + } else { - if (fsrv->out_dir_path == NULL) { NYX_PRE_FATAL(fsrv, "Nyx workdir path not found..."); } + + if (fsrv->out_dir_path == NULL) { + + NYX_PRE_FATAL(fsrv, "Nyx workdir path not found..."); + + } + } /* libnyx expects an absolute path */ - char* outdir_path_absolute = realpath(fsrv->out_dir_path, NULL); - if (outdir_path_absolute == NULL) { NYX_PRE_FATAL(fsrv, "Nyx workdir path cannot be resolved ..."); } + char *outdir_path_absolute = realpath(fsrv->out_dir_path, NULL); + if (outdir_path_absolute == NULL) { + + NYX_PRE_FATAL(fsrv, "Nyx workdir path cannot be resolved ..."); + + } char *workdir_path = alloc_printf("%s/workdir", outdir_path_absolute); - if (fsrv->nyx_id == 0xFFFFFFFF) {NYX_PRE_FATAL(fsrv, "Nyx ID is not set..."); } + if (fsrv->nyx_id == 0xFFFFFFFF) { + + NYX_PRE_FATAL(fsrv, "Nyx ID is not set..."); + + } if (fsrv->nyx_bind_cpu_id == 0xFFFFFFFF) { + NYX_PRE_FATAL(fsrv, "Nyx CPU ID is not set..."); + } - void* nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); + void *nyx_config = fsrv->nyx_handlers->nyx_config_load(fsrv->target_path); fsrv->nyx_handlers->nyx_config_set_workdir_path(nyx_config, workdir_path); fsrv->nyx_handlers->nyx_config_set_input_buffer_size(nyx_config, MAX_FILE); - fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); + fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, + true); if (fsrv->nyx_standalone) { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, StandAlone); + } else { + if (fsrv->nyx_parent) { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, Parent); + } else { + fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, Child); + } + } - if (getenv("NYX_REUSE_SNAPSHOT") != NULL){ + if (getenv("NYX_REUSE_SNAPSHOT") != NULL) { if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) { + NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not exist"); + } - /* stupid sanity check to avoid passing an empty or invalid snapshot directory */ - char* snapshot_file_path = alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT")); + /* stupid sanity check to avoid passing an empty or invalid snapshot + * directory */ + char *snapshot_file_path = + alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT")); if (access(snapshot_file_path, R_OK) == -1) { - NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); + + NYX_PRE_FATAL( + fsrv, + "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot"); + } + ck_free(snapshot_file_path); /* another sanity check to avoid passing a snapshot directory that is - * located in the current workdir (the workdir will be wiped by libnyx on startup) */ - char* workdir_snapshot_path = alloc_printf("%s/workdir/snapshot", outdir_path_absolute); - char* reuse_snapshot_path_real = realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL); + * located in the current workdir (the workdir will be wiped by libnyx on + * startup) */ + char *workdir_snapshot_path = + alloc_printf("%s/workdir/snapshot", outdir_path_absolute); + char *reuse_snapshot_path_real = + realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL); + + if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0) { + + NYX_PRE_FATAL(fsrv, + "NYX_REUSE_SNAPSHOT path is located in current workdir " + "(use another output directory)"); - if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0){ - NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path is located in current workdir (use another output directory)"); } ck_free(reuse_snapshot_path_real); ck_free(workdir_snapshot_path); - fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path(nyx_config, getenv("NYX_REUSE_SNAPSHOT")); + fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path( + nyx_config, getenv("NYX_REUSE_SNAPSHOT")); + } - fsrv->nyx_runner = fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); + fsrv->nyx_runner = + fsrv->nyx_handlers->nyx_new(nyx_config, fsrv->nyx_bind_cpu_id); ck_free(workdir_path); ck_free(outdir_path_absolute); @@ -621,7 +683,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, /* autodict in Nyx mode */ if (!ignore_autodict) { - char* x = alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); + char *x = + alloc_printf("%s/workdir/dump/afl_autodict.txt", fsrv->out_dir_path); int nyx_autodict_fd = open(x, O_RDONLY); ck_free(x); @@ -634,8 +697,9 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, u8 *dict = ck_alloc(f_len); if (dict == NULL) { - NYX_PRE_FATAL(fsrv, "Could not allocate %u bytes of autodictionary memory", - f_len); + NYX_PRE_FATAL( + fsrv, "Could not allocate %u bytes of autodictionary memory", + f_len); } @@ -652,7 +716,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } else { - NYX_PRE_FATAL(fsrv, + NYX_PRE_FATAL( + fsrv, "Reading autodictionary fail at position %u with %u bytes " "left.", offset, len); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 832730fd..df030672 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -444,8 +444,11 @@ static void showmap_run_target_nyx_mode(afl_forkserver_t *fsrv) { FSRV_RUN_ERROR) { FATAL("Error running target in Nyx mode"); + } + } + #endif /* Execute target application. */ @@ -890,7 +893,7 @@ int main(int argc, char **argv_orig, char **envp) { if (getenv("AFL_QUIET") != NULL) { be_quiet = true; } - while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshX")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:AeqCZOH:QUWbcrshXY")) > 0) { switch (opt) { @@ -1078,7 +1081,8 @@ int main(int argc, char **argv_orig, char **envp) { break; - #ifdef __linux__ + case 'Y': // fallthough +#ifdef __linux__ case 'X': /* NYX mode */ if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } @@ -1088,11 +1092,11 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->nyx_standalone = true; break; - #else +#else case 'X': FATAL("Nyx mode is only availabe on linux..."); break; - #endif +#endif case 'b': @@ -1166,12 +1170,16 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); #ifdef __linux__ - if(!fsrv->nyx_mode){ + if (!fsrv->nyx_mode) { + fsrv->target_path = find_binary(argv[optind]); - } - else{ + + } else { + fsrv->target_path = ck_strdup(argv[optind]); + } + #else fsrv->target_path = find_binary(argv[optind]); #endif @@ -1232,11 +1240,12 @@ int main(int argc, char **argv_orig, char **envp) { get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); #ifdef __linux__ + } else if (fsrv->nyx_mode) { use_argv = ck_alloc(sizeof(char *) * (1)); use_argv[0] = argv[0]; - + fsrv->nyx_id = 0; u8 *libnyx_binary = find_afl_binary(use_argv[0], "libnyx.so"); @@ -1288,9 +1297,12 @@ int main(int argc, char **argv_orig, char **envp) { } #ifdef __linux__ - if(!fsrv->nyx_mode && in_dir){ + if (!fsrv->nyx_mode && in_dir) { + (void)check_binary_signatures(fsrv->target_path); + } + #else if (in_dir) { (void)check_binary_signatures(fsrv->target_path); } #endif @@ -1313,14 +1325,14 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->shmem_fuzz_len = (u32 *)map; fsrv->shmem_fuzz = map + sizeof(u32); - configure_afl_kill_signals( - fsrv, NULL, NULL, (fsrv->qemu_mode || unicorn_mode - #ifdef __linux__ - || fsrv->nyx_mode - #endif - ) - ? SIGKILL - : SIGTERM); + configure_afl_kill_signals(fsrv, NULL, NULL, + (fsrv->qemu_mode || unicorn_mode +#ifdef __linux__ + || fsrv->nyx_mode +#endif + ) + ? SIGKILL + : SIGTERM); if (!fsrv->cs_mode && !fsrv->qemu_mode && !unicorn_mode) { @@ -1464,13 +1476,18 @@ int main(int argc, char **argv_orig, char **envp) { shm_fuzz = deinit_shmem(fsrv, shm_fuzz); #ifdef __linux__ - if(!fsrv->nyx_mode){ + if (!fsrv->nyx_mode) { + #endif showmap_run_target(fsrv, use_argv); #ifdef __linux__ + } else { + showmap_run_target_nyx_mode(fsrv); + } + #endif tcnt = write_results_to_file(fsrv, out_file); if (!quiet_mode) { @@ -1522,7 +1539,6 @@ int main(int argc, char **argv_orig, char **envp) { if (fsrv->target_path) { ck_free(fsrv->target_path); } - afl_fsrv_deinit(fsrv); if (stdin_file) { ck_free(stdin_file); } diff --git a/src/afl-tmin.c b/src/afl-tmin.c index 98403049..e7442d1d 100644 --- a/src/afl-tmin.c +++ b/src/afl-tmin.c @@ -846,7 +846,7 @@ int main(int argc, char **argv_orig, char **envp) { SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n"); - while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXHh")) > 0) { + while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeAOQUWXYHh")) > 0) { switch (opt) { @@ -1004,7 +1004,8 @@ int main(int argc, char **argv_orig, char **envp) { break; - #ifdef __linux__ + case 'Y': // fallthough +#ifdef __linux__ case 'X': /* NYX mode */ if (fsrv->nyx_mode) { FATAL("Multiple -X options not supported"); } @@ -1014,11 +1015,11 @@ int main(int argc, char **argv_orig, char **envp) { fsrv->nyx_standalone = true; break; - #else +#else case 'X': FATAL("Nyx mode is only availabe on linux..."); break; - #endif +#endif case 'H': /* Hang Mode */ @@ -1086,12 +1087,16 @@ int main(int argc, char **argv_orig, char **envp) { set_up_environment(fsrv, argv); #ifdef __linux__ - if(!fsrv->nyx_mode){ + if (!fsrv->nyx_mode) { + fsrv->target_path = find_binary(argv[optind]); - } - else{ + + } else { + fsrv->target_path = ck_strdup(argv[optind]); + } + #else fsrv->target_path = find_binary(argv[optind]); #endif @@ -1120,6 +1125,7 @@ int main(int argc, char **argv_orig, char **envp) { get_cs_argv(argv[0], &fsrv->target_path, argc - optind, argv + optind); #ifdef __linux__ + } else if (fsrv->nyx_mode) { fsrv->nyx_id = 0; @@ -1127,7 +1133,9 @@ int main(int argc, char **argv_orig, char **envp) { u8 *libnyx_binary = find_afl_binary(argv[0], "libnyx.so"); fsrv->nyx_handlers = afl_load_libnyx_plugin(libnyx_binary); if (fsrv->nyx_handlers == NULL) { + FATAL("failed to initialize libnyx.so..."); + } fsrv->nyx_use_tmp_workdir = true; @@ -1207,9 +1215,7 @@ int main(int argc, char **argv_orig, char **envp) { read_initial_file(); #ifdef __linux__ - if(!fsrv->nyx_mode){ - (void)check_binary_signatures(fsrv->target_path); - } + if (!fsrv->nyx_mode) { (void)check_binary_signatures(fsrv->target_path); } #else (void)check_binary_signatures(fsrv->target_path); #endif @@ -1316,7 +1322,6 @@ int main(int argc, char **argv_orig, char **envp) { OKF("We're done here. Have a nice day!\n"); - remove_shm = 0; afl_shm_deinit(&shm); if (fsrv->use_shmem_fuzz) shm_fuzz = deinit_shmem(fsrv, shm_fuzz); diff --git a/utils/aflpp_driver/aflpp_driver.c b/utils/aflpp_driver/aflpp_driver.c index 34294809..4e8f466d 100644 --- a/utils/aflpp_driver/aflpp_driver.c +++ b/utils/aflpp_driver/aflpp_driver.c @@ -78,10 +78,10 @@ extern unsigned int __afl_map_size; on the other hand this is what Google needs to make LLVMFuzzerRunDriver() work. Choose your poison Google! */ /*__attribute__((weak))*/ int LLVMFuzzerTestOneInput(const uint8_t *Data, - size_t Size); -__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); -__attribute__((weak)) int LLVMFuzzerRunDriver( - int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size)); + size_t Size); +__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv); +__attribute__((weak)) int LLVMFuzzerRunDriver( + int *argc, char ***argv, int (*callback)(const uint8_t *data, size_t size)); // Default nop ASan hooks for manual poisoning when not linking the ASan // runtime @@ -268,15 +268,16 @@ static int ExecuteFilesOnyByOne(int argc, char **argv, __attribute__((weak)) int main(int argc, char **argv) { -// Enable if LLVMFuzzerTestOneInput() has the weak attribute -/* - if (!LLVMFuzzerTestOneInput) { + // Enable if LLVMFuzzerTestOneInput() has the weak attribute + /* + if (!LLVMFuzzerTestOneInput) { - fprintf(stderr, "Error: function LLVMFuzzerTestOneInput() not found!\n"); - abort(); + fprintf(stderr, "Error: function LLVMFuzzerTestOneInput() not found!\n"); + abort(); - } -*/ + } + + */ if (argc < 2 || strncmp(argv[1], "-h", 2) == 0) printf( -- cgit 1.4.1 From 7f734c96d187312868178e8ead95dc103c557c1f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 17 Apr 2023 10:25:10 +0200 Subject: v4.06c release --- README.md | 4 ++-- docs/Changelog.md | 5 +++-- include/config.h | 2 +- 3 files changed, 6 insertions(+), 5 deletions(-) (limited to 'include') diff --git a/README.md b/README.md index 821b8cb7..c012c400 100644 --- a/README.md +++ b/README.md @@ -2,9 +2,9 @@ AFL++ logo -Release version: [4.05c](https://github.com/AFLplusplus/AFLplusplus/releases) +Release version: [4.06c](https://github.com/AFLplusplus/AFLplusplus/releases) -GitHub version: 4.06a +GitHub version: 4.07a Repository: [https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus) diff --git a/docs/Changelog.md b/docs/Changelog.md index 3337feb9..587fb64c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,7 +3,7 @@ This is the list of all noteworthy changes made in every public release of the tool. See README.md for the general instruction manual. -### Version ++4.06a (dev) +### Version ++4.06c (release) - afl-fuzz: - ensure temporary file descriptor is closed when not used - added `AFL_NO_WARN_INSTABILITY` @@ -29,9 +29,10 @@ - fix issue on MacOS - unicorn_mode: - updated and minor issues fixed + - nyx_mode support for all tools + - better sanitizer default options support for all tools - new custom module: autotoken, a grammar free fuzzer for text inputs - fixed custom mutator C examples - - better sanitizer default options support for all tools - more minor fixes and cross-platform support ### Version ++4.05c (release) diff --git a/include/config.h b/include/config.h index e46f515a..b6249a0f 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.06a" +#define VERSION "++4.06c" /****************************************************** * * -- cgit 1.4.1 From 02b9e583f2a5dd7d83bd4c02af8d2081532689ed Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 17 Apr 2023 14:41:05 +0200 Subject: v4.07a init --- docs/Changelog.md | 4 ++++ include/config.h | 2 +- 2 files changed, 5 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/docs/Changelog.md b/docs/Changelog.md index 587fb64c..30e76f2c 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -3,6 +3,10 @@ This is the list of all noteworthy changes made in every public release of the tool. See README.md for the general instruction manual. +### Version ++4.07a (dev) + - soon :) + + ### Version ++4.06c (release) - afl-fuzz: - ensure temporary file descriptor is closed when not used diff --git a/include/config.h b/include/config.h index b6249a0f..764c29dc 100644 --- a/include/config.h +++ b/include/config.h @@ -26,7 +26,7 @@ /* Version string: */ // c = release, a = volatile github dev, e = experimental branch -#define VERSION "++4.06c" +#define VERSION "++4.07a" /****************************************************** * * -- cgit 1.4.1 From 9ab902402cd33156257fc0355c0105e7e03f5ba3 Mon Sep 17 00:00:00 2001 From: Maik Betka <9078425+voidptr127@users.noreply.github.com> Date: Mon, 17 Apr 2023 17:09:48 +0200 Subject: fixed code clones in atnwalk.c, introduced new environment variable AFL_POST_PROCESS_KEEP_ORIGINAL in AFL++ to integrate atnwalk without re-compiling afl-fuzz --- custom_mutators/atnwalk/atnwalk.c | 144 +++++++++++++------------------------- include/afl-fuzz.h | 4 +- include/envs.h | 1 + src/afl-fuzz-run.c | 11 +-- src/afl-fuzz-state.c | 7 ++ src/afl-fuzz.c | 2 + 6 files changed, 66 insertions(+), 103 deletions(-) (limited to 'include') diff --git a/custom_mutators/atnwalk/atnwalk.c b/custom_mutators/atnwalk/atnwalk.c index 0194ff18..901b8a9e 100644 --- a/custom_mutators/atnwalk/atnwalk.c +++ b/custom_mutators/atnwalk/atnwalk.c @@ -1,4 +1,4 @@ -#include "../../include/afl-fuzz.h" +#include "afl-fuzz.h" #include #include @@ -9,7 +9,7 @@ #include #define BUF_SIZE_INIT 4096 -#define SOCKET_NAME "/tmp/atnwalk.socket" +#define SOCKET_NAME "./atnwalk.socket" // how many errors (e.g. timeouts) to tolerate until moving on to the next queue entry #define ATNWALK_ERRORS_MAX 1 @@ -155,6 +155,29 @@ unsigned int afl_custom_fuzz_count(atnwalk_mutator_t *data, const unsigned char return data->stage_havoc_max + data->stage_splice_max; } + +size_t fail_fatal(int fd_socket, uint8_t **out_buf) { + if (fd_socket != -1) { + close(fd_socket); + } + *out_buf = NULL; + return 0; +} + + +size_t fail_gracefully(int fd_socket, atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, uint8_t **out_buf) { + if (fd_socket != -1) { + close(fd_socket); + } + data->atnwalk_error_count++; + if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { + data->afl->stage_max = data->afl->stage_cur; + } + *out_buf = buf; + return buf_size; +} + + /** * Perform custom mutations on a given input * @@ -202,7 +225,7 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u } } - // keep track of found new corpus seeds per stage and run the stage twice as long as initially planned + // keep track of found new corpus seeds per stage if (data->afl->queued_items + data->afl->saved_crashes > data->prev_hits) { if (data->stage_splice_cur <= 1) { data->afl->stage_finds[STAGE_HAVOC] += data->afl->queued_items + data->afl->saved_crashes - data->prev_hits; @@ -216,38 +239,28 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u // check whether this input produces a lot of timeouts, if it does then abandon this queue entry if (data->afl->total_tmouts - data->prev_timeouts >= EXEC_TIMEOUT_MAX) { data->afl->stage_max = data->afl->stage_cur; - *out_buf = buf; - return buf_size; + return fail_gracefully(-1, data, buf, buf_size, out_buf); } // initialize the socket fd_socket = socket(AF_UNIX, SOCK_STREAM, 0); - if (fd_socket == -1) { - *out_buf = NULL; - return 0; - } + if (fd_socket == -1) { return fail_fatal(fd_socket, out_buf); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1); if (connect(fd_socket, (const struct sockaddr *) &addr, sizeof(addr)) == -1) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // ask whether the server is alive ctrl_buf[0] = SERVER_ARE_YOU_ALIVE; if (!write_all(fd_socket, ctrl_buf, 1)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // see whether the server replies as expected if (!read_all(fd_socket, ctrl_buf, 1) || ctrl_buf[0] != SERVER_YES_I_AM_ALIVE) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // tell the server what we want to do @@ -262,88 +275,48 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u ctrl_buf[0] = wanted; put_uint32(ctrl_buf + 1, (uint32_t) buf_size); if (!write_all(fd_socket, ctrl_buf, 5)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // send the data to mutate and encode if (!write_all(fd_socket, buf, buf_size)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } if (wanted & SERVER_CROSSOVER_BIT) { // since we requested crossover, we will first tell how much additional data is to be expected put_uint32(ctrl_buf, (uint32_t) add_buf_size); if (!write_all(fd_socket, ctrl_buf, 4)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // send the additional data for crossover if (!write_all(fd_socket, add_buf, add_buf_size)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // lastly, a seed is required for crossover so send one put_uint64(ctrl_buf, (uint64_t) rand()); if (!write_all(fd_socket, ctrl_buf, 8)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } } // since we requested mutation, we need to provide a seed for that put_uint64(ctrl_buf, (uint64_t) rand()); if (!write_all(fd_socket, ctrl_buf, 8)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // obtain the required buffer size for the data that will be returned if (!read_all(fd_socket, ctrl_buf, 4)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } size_t new_size = (size_t) to_uint32(ctrl_buf); // if the data is too large then we ignore this round if (new_size > max_size) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } if (new_size > buf_size) { @@ -360,13 +333,7 @@ size_t afl_custom_fuzz(atnwalk_mutator_t *data, uint8_t *buf, size_t buf_size, u // obtain the encoded data if (!read_all(fd_socket, *out_buf, new_size)) { - close(fd_socket); - data->atnwalk_error_count++; - if (data->atnwalk_error_count > ATNWALK_ERRORS_MAX) { - data->afl->stage_max = data->afl->stage_cur; - } - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } close(fd_socket); @@ -398,54 +365,41 @@ size_t afl_custom_post_process(atnwalk_mutator_t *data, uint8_t *buf, size_t buf // initialize the socket fd_socket = socket(AF_UNIX, SOCK_STREAM, 0); if (fd_socket == -1) { - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } memset(&addr, 0, sizeof(addr)); addr.sun_family = AF_UNIX; strncpy(addr.sun_path, SOCKET_NAME, sizeof(addr.sun_path) - 1); if (connect(fd_socket, (const struct sockaddr *) &addr, sizeof(addr)) == -1) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // ask whether the server is alive ctrl_buf[0] = SERVER_ARE_YOU_ALIVE; if (!write_all(fd_socket, ctrl_buf, 1)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // see whether the server replies as expected if (!read_all(fd_socket, ctrl_buf, 1) || ctrl_buf[0] != SERVER_YES_I_AM_ALIVE) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_fatal(fd_socket, out_buf); } // tell the server what we want and how much data will be sent ctrl_buf[0] = SERVER_DECODE_BIT; put_uint32(ctrl_buf + 1, (uint32_t) buf_size); if (!write_all(fd_socket, ctrl_buf, 5)) { - close(fd_socket); - *out_buf = NULL; - return 0; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // send the data to decode if (!write_all(fd_socket, buf, buf_size)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } // obtain the required buffer size for the data that will be returned if (!read_all(fd_socket, ctrl_buf, 4)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } size_t new_size = (size_t) to_uint32(ctrl_buf); @@ -458,9 +412,7 @@ size_t afl_custom_post_process(atnwalk_mutator_t *data, uint8_t *buf, size_t buf // obtain the decoded data if (!read_all(fd_socket, *out_buf, new_size)) { - close(fd_socket); - *out_buf = buf; - return buf_size; + return fail_gracefully(fd_socket, data, buf, buf_size, out_buf); } close(fd_socket); diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 23c20cc4..5d9b17e7 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -386,8 +386,8 @@ typedef struct afl_env_vars { afl_bench_until_crash, afl_debug_child, afl_autoresume, afl_cal_fast, afl_cycle_schedules, afl_expand_havoc, afl_statsd, afl_cmplog_only_new, afl_exit_on_seed_issues, afl_try_affinity, afl_ignore_problems, - afl_keep_timeouts, afl_pizza_mode, afl_no_crash_readme, - afl_no_startup_calibration; + afl_keep_timeouts, afl_pizza_mode, afl_post_process_keep_original, + afl_no_crash_readme, afl_no_startup_calibration; u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path, *afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload, diff --git a/include/envs.h b/include/envs.h index 2204a100..1527dfcb 100644 --- a/include/envs.h +++ b/include/envs.h @@ -177,6 +177,7 @@ static char *afl_environment_variables[] = { "AFL_PATH", "AFL_PERFORMANCE_FILE", "AFL_PERSISTENT_RECORD", + "AFL_POST_PROCESS_KEEP_ORIGINAL", "AFL_PRELOAD", "AFL_TARGET_ENV", "AFL_PYTHON_MODULE", diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index 26a1ea36..3c3d4817 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -130,15 +130,16 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { new_size = afl->max_length; } - // TODO: think about how to enable the change without breaking other implementations - // if (new_mem != *mem) { *mem = new_mem; } /* everything as planned. use the potentially new data. */ - // TODO: think about how to enable the change without breaking other implementations afl_fsrv_write_to_testcase(&afl->fsrv, new_mem, new_size); - // TODO: think about how to enable the change without breaking other implementations - // len = new_size; + if (likely(!afl->afl_env.afl_post_process_keep_original)) { + + if (new_mem != *mem) { *mem = new_mem; } + len = new_size; + + } } else { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 0576f84f..10bc2768 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -377,6 +377,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_statsd = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_POST_PROCESS_KEEP_ORIGINAL", + + afl_environment_variable_len)) { + + afl->afl_env.afl_post_process_keep_original = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_TMPDIR", afl_environment_variable_len)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 1f0fcab1..b83af257 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -284,6 +284,8 @@ static void usage(u8 *argv0, int more_help) { PERSISTENT_MSG + "AFL_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to the queue,\n" + " but execute the post-processed one\n" "AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n" "AFL_TARGET_ENV: pass extra environment variables to target\n" "AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n" -- cgit 1.4.1 From 4e5f42cab6b8c501eeaf76ec7ca920089f6e0f3a Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 20 Apr 2023 10:39:23 +0200 Subject: afl-showmap custom mutator support --- GNUmakefile | 2 +- TODO.md | 4 +-- afl-cmin | 2 ++ afl-cmin.bash | 2 ++ docs/Changelog.md | 3 +- include/afl-fuzz.h | 8 +++-- src/afl-showmap.c | 93 +++++++++++++++++++++++++++++++++++++++++++++++++++++- 7 files changed, 107 insertions(+), 7 deletions(-) (limited to 'include') diff --git a/GNUmakefile b/GNUmakefile index 5bc3f9d5..0f890308 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -453,7 +453,7 @@ afl-fuzz: $(COMM_HDR) include/afl-fuzz.h $(AFL_FUZZ_FILES) src/afl-common.o src/ $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) $(AFL_FUZZ_FILES) src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) -lm afl-showmap: src/afl-showmap.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86 - $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS) + $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-fuzz-mutators.c src/afl-fuzz-python.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(PYFLAGS) $(LDFLAGS) afl-tmin: src/afl-tmin.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o $(COMM_HDR) | test_x86 $(CC) $(CFLAGS) $(COMPILE_STATIC) $(CFLAGS_FLTO) src/$@.c src/afl-common.o src/afl-sharedmem.o src/afl-forkserver.o src/afl-performance.o -o $@ $(LDFLAGS) diff --git a/TODO.md b/TODO.md index e7789cf6..dba75070 100644 --- a/TODO.md +++ b/TODO.md @@ -3,14 +3,14 @@ ## Should - splicing selection weighted? - - support afl_custom_{send,post_process}, persistent and deferred fork - server in afl-showmap + - support persistent and deferred fork server in afl-showmap? - better autodetection of shifting runtime timeout values - Update afl->pending_not_fuzzed for MOpt - afl-plot to support multiple plot_data - parallel builds for source-only targets - get rid of check_binary, replace with more forkserver communication - first fuzzer should be a main automatically? not sure. + - reload fuzz binary on signal ## Maybe diff --git a/afl-cmin b/afl-cmin index c5e64410..e2c26d91 100755 --- a/afl-cmin +++ b/afl-cmin @@ -133,6 +133,8 @@ function usage() { "AFL_PRINT_FILENAMES: If set, the filename currently processed will be " \ "printed to stdout\n" \ "AFL_SKIP_BIN_CHECK: skip afl instrumentation checks for target binary\n" +"AFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send)\n" +"AFL_PYTHON_MODULE: custom mutator library (post_process and send)\n" exit 1 } diff --git a/afl-cmin.bash b/afl-cmin.bash index bcf62eba..5258758e 100755 --- a/afl-cmin.bash +++ b/afl-cmin.bash @@ -151,6 +151,8 @@ AFL_KEEP_TRACES: leave the temporary \.traces directory AFL_NO_FORKSRV: run target via execve instead of using the forkserver AFL_PATH: last resort location to find the afl-showmap binary AFL_SKIP_BIN_CHECK: skip check for target binary +AFL_CUSTOM_MUTATOR_LIBRARY: custom mutator library (post_process and send) +AFL_PYTHON_MODULE: custom mutator library (post_process and send) _EOF_ exit 1 fi diff --git a/docs/Changelog.md b/docs/Changelog.md index 30e76f2c..5ed5ef2b 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,7 +4,8 @@ release of the tool. See README.md for the general instruction manual. ### Version ++4.07a (dev) - - soon :) + - afl-showmap: + - added custom mutator post_process and send support ### Version ++4.06c (release) diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 8b6502b4..ec69ba17 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -1103,7 +1103,6 @@ u32 count_bits(afl_state_t *, u8 *); u32 count_bytes(afl_state_t *, u8 *); u32 count_non_255_bytes(afl_state_t *, u8 *); void simplify_trace(afl_state_t *, u8 *); -void classify_counts(afl_forkserver_t *); #ifdef WORD_SIZE_64 void discover_word(u8 *ret, u64 *current, u64 *virgin); #else @@ -1117,6 +1116,9 @@ u8 *describe_op(afl_state_t *, u8, size_t); u8 save_if_interesting(afl_state_t *, void *, u32, u8); u8 has_new_bits(afl_state_t *, u8 *); u8 has_new_bits_unclassified(afl_state_t *, u8 *); +#ifndef AFL_SHOWMAP +void classify_counts(afl_forkserver_t *); +#endif /* Extras */ @@ -1192,11 +1194,13 @@ void fix_up_sync(afl_state_t *); void check_asan_opts(afl_state_t *); void check_binary(afl_state_t *, u8 *); void check_if_tty(afl_state_t *); -void setup_signal_handlers(void); void save_cmdline(afl_state_t *, u32, char **); void read_foreign_testcases(afl_state_t *, int); void write_crash_readme(afl_state_t *afl); u8 check_if_text_buf(u8 *buf, u32 len); +#ifndef AFL_SHOWMAP +void setup_signal_handlers(void); +#endif /* CmpLog */ diff --git a/src/afl-showmap.c b/src/afl-showmap.c index df030672..b5a61de5 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -30,8 +30,10 @@ */ #define AFL_MAIN +#define AFL_SHOWMAP #include "config.h" +#include "afl-fuzz.h" #include "types.h" #include "debug.h" #include "alloc-inl.h" @@ -62,6 +64,8 @@ #include #include +static afl_state_t *afl; + static char *stdin_file; /* stdin file */ static u8 *in_dir = NULL, /* input folder */ @@ -308,12 +312,73 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) { } +void pre_afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *mem, u32 len) { + + static u8 buf[MAX_FILE]; + u32 sent = 0; + + if (unlikely(afl->custom_mutators_count)) { + + ssize_t new_size = len; + u8 *new_mem = mem; + 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)) { + + return; + + } else { + + new_mem = new_buf; + len = new_size; + + } + + } + + }); + + if (new_mem != mem && new_mem != NULL) { + + mem = buf; + memcpy(mem, new_mem, new_size); + + } + + if (unlikely(afl->custom_mutators_count)) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + el->afl_custom_fuzz_send(el->data, mem, len); + sent = 1; + + } + + }); + + } + + } + + if (likely(!sent)) { afl_fsrv_write_to_testcase(fsrv, mem, len); } + +} + /* Execute target application. */ static void showmap_run_target_forkserver(afl_forkserver_t *fsrv, u8 *mem, u32 len) { - afl_fsrv_write_to_testcase(fsrv, mem, len); + pre_afl_fsrv_write_to_testcase(fsrv, mem, len); if (!quiet_mode) { SAYF("-- Program output begins --\n" cRST); } @@ -835,6 +900,10 @@ static void usage(u8 *argv0) { "This tool displays raw tuple data captured by AFL instrumentation.\n" "For additional help, consult %s/README.md.\n\n" + "If you use -i mode, then custom mutator post_process send send " + "functionality\n" + "is supported.\n\n" + "Environment variables used:\n" "LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n" "AFL_CMIN_CRASHES_ONLY: (cmin_mode) only write tuples for crashing " @@ -1266,6 +1335,8 @@ int main(int argc, char **argv_orig, char **envp) { } + afl = calloc(1, sizeof(afl_state_t)); + if (getenv("AFL_FORKSRV_INIT_TMOUT")) { s32 forksrv_init_tmout = atoi(getenv("AFL_FORKSRV_INIT_TMOUT")); @@ -1380,6 +1451,26 @@ int main(int argc, char **argv_orig, char **envp) { } + if (in_dir) { + + afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); + afl->afl_env.afl_custom_mutator_library = + getenv("AFL_CUSTOM_MUTATOR_LIBRARY"); + afl->afl_env.afl_python_module = getenv("AFL_PYTHON_MODULE"); + setup_custom_mutators(afl); + + } else { + + if (getenv("AFL_CUSTOM_MUTATOR_LIBRARY") || getenv("AFL_PYTHON_MODULE")) { + + WARNF( + "Custom mutator environment detected, this is only supported in -i " + "mode!\n"); + + } + + } + if (in_dir) { DIR *dir_in, *dir_out = NULL; -- cgit 1.4.1 From 30495e6bfe4119c9be6597ad0def01e7e0cb8a67 Mon Sep 17 00:00:00 2001 From: eleguevel Date: Fri, 21 Apr 2023 12:00:56 +0200 Subject: frida mode: add dynamic loaded code exclusion Add the AFL_FRIDA_INST_NO_DYNAMIC_LOAD environment variable and its associated JS function setInstrumentNoDynamicLoad to prevent the instrumentation of late dynamic loaded code. Resolve #1708 --- docs/env_variables.md | 2 ++ frida_mode/README.md | 4 +++- frida_mode/Scripting.md | 6 ++++++ frida_mode/frida.map | 1 + frida_mode/include/ranges.h | 1 + frida_mode/src/js/api.js | 7 +++++++ frida_mode/src/js/js_api.c | 7 +++++++ frida_mode/src/ranges.c | 39 ++++++++++++++++++++++++++++++++++++--- frida_mode/ts/lib/afl.ts | 12 ++++++++++++ include/envs.h | 1 + 10 files changed, 76 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/docs/env_variables.md b/docs/env_variables.md index a6a0ae44..c5995d13 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -677,6 +677,8 @@ support. * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled code. Code is considered to be JIT if the executable segment is not backed by a file. +* `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` - Don't instrument the code loaded late at + runtime. Strictly limits instrumentation to what has been included. * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use `AFL_FRIDA_INST_TRACE`. diff --git a/frida_mode/README.md b/frida_mode/README.md index aac13153..49a1fe38 100644 --- a/frida_mode/README.md +++ b/frida_mode/README.md @@ -178,11 +178,13 @@ Default is 256Mb. * `AFL_FRIDA_INST_JIT` - Enable the instrumentation of Just-In-Time compiled code. Code is considered to be JIT if the executable segment is not backed by a file. +* `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` - Don't instrument the code loaded late at + runtime. Strictly limits instrumentation to what has been included. * `AFL_FRIDA_INST_NO_OPTIMIZE` - Don't use optimized inline assembly coverage instrumentation (the default where available). Required to use + `AFL_FRIDA_INST_TRACE`. * `AFL_FRIDA_INST_REGS_FILE` - File to write raw register contents at the start of each block. - `AFL_FRIDA_INST_TRACE`. * `AFL_FRIDA_INST_NO_CACHE` - Don't use a look-up table to cache real to instrumented address block translations. * `AFL_FRIDA_INST_NO_PREFETCH` - Disable prefetching. By default, the child will diff --git a/frida_mode/Scripting.md b/frida_mode/Scripting.md index 023e4a19..dfd09e7b 100644 --- a/frida_mode/Scripting.md +++ b/frida_mode/Scripting.md @@ -844,6 +844,12 @@ class Afl { static setInstrumentLibraries() { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` + */ + static setInstrumentNoDynamicLoad() { + Afl.jsApiSetInstrumentNoDynamicLoad(); + } /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ diff --git a/frida_mode/frida.map b/frida_mode/frida.map index baf067ab..a98c2096 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -19,6 +19,7 @@ js_api_set_instrument_jit; js_api_set_instrument_libraries; js_api_set_instrument_instructions; + js_api_set_instrument_no_dynamic_load; js_api_set_instrument_no_optimize; js_api_set_instrument_regs_file; js_api_set_instrument_seed; diff --git a/frida_mode/include/ranges.h b/frida_mode/include/ranges.h index 3bd9eaa6..ca28acd9 100644 --- a/frida_mode/include/ranges.h +++ b/frida_mode/include/ranges.h @@ -6,6 +6,7 @@ extern gboolean ranges_debug_maps; extern gboolean ranges_inst_libs; extern gboolean ranges_inst_jit; +extern gboolean ranges_inst_dynamic_load; void ranges_config(void); void ranges_init(void); diff --git a/frida_mode/src/js/api.js b/frida_mode/src/js/api.js index f9ea1ffb..a65d32df 100644 --- a/frida_mode/src/js/api.js +++ b/frida_mode/src/js/api.js @@ -150,6 +150,12 @@ class Afl { static setInstrumentLibraries() { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` + */ + static setInstrumentNoDynamicLoad() { + Afl.jsApiSetInstrumentNoDynamicLoad(); + } /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -342,6 +348,7 @@ Afl.jsApiSetInstrumentDebugFile = Afl.jsApiGetFunction("js_api_set_instrument_de Afl.jsApiSetInstrumentInstructions = Afl.jsApiGetFunction("js_api_set_instrument_instructions", "void", []); Afl.jsApiSetInstrumentJit = Afl.jsApiGetFunction("js_api_set_instrument_jit", "void", []); Afl.jsApiSetInstrumentLibraries = Afl.jsApiGetFunction("js_api_set_instrument_libraries", "void", []); +Afl.jsApiSetInstrumentNoDynamicLoad = Afl.jsApiGetFunction("js_api_set_instrument_no_dynamic_load", "void", []); Afl.jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction("js_api_set_instrument_no_optimize", "void", []); Afl.jsApiSetInstrumentRegsFile = Afl.jsApiGetFunction("js_api_set_instrument_regs_file", "void", ["pointer"]); Afl.jsApiSetInstrumentSeed = Afl.jsApiGetFunction("js_api_set_instrument_seed", "void", ["uint64"]); diff --git a/frida_mode/src/js/js_api.c b/frida_mode/src/js/js_api.c index 2e996c1c..00278082 100644 --- a/frida_mode/src/js/js_api.c +++ b/frida_mode/src/js/js_api.c @@ -156,6 +156,13 @@ __attribute__((visibility("default"))) void js_api_set_instrument_instructions( } +__attribute__((visibility("default"))) void js_api_set_instrument_no_dynamic_load( + void) { + + ranges_inst_dynamic_load = FALSE; + +} + __attribute__((visibility("default"))) void js_api_set_instrument_no_optimize( void) { diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c index 72cb9730..e9fc3b4e 100644 --- a/frida_mode/src/ranges.c +++ b/frida_mode/src/ranges.c @@ -18,6 +18,7 @@ typedef struct { gboolean ranges_debug_maps = FALSE; gboolean ranges_inst_libs = FALSE; gboolean ranges_inst_jit = FALSE; +gboolean ranges_inst_dynamic_load = TRUE; static GArray *module_ranges = NULL; static GArray *libs_ranges = NULL; @@ -25,6 +26,7 @@ static GArray *jit_ranges = NULL; static GArray *include_ranges = NULL; static GArray *exclude_ranges = NULL; static GArray *ranges = NULL; +static GArray *whole_memory_ranges = NULL; static void convert_address_token(gchar *token, GumMemoryRange *range) { @@ -387,6 +389,21 @@ static GArray *collect_jit_ranges(void) { } +static GArray *collect_whole_mem_ranges(void) { + + GArray *result; + GumMemoryRange range; + result = g_array_new(false, false, sizeof(GumMemoryRange)); + + range.base_address = 0; + range.size = G_MAXULONG; + + g_array_append_val(result, range); + + return result; + +} + static gboolean intersect_range(GumMemoryRange *rr, GumMemoryRange *ra, GumMemoryRange *rb) { @@ -574,11 +591,17 @@ void ranges_config(void) { if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) { ranges_debug_maps = TRUE; } if (getenv("AFL_INST_LIBS") != NULL) { ranges_inst_libs = TRUE; } if (getenv("AFL_FRIDA_INST_JIT") != NULL) { ranges_inst_jit = TRUE; } + if (getenv("AFL_FRIDA_INST_NO_DYNAMIC_LOAD") != NULL) { + + ranges_inst_dynamic_load = FALSE; + + } if (ranges_debug_maps) { ranges_print_debug_maps(); } include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES"); exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES"); + whole_memory_ranges = collect_whole_mem_ranges(); } @@ -628,10 +651,20 @@ void ranges_init(void) { print_ranges("step4", step4); /* - * After step4, we have the total ranges to be instrumented, we now subtract - * that from the original ranges of the modules to configure stalker. + * After step 4 we have the total ranges to be instrumented, we now subtract + * that either from the original ranges of the modules or from the whole + * memory if AFL_INST_NO_DYNAMIC_LOAD to configure the stalker. */ - step5 = subtract_ranges(module_ranges, step4); + if (ranges_inst_dynamic_load) { + + step5 = subtract_ranges(module_ranges, step4); + + } else { + + step5 = subtract_ranges(whole_memory_ranges, step4); + + } + print_ranges("step5", step5); ranges = merge_ranges(step5); diff --git a/frida_mode/ts/lib/afl.ts b/frida_mode/ts/lib/afl.ts index 6a2350e7..7d1fac6b 100644 --- a/frida_mode/ts/lib/afl.ts +++ b/frida_mode/ts/lib/afl.ts @@ -178,6 +178,13 @@ class Afl { Afl.jsApiSetInstrumentLibraries(); } + /** + * See `AFL_FRIDA_INST_NO_DYNAMIC_LOAD` + */ + public static setInstrumentNoDynamicLoad(): void { + Afl.jsApiSetInstrumentNoDynamicLoad(); + } + /** * See `AFL_FRIDA_INST_NO_OPTIMIZE` */ @@ -443,6 +450,11 @@ class Afl { "void", []); + private static readonly jsApiSetInstrumentNoDynamicLoad = Afl.jsApiGetFunction( + "js_api_set_instrument_no_dynamic_load", + "void", + []); + private static readonly jsApiSetInstrumentNoOptimize = Afl.jsApiGetFunction( "js_api_set_instrument_no_optimize", "void", diff --git a/include/envs.h b/include/envs.h index 066921b9..41eabf60 100644 --- a/include/envs.h +++ b/include/envs.h @@ -65,6 +65,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_INST_INSN", "AFL_FRIDA_INST_JIT", "AFL_FRIDA_INST_NO_CACHE", + "AFL_FRIDA_INST_NO_DYNAMIC_LOAD", "AFL_FRIDA_INST_NO_OPTIMIZE", "AFL_FRIDA_INST_NO_PREFETCH", "AFL_FRIDA_INST_NO_PREFETCH_BACKPATCH", -- cgit 1.4.1 From 7b33148b7553f11dac7a382495a6829fa14f23fe Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 08:23:27 +0200 Subject: add AFL_LLVM_LTO_SKIPINIT to envs.h --- include/envs.h | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) (limited to 'include') diff --git a/include/envs.h b/include/envs.h index 23599b26..5e68c80b 100644 --- a/include/envs.h +++ b/include/envs.h @@ -160,8 +160,9 @@ static char *afl_environment_variables[] = { "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY", "AFL_TRY_AFFINITY", - "AFL_LLVM_LTO_STARTID", "AFL_LLVM_LTO_DONTWRITEID", + "AFL_LLVM_LTO_SKIPINIT" + "AFL_LLVM_LTO_STARTID", "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN", -- cgit 1.4.1 From 21865c622483d2e2285de3dfad4626c28ca27843 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 25 Apr 2023 16:47:37 +0200 Subject: rename env to AFL_IGNORE_PROBLEMS_COVERAGE --- docs/FAQ.md | 3 ++- docs/env_variables.md | 3 ++- include/envs.h | 1 + instrumentation/afl-compiler-rt.o.c | 4 ++-- src/afl-fuzz.c | 2 ++ 5 files changed, 9 insertions(+), 4 deletions(-) (limited to 'include') diff --git a/docs/FAQ.md b/docs/FAQ.md index 4a9080f8..76350c79 100644 --- a/docs/FAQ.md +++ b/docs/FAQ.md @@ -229,7 +229,8 @@ If you find an interesting or important question missing, submit it via If this is not a viable option, you can set `AFL_IGNORE_PROBLEMS=1` but then the existing map will be used also for the newly loaded libraries, which allows it to work, however, the efficiency of the fuzzing will be partially - degraded. + degraded. Note that there is additionally `AFL_IGNORE_PROBLEMS_COVERAGE` to + additionally tell AFL++ to ignore any coverage from the late loaded libaries.

diff --git a/docs/env_variables.md b/docs/env_variables.md index 087ccdb7..b1f23159 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -406,7 +406,8 @@ checks or alter some of the more exotic semantics of the tool: - If afl-fuzz encounters an incorrect fuzzing setup during a fuzzing session (not at startup), it will terminate. If you do not want this, then you can - set `AFL_IGNORE_PROBLEMS`. + set `AFL_IGNORE_PROBLEMS`. If you additionally want to also ignore coverage + from late loaded libraries, you can set `AFL_IGNORE_PROBLEMS_COVERAGE`. - When running in the `-M` or `-S` mode, setting `AFL_IMPORT_FIRST` causes the fuzzer to import test cases from other instances before doing anything else. diff --git a/include/envs.h b/include/envs.h index 5e68c80b..fe5ee0e3 100644 --- a/include/envs.h +++ b/include/envs.h @@ -106,6 +106,7 @@ static char *afl_environment_variables[] = { "AFL_HARDEN", "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES", "AFL_IGNORE_PROBLEMS", + "AFL_IGNORE_PROBLEMS_COVERAGE", "AFL_IGNORE_TIMEOUTS", "AFL_IGNORE_UNKNOWN_ENVS", "AFL_IMPORT_FIRST", diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 74506e4c..0912e52b 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -1565,13 +1565,13 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) { "be able to fuzz them or LD_PRELOAD to run outside of afl-fuzz.\n" "To ignore this set AFL_IGNORE_PROBLEMS=1 but this will lead to " "ambiguous coverage data.\n" - "In addition, you can set AFL_LLVM_IGNORE_PROBLEMS_COVERAGE=1 to " + "In addition, you can set AFL_IGNORE_PROBLEMS_COVERAGE=1 to " "ignore the additional coverage instead (use with caution!).\n"); abort(); } else { - u8 ignore_dso_after_fs = !!getenv("AFL_LLVM_IGNORE_PROBLEMS_COVERAGE"); + u8 ignore_dso_after_fs = !!getenv("AFL_IGNORE_PROBLEMS_COVERAGE"); if (__afl_debug && ignore_dso_after_fs) { fprintf(stderr, "Ignoring coverage from dynamically loaded code\n"); diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index ebdbb3fa..c44144f5 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -259,6 +259,8 @@ static void usage(u8 *argv0, int more_help) { "AFL_HANG_TMOUT: override timeout value (in milliseconds)\n" "AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n" "AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n" + "AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n + " ignore those libs for coverage\n" "AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n" "AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n" "AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n" -- cgit 1.4.1