diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/afl-cc.c | 14 | ||||
-rw-r--r-- | src/afl-forkserver.c | 2 | ||||
-rw-r--r-- | src/afl-fuzz-bitmap.c | 91 | ||||
-rw-r--r-- | src/afl-fuzz-init.c | 78 | ||||
-rw-r--r-- | src/afl-fuzz-queue.c | 5 | ||||
-rw-r--r-- | src/afl-fuzz-run.c | 65 | ||||
-rw-r--r-- | src/afl-fuzz-state.c | 10 | ||||
-rw-r--r-- | src/afl-fuzz-stats.c | 37 | ||||
-rw-r--r-- | src/afl-fuzz.c | 14 | ||||
-rw-r--r-- | src/afl-performance.c | 310 | ||||
-rw-r--r-- | src/afl-showmap.c | 15 |
11 files changed, 546 insertions, 95 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c index 469aad13..7afab850 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -525,7 +525,7 @@ void find_built_deps(aflcc_state_t *aflcc) { char *ptr = NULL; -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(__i386__) if ((ptr = find_object(aflcc, "afl-as")) != NULL) { #ifndef __APPLE__ @@ -2793,11 +2793,11 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) { "MODES: NCC PERSIST DICT LAF " "CMPLOG SELECT\n" " [LLVM] LLVM: %s%s\n" - " PCGUARD %s yes yes module yes yes " + " PCGUARD %s yes yes module yes yes " "yes\n" " NATIVE AVAILABLE no yes no no " "part. yes\n" - " CLASSIC %s no yes module yes yes " + " CLASSIC %s no yes module yes yes " "yes\n" " - NORMAL\n" " - CALLER\n" @@ -2814,10 +2814,10 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) { " [GCC/CLANG] simple gcc/clang: %s%s\n" " CLASSIC DEFAULT no no no no no " "no\n\n", - aflcc->have_llvm ? "AVAILABLE" : "unavailable!", + aflcc->have_llvm ? "AVAILABLE " : "unavailable!", aflcc->compiler_mode == LLVM ? " [SELECTED]" : "", - aflcc->have_llvm ? "AVAILABLE" : "unavailable!", - aflcc->have_llvm ? "AVAILABLE" : "unavailable!", + aflcc->have_llvm ? "AVAILABLE " : "unavailable!", + aflcc->have_llvm ? "AVAILABLE " : "unavailable!", aflcc->have_lto ? "AVAILABLE" : "unavailable!", aflcc->compiler_mode == LTO ? " [SELECTED]" : "", aflcc->have_gcc_plugin ? "AVAILABLE" : "unavailable!", @@ -2843,7 +2843,7 @@ static void maybe_usage(aflcc_state_t *aflcc, int argc, char **argv) { " The best is LTO but it often needs RANLIB and AR settings outside " "of afl-cc.\n\n"); -#if LLVM_MAJOR > 10 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) +#if LLVM_MAJOR >= 11 || (LLVM_MAJOR == 10 && LLVM_MINOR > 0) #define NATIVE_MSG \ " LLVM-NATIVE: use llvm's native PCGUARD instrumentation (less " \ "performant)\n" diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index e5f64c81..beb6bdeb 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -578,7 +578,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, 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_size(nyx_config, fsrv->max_length); fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config, true); diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c index 5d4d80af..03bc5d6c 100644 --- a/src/afl-fuzz-bitmap.c +++ b/src/afl-fuzz-bitmap.c @@ -527,12 +527,24 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - queue_fn = alloc_printf( - "%s/queue/id:%06u,%s%s%s", afl->out_dir, afl->queued_items, - describe_op(afl, new_bits + is_timeout, - NAME_MAX - strlen("id:000000,")), - afl->file_extension ? "." : "", - afl->file_extension ? (const char *)afl->file_extension : ""); + if (!afl->afl_env.afl_sha1_filenames) { + + queue_fn = alloc_printf( + "%s/queue/id:%06u,%s%s%s", afl->out_dir, afl->queued_items, + describe_op(afl, new_bits + is_timeout, + NAME_MAX - strlen("id:000000,")), + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + + } else { + + const char *hex = sha1_hex(mem, len); + queue_fn = alloc_printf( + "%s/queue/%s%s%s", afl->out_dir, hex, afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + ck_free((char *)hex); + + } #else @@ -542,10 +554,14 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { afl->file_extension ? (const char *)afl->file_extension : ""); #endif /* ^!SIMPLE_FILES */ - fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); - if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); } - ck_write(fd, mem, len, queue_fn); - close(fd); + fd = permissive_create(afl, queue_fn); + if (likely(fd >= 0)) { + + ck_write(fd, mem, len, queue_fn); + close(fd); + + } + add_to_queue(afl, queue_fn, len, 0); if (unlikely(afl->fuzz_mode) && @@ -743,11 +759,23 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s%s%s", afl->out_dir, - afl->saved_hangs, - describe_op(afl, 0, NAME_MAX - strlen("id:000000,")), - afl->file_extension ? "." : "", - afl->file_extension ? (const char *)afl->file_extension : ""); + if (!afl->afl_env.afl_sha1_filenames) { + + snprintf(fn, PATH_MAX, "%s/hangs/id:%06llu,%s%s%s", afl->out_dir, + afl->saved_hangs, + describe_op(afl, 0, NAME_MAX - strlen("id:000000,")), + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + + } else { + + const char *hex = sha1_hex(mem, len); + snprintf(fn, PATH_MAX, "%s/hangs/%s%s%s", afl->out_dir, hex, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + ck_free((char *)hex); + + } #else @@ -799,11 +827,23 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { #ifndef SIMPLE_FILES - snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s", - afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, - describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,")), - afl->file_extension ? "." : "", - afl->file_extension ? (const char *)afl->file_extension : ""); + if (!afl->afl_env.afl_sha1_filenames) { + + snprintf(fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%s", + afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal, + describe_op(afl, 0, NAME_MAX - strlen("id:000000,sig:00,")), + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + + } else { + + const char *hex = sha1_hex(mem, len); + snprintf(fn, PATH_MAX, "%s/crashes/%s%s%s", afl->out_dir, hex, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + ck_free((char *)hex); + + } #else @@ -873,10 +913,13 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) { /* If we're here, we apparently want to save the crash or hang test case, too. */ - fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); - if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn); } - ck_write(fd, mem, len, fn); - close(fd); + fd = permissive_create(afl, fn); + if (fd >= 0) { + + ck_write(fd, mem, len, fn); + close(fd); + + } #ifdef __linux__ if (afl->fsrv.nyx_mode && fault == FSRV_RUN_CRASH) { diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c index 01d0730d..7310e49f 100644 --- a/src/afl-fuzz-init.c +++ b/src/afl-fuzz-init.c @@ -1190,14 +1190,27 @@ void perform_dry_run(afl_state_t *afl) { #ifndef SIMPLE_FILES - snprintf( - crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%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->file_extension ? "." : "", - afl->file_extension ? (const char *)afl->file_extension : ""); + if (!afl->afl_env.afl_sha1_filenames) { + + snprintf( + crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s%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->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + + } else { + + const char *hex = sha1_hex(use_mem, read_len); + snprintf( + crash_fn, PATH_MAX, "%s/crashes/%s%s%s", afl->out_dir, hex, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + ck_free((char *)hex); + + } #else @@ -1518,10 +1531,23 @@ void pivot_inputs(afl_state_t *afl) { } - nfn = alloc_printf( - "%s/queue/id:%06u,time:0,execs:%llu,orig:%s%s%s", afl->out_dir, id, - afl->fsrv.total_execs, use_name, afl->file_extension ? "." : "", - afl->file_extension ? (const char *)afl->file_extension : ""); + if (!afl->afl_env.afl_sha1_filenames) { + + nfn = alloc_printf( + "%s/queue/id:%06u,time:0,execs:%llu,orig:%s%s%s", afl->out_dir, id, + afl->fsrv.total_execs, use_name, afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + + } else { + + const char *hex = sha1_hex_for_file(q->fname, q->len); + nfn = alloc_printf( + "%s/queue/%s%s%s", afl->out_dir, hex, + afl->file_extension ? "." : "", + afl->file_extension ? (const char *)afl->file_extension : ""); + ck_free((char *)hex); + + } u8 *pos = strrchr(nfn, '/'); no_spaces(pos + 30); @@ -1738,10 +1764,11 @@ double get_runnable_processes(void) { void nuke_resume_dir(afl_state_t *afl) { - u8 *fn; + u8 *const case_prefix = afl->afl_env.afl_sha1_filenames ? "" : CASE_PREFIX; + u8 *fn; fn = alloc_printf("%s/_resume/.state/deterministic_done", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume/.state/auto_extras", afl->out_dir); @@ -1749,11 +1776,11 @@ void nuke_resume_dir(afl_state_t *afl) { ck_free(fn); fn = alloc_printf("%s/_resume/.state/redundant_edges", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume/.state/variable_behavior", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/_resume/.state", afl->out_dir); @@ -1761,7 +1788,7 @@ void nuke_resume_dir(afl_state_t *afl) { ck_free(fn); fn = alloc_printf("%s/_resume", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); return; @@ -1778,8 +1805,9 @@ dir_cleanup_failed: static void handle_existing_out_dir(afl_state_t *afl) { - FILE *f; - u8 *fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); + u8 *const case_prefix = afl->afl_env.afl_sha1_filenames ? "" : CASE_PREFIX; + FILE *f; + u8 *fn = alloc_printf("%s/fuzzer_stats", afl->out_dir); /* See if the output directory is locked. If yes, bail out. If not, create a lock that will persist for the lifetime of the process @@ -1901,7 +1929,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { /* Next, we need to clean up <afl->out_dir>/queue/.state/ subdirectories: */ fn = alloc_printf("%s/queue/.state/deterministic_done", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/queue/.state/auto_extras", afl->out_dir); @@ -1909,11 +1937,11 @@ static void handle_existing_out_dir(afl_state_t *afl) { ck_free(fn); fn = alloc_printf("%s/queue/.state/redundant_edges", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/queue/.state/variable_behavior", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); /* Then, get rid of the .state subdirectory itself (should be empty by now) @@ -1924,7 +1952,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { ck_free(fn); fn = alloc_printf("%s/queue", afl->out_dir); - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); /* All right, let's do <afl->out_dir>/crashes/id:* and @@ -1971,7 +1999,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { #ifdef AFL_PERSISTENT_RECORD delete_files(fn, RECORD_PREFIX); #endif - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); fn = alloc_printf("%s/hangs", afl->out_dir); @@ -2006,7 +2034,7 @@ static void handle_existing_out_dir(afl_state_t *afl) { #ifdef AFL_PERSISTENT_RECORD delete_files(fn, RECORD_PREFIX); #endif - if (delete_files(fn, CASE_PREFIX)) { goto dir_cleanup_failed; } + if (delete_files(fn, case_prefix)) { goto dir_cleanup_failed; } ck_free(fn); /* And now, for some finishing touches. */ diff --git a/src/afl-fuzz-queue.c b/src/afl-fuzz-queue.c index 5987ad0c..2318df60 100644 --- a/src/afl-fuzz-queue.c +++ b/src/afl-fuzz-queue.c @@ -371,9 +371,8 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) { s32 fd; if (unlikely(afl->afl_env.afl_disable_redundant)) { q->disabled = 1; } - fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION); - if (fd < 0) { PFATAL("Unable to create '%s'", fn); } - close(fd); + fd = permissive_create(afl, fn); + if (fd >= 0) { close(fd); } } else { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ed7cb4ce..b62db1ea 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -606,6 +606,8 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem, } q->exec_us = diff_us / afl->stage_max; + if (unlikely(!q->exec_us)) { q->exec_us = 1; } + q->bitmap_size = count_bytes(afl, afl->fsrv.trace_bits); q->handicap = handicap; q->cal_failed = 0; @@ -1028,6 +1030,68 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) { if (needs_write) { + // run afl_custom_post_process + + if (unlikely(afl->custom_mutators_count) && + likely(!afl->afl_env.afl_post_process_keep_original)) { + + ssize_t new_size = q->len; + u8 *new_mem = in_buf; + 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)) { + + new_size = 0; + new_buf = new_mem; + + } else { + + new_mem = new_buf; + + } + + } + + }); + + if (unlikely(!new_size)) { + + new_size = q->len; + new_mem = in_buf; + + } + + if (unlikely(new_size < afl->min_length)) { + + new_size = afl->min_length; + + } else if (unlikely(new_size > afl->max_length)) { + + new_size = afl->max_length; + + } + + q->len = new_size; + + if (new_mem != in_buf && new_mem != NULL) { + + new_buf = afl_realloc(AFL_BUF_PARAM(out_scratch), new_size); + if (unlikely(!new_buf)) { PFATAL("alloc"); } + memcpy(new_buf, new_mem, new_size); + + in_buf = new_buf; + + } + + } + s32 fd; if (unlikely(afl->no_unlink)) { @@ -1131,4 +1195,3 @@ common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) { return 0; } - diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c index 543fdc1c..333d57b2 100644 --- a/src/afl-fuzz-state.c +++ b/src/afl-fuzz-state.c @@ -295,6 +295,9 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } else if (!strncmp(env, "AFL_DISABLE_REDUNDANT", + afl_environment_variable_len) || + !strncmp(env, "AFL_NO_REDUNDANT", + afl_environment_variable_len)) { afl->afl_env.afl_disable_redundant = @@ -626,6 +629,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) { } + } else if (!strncmp(env, "AFL_SHA1_FILENAMES", + + afl_environment_variable_len)) { + + afl->afl_env.afl_sha1_filenames = + get_afl_env(afl_environment_variables[i]) ? 1 : 0; + } } else { diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c index 755e1c50..eafeebba 100644 --- a/src/afl-fuzz-stats.c +++ b/src/afl-fuzz-stats.c @@ -321,8 +321,10 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, #ifndef __HAIKU__ if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; } #endif - u64 runtime = afl->prev_run_time + cur_time - afl->start_time; - if (!runtime) { runtime = 1; } + u64 runtime_ms = afl->prev_run_time + cur_time - afl->start_time; + u64 overhead_ms = + (afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) / 1000; + if (!runtime_ms) { runtime_ms = 1; } fprintf( f, @@ -375,20 +377,17 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg, "target_mode : %s%s%s%s%s%s%s%s%s%s\n" "command_line : %s\n", (afl->start_time /*- afl->prev_run_time*/) / 1000, cur_time / 1000, - runtime / 1000, (u32)getpid(), + runtime_ms / 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), - (runtime - - ((afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) / - 1000)) / - 1000, + (runtime_ms - MIN(runtime_ms, overhead_ms)) / 1000, afl->calibration_time_us / 1000000, afl->sync_time_us / 1000000, afl->trim_time_us / 1000000, afl->fsrv.total_execs, - afl->fsrv.total_execs / ((double)(runtime) / 1000), + afl->fsrv.total_execs / ((double)(runtime_ms) / 1000), afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored, afl->queued_discovered, afl->queued_imported, afl->queued_variable, afl->max_depth, afl->current_entry, afl->pending_favored, @@ -632,9 +631,10 @@ void show_stats_normal(afl_state_t *afl) { cur_ms = get_cur_time(); - if (afl->most_time_key) { + if (afl->most_time_key && afl->queue_cycle) { - if (afl->most_time * 1000 < cur_ms - afl->start_time) { + if (afl->most_time * 1000 + afl->sync_time_us / 1000 < + cur_ms - afl->start_time) { afl->most_time_key = 2; afl->stop_soon = 2; @@ -643,7 +643,7 @@ void show_stats_normal(afl_state_t *afl) { } - if (afl->most_execs_key == 1) { + if (afl->most_execs_key == 1 && afl->queue_cycle) { if (afl->most_execs <= afl->fsrv.total_execs) { @@ -1331,7 +1331,9 @@ void show_stats_normal(afl_state_t *afl) { sprintf(tmp, "disabled, "); - } else if (unlikely(!afl->bytes_trim_out)) { + } else if (unlikely(!afl->bytes_trim_out || + + afl->bytes_trim_in <= afl->bytes_trim_out)) { sprintf(tmp, "n/a, "); @@ -1348,7 +1350,9 @@ void show_stats_normal(afl_state_t *afl) { strcat(tmp, "disabled"); - } else if (unlikely(!afl->blocks_eff_total)) { + } else if (unlikely(!afl->blocks_eff_total || + + afl->blocks_eff_select >= afl->blocks_eff_total)) { strcat(tmp, "n/a"); @@ -1462,9 +1466,10 @@ void show_stats_pizza(afl_state_t *afl) { cur_ms = get_cur_time(); - if (afl->most_time_key) { + if (afl->most_time_key && afl->queue_cycle) { - if (afl->most_time * 1000 < cur_ms - afl->start_time) { + if (afl->most_time * 1000 + afl->sync_time_us / 1000 < + cur_ms - afl->start_time) { afl->most_time_key = 2; afl->stop_soon = 2; @@ -1473,7 +1478,7 @@ void show_stats_pizza(afl_state_t *afl) { } - if (afl->most_execs_key == 1) { + if (afl->most_execs_key == 1 && afl->queue_cycle) { if (afl->most_execs <= afl->fsrv.total_execs) { diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 329ce942..70ab983c 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1565,7 +1565,11 @@ int main(int argc, char **argv_orig, char **envp) { setenv("__AFL_OUT_DIR", afl->out_dir, 1); - if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; } + if (get_afl_env("AFL_DISABLE_TRIM") || get_afl_env("AFL_NO_TRIM")) { + + afl->disable_trim = 1; + + } if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) { @@ -1801,6 +1805,7 @@ int main(int argc, char **argv_orig, char **envp) { afl_realloc(AFL_BUF_PARAM(ex), min_alloc); afl->fsrv.use_fauxsrv = afl->non_instrumented_mode == 1 || afl->no_forkserver; + afl->fsrv.max_length = afl->max_length; #ifdef __linux__ if (!afl->fsrv.nyx_mode) { @@ -2589,13 +2594,6 @@ int main(int argc, char **argv_orig, char **envp) { sync_fuzzers(afl); - if (!afl->queue_cycle && afl->afl_env.afl_import_first) { - - // real start time, we reset, so this works correctly with -V - afl->start_time = get_cur_time(); - - } - } ++afl->queue_cycle; diff --git a/src/afl-performance.c b/src/afl-performance.c index f730ca53..6c6e3c8b 100644 --- a/src/afl-performance.c +++ b/src/afl-performance.c @@ -95,3 +95,313 @@ inline u64 hash64(u8 *key, u32 len, u64 seed) { } +// Public domain SHA1 implementation copied from: +// https://github.com/x42/liboauth/blob/7001b8256cd654952ec2515b055d2c5b243be600/src/sha1.c + +/* This code is public-domain - it is based on libcrypt + * placed in the public domain by Wei Dai and other contributors. + */ +// gcc -Wall -DSHA1TEST -o sha1test sha1.c && ./sha1test + +#include <stdint.h> +#include <string.h> + +#ifdef __BIG_ENDIAN__ + #define SHA_BIG_ENDIAN +#elif defined __LITTLE_ENDIAN__ +/* override */ +#elif defined __BYTE_ORDER + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define SHA_BIG_ENDIAN + #endif +#else // ! defined __LITTLE_ENDIAN__ + #include <endian.h> // machine/endian.h + #if __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__ + #define SHA_BIG_ENDIAN + #endif +#endif + +/* header */ + +#define HASH_LENGTH 20 +#define BLOCK_LENGTH 64 + +typedef struct sha1nfo { + + uint32_t buffer[BLOCK_LENGTH / 4]; + uint32_t state[HASH_LENGTH / 4]; + uint32_t byteCount; + uint8_t bufferOffset; + uint8_t keyBuffer[BLOCK_LENGTH]; + uint8_t innerHash[HASH_LENGTH]; + +} sha1nfo; + +/* public API - prototypes - TODO: doxygen*/ + +/** + */ +void sha1_init(sha1nfo *s); +/** + */ +void sha1_writebyte(sha1nfo *s, uint8_t data); +/** + */ +void sha1_write(sha1nfo *s, const char *data, size_t len); +/** + */ +uint8_t *sha1_result(sha1nfo *s); +/** + */ +void sha1_initHmac(sha1nfo *s, const uint8_t *key, int keyLength); +/** + */ +uint8_t *sha1_resultHmac(sha1nfo *s); + +/* code */ +#define SHA1_K0 0x5a827999 +#define SHA1_K20 0x6ed9eba1 +#define SHA1_K40 0x8f1bbcdc +#define SHA1_K60 0xca62c1d6 + +void sha1_init(sha1nfo *s) { + + s->state[0] = 0x67452301; + s->state[1] = 0xefcdab89; + s->state[2] = 0x98badcfe; + s->state[3] = 0x10325476; + s->state[4] = 0xc3d2e1f0; + s->byteCount = 0; + s->bufferOffset = 0; + +} + +uint32_t sha1_rol32(uint32_t number, uint8_t bits) { + + return ((number << bits) | (number >> (32 - bits))); + +} + +void sha1_hashBlock(sha1nfo *s) { + + uint8_t i; + uint32_t a, b, c, d, e, t; + + a = s->state[0]; + b = s->state[1]; + c = s->state[2]; + d = s->state[3]; + e = s->state[4]; + for (i = 0; i < 80; i++) { + + if (i >= 16) { + + t = s->buffer[(i + 13) & 15] ^ s->buffer[(i + 8) & 15] ^ + s->buffer[(i + 2) & 15] ^ s->buffer[i & 15]; + s->buffer[i & 15] = sha1_rol32(t, 1); + + } + + if (i < 20) { + + t = (d ^ (b & (c ^ d))) + SHA1_K0; + + } else if (i < 40) { + + t = (b ^ c ^ d) + SHA1_K20; + + } else if (i < 60) { + + t = ((b & c) | (d & (b | c))) + SHA1_K40; + + } else { + + t = (b ^ c ^ d) + SHA1_K60; + + } + + t += sha1_rol32(a, 5) + e + s->buffer[i & 15]; + e = d; + d = c; + c = sha1_rol32(b, 30); + b = a; + a = t; + + } + + s->state[0] += a; + s->state[1] += b; + s->state[2] += c; + s->state[3] += d; + s->state[4] += e; + +} + +void sha1_addUncounted(sha1nfo *s, uint8_t data) { + + uint8_t *const b = (uint8_t *)s->buffer; +#ifdef SHA_BIG_ENDIAN + b[s->bufferOffset] = data; +#else + b[s->bufferOffset ^ 3] = data; +#endif + s->bufferOffset++; + if (s->bufferOffset == BLOCK_LENGTH) { + + sha1_hashBlock(s); + s->bufferOffset = 0; + + } + +} + +void sha1_writebyte(sha1nfo *s, uint8_t data) { + + ++s->byteCount; + sha1_addUncounted(s, data); + +} + +void sha1_write(sha1nfo *s, const char *data, size_t len) { + + for (; len--;) + sha1_writebyte(s, (uint8_t)*data++); + +} + +void sha1_pad(sha1nfo *s) { + + // Implement SHA-1 padding (fips180-2 ยง5.1.1) + + // Pad with 0x80 followed by 0x00 until the end of the block + sha1_addUncounted(s, 0x80); + while (s->bufferOffset != 56) + sha1_addUncounted(s, 0x00); + + // Append length in the last 8 bytes + sha1_addUncounted(s, 0); // We're only using 32 bit lengths + sha1_addUncounted(s, 0); // But SHA-1 supports 64 bit lengths + sha1_addUncounted(s, 0); // So zero pad the top bits + sha1_addUncounted(s, s->byteCount >> 29); // Shifting to multiply by 8 + sha1_addUncounted( + s, s->byteCount >> 21); // as SHA-1 supports bitstreams as well as + sha1_addUncounted(s, s->byteCount >> 13); // byte. + sha1_addUncounted(s, s->byteCount >> 5); + sha1_addUncounted(s, s->byteCount << 3); + +} + +uint8_t *sha1_result(sha1nfo *s) { + + // Pad to complete the last block + sha1_pad(s); + +#ifndef SHA_BIG_ENDIAN + // Swap byte order back + int i; + for (i = 0; i < 5; i++) { + + s->state[i] = (((s->state[i]) << 24) & 0xff000000) | + (((s->state[i]) << 8) & 0x00ff0000) | + (((s->state[i]) >> 8) & 0x0000ff00) | + (((s->state[i]) >> 24) & 0x000000ff); + + } + +#endif + + // Return pointer to hash (20 characters) + return (uint8_t *)s->state; + +} + +#define HMAC_IPAD 0x36 +#define HMAC_OPAD 0x5c + +void sha1_initHmac(sha1nfo *s, const uint8_t *key, int keyLength) { + + uint8_t i; + memset(s->keyBuffer, 0, BLOCK_LENGTH); + if (keyLength > BLOCK_LENGTH) { + + // Hash long keys + sha1_init(s); + for (; keyLength--;) + sha1_writebyte(s, *key++); + memcpy(s->keyBuffer, sha1_result(s), HASH_LENGTH); + + } else { + + // Block length keys are used as is + memcpy(s->keyBuffer, key, keyLength); + + } + + // Start inner hash + sha1_init(s); + for (i = 0; i < BLOCK_LENGTH; i++) { + + sha1_writebyte(s, s->keyBuffer[i] ^ HMAC_IPAD); + + } + +} + +uint8_t *sha1_resultHmac(sha1nfo *s) { + + uint8_t i; + // Complete inner hash + memcpy(s->innerHash, sha1_result(s), HASH_LENGTH); + // Calculate outer hash + sha1_init(s); + for (i = 0; i < BLOCK_LENGTH; i++) + sha1_writebyte(s, s->keyBuffer[i] ^ HMAC_OPAD); + for (i = 0; i < HASH_LENGTH; i++) + sha1_writebyte(s, s->innerHash[i]); + return sha1_result(s); + +} + +// End public domain SHA1 implementation + +void sha1(const u8 *data, size_t len, u8 *out) { + + sha1nfo s; + sha1_init(&s); + sha1_write(&s, (const char *)data, len); + memcpy(out, sha1_result(&s), HASH_LENGTH); + +} + +char *sha1_hex(const u8 *data, size_t len) { + + u8 digest[HASH_LENGTH]; + sha1(data, len, digest); + u8 *hex = ck_alloc(HASH_LENGTH * 2 + 1); + for (size_t i = 0; i < HASH_LENGTH; ++i) { + + sprintf((char *)(hex + i * 2), "%02x", digest[i]); + + } + + return hex; + +} + +char *sha1_hex_for_file(const char *fname, u32 len) { + + int fd = open(fname, O_RDONLY); + if (fd < 0) { PFATAL("Unable to open '%s'", fname); } + + u32 read_len = MIN(len, (u32)MAX_FILE); + u8 *tmp = ck_alloc(read_len); + ck_read(fd, tmp, read_len, fname); + + close(fd); + + char *hex = sha1_hex(tmp, read_len); + ck_free(tmp); + return hex; + +} + diff --git a/src/afl-showmap.c b/src/afl-showmap.c index 07a4844a..7e875040 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -178,7 +178,8 @@ fsrv_run_result_t fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, void classify_counts(afl_forkserver_t *fsrv) { u8 *mem = fsrv->trace_bits; - const u8 *map = binary_mode ? count_class_binary : count_class_human; + const u8 *map = (binary_mode || collect_coverage) ? count_class_binary + : count_class_human; u32 i = map_size; @@ -240,14 +241,7 @@ static void analyze_results(afl_forkserver_t *fsrv) { u32 i; for (i = 0; i < map_size; i++) { - if (fsrv->trace_bits[i]) { - - total += fsrv->trace_bits[i]; - if (fsrv->trace_bits[i] > highest) highest = fsrv->trace_bits[i]; - // if (!coverage_map[i]) { coverage_map[i] = 1; } - coverage_map[i] |= fsrv->trace_bits[i]; - - } + if (fsrv->trace_bits[i]) { coverage_map[i] |= fsrv->trace_bits[i]; } } @@ -1339,6 +1333,8 @@ int main(int argc, char **argv_orig, char **envp) { } + if (collect_coverage) { binary_mode = false; } // ensure this + if (optind == argc || !out_file) { usage(argv[0]); } if (in_dir && in_filelist) { FATAL("you can only specify either -i or -I"); } @@ -1677,7 +1673,6 @@ int main(int argc, char **argv_orig, char **envp) { if ((coverage_map = (u8 *)malloc(map_size + 64)) == NULL) FATAL("coult not grab memory"); edges_only = false; - raw_instr_output = true; } |