From b8568034f0c120ab8500c03ed4982d641eaa88fb Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Tue, 18 Jun 2024 15:42:34 +0200 Subject: code format and changelog --- docs/Changelog.md | 5 +++++ 1 file changed, 5 insertions(+) (limited to 'docs/Changelog.md') diff --git a/docs/Changelog.md b/docs/Changelog.md index 1590b2df..f146534f 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -4,6 +4,11 @@ release of the tool. See README.md for the general instruction manual. ### Version ++4.22a (dev) + - afl-fuzz: + - fastresume feature added. if you abort fuzzing and resume fuzzing + with `-i -` or `AFL_AUTORESUME=1` and the target binary has not changed + then a dump will be loaded and the calibration phase skipped. + to disable this feature set `AFL_NO_FASTRESUME=1` - frida_mode: - AFL_FRIDA_PERSISTENT_ADDR can now be be any reachable address not just a function entry -- cgit 1.4.1 From ecb5854be08fa978be3320c1f8333f6cc3261fec Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 21 Jun 2024 14:40:16 +0200 Subject: add zlib compression for fast resume --- GNUmakefile | 8 ++++ docs/Changelog.md | 1 + include/debug.h | 2 - src/afl-fuzz.c | 135 +++++++++++++++++++++++++++++++++++++++++++----------- 4 files changed, 116 insertions(+), 30 deletions(-) (limited to 'docs/Changelog.md') diff --git a/GNUmakefile b/GNUmakefile index e79d3f83..9f862120 100644 --- a/GNUmakefile +++ b/GNUmakefile @@ -441,6 +441,14 @@ test_shm: @echo "[-] shmat seems not to be working, switching to mmap implementation" endif +ifeq "$(shell echo '$(HASH)include @int main() {return 0; }' | tr @ '\n' | $(CC) $(CFLAGS) -Werror -x c - -lz -o .test 2>/dev/null && echo 1 || echo 0 ; rm -f .test )" "1" + override SPECIAL_PERFORMANCE += -DHAVE_ZLIB + override LDFLAGS += -lz + $(info [+] ZLIB detected) +else + $(info [!] Warning: no ZLIB detected) +endif + .PHONY: test_python ifeq "$(PYTHON_OK)" "1" test_python: diff --git a/docs/Changelog.md b/docs/Changelog.md index f146534f..c6266e86 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -9,6 +9,7 @@ with `-i -` or `AFL_AUTORESUME=1` and the target binary has not changed then a dump will be loaded and the calibration phase skipped. to disable this feature set `AFL_NO_FASTRESUME=1` + zlib compression is used if zlib is found at compile time - frida_mode: - AFL_FRIDA_PERSISTENT_ADDR can now be be any reachable address not just a function entry diff --git a/include/debug.h b/include/debug.h index 5496135c..c66d0334 100644 --- a/include/debug.h +++ b/include/debug.h @@ -409,8 +409,6 @@ static inline const char *colorfilter(const char *x) { \ } while (1); \ \ - \ - \ } while (0) #define ck_read(fd, buf, len, fn) \ diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 0ae12fc1..b53a9a2d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -36,6 +36,67 @@ #include #include #endif +#ifdef HAVE_ZLIB + + #define ck_gzread(fd, buf, len, fn) \ + do { \ + \ + s32 _len = (s32)(len); \ + s32 _res = gzread(fd, buf, _len); \ + if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \ + \ + } while (0) + + #define ck_gzwrite(fd, buf, len, fn) \ + do { \ + \ + if (len <= 0) break; \ + s32 _written = 0, _off = 0, _len = (s32)(len); \ + \ + do { \ + \ + s32 _res = gzwrite(fd, (buf) + _off, _len); \ + if (_res != _len && (_res > 0 && _written + _res != _len)) { \ + \ + if (_res > 0) { \ + \ + _written += _res; \ + _len -= _res; \ + _off += _res; \ + \ + } else { \ + \ + RPFATAL(_res, "Short write to %s (%d of %d bytes)", fn, _res, \ + _len); \ + \ + } \ + \ + } else { \ + \ + break; \ + \ + } \ + \ + } while (1); \ + \ + \ + \ + } while (0) + + #include + #define ZLIBOPEN gzopen + #define ZLIBREAD ck_gzread + #define NZLIBREAD gzread + #define ZLIBWRITE ck_gzwrite + #define ZLIBCLOSE gzclose + #define ZLIB_EXTRA "9" +#else + #define ZLIBOPEN open + #define NZLIBREAD read + #define ZLIBREAD ck_read + #define ZLIBWRITE ck_write + #define ZLIBCLOSE close +#endif #ifdef __APPLE__ #include @@ -1875,7 +1936,9 @@ int main(int argc, char **argv_orig, char **envp) { if (afl->fsrv.mem_limit) { - WARNF("in the Frida Address Sanitizer Mode we disable all memory limits"); + WARNF( + "in the Frida Address Sanitizer Mode we disable all memory " + "limits"); afl->fsrv.mem_limit = 0; } @@ -2117,22 +2180,27 @@ int main(int argc, char **argv_orig, char **envp) { check_binary(afl, argv[optind]); u64 prev_target_hash = 0; - s32 fast_resume = 0, fr_fd = -1; + s32 fast_resume = 0; + #ifdef HAVE_ZLIB + gzFile fr_fd = NULL; + #else + s32 fr_fd = -1; + #endif if (afl->in_place_resume && !afl->afl_env.afl_no_fastresume) { u8 fn[PATH_MAX], buf[32]; snprintf(fn, PATH_MAX, "%s/target_hash", afl->out_dir); - fr_fd = open(fn, O_RDONLY); - if (fr_fd >= 0) { + s32 fd = open(fn, O_RDONLY); + if (fd >= 0) { - if (read(fr_fd, buf, 32) >= 16) { + if (read(fd, buf, 32) >= 16) { sscanf(buf, "%p", (void **)&prev_target_hash); } - close(fr_fd); + close(fd); } @@ -2152,14 +2220,21 @@ int main(int argc, char **argv_orig, char **envp) { u8 fn[PATH_MAX]; snprintf(fn, PATH_MAX, "%s/fastresume.bin", afl->out_dir); + #ifdef HAVE_ZLIB + if ((fr_fd = ZLIBOPEN(fn, "rb")) != NULL) { + + #else if ((fr_fd = open(fn, O_RDONLY)) >= 0) { + #endif + u8 ver_string[8]; u64 *ver = (u64 *)ver_string; u64 expect_ver = afl->shm.cmplog_mode + (sizeof(struct queue_entry) << 1); - if (read(fr_fd, ver_string, sizeof(ver_string)) != sizeof(ver_string)) + if (NZLIBREAD(fr_fd, ver_string, sizeof(ver_string)) != + sizeof(ver_string)) WARNF("Emtpy fastresume.bin, ignoring, cannot perform FAST RESUME"); else if (expect_ver != *ver) WARNF( @@ -2538,10 +2613,10 @@ int main(int argc, char **argv_orig, char **envp) { u64 resume_start = get_cur_time_us(); // if we get here then we should abort on errors - ck_read(fr_fd, afl->virgin_bits, afl->fsrv.map_size, "virgin_bits"); - ck_read(fr_fd, afl->virgin_tmout, afl->fsrv.map_size, "virgin_tmout"); - ck_read(fr_fd, afl->virgin_crash, afl->fsrv.map_size, "virgin_crash"); - ck_read(fr_fd, afl->var_bytes, afl->fsrv.map_size, "var_bytes"); + ZLIBREAD(fr_fd, afl->virgin_bits, afl->fsrv.map_size, "virgin_bits"); + ZLIBREAD(fr_fd, afl->virgin_tmout, afl->fsrv.map_size, "virgin_tmout"); + ZLIBREAD(fr_fd, afl->virgin_crash, afl->fsrv.map_size, "virgin_crash"); + ZLIBREAD(fr_fd, afl->var_bytes, afl->fsrv.map_size, "var_bytes"); u8 res[1] = {0}; u8 *o_start = (u8 *)&(afl->queue_buf[0]->colorized); @@ -2554,12 +2629,12 @@ int main(int argc, char **argv_orig, char **envp) { for (u32 i = 0; i < afl->queued_items; i++) { q = afl->queue_buf[i]; - ck_read(fr_fd, (u8 *)&(q->colorized), q_len, "queue data"); - ck_read(fr_fd, res, 1, "check map"); + ZLIBREAD(fr_fd, (u8 *)&(q->colorized), q_len, "queue data"); + ZLIBREAD(fr_fd, res, 1, "check map"); if (res[0]) { q->trace_mini = ck_alloc(m_len); - ck_read(fr_fd, q->trace_mini, m_len, "trace_mini"); + ZLIBREAD(fr_fd, q->trace_mini, m_len, "trace_mini"); r += q_len + m_len + 1; } else { @@ -2592,14 +2667,14 @@ int main(int argc, char **argv_orig, char **envp) { } u8 buf[4]; - if (read(fr_fd, buf, 3) > 0) { + if (NZLIBREAD(fr_fd, buf, 3) > 0) { FATAL("invalid trailing data in fastresume.bin"); } OKF("Successfully loaded fastresume.bin (%u bytes)!", r); - close(fr_fd); + ZLIBCLOSE(fr_fd); afl->reinit_table = 1; update_calibration_time(afl, &resume_start); @@ -3248,20 +3323,24 @@ stop_fuzzing: u8 fr[PATH_MAX]; snprintf(fr, PATH_MAX, "%s/fastresume.bin", afl->out_dir); ACTF("Writing %s ...", fr); + #ifdef HAVE_ZLIB + if ((fr_fd = ZLIBOPEN(fr, "wb9")) != NULL) { + + #else if ((fr_fd = open(fr, O_WRONLY | O_TRUNC | O_CREAT, DEFAULT_PERMISSION)) >= - 0) { + #endif u8 ver_string[8]; u32 w = 0; u64 *ver = (u64 *)ver_string; *ver = afl->shm.cmplog_mode + (sizeof(struct queue_entry) << 1); - w += write(fr_fd, ver_string, sizeof(ver_string)); - - w += write(fr_fd, afl->virgin_bits, afl->fsrv.map_size); - w += write(fr_fd, afl->virgin_tmout, afl->fsrv.map_size); - w += write(fr_fd, afl->virgin_crash, afl->fsrv.map_size); - w += write(fr_fd, afl->var_bytes, afl->fsrv.map_size); + ZLIBWRITE(fr_fd, ver_string, sizeof(ver_string), "ver_string"); + ZLIBWRITE(fr_fd, afl->virgin_bits, afl->fsrv.map_size, "virgin_bits"); + ZLIBWRITE(fr_fd, afl->virgin_tmout, afl->fsrv.map_size, "virgin_tmout"); + ZLIBWRITE(fr_fd, afl->virgin_crash, afl->fsrv.map_size, "virgin_crash"); + ZLIBWRITE(fr_fd, afl->var_bytes, afl->fsrv.map_size, "var_bytes"); + w += sizeof(ver_string) + afl->fsrv.map_size * 4; u8 on[1] = {1}, off[1] = {0}; u8 *o_start = (u8 *)&(afl->queue_buf[0]->colorized); @@ -3276,23 +3355,23 @@ stop_fuzzing: for (u32 i = 0; i < afl->queued_items; i++) { q = afl->queue_buf[i]; - ck_write(fr_fd, (u8 *)&(q->colorized), q_len, "queue data"); + ZLIBWRITE(fr_fd, (u8 *)&(q->colorized), q_len, "queue data"); if (!q->trace_mini) { - ck_write(fr_fd, off, 1, "no_mini"); + ZLIBWRITE(fr_fd, off, 1, "no_mini"); w += q_len + 1; } else { - ck_write(fr_fd, on, 1, "yes_mini"); - ck_write(fr_fd, q->trace_mini, m_len, "trace_mini"); + ZLIBWRITE(fr_fd, on, 1, "yes_mini"); + ZLIBWRITE(fr_fd, q->trace_mini, m_len, "trace_mini"); w += q_len + m_len + 1; } } - close(fr_fd); + ZLIBCLOSE(fr_fd); afl->var_byte_count = count_bytes(afl, afl->var_bytes); OKF("Written fastresume.bin with %u bytes!", w); -- cgit 1.4.1 From af47531745ccdc61b5966f213f6cd6cd9030cc2f Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 26 Jun 2024 01:12:04 +0200 Subject: improved seed selection algorithm --- TODO.md | 3 +- custom_mutators/gramatron/json-c | 2 +- docs/Changelog.md | 1 + src/afl-fuzz-bitmap.c | 4 +- src/afl-fuzz-queue.c | 126 +++++++++++++++++++++++++++++++++------ 5 files changed, 112 insertions(+), 24 deletions(-) (limited to 'docs/Changelog.md') diff --git a/TODO.md b/TODO.md index 6f7505a6..a1431afa 100644 --- a/TODO.md +++ b/TODO.md @@ -2,8 +2,7 @@ ## Must - - fast resume: - use gzopen(fn, "rb"/"wb9-/f/h", gzwrite, gzread and gzclose + - docs: AFL_DISABLE_REDUNDANT (large/slow/LAF) - check for null ptr for xml/curl/g_ string transform functions - hardened_usercopy=0 page_alloc.shuffle=0 - add value_profile but only enable after 15 minutes without finds diff --git a/custom_mutators/gramatron/json-c b/custom_mutators/gramatron/json-c index 11546bfd..af8dd4a3 160000 --- a/custom_mutators/gramatron/json-c +++ b/custom_mutators/gramatron/json-c @@ -1 +1 @@ -Subproject commit 11546bfd07a575c47416924cb98de3d33a4e6424 +Subproject commit af8dd4a307e7b837f9fa2959549548ace4afe08b diff --git a/docs/Changelog.md b/docs/Changelog.md index c6266e86..09ea8cb6 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -10,6 +10,7 @@ then a dump will be loaded and the calibration phase skipped. to disable this feature set `AFL_NO_FASTRESUME=1` zlib compression is used if zlib is found at compile time + - improved seed selection algorithm - frida_mode: - AFL_FRIDA_PERSISTENT_ADDR can now be be any reachable address not just a function entry diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 405d2dd6..97ccd3d3 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -463,7 +463,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { if (unlikely(fault == FSRV_RUN_TMOUT && afl->afl_env.afl_ignore_timeouts)) { - if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { classify_counts(&afl->fsrv); u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST); @@ -489,7 +489,7 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { /* Generating a hash on every input is super expensive. Bad idea and should only be used for special schedules */ - if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { classify_counts(&afl->fsrv); classified = 1; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 6069f5b9..999929a1 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -123,7 +123,7 @@ void create_alias_table(afl_state_t *afl) { double weight = 1.0; { // inline does result in a compile error with LTO, weird - if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) { u32 hits = afl->n_fuzz[q->n_fuzz_entry]; if (likely(hits)) { weight /= (log10(hits) + 1); } @@ -133,39 +133,127 @@ void create_alias_table(afl_state_t *afl) { if (likely(afl->schedule < RARE)) { double t = q->exec_us / avg_exec_us; + if (likely(t < 0.1)) { // nothing - } else if (likely(t <= 0.25)) + } else if (likely(t <= 0.25)) { + + weight *= 0.95; - weight *= 0.9; - else if (likely(t <= 0.5)) { + } else if (likely(t <= 0.5)) { // nothing - } else if (likely(t < 1.0)) + } else if (likely(t <= 0.75)) { + + weight *= 1.05; + + } else if (likely(t <= 1.0)) { + + weight *= 1.1; + + } else if (likely(t < 1.25)) { + + weight *= 0.2; // WTF ??? makes no sense + + } else if (likely(t <= 1.5)) { + + // nothing + + } else if (likely(t <= 2.0)) { + + weight *= 1.1; + + } else if (likely(t <= 2.5)) { + + } else if (likely(t <= 5.0)) { weight *= 1.15; - else if (unlikely(t > 2.5 && t < 5.0)) + + } else if (likely(t <= 20.0)) { + weight *= 1.1; - // else nothing + // else nothing + + } } double l = q->len / avg_len; - if (likely(l < 0.1)) - weight *= 0.75; - else if (likely(l < 0.25)) - weight *= 1.1; - else if (unlikely(l >= 10)) - weight *= 1.1; + if (likely(l < 0.1)) { + + weight *= 0.5; + + } else if (likely(l <= 0.5)) { + + // nothing + + } else if (likely(l <= 1.25)) { + + weight *= 1.05; + + } else if (likely(l <= 1.75)) { + + // nothing + + } else if (likely(l <= 2.0)) { + + weight *= 0.95; + + } else if (likely(l <= 5.0)) { + + // nothing + + } else if (likely(l <= 10.0)) { + + weight *= 1.05; + + } else { + + weight *= 1.15; + + } double bms = q->bitmap_size / avg_bitmap_size; - if (likely(bms < 0.5)) - weight *= (1.0 + ((bms - 0.5) / 2)); - else if (unlikely(bms > 1.33)) - weight *= 1.1; + if (likely(bms < 0.1)) { + + weight *= 0.01; + + } else if (likely(bms <= 0.25)) { + + weight *= 0.55; + + } else if (likely(bms <= 0.5)) { + + // nothing + + } else if (likely(bms <= 0.75)) { + + weight *= 1.2; + + } else if (likely(bms <= 1.25)) { + + weight *= 1.3; + + } else if (likely(bms <= 1.75)) { + + weight *= 1.25; + + } else if (likely(bms <= 2.0)) { + + // nothing + + } else if (likely(bms <= 2.5)) { + + weight *= 1.3; + + } else { + + weight *= 0.75; + + } if (unlikely(!q->was_fuzzed)) { weight *= 2.5; } if (unlikely(q->fs_redundant)) { weight *= 0.75; } @@ -741,7 +829,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 fav_factor; u64 fuzz_p2; - if (likely(afl->schedule >= FAST && afl->schedule < RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) { fuzz_p2 = 0; // Skip the fuzz_p2 comparison @@ -777,7 +865,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) { u64 top_rated_fav_factor; u64 top_rated_fuzz_p2; - if (likely(afl->schedule >= FAST && afl->schedule < RARE)) { + if (unlikely(afl->schedule >= FAST && afl->schedule < RARE)) { top_rated_fuzz_p2 = 0; // Skip the fuzz_p2 comparison -- cgit 1.4.1 From ba7313b521df7a347cd9f96a694cd8caa63b9b41 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Thu, 27 Jun 2024 18:51:54 +0200 Subject: AFL_CUSTOM_MUTATOR_LATE_SEND added --- docs/Changelog.md | 2 ++ docs/custom_mutators.md | 5 +++++ docs/env_variables.md | 4 ++++ include/afl-fuzz.h | 5 +++-- include/envs.h | 19 ++++++++++--------- include/forkserver.h | 5 +++++ src/afl-forkserver.c | 10 ++++++++++ src/afl-fuzz-run.c | 12 +++++++++++- src/afl-fuzz-state.c | 7 +++++++ src/afl-fuzz.c | 25 +++++++++++++++++++++++++ 10 files changed, 82 insertions(+), 12 deletions(-) (limited to 'docs/Changelog.md') diff --git a/docs/Changelog.md b/docs/Changelog.md index 09ea8cb6..c16214e4 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -11,6 +11,8 @@ to disable this feature set `AFL_NO_FASTRESUME=1` zlib compression is used if zlib is found at compile time - improved seed selection algorithm + - added `AFL_CUSTOM_MUTATOR_LATE_SEND=1` to call the custom send() + function after the target has been restarted. - frida_mode: - AFL_FRIDA_PERSISTENT_ADDR can now be be any reachable address not just a function entry diff --git a/docs/custom_mutators.md b/docs/custom_mutators.md index b7a7032f..3067ceab 100644 --- a/docs/custom_mutators.md +++ b/docs/custom_mutators.md @@ -198,6 +198,11 @@ def deinit(): # optional for Python This method can be used if you want to send data to the target yourself, e.g. via IPC. This replaces some usage of utils/afl_proxy but requires that you start the target with afl-fuzz. + + Setting `AFL_CUSTOM_MUTATOR_LATE_SEND` will call the afl_custom_fuzz_send() + function after the target has been restarted. (This is needed for e.g. TCP + services.) + Example: [custom_mutators/examples/custom_send.c](../custom_mutators/examples/custom_send.c) - `queue_new_entry` (optional): diff --git a/docs/env_variables.md b/docs/env_variables.md index 6db31df0..eebbcbda 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -368,6 +368,10 @@ checks or alter some of the more exotic semantics of the tool: XML or other highly flexible structured input. For details, see [custom_mutators.md](custom_mutators.md). + - Setting `AFL_CUSTOM_MUTATOR_LATE_SEND` will call the afl_custom_fuzz_send() + function after the target has been restarted. (This is needed for e.g. TCP + services.) + - Setting `AFL_CYCLE_SCHEDULES` will switch to a different schedule every time a cycle is finished. diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index 45600698..0f0e45d3 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -449,8 +449,9 @@ extern char *power_names[POWER_SCHEDULES_NUM]; typedef struct afl_env_vars { u8 afl_skip_cpufreq, afl_exit_when_done, afl_no_affinity, afl_skip_bin_check, - afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, afl_no_ui, - afl_force_ui, afl_i_dont_care_about_missing_crashes, afl_bench_just_one, + afl_dumb_forksrv, afl_import_first, afl_custom_mutator_only, + afl_custom_mutator_late_send, afl_no_ui, afl_force_ui, + afl_i_dont_care_about_missing_crashes, afl_bench_just_one, 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, diff --git a/include/envs.h b/include/envs.h index ef522ab4..6a0d329b 100644 --- a/include/envs.h +++ b/include/envs.h @@ -24,15 +24,16 @@ static char *afl_environment_variables[] = { "AFL_DUMP_CYCLOMATIC_COMPLEXITY", "AFL_CMPLOG_MAX_LEN", "AFL_COMPCOV_LEVEL", "AFL_CRASH_EXITCODE", "AFL_CRASHING_SEEDS_AS_NEW_CRASH", "AFL_CUSTOM_MUTATOR_LIBRARY", "AFL_CUSTOM_MUTATOR_ONLY", - "AFL_CUSTOM_INFO_PROGRAM", "AFL_CUSTOM_INFO_PROGRAM_ARGV", - "AFL_CUSTOM_INFO_PROGRAM_INPUT", "AFL_CUSTOM_INFO_OUT", "AFL_CXX", - "AFL_CYCLE_SCHEDULES", "AFL_DEBUG", "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", - "AFL_DEBUG_UNICORN", "AFL_DISABLE_REDUNDANT", "AFL_NO_REDUNDANT", - "AFL_DISABLE_TRIM", "AFL_NO_TRIM", "AFL_DISABLE_LLVM_INSTRUMENTATION", - "AFL_DONT_OPTIMIZE", "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", - "AFL_DUMB_FORKSRV", "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", - "AFL_EXIT_WHEN_DONE", "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", - "AFL_FAST_CAL", "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", + "AFL_CUSTOM_MUTATOR_LATE_SEND", "AFL_CUSTOM_INFO_PROGRAM", + "AFL_CUSTOM_INFO_PROGRAM_ARGV", "AFL_CUSTOM_INFO_PROGRAM_INPUT", + "AFL_CUSTOM_INFO_OUT", "AFL_CXX", "AFL_CYCLE_SCHEDULES", "AFL_DEBUG", + "AFL_DEBUG_CHILD", "AFL_DEBUG_GDB", "AFL_DEBUG_UNICORN", + "AFL_DISABLE_REDUNDANT", "AFL_NO_REDUNDANT", "AFL_DISABLE_TRIM", + "AFL_NO_TRIM", "AFL_DISABLE_LLVM_INSTRUMENTATION", "AFL_DONT_OPTIMIZE", + "AFL_DRIVER_STDERR_DUPLICATE_FILENAME", "AFL_DUMB_FORKSRV", + "AFL_EARLY_FORKSERVER", "AFL_ENTRYPOINT", "AFL_EXIT_WHEN_DONE", + "AFL_EXIT_ON_TIME", "AFL_EXIT_ON_SEED_ISSUES", "AFL_FAST_CAL", + "AFL_FINAL_SYNC", "AFL_FORCE_UI", "AFL_FRIDA_DEBUG_MAPS", "AFL_FRIDA_DRIVER_NO_HOOK", "AFL_FRIDA_EXCLUDE_RANGES", "AFL_FRIDA_INST_CACHE_SIZE", "AFL_FRIDA_INST_COVERAGE_ABSOLUTE", "AFL_FRIDA_INST_COVERAGE_FILE", "AFL_FRIDA_INST_DEBUG_FILE", diff --git a/include/forkserver.h b/include/forkserver.h index 3fd813a4..6c649528 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -210,6 +210,11 @@ typedef struct afl_forkserver { u8 *persistent_trace_bits; /* Persistent copy of bitmap */ #endif + void *custom_data_ptr; + u8 *custom_input; + u32 custom_input_len; + void (*late_send)(void *, const u8 *, size_t); + } afl_forkserver_t; typedef enum fsrv_run_result { diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index a998c10f..cec91f76 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -292,6 +292,9 @@ void afl_fsrv_init_dup(afl_forkserver_t *fsrv_to, afl_forkserver_t *from) { fsrv_to->use_fauxsrv = 0; fsrv_to->last_run_timed_out = 0; + fsrv_to->late_send = from->late_send; + fsrv_to->custom_data_ptr = from->custom_data_ptr; + fsrv_to->init_child_func = from->init_child_func; // Note: do not copy ->add_extra_func or ->persistent_record* @@ -1952,6 +1955,13 @@ afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, } + if (unlikely(fsrv->late_send)) { + + fsrv->late_send(fsrv->custom_data_ptr, fsrv->custom_input, + fsrv->custom_input_len); + + } + exec_ms = read_s32_timed(fsrv->fsrv_st_fd, &fsrv->child_status, timeout, stop_soon_p); diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index c234fc42..2f244a1d 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -194,7 +194,17 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { if (el->afl_custom_fuzz_send) { - el->afl_custom_fuzz_send(el->data, *mem, new_size); + if (!afl->afl_env.afl_custom_mutator_late_send) { + + el->afl_custom_fuzz_send(el->data, *mem, new_size); + + } else { + + afl->fsrv.custom_input = *mem; + afl->fsrv.custom_input_len = new_size; + + } + sent = 1; } diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index dd684a19..eead3e50 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -300,6 +300,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_custom_mutator_only = get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_LATE_SEND", + + afl_environment_variable_len)) { + + afl->afl_env.afl_custom_mutator_late_send = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } else if (!strncmp(env, "AFL_CMPLOG_ONLY_NEW", afl_environment_variable_len)) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index b53a9a2d..8a84d447 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -2142,6 +2142,31 @@ int main(int argc, char **argv_orig, char **envp) { } + if (afl->custom_mutators_count && afl->afl_env.afl_custom_mutator_late_send) { + + u32 count_send = 0; + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + if (count_send) { + + FATAL( + "You can only have one custom send() function if you are using " + "AFL_CUSTOM_MUTATOR_LATE_SEND!"); + + } + + afl->fsrv.late_send = el->afl_custom_fuzz_send; + afl->fsrv.custom_data_ptr = el->data; + count_send = 1; + + } + + }); + + } + if (afl->limit_time_sig > 0 && afl->custom_mutators_count) { if (afl->custom_only) { -- cgit 1.4.1 From f7bbd467b53d0ee7c3ca366750ed1fa60972981c Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Fri, 28 Jun 2024 16:00:19 +0200 Subject: add custom_send_tcp --- custom_mutators/custom_send_tcp/Makefile | 7 ++ custom_mutators/custom_send_tcp/README.md | 13 +++ custom_mutators/custom_send_tcp/custom_send_tcp.c | 113 ++++++++++++++++++++++ docs/Changelog.md | 2 + 4 files changed, 135 insertions(+) create mode 100644 custom_mutators/custom_send_tcp/Makefile create mode 100644 custom_mutators/custom_send_tcp/README.md create mode 100644 custom_mutators/custom_send_tcp/custom_send_tcp.c (limited to 'docs/Changelog.md') diff --git a/custom_mutators/custom_send_tcp/Makefile b/custom_mutators/custom_send_tcp/Makefile new file mode 100644 index 00000000..8549ccad --- /dev/null +++ b/custom_mutators/custom_send_tcp/Makefile @@ -0,0 +1,7 @@ +all: custom_send_tcp.so + +custom_send_tcp.so: + $(CC) -Wno-unused-result -g -O3 -shared -fPIC -o custom_send_tcp.so -I../../include custom_send_tcp.c + +clean: + rm -f custom_send_tcp.so *.o *~ core diff --git a/custom_mutators/custom_send_tcp/README.md b/custom_mutators/custom_send_tcp/README.md new file mode 100644 index 00000000..7b4bb869 --- /dev/null +++ b/custom_mutators/custom_send_tcp/README.md @@ -0,0 +1,13 @@ +# Send testcases via TCP custom mutator + +This custom mutator sends the fuzzing testcases via TCP. + +`AFL_CUSTOM_MUTATOR_LATE_SEND` - MUST be set! +`CUSTOM_SEND_IP` - the IP address to send to (basically only 127.0.0.1 makes sense) +`CUSTOM_SEND_PORT` - the TCP port to send to +`CUSTOM_SEND_READ` - if the custom mutator should wait for a reply from the target + +Example: +``` +CUSTOM_SEND_IP=127.0.0.1 CUSTOM_SEND_PORT=8000 CUSTOM_SEND_READ=1 AFL_CUSTOM_MUTATOR_LATE_SEND=1 AFL_CUSTOM_MUTATOR_LIBRARY=custom_send_tcp.so ./afl-fuzz ... +``` diff --git a/custom_mutators/custom_send_tcp/custom_send_tcp.c b/custom_mutators/custom_send_tcp/custom_send_tcp.c new file mode 100644 index 00000000..53689ced --- /dev/null +++ b/custom_mutators/custom_send_tcp/custom_send_tcp.c @@ -0,0 +1,113 @@ +#include +#include +#include +#include +#include +#include +#include +#include + +#include "afl-fuzz.h" + +static int my_debug = 0; +static int my_read = 0; + +#define DEBUG(...) if (my_debug) printf(__VA_ARGS__) + +typedef struct tcp_send_mutator { + afl_state_t* afl; + struct sockaddr_in server_addr; +} tcp_send_mutator_t; + +void *afl_custom_init(afl_state_t* afl, uint32_t seed) { + const char* ip = getenv("CUSTOM_SEND_IP"); + const char* port = getenv("CUSTOM_SEND_PORT"); + + if (getenv("AFL_DEBUG")) my_debug = 1; + if (getenv("CUSTOM_SEND_READ")) my_read = 1; + + if (!ip || !port) { + fprintf(stderr, "You forgot to set CUSTOM_SEND_IP and/or CUSTOM_SEND_PORT\n"); + exit(1); + } + + tcp_send_mutator_t* mutator = calloc(1, sizeof(tcp_send_mutator_t)); + if (!mutator) { + fprintf(stderr, "Failed to allocate mutator struct\n"); + exit(1); + } + + mutator->afl = afl; + + bzero(&mutator->server_addr, sizeof(mutator->server_addr)); + mutator->server_addr.sin_family = AF_INET; + if (inet_pton(AF_INET, ip, &mutator->server_addr.sin_addr) <= 0) { + fprintf(stderr, "Could not convert target ip address!\n"); + exit(1); + } + mutator->server_addr.sin_port = htons(atoi(port)); + + printf("[+] Custom tcp send mutator setup ready to go!\n"); + + return mutator; +} + +int try_connect(tcp_send_mutator_t *mutator, int sock, int max_attempts) { + while (max_attempts > 0) { + if (connect(sock, (struct sockaddr*)&mutator->server_addr, sizeof(mutator->server_addr)) == 0) { + return 0; + } + + // Even with AFL_CUSTOM_LATE_SEND=1, there is a race between the + // application under test having started to listen for connections and + // afl_custom_fuzz_send being called. To address this race, we attempt + // to connect N times and sleep a short period of time in between + // connection attempts. + struct timespec t; + t.tv_sec = 0; + t.tv_nsec = 100; + nanosleep(&t, NULL); + --max_attempts; + } + return 1; +} + +void afl_custom_fuzz_send(tcp_send_mutator_t *mutator, uint8_t *buf, size_t buf_size) { + int sock = socket(AF_INET, SOCK_STREAM, 0); + + int written = 0; + if (sock >= 0 && try_connect(mutator, sock, 10000) == 0) { + DEBUG("connected, write()\n"); + written = write(sock, buf, buf_size); + } else { + DEBUG("socket() or connect() error: %d\n", errno); + } + + if (written < 0) { + DEBUG("write() error: %d\n", errno); + } else if (my_read) { + struct timeval timeout; + timeout.tv_sec = 1; + timeout.tv_usec = 0; + + fd_set set; + FD_ZERO(&set); + FD_SET(sock, &set); + + int select_res = select(sock + 1, &set, NULL, NULL, &timeout); + if (select_res == -1) { + DEBUG("select() error: %d\n", errno); + } else if (select_res == 0) { + DEBUG("read() timeout!\n"); + } else { + uint8_t buf[64]; + (void)read(sock, buf, sizeof(buf)); + } + } + + close(sock); +} + +void afl_custom_deinit(tcp_send_mutator_t* mutator) { + free(mutator); +} diff --git a/docs/Changelog.md b/docs/Changelog.md index c16214e4..0212fd61 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -18,6 +18,8 @@ a function entry - AFL_DEBUG is now the same as AFL_FRIDA_VERBOSE - AFL_FRIDA_DEBUG_MAPS now works as expected + - custom mutators: + - custom_send_tcp custom mutator added, thanks to @dergoegge ### Version ++4.21c (release) -- cgit 1.4.1 From 50ae95cee44a8df1629ee360de5d2582ff7d177e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Sat, 29 Jun 2024 16:31:08 +0200 Subject: add AFL_OLD_FORKSERVER feature --- docs/Changelog.md | 4 ++ docs/env_variables.md | 37 +++++++++---- include/envs.h | 5 +- instrumentation/afl-compiler-rt.o.c | 103 ++++++++++++++++++++++-------------- 4 files changed, 96 insertions(+), 53 deletions(-) (limited to 'docs/Changelog.md') diff --git a/docs/Changelog.md b/docs/Changelog.md index 0212fd61..487c5688 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -20,6 +20,10 @@ - AFL_FRIDA_DEBUG_MAPS now works as expected - custom mutators: - custom_send_tcp custom mutator added, thanks to @dergoegge + - afl-cc + - new runtime (!) variable: `AFL_OLD_FORKSERVER` to use the old vanilla + AFL type forkserver. Useful for symcc/symqemu/nautilus/etc. with + AFL_LLVM_INSTRUMENT=CLASSIC ### Version ++4.21c (release) diff --git a/docs/env_variables.md b/docs/env_variables.md index eebbcbda..8c2d5848 100644 --- a/docs/env_variables.md +++ b/docs/env_variables.md @@ -331,7 +331,26 @@ mode. the target performs only a few loops, then this will give a small performance boost. -## 4) Settings for afl-fuzz +## 4) Runtime settings + +The following environment variables are for a compiled AFL++ target. + + - Setting `AFL_DUMP_MAP_SIZE` when executing the target directly will + dump the map size of the target and exit. + + - Setting `AFL_OLD_FORKSERVER` will use the old AFL vanilla forkserver. + This makes only sense when you + a) compile in a classic colliding coverage mode (e.g. + AFL_LLVM_INSTRUMENT=CLASSIC) or if the map size of the target is + below MAP_SIZE (65536 by default), AND + b) you want to use this compiled AFL++ target with a different tool + that expects vanilla AFL behaviour, e.g. symcc, symqemu, nautilus, etc. + You would use this option together with the target fuzzing application. + + - Setting `AFL_DISABLE_LLVM_INSTRUMENTATION` will disable collecting + instrumentation. (More of an internal option.) + +## 5) Settings for afl-fuzz The main fuzzer binary accepts several options that disable a couple of sanity checks or alter some of the more exotic semantics of the tool: @@ -642,7 +661,7 @@ checks or alter some of the more exotic semantics of the tool: 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 +## 6) Settings for afl-qemu-trace The QEMU wrapper used to instrument binary-only code supports several settings: @@ -714,7 +733,7 @@ The QEMU wrapper used to instrument binary-only code supports several settings: crash is found. Setting `AFL_NO_CRASH_README` will prevent this. Useful when counting crashes based on a file count in that directory. -## 7) Settings for afl-frida-trace +## 8) Settings for afl-frida-trace The FRIDA wrapper used to instrument binary-only code supports many of the same options as `afl-qemu-trace`, but also has a number of additional advanced @@ -804,7 +823,7 @@ support. dump you must set a sufficient timeout (using `-t`) to avoid `afl-fuzz` killing the process whilst it is being dumped. -## 8) Settings for afl-cmin +## 9) Settings for afl-cmin The corpus minimization script offers very little customization: @@ -822,7 +841,7 @@ The corpus minimization script offers very little customization: - `AFL_PRINT_FILENAMES` prints each filename to stdout, as it gets processed. This can help when embedding `afl-cmin` or `afl-showmap` in other scripts. -## 9) Settings for afl-tmin +## 10) Settings for afl-tmin Virtually nothing to play with. Well, in QEMU mode (`-Q`), `AFL_PATH` will be searched for afl-qemu-trace. In addition to this, `TMPDIR` may be used if a @@ -833,12 +852,12 @@ to match when minimizing crashes. This will make minimization less useful, but may prevent the tool from "jumping" from one crashing condition to another in very buggy software. You probably want to combine it with the `-e` flag. -## 10) Settings for afl-analyze +## 11) Settings for afl-analyze You can set `AFL_ANALYZE_HEX` to get file offsets printed as hexadecimal instead of decimal. -## 11) Settings for libdislocator +## 12) Settings for libdislocator The library honors these environment variables: @@ -860,12 +879,12 @@ The library honors these environment variables: - `AFL_LD_VERBOSE` causes the library to output some diagnostic messages that may be useful for pinpointing the cause of any observed issues. -## 11) Settings for libtokencap +## 13) Settings for libtokencap This library accepts `AFL_TOKEN_FILE` to indicate the location to which the discovered tokens should be written. -## 12) Third-party variables set by afl-fuzz & other tools +## 14) Third-party variables set by afl-fuzz & other tools Several variables are not directly interpreted by afl-fuzz, but are set to optimal values if not already present in the environment: diff --git a/include/envs.h b/include/envs.h index 6a0d329b..3accbda0 100644 --- a/include/envs.h +++ b/include/envs.h @@ -40,8 +40,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", - "AFL_FRIDA_INST_NO_SUPPRESS" - "AFL_FRIDA_INST_RANGES", + "AFL_FRIDA_INST_NO_SUPPRESS", "AFL_FRIDA_INST_RANGES", "AFL_FRIDA_INST_REGS_FILE", "AFL_FRIDA_INST_SEED", "AFL_FRIDA_INST_TRACE", "AFL_FRIDA_INST_TRACE_UNIQUE", "AFL_FRIDA_INST_UNSTABLE_COVERAGE_FILE", "AFL_FRIDA_JS_SCRIPT", "AFL_FRIDA_OUTPUT_STDOUT", "AFL_FRIDA_OUTPUT_STDERR", @@ -50,7 +49,7 @@ static char *afl_environment_variables[] = { "AFL_FRIDA_PERSISTENT_RET", "AFL_FRIDA_STALKER_ADJACENT_BLOCKS", "AFL_FRIDA_STALKER_IC_ENTRIES", "AFL_FRIDA_STALKER_NO_BACKPATCH", "AFL_FRIDA_STATS_FILE", "AFL_FRIDA_STATS_INTERVAL", "AFL_FRIDA_TRACEABLE", - "AFL_FRIDA_VERBOSE", + "AFL_FRIDA_VERBOSE", "AFL_OLD_FORKSERVER", "AFL_FUZZER_ARGS", // oss-fuzz "AFL_FUZZER_STATS_UPDATE_INTERVAL", "AFL_GDB", "AFL_GCC_ALLOWLIST", "AFL_GCC_DENYLIST", "AFL_GCC_BLOCKLIST", "AFL_GCC_INSTRUMENT_FILE", diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index c08e6380..83aa9486 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -118,6 +118,7 @@ u32 __afl_map_size = MAP_SIZE; u32 __afl_dictionary_len; u64 __afl_map_addr; u32 __afl_first_final_loc; +u32 __afl_old_forkserver; #ifdef __AFL_CODE_COVERAGE typedef struct afl_module_info_t afl_module_info_t; @@ -616,7 +617,7 @@ static void __afl_map_shm(void) { fprintf(stderr, "DEBUG: (2) id_str %s, __afl_area_ptr %p, __afl_area_initial %p, " "__afl_area_ptr_dummy %p, __afl_map_addr 0x%llx, MAP_SIZE " - "%u, __afl_final_loc %u, __afl_map_size %u", + "%u, __afl_final_loc %u, __afl_map_size %u\n", id_str == NULL ? "" : id_str, __afl_area_ptr, __afl_area_initial, __afl_area_ptr_dummy, __afl_map_addr, MAP_SIZE, __afl_final_loc, __afl_map_size); @@ -856,7 +857,7 @@ static void __afl_start_forkserver(void) { signal(SIGTERM, at_exit); u32 already_read_first = 0; - u32 was_killed; + u32 was_killed = 0; u32 version = 0x41464c00 + FS_NEW_VERSION_MAX; u32 tmp = version ^ 0xffffffff, status2, status = version; u8 *msg = (u8 *)&status; @@ -866,75 +867,95 @@ static void __afl_start_forkserver(void) { void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL); + if (getenv("AFL_OLD_FORKSERVER")) { + + __afl_old_forkserver = 1; + status = 0; + + if (__afl_final_loc && __afl_final_loc > MAP_SIZE) { + + fprintf(stderr, + "Warning: AFL_OLD_FORKSERVER is used with a target compiled with " + "non-colliding coverage instead of AFL_LLVM_INSTRUMENT=CLASSIC - " + "this target may crash!\n"); + + } + + } + /* Phone home and tell the parent that we're OK. If parent isn't there, assume we're not running in forkserver mode and just execute program. */ // return because possible non-forkserver usage if (write(FORKSRV_FD + 1, msg, 4) != 4) { return; } - if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); } - if (tmp != status2) { + if (!__afl_old_forkserver) { - write_error("wrong forkserver message from AFL++ tool"); - _exit(1); + if (read(FORKSRV_FD, reply, 4) != 4) { _exit(1); } + if (tmp != status2) { - } + write_error("wrong forkserver message from AFL++ tool"); + _exit(1); - // send the set/requested options to forkserver - status = FS_NEW_OPT_MAPSIZE; // we always send the map size - if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; } - if (__afl_dictionary_len && __afl_dictionary) { + } - status |= FS_NEW_OPT_AUTODICT; + // send the set/requested options to forkserver + status = FS_NEW_OPT_MAPSIZE; // we always send the map size + if (__afl_sharedmem_fuzzing) { status |= FS_NEW_OPT_SHDMEM_FUZZ; } + if (__afl_dictionary_len && __afl_dictionary) { - } + status |= FS_NEW_OPT_AUTODICT; - if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } + } - // Now send the parameters for the set options, increasing by option number + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - // FS_NEW_OPT_MAPSIZE - we always send the map size - status = __afl_map_size; - if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } + // Now send the parameters for the set options, increasing by option number - // FS_NEW_OPT_SHDMEM_FUZZ - no data + // FS_NEW_OPT_MAPSIZE - we always send the map size + status = __afl_map_size; + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - // FS_NEW_OPT_AUTODICT - send autodictionary - if (__afl_dictionary_len && __afl_dictionary) { + // FS_NEW_OPT_SHDMEM_FUZZ - no data - // pass the dictionary through the forkserver FD - u32 len = __afl_dictionary_len, offset = 0; + // FS_NEW_OPT_AUTODICT - send autodictionary + if (__afl_dictionary_len && __afl_dictionary) { - if (write(FORKSRV_FD + 1, &len, 4) != 4) { + // pass the dictionary through the forkserver FD + u32 len = __afl_dictionary_len, offset = 0; - write(2, "Error: could not send dictionary len\n", - strlen("Error: could not send dictionary len\n")); - _exit(1); + if (write(FORKSRV_FD + 1, &len, 4) != 4) { - } + write(2, "Error: could not send dictionary len\n", + strlen("Error: could not send dictionary len\n")); + _exit(1); - while (len != 0) { + } - s32 ret; - ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); + while (len != 0) { - if (ret < 1) { + s32 ret; + ret = write(FORKSRV_FD + 1, __afl_dictionary + offset, len); - write_error("could not send dictionary"); - _exit(1); + if (ret < 1) { - } + write_error("could not send dictionary"); + _exit(1); - len -= ret; - offset += ret; + } + + len -= ret; + offset += ret; + + } } - } + // send welcome message as final message + status = version; + if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } - // send welcome message as final message - status = version; - if (write(FORKSRV_FD + 1, msg, 4) != 4) { _exit(1); } + } // END forkserver handshake -- cgit 1.4.1 From 43014cd465eec8cc47eda041802001776dbb5dd5 Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Mon, 1 Jul 2024 08:57:26 +0200 Subject: changelog --- TODO.md | 3 +-- docs/Changelog.md | 3 +++ 2 files changed, 4 insertions(+), 2 deletions(-) (limited to 'docs/Changelog.md') diff --git a/TODO.md b/TODO.md index c6da7fc5..81196339 100644 --- a/TODO.md +++ b/TODO.md @@ -2,8 +2,7 @@ ## Must - - in CLASSIC mode - do old forkserver model - - docs: AFL_DISABLE_REDUNDANT (large/slow/LAF) + - ijon support? - check for null ptr for xml/curl/g_ string transform functions - hardened_usercopy=0 page_alloc.shuffle=0 - add value_profile but only enable after 15 minutes without finds diff --git a/docs/Changelog.md b/docs/Changelog.md index 487c5688..d33d3121 100644 --- a/docs/Changelog.md +++ b/docs/Changelog.md @@ -18,6 +18,9 @@ a function entry - AFL_DEBUG is now the same as AFL_FRIDA_VERBOSE - AFL_FRIDA_DEBUG_MAPS now works as expected + - qemu_mode: + - new hooks supported (optional), see qemu_mode/hooking_bridge - thanks to + @CowBoy4mH3LL - custom mutators: - custom_send_tcp custom mutator added, thanks to @dergoegge - afl-cc -- cgit 1.4.1