diff options
author | van Hauser <vh@thc.org> | 2023-08-09 18:29:25 +0000 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-08-09 18:29:25 +0000 |
commit | fa44d8f79f03c0aab3cfea93c37b70edc367c1bb (patch) | |
tree | f39de203508117dcb50b66baa8fd335a887a9c54 /src | |
parent | 18d9234dfe4b6db32a2da335834908e49300e5cd (diff) | |
parent | 55d696fbae435e0e69adf75cb2df1361186fb999 (diff) | |
download | afl++-fa44d8f79f03c0aab3cfea93c37b70edc367c1bb.tar.gz |
Merge pull request #1831 from AFLplusplus/dev
push to stable
Diffstat (limited to 'src')
-rw-r--r-- | src/afl-forkserver.c | 63 | ||||
-rw-r--r-- | src/afl-fuzz-bitmap.c | 3 | ||||
-rw-r--r-- | src/afl-fuzz-init.c | 105 | ||||
-rw-r--r-- | src/afl-fuzz-one.c | 2 | ||||
-rw-r--r-- | src/afl-fuzz-redqueen.c | 336 | ||||
-rw-r--r-- | src/afl-fuzz-state.c | 7 | ||||
-rw-r--r-- | src/afl-fuzz-stats.c | 9 | ||||
-rw-r--r-- | src/afl-fuzz.c | 60 | ||||
-rw-r--r-- | src/afl-showmap.c | 1 |
9 files changed, 395 insertions, 191 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index ba7cdd66..9da096f7 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -129,6 +129,10 @@ 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; } + plugin->nyx_config_set_aux_buffer_size = + dlsym(handle, "nyx_config_set_aux_buffer_size"); + if (plugin->nyx_config_set_aux_buffer_size == NULL) { goto fail; } + OKF("libnyx plugin is ready!"); return plugin; @@ -160,6 +164,8 @@ void afl_nyx_runner_kill(afl_forkserver_t *fsrv) { } + if (fsrv->nyx_log_fd >= 0) { close(fsrv->nyx_log_fd); } + } } @@ -214,6 +220,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) { fsrv->nyx_bind_cpu_id = 0xFFFFFFFF; fsrv->nyx_use_tmp_workdir = false; fsrv->nyx_tmp_workdir_path = NULL; + fsrv->nyx_log_fd = -1; #endif // this structure needs default so we initialize it if this was not done @@ -571,6 +578,22 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); + char *nyx_log_path = getenv("AFL_NYX_LOG"); + if (nyx_log_path) { + + fsrv->nyx_log_fd = + open(nyx_log_path, O_CREAT | O_TRUNC | O_WRONLY, DEFAULT_PERMISSION); + if (fsrv->nyx_log_fd < 0) { + + NYX_PRE_FATAL(fsrv, "AFL_NYX_LOG path could not be written"); + + } + + fsrv->nyx_handlers->nyx_config_set_hprintf_fd(nyx_config, + fsrv->nyx_log_fd); + + } + if (fsrv->nyx_standalone) { fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, StandAlone); @@ -589,23 +612,36 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, } - if (getenv("NYX_REUSE_SNAPSHOT") != NULL) { + if (getenv("AFL_NYX_AUX_SIZE") != NULL) { + + if (fsrv->nyx_handlers->nyx_config_set_aux_buffer_size( + nyx_config, atoi(getenv("AFL_NYX_AUX_SIZE"))) != 1) { + + NYX_PRE_FATAL(fsrv, + "Invalid AFL_NYX_AUX_SIZE value set (must be a multiple " + "of 4096) ..."); + + } + + } + + if (getenv("AFL_NYX_REUSE_SNAPSHOT") != NULL) { - if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) { + if (access(getenv("AFL_NYX_REUSE_SNAPSHOT"), F_OK) == -1) { - NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not exist"); + NYX_PRE_FATAL(fsrv, "AFL_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")); + alloc_printf("%s/global.state", getenv("AFL_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, + "AFL_NYX_REUSE_SNAPSHOT path does not contain a valid " + "Nyx snapshot"); } @@ -617,13 +653,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, char *workdir_snapshot_path = alloc_printf("%s/workdir/snapshot", outdir_path_absolute); char *reuse_snapshot_path_real = - realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL); + realpath(getenv("AFL_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)"); + NYX_PRE_FATAL( + fsrv, + "AFL_NYX_REUSE_SNAPSHOT path is located in current workdir " + "(use another output directory)"); } @@ -631,7 +668,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, ck_free(workdir_snapshot_path); fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path( - nyx_config, getenv("NYX_REUSE_SNAPSHOT")); + nyx_config, getenv("AFL_NYX_REUSE_SNAPSHOT")); } @@ -653,7 +690,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner); fsrv->nyx_handlers->nyx_option_set_reload_mode( - fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL); + fsrv->nyx_runner, getenv("AFL_NYX_DISABLE_SNAPSHOT_MODE") == NULL); fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner); fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0); diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index fb8a1d4b..87157cad 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -533,7 +533,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { close(fd); add_to_queue(afl, queue_fn, len, 0); - if (unlikely(afl->fuzz_mode) && likely(afl->switch_fuzz_mode)) { + if (unlikely(afl->fuzz_mode) && + likely(afl->switch_fuzz_mode && !afl->non_instrumented_mode)) { if (afl->afl_env.afl_no_ui) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 24fd7077..5a530821 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1058,7 +1058,19 @@ void perform_dry_run(afl_state_t *afl) { } else { - WARNF("Test case '%s' results in a crash, skipping", fn); + if (afl->afl_env.afl_crashing_seeds_as_new_crash) { + + WARNF( + "Test case '%s' results in a crash, " + "as AFL_CRASHING_SEEDS_AS_NEW_CRASH is set, " + "saving as a new crash", + fn); + + } else { + + WARNF("Test case '%s' results in a crash, skipping", fn); + + } } @@ -1078,36 +1090,95 @@ void perform_dry_run(afl_state_t *afl) { } - q->disabled = 1; - q->perf_score = 0; + /* Crashing seeds will be regarded as new crashes on startup */ + if (afl->afl_env.afl_crashing_seeds_as_new_crash) { - u32 i = 0; - while (unlikely(i < afl->queued_items && afl->queue_buf[i] && - afl->queue_buf[i]->disabled)) { + ++afl->total_crashes; - ++i; + if (likely(!afl->non_instrumented_mode)) { - } + classify_counts(&afl->fsrv); + + simplify_trace(afl, afl->fsrv.trace_bits); + + if (!has_new_bits(afl, afl->virgin_crash)) { break; } + + } + + if (unlikely(!afl->saved_crashes) && + (afl->afl_env.afl_no_crash_readme != 1)) { + + write_crash_readme(afl); + + } + + u8 crash_fn[PATH_MAX]; + u8 *use_name = strstr(q->fname, ",orig:"); + + afl->stage_name = "dry_run"; + afl->stage_short = "dry_run"; + +#ifndef SIMPLE_FILES - if (i < afl->queued_items && afl->queue_buf[i]) { + snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s", + afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, + describe_op(afl, 0, + NAME_MAX - strlen("id:000000,sig:00,") - + strlen(use_name)), + use_name); - afl->queue = afl->queue_buf[i]; +#else + + snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u", + afl->out_dir, afl->saved_crashes, + afl->fsrv.last_kill_signal); + +#endif + + ++afl->saved_crashes; + + fd = open(crash_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); + if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", crash_fn); } + ck_write(fd, use_mem, read_len, crash_fn); + close(fd); + + afl->last_crash_time = get_cur_time(); + afl->last_crash_execs = afl->fsrv.total_execs; } else { - afl->queue = afl->queue_buf[0]; + u32 i = 0; + while (unlikely(i < afl->queued_items && afl->queue_buf[i] && + afl->queue_buf[i]->disabled)) { - } + ++i; + + } + + if (i < afl->queued_items && afl->queue_buf[i]) { - afl->max_depth = 0; - for (i = 0; i < afl->queued_items && likely(afl->queue_buf[i]); i++) { + afl->queue = afl->queue_buf[i]; - if (!afl->queue_buf[i]->disabled && - afl->queue_buf[i]->depth > afl->max_depth) - afl->max_depth = afl->queue_buf[i]->depth; + } else { + + afl->queue = afl->queue_buf[0]; + + } + + afl->max_depth = 0; + for (i = 0; i < afl->queued_items && likely(afl->queue_buf[i]); i++) { + + if (!afl->queue_buf[i]->disabled && + afl->queue_buf[i]->depth > afl->max_depth) + afl->max_depth = afl->queue_buf[i]->depth; + + } } + q->disabled = 1; + q->perf_score = 0; + break; case FSRV_RUN_ERROR: diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c index 8ee50bbf..2ad4697e 100644 --- a/src/afl-fuzz-one.c +++ b/src/afl-fuzz-one.c @@ -2995,7 +2995,7 @@ havoc_stage: // fprintf(stderr, "val: %u-%u = %ld\n", off, off2, val); char buf[20]; - snprintf(buf, sizeof(buf), "%ld", val); + snprintf(buf, sizeof(buf), "%" PRId64, val); // fprintf(stderr, "BEFORE: %s\n", out_buf); diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 73e188e7..db4991db 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -129,7 +129,6 @@ static struct range *pop_biggest_range(struct range **ranges) { } #ifdef _DEBUG -// static int logging = 0; static void dump(char *txt, u8 *buf, u32 len) { u32 i; @@ -140,6 +139,7 @@ static void dump(char *txt, u8 *buf, u32 len) { } +/* static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) { char fn[4096]; @@ -155,6 +155,8 @@ static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) { } +*/ + #endif static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) { @@ -571,7 +573,6 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) { } -// #ifdef CMPLOG_SOLVE_TRANSFORM static int strntoll(const char *str, size_t sz, char **end, int base, long long *out) { @@ -656,7 +657,6 @@ static int is_hex(const char *str) { } -#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 // tests 4 bytes at location static int is_base64(const char *str) { @@ -732,12 +732,14 @@ static u32 from_base64(u8 *src, u8 *dst, u32 dst_len) { } -static void to_base64(u8 *src, u8 *dst, u32 dst_len) { +static u32 to_base64(u8 *src, u8 *dst, u32 dst_len) { u32 i, j, v; - u32 len = (dst_len >> 2) * 3; + // u32 len = (dst_len >> 2) * 3; + u32 len = (dst_len / 3) * 4; + if (dst_len % 3) len += 4; - for (i = 0, j = 0; i < len; i += 3, j += 4) { + for (i = 0, j = 0; j < len; i += 3, j += 4) { v = src[i]; v = i + 1 < len ? v << 8 | src[i + 1] : v << 8; @@ -745,7 +747,8 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) { dst[j] = base64_encode_table[(v >> 18) & 0x3F]; dst[j + 1] = base64_encode_table[(v >> 12) & 0x3F]; - if (i + 1 < len) { + + if (i + 1 < dst_len) { dst[j + 2] = base64_encode_table[(v >> 6) & 0x3F]; @@ -755,7 +758,7 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) { } - if (i + 2 < len) { + if (i + 2 < dst_len) { dst[j + 3] = base64_encode_table[v & 0x3F]; @@ -767,11 +770,10 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) { } -} - -#endif + dst[len] = 0; + return len; -// #endif +} static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, u64 pattern, u64 repl, u64 o_pattern, @@ -797,42 +799,54 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, } - // fprintf(stderr, - // "Encode: %llx->%llx into %llx(<-%llx) at idx=%u " - // "taint_len=%u shape=%u attr=%u\n", - // o_pattern, pattern, repl, changed_val, idx, taint_len, - // hshape, attr); + /* + fprintf(stderr, + "Encode: %llx->%llx into %llx(<-%llx) at idx=%u " + "taint_len=%u shape=%u attr=%u\n", + o_pattern, pattern, repl, changed_val, idx, taint_len, + hshape, attr); + */ - // #ifdef CMPLOG_SOLVE_TRANSFORM // reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3 if (afl->cmplog_enable_transform && (lvl & LVL3)) { u8 *endptr; u8 use_num = 0, use_unum = 0; - unsigned long long unum; - long long num; + unsigned long long unum = 0; + long long num = 0; + + // if (afl->queue_cur->is_ascii) { + + // we first check if our input are ascii numbers that are transformed to + // an integer and used for comparison: - if (afl->queue_cur->is_ascii) { + endptr = buf_8; + if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) { - endptr = buf_8; - if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) { + if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) { - if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) - use_unum = 1; + use_unum = 1; - } else + } + + } else { - use_num = 1; + use_num = 1; } + //} + #ifdef _DEBUG if (idx == 0) - fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n", - afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern); + fprintf(stderr, + "ASCII is=%u use_num=%u>%lld use_unum=%u>%llu idx=%u " + "pattern=0x%llx\n", + afl->queue_cur->is_ascii, use_num, num, use_unum, unum, idx, + pattern); #endif - // num is likely not pattern as atoi("AAA") will be zero... + // atoi("AAA") == 0 so !num means we have to investigate if (use_num && ((u64)num == pattern || !num)) { u8 tmp_buf[32]; @@ -961,10 +975,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..." s64 diff = pattern - b_val; s64 o_diff = o_pattern - o_b_val; - /* fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx, - hshape, o_pattern, o_b_val, o_diff); - fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern, - b_val, diff); */ + /* + fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx, + hshape, o_pattern, o_b_val, o_diff); + fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern, + b_val, diff); + */ if (diff == o_diff && diff) { // this could be an arithmetic transformation @@ -1275,7 +1291,6 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h, // 16 = modified float, 32 = modified integer (modified = wont match // in original buffer) - // #ifdef CMPLOG_SOLVE_ARITHMETIC if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) { return 0; @@ -2009,8 +2024,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, its_len = MIN(its_len, taint_len); u32 saved_its_len = its_len; + // fprintf(stderr, "its_len=%u repl=%s\n", its_len, repl); + + if (its_len <= 1) { return 0; } + if (lvl & LVL3) { + if (memcmp(changed_val, repl, its_len) != 0) { return 0; } + u32 max_to = MIN(4U, idx); if (!(lvl & LVL1) && max_to) { from = 1; } to = max_to; @@ -2021,27 +2042,32 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, (void)(j); #ifdef _DEBUG - fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl, - o->v0_len >= 0x80 ? 1 : 0, hshape, l0); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", orig_buf[idx + j]); - fprintf(stderr, " -> "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", o_pattern[j]); - fprintf(stderr, " <= "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", repl[j]); - fprintf(stderr, "\n"); - fprintf(stderr, " "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", buf[idx + j]); - fprintf(stderr, " -> "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", pattern[j]); - fprintf(stderr, " <= "); - for (j = 0; j < 8; j++) - fprintf(stderr, "%02x", changed_val[j]); - fprintf(stderr, "\n"); + if (idx == 0) { + + fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl, + o->v0_len >= 0x80 ? 1 : 0, hshape, l0); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", orig_buf[idx + j]); + fprintf(stderr, " -> "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", o_pattern[j]); + fprintf(stderr, " <= "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", repl[j]); + fprintf(stderr, "\n"); + fprintf(stderr, " "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", buf[idx + j]); + fprintf(stderr, " -> "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", pattern[j]); + fprintf(stderr, " <= "); + for (j = 0; j < 8; j++) + fprintf(stderr, "%02x", changed_val[j]); + fprintf(stderr, "\n"); + + } + #endif // Try to match the replace value up to 4 bytes before the current idx. @@ -2050,6 +2076,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, // if (memcmp(user_val, "TEST-VALUE") == 0) ... // We only do this in lvl 3, otherwise we only do direct matching + // fprintf(stderr, "XXXX FROMB64 saved_idx=%u its_len=%u from=%u to=%u FROMHEX + // repl=%s\n", saved_idx, saved_its_len, from, to, repl); + for (pre = from; pre <= to; pre++) { if (*status != 1 && (!pre || !memcmp(buf + saved_idx - pre, repl, pre))) { @@ -2089,9 +2118,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, if (afl->cmplog_enable_transform && (lvl & LVL3)) { u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0; -#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 u32 tob64 = 0, fromb64 = 0; -#endif u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0; u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0; u8 xor_val[32], arith_val[32], tmp[48]; @@ -2144,7 +2171,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - if (i < 16 && is_hex(repl + (i << 1))) { + if (afl->cmplog_enable_xtreme_transform && i < 16 && + is_hex(repl + (i << 1))) { ++tohex; @@ -2163,9 +2191,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - if ((i % 2)) { + if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1) { - if (len > idx + i + 1 && is_hex(orig_buf + idx + i)) { + if (len > idx + i + 1 && is_hex(orig_buf + idx + i - 1)) { fromhex += 2; @@ -2187,20 +2215,23 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } -#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 - if (i % 3 == 2 && i < 24) { + if (afl->cmplog_enable_xtreme_transform) { - if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; + if (i % 3 == 2 && i < 24) { - } + if (is_base64(repl + ((i / 3) << 2))) tob64 += 3; - if (i % 4 == 3 && i < 24) { + } - if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4; + // fprintf(stderr, "X FROMB64 idx=%u i=%u repl=%s\n", saved_idx, i, + // repl); + if (i % 4 == 3 && i < 24) { - } + if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4; -#endif + } + + } if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) { @@ -2229,45 +2260,70 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } #ifdef _DEBUG - fprintf(stderr, - "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u " - "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u " - "from_0=%u from_slash=%u from_x=%u\n", - idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, - to_slash, to_x, from_0, from_slash, from_x); - #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 - fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64, - fromb64); - #endif + if (idx == 0) { + + fprintf(stderr, "RTN Z %s %s %s %s repl=%s\n", buf, pattern, orig_buf, + o_pattern, repl); + fprintf( + stderr, + "RTN Z idx=%u len=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u " + "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u " + "from_0=%u from_slash=%u from_x=%u\n", + idx, its_len, i, xor, arith, tolower, toupper, tohex, fromhex, to_0, + to_slash, to_x, from_0, from_slash, from_x); + if (afl->cmplog_enable_xtreme_transform) { + + fprintf(stderr, "RTN Z idx=%u loop=%u tob64=%u from64=%u\n", idx, i, + tob64, fromb64); + + } + + } + #endif -#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 - // input is base64 and converted to binary? convert repl to base64! - if ((i % 4) == 3 && i < 24 && fromb64 > i) { + if (afl->cmplog_enable_xtreme_transform) { - to_base64(repl, tmp, i + 1); - memcpy(buf + idx, tmp, i + 1); - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64, - // *status); + // input is base64 and converted to binary? convert repl to base64! + // fprintf(stderr, "FROMB64 idx=%u i=%u %% 4 == 3 && i < 24 && + // fromb64=%u > i, repl=%s\n", saved_idx, i, fromb64, repl); + if ((i % 4) == 3 && i < 24 && fromb64 > i) { - } + for (u32 hlen = i; hlen + saved_idx < len && hlen <= its_len; + ++hlen) { - // input is converted to base64? decode repl with base64! - if ((i % 3) == 2 && i < 24 && tob64 > i) { + u32 res = to_base64(repl, tmp, hlen); + // fprintf(stderr, "FROMB64 GOGO! idx=%u repl=%s tmp[%u]=%s + // hlen=%u\n", saved_idx, repl, res, tmp, hlen); + if (res + saved_idx < len) { - u32 olen = from_base64(repl, tmp, i + 1); - memcpy(buf + idx, tmp, olen); - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64, - // idx, *status); + memcpy(buf + idx, tmp, res); + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + // fprintf(stderr, "RTN ATTEMPT FROMB64 idx=%u fromb64 %u %s %s + // result %u\n", saved_idx, fromb64, tmp, repl, + // *status); - } + } -#endif + } + + } + + // input is converted to base64? decode repl with base64! + if ((i % 3) == 2 && i < 24 && tob64 > i) { + + u32 olen = from_base64(repl, tmp, i + 1); + memcpy(buf + idx, tmp, olen); + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64, + // idx, *status); + + } + + } // input is converted to hex? convert repl to binary! - if (i < 16 && tohex > i) { + if (afl->cmplog_enable_xtreme_transform && i < 16 && tohex > i) { u32 off; if (to_slash + to_x + to_0 == 2) { @@ -2292,8 +2348,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } // input is hex and converted to binary? convert repl to hex! - if (i && (i % 2) && i < 16 && fromhex && - fromhex + from_slash + from_x + from_0 > i) { + if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1 && i < 16 && + fromhex && fromhex + from_slash + from_x + from_0 > i) { u8 off = 0; if (from_slash && from_x) { @@ -2328,31 +2384,36 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - if (to_up == 1) { + for (u32 hlen = i; hlen <= (i << 1) && hlen + idx < len; hlen += i) { - for (j = 0; j <= (i >> 1); j++) { + if (to_up == 1) { - tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4]; - tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16]; + for (j = 0; j <= (hlen >> 1); j++) { - } + tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4]; + tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16]; - } else { + } + + } else { - for (j = 0; j <= (i >> 1); j++) { + for (j = 0; j <= (hlen >> 1); j++) { - tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4]; - tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16]; + tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4]; + tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16]; + + } } - } + memcpy(buf + idx, tmp, hlen + 1 + off); + if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } + tmp[hlen + 1 + off] = 0; + // fprintf(stderr, "RTN ATTEMPT idx=%u len=%u fromhex %u %s %s result + // %u\n", idx, len, fromhex, tmp, repl, *status); + memcpy(buf + idx, save, hlen + 1 + off); - memcpy(buf + idx, tmp, i + 1 + off); - if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; } - // fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex, - // *status); - memcpy(buf + idx, save, i + 1 + off); + } } @@ -2401,11 +2462,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, if ((i >= 7 && (i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i > - (fromhex + from_0 + from_x + from_slash + 1) -#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64 - && i > tob64 + 3 && i > fromb64 + 4 -#endif - )) || + (fromhex + from_0 + from_x + from_slash + 1) && + (afl->cmplog_enable_xtreme_transform && i > tob64 + 3 && + i > fromb64 + 4))) || repl[i] != changed_val[i] || *status == 1) { break; @@ -2418,8 +2477,6 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - // #endif - return 0; } @@ -2429,7 +2486,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, struct tainted *t; struct cmp_header *h = &afl->shm.cmp_map->headers[key]; - u32 i, j, idx, have_taint = 1, taint_len, loggeds; + u32 i, idx, have_taint = 1, taint_len, loggeds; u8 status = 0, found_one = 0; hshape = SHAPE_BYTES(h->shape); @@ -2452,19 +2509,23 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, struct cmpfn_operands *orig_o = &((struct cmpfn_operands *)afl->orig_cmp_map->log[key])[i]; - // opt not in the paper - for (j = 0; j < i; ++j) { + /* + // opt not in the paper + for (j = 0; j < i; ++j) { - if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j], o, - sizeof(struct cmpfn_operands))) { + if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j], + o, sizeof(struct cmpfn_operands))) { - goto rtn_fuzz_next_iter; + goto rtn_fuzz_next_iter; - } + } - } + } - /* + */ + +#ifdef _DEBUG + u32 j; struct cmp_header *hh = &afl->orig_cmp_map->headers[key]; fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id, hshape, h->attribute); @@ -2481,7 +2542,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v1[j]); fprintf(stderr, "\n"); - */ +#endif t = taint; while (t->next) { @@ -2515,7 +2576,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, status = 0; #ifdef _DEBUG - int w; + u32 w; fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx, hshape); for (w = 0; w < hshape; ++w) fprintf(stderr, "%02x", orig_o->v0[w]); @@ -2605,7 +2666,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf, } - rtn_fuzz_next_iter: + // rtn_fuzz_next_iter: afl->stage_cur++; } @@ -2818,12 +2879,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) { } - } else if ((lvl & LVL1) - - // #ifdef CMPLOG_SOLVE_TRANSFORM - || ((lvl & LVL3) && afl->cmplog_enable_transform) - // #endif - ) { + } else if ((lvl & LVL1) || ((lvl & LVL3) && afl->cmplog_enable_transform)) { if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) { diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 99f69314..5a6b95cf 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -200,6 +200,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { afl->afl_env.afl_exit_on_time = (u8 *)get_afl_env(afl_environment_variables[i]); + } else if (!strncmp(env, "AFL_CRASHING_SEEDS_AS_NEW_CRASH", + + afl_environment_variable_len)) { + + afl->afl_env.afl_crashing_seeds_as_new_crash = + atoi((u8 *)get_afl_env(afl_environment_variables[i])); + } else if (!strncmp(env, "AFL_NO_AFFINITY", afl_environment_variable_len)) { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 4013370d..3d0a9b9a 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -37,8 +37,13 @@ char *get_fuzzing_state(afl_state_t *afl) { u64 cur_run_time = cur_ms - afl->start_time; u64 cur_total_run_time = afl->prev_run_time + cur_run_time; - if (unlikely(cur_run_time < 60 * 3 * 1000 || - cur_total_run_time < 60 * 5 * 1000)) { + if (unlikely(afl->non_instrumented_mode)) { + + return fuzzing_state[1]; + + } else if (unlikely(cur_run_time < 60 * 3 * 1000 || + + cur_total_run_time < 60 * 5 * 1000)) { return fuzzing_state[0]; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 9afece66..cdb3f996 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -180,12 +180,14 @@ static void usage(u8 *argv0, int more_help) { "it.\n" " if using QEMU/FRIDA or the fuzzing target is " "compiled\n" - " for CmpLog then just use -c 0.\n" + " for CmpLog then use '-c 0'. To disable Cmplog use '-c " + "-'.\n" " -l cmplog_opts - CmpLog configuration values (e.g. \"2ATR\"):\n" " 1=small files, 2=larger files (default), 3=all " "files,\n" " A=arithmetic solving, T=transformational solving,\n" - " R=random colorization bytes.\n\n" + " X=extreme transform solving, R=random colorization " + "bytes.\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " "random\n" @@ -277,7 +279,8 @@ static void usage(u8 *argv0, int more_help) { "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" + "AFL_PIZZA_MODE: 1 - enforce pizza mode, -1 - disable for April 1st,\n" + " 0 (default) - activate on April 1st\n" "AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n" " (default: SIGKILL)\n" "AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n" @@ -297,7 +300,12 @@ static void usage(u8 *argv0, int more_help) { "AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n" "AFL_NO_STARTUP_CALIBRATION: no initial seed calibration, start fuzzing at once\n" "AFL_NO_UI: switch status screen off\n" - + "AFL_NYX_AUX_SIZE: size of the Nyx auxiliary buffer. Must be a multiple of 4096.\n" + " Increase this value in case the crash reports are truncated.\n" + " Default value is 4096.\n" + "AFL_NYX_DISABLE_SNAPSHOT_MODE: disable snapshot mode (must be supported by the agent)\n" + "AFL_NYX_LOG: output NYX hprintf messages to another file\n" + "AFL_NYX_REUSE_SNAPSHOT: reuse an existing Nyx root snapshot\n" DYN_COLOR "AFL_PATH: path to AFL support binaries\n" @@ -306,8 +314,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_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to\n" + " the queue, 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" @@ -318,18 +326,17 @@ static void usage(u8 *argv0, int more_help) { "AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n" "AFL_STATSD_PORT: change default statsd port (default: 8125)\n" "AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n" - " Supported formats are: 'dogstatsd', 'librato',\n" - " 'signalfx' and 'influxdb'\n" + " suported formats: dogstatsd, librato, signalfx, influxdb\n" "AFL_SYNC_TIME: sync time between fuzzing instances (in minutes)\n" "AFL_NO_CRASH_README: do not create a README in the crashes directory\n" "AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n" "AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n" "AFL_EARLY_FORKSERVER: force an early forkserver in an afl-clang-fast/\n" " 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" + "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 shared lib)\n" + "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in\n" + " seconds (default: 60, minimum: 1)\n" "\n" ); @@ -594,8 +601,23 @@ int main(int argc, char **argv_orig, char **envp) { case 'c': { - afl->shm.cmplog_mode = 1; - afl->cmplog_binary = ck_strdup(optarg); + if (strcmp(optarg, "-") == 0) { + + if (afl->shm.cmplog_mode) { + + ACTF("Disabling cmplog again because of '-c -'."); + afl->shm.cmplog_mode = 0; + afl->cmplog_binary = NULL; + + } + + } else { + + afl->shm.cmplog_mode = 1; + afl->cmplog_binary = ck_strdup(optarg); + + } + break; } @@ -1120,6 +1142,10 @@ int main(int argc, char **argv_orig, char **envp) { case 'T': afl->cmplog_enable_transform = 1; break; + case 'x': + case 'X': + afl->cmplog_enable_xtreme_transform = 1; + break; case 'r': case 'R': afl->cmplog_random_colorization = 1; @@ -1500,8 +1526,7 @@ int main(int argc, char **argv_orig, char **envp) { if (!afl->use_banner) { afl->use_banner = argv[optind]; } - if (afl->shm.cmplog_mode && - (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) { + if (afl->shm.cmplog_mode && strcmp("0", afl->cmplog_binary) == 0) { afl->cmplog_binary = strdup(argv[optind]); @@ -2755,7 +2780,8 @@ int main(int argc, char **argv_orig, char **envp) { u64 cur_time = get_cur_time(); - if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0) && + if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0 && + !afl->non_instrumented_mode) && unlikely(cur_time > afl->last_find_time + afl->switch_fuzz_mode)) { if (afl->afl_env.afl_no_ui) { diff --git a/src/afl-showmap.c b/src/afl-showmap.c index b82bcd72..7a639cf6 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -1611,6 +1611,7 @@ int main(int argc, char **argv_orig, char **envp) { if (in_dir || in_filelist) { afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY); + if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); } afl->afl_env.afl_custom_mutator_library = getenv("AFL_CUSTOM_MUTATOR_LIBRARY"); afl->afl_env.afl_python_module = getenv("AFL_PYTHON_MODULE"); |