From dd762726dc7055f4b1c48da2ee1b22ff6fdde35e Mon Sep 17 00:00:00 2001 From: vanhauser-thc Date: Wed, 12 Jun 2024 09:10:35 +0200 Subject: fastresume implementation --- src/afl-fuzz-queue.c | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) (limited to 'src/afl-fuzz-queue.c') diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index f4cb930d..a28172f9 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -401,7 +401,7 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { } else { - if (unlink(fn)) { PFATAL("Unable to remove '%s'", fn); } + if (unlink(fn)) { /*PFATAL("Unable to remove '%s'", fn);*/ } } @@ -699,12 +699,11 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) { void destroy_queue(afl_state_t *afl) { - u32 i; + u32 i; + struct queue_entry *q; for (i = 0; i < afl->queued_items; i++) { - struct queue_entry *q; - q = afl->queue_buf[i]; ck_free(q->fname); ck_free(q->trace_mini); -- cgit 1.4.1 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 +++ include/envs.h | 3 +- src/afl-fuzz-queue.c | 4 ++- src/afl-fuzz.c | 90 +++++++++++++++++++++++++++------------------------- 4 files changed, 56 insertions(+), 46 deletions(-) (limited to 'src/afl-fuzz-queue.c') 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 diff --git a/include/envs.h b/include/envs.h index 928f4185..ef522ab4 100644 --- a/include/envs.h +++ b/include/envs.h @@ -115,7 +115,8 @@ static char *afl_environment_variables[] = { "AFL_TRACE_PC", "AFL_USE_ASAN", "AFL_USE_MSAN", "AFL_USE_TRACE_PC", "AFL_USE_UBSAN", "AFL_USE_TSAN", "AFL_USE_CFISAN", "AFL_USE_LSAN", "AFL_WINE_PATH", "AFL_NO_SNAPSHOT", "AFL_EXPAND_HAVOC_NOW", "AFL_USE_FASAN", - "AFL_USE_QASAN", "AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", "AFL_NO_FASTRESUME", NULL + "AFL_USE_QASAN", "AFL_PRINT_FILENAMES", "AFL_PIZZA_MODE", + "AFL_NO_FASTRESUME", NULL }; diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index a28172f9..6069f5b9 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -401,7 +401,9 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { } else { - if (unlink(fn)) { /*PFATAL("Unable to remove '%s'", fn);*/ } + if (unlink(fn)) { /*PFATAL("Unable to remove '%s'", fn);*/ + + } } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 2bfbee15..a09a53ec 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -3214,64 +3214,66 @@ stop_fuzzing: #endif if (!afl->afl_env.afl_no_fastresume) { - /* create fastresume.bin */ - u8 fr[PATH_MAX]; - snprintf(fr, PATH_MAX, "%s/fastresume.bin", afl->out_dir); - ACTF("Writing %s ...", fr); - if ((fr_fd = open(fr, O_WRONLY | O_TRUNC | O_CREAT, DEFAULT_PERMISSION)) >= - 0) { - - 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); - - u8 on[1] = {1}, off[1] = {0}; - u8 *o_start = (u8 *)&(afl->queue_buf[0]->colorized); - u8 *o_end = (u8 *)&(afl->queue_buf[0]->mother); - u32 q_len = o_end - o_start; - u32 m_len = (afl->fsrv.map_size >> 3); - struct queue_entry *q; - afl->pending_not_fuzzed = afl->queued_items; - afl->active_items = afl->queued_items; + /* create fastresume.bin */ + u8 fr[PATH_MAX]; + snprintf(fr, PATH_MAX, "%s/fastresume.bin", afl->out_dir); + ACTF("Writing %s ...", fr); + if ((fr_fd = open(fr, O_WRONLY | O_TRUNC | O_CREAT, DEFAULT_PERMISSION)) >= + 0) { - for (u32 i = 0; i < afl->queued_items; i++) { + u8 ver_string[8]; + u32 w = 0; + u64 *ver = (u64 *)ver_string; + *ver = afl->shm.cmplog_mode + (sizeof(struct queue_entry) << 1); - q = afl->queue_buf[i]; - ck_write(fr_fd, (u8 *)&(q->colorized), q_len, "queue data"); - if (!q->trace_mini) { + w += write(fr_fd, ver_string, sizeof(ver_string)); - ck_write(fr_fd, off, 1, "no_mini"); - w += q_len + 1; + 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); - } else { + u8 on[1] = {1}, off[1] = {0}; + u8 *o_start = (u8 *)&(afl->queue_buf[0]->colorized); + u8 *o_end = (u8 *)&(afl->queue_buf[0]->mother); + u32 q_len = o_end - o_start; + u32 m_len = (afl->fsrv.map_size >> 3); + struct queue_entry *q; + + afl->pending_not_fuzzed = afl->queued_items; + afl->active_items = afl->queued_items; - ck_write(fr_fd, on, 1, "yes_mini"); - ck_write(fr_fd, q->trace_mini, m_len, "trace_mini"); - w += q_len + m_len + 1; + 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"); + if (!q->trace_mini) { + + ck_write(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"); + w += q_len + m_len + 1; + + } } - } + close(fr_fd); + afl->var_byte_count = count_bytes(afl, afl->var_bytes); + OKF("Written fastresume.bin with %u bytes!", w); - close(fr_fd); - afl->var_byte_count = count_bytes(afl, afl->var_bytes); - OKF("Written fastresume.bin with %u bytes!", w); + } else { - } else { + WARNF("Could not create fastresume.bin"); - WARNF("Could not create fastresume.bin"); + } } - } destroy_queue(afl); destroy_extras(afl); -- 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 'src/afl-fuzz-queue.c') 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