Merge pull request #1759 from AFLplusplus/dev

Dev
This commit is contained in:
van Hauser
2023-06-06 17:36:04 +03:00
committed by GitHub
122 changed files with 5472 additions and 2555 deletions

View File

@ -124,7 +124,8 @@ static void usage(u8 *argv0, int more_help) {
"\n%s [ options ] -- /path/to/fuzzed_app [ ... ]\n\n"
"Required parameters:\n"
" -i dir - input directory with test cases\n"
" -i dir - input directory with test cases (or '-' to resume, "
"also see AFL_AUTORESUME)\n"
" -o dir - output directory for fuzzer findings\n\n"
"Execution control settings:\n"
@ -173,7 +174,6 @@ static void usage(u8 *argv0, int more_help) {
" pacemaker mode (minutes of no new finds). 0 = "
"immediately,\n"
" -1 = immediately and together with normal mutation.\n"
" See docs/README.MOpt.md\n"
" -c program - enable CmpLog by specifying a binary compiled for "
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
@ -269,6 +269,8 @@ static void usage(u8 *argv0, int more_help) {
"AFL_HANG_TMOUT: override timeout value (in milliseconds)\n"
"AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES: don't warn about core dump handlers\n"
"AFL_IGNORE_PROBLEMS: do not abort fuzzing if an incorrect setup is detected\n"
"AFL_IGNORE_PROBLEMS_COVERAGE: if set in addition to AFL_IGNORE_PROBLEMS - also\n"
" ignore those libs for coverage\n"
"AFL_IGNORE_TIMEOUTS: do not process or save any timeouts\n"
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
@ -302,6 +304,8 @@ static void usage(u8 *argv0, int more_help) {
PERSISTENT_MSG
"AFL_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to the queue,\n"
" but execute the post-processed one\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_TARGET_ENV: pass extra environment variables to target\n"
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
@ -336,7 +340,7 @@ static void usage(u8 *argv0, int more_help) {
}
#ifdef USE_PYTHON
SAYF("Compiled with %s module support, see docs/custom_mutator.md\n",
SAYF("Compiled with %s module support, see docs/custom_mutators.md\n",
(char *)PYTHON_VERSION);
#else
SAYF("Compiled without Python module support.\n");
@ -445,69 +449,6 @@ static void fasan_check_afl_preload(char *afl_preload) {
}
#ifdef __linux__
#include <dlfcn.h>
nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
void *handle;
nyx_plugin_handler_t *plugin = calloc(1, sizeof(nyx_plugin_handler_t));
ACTF("Trying to load libnyx.so plugin...");
handle = dlopen((char *)libnyx_binary, RTLD_NOW);
if (!handle) { goto fail; }
plugin->nyx_new = dlsym(handle, "nyx_new");
if (plugin->nyx_new == NULL) { goto fail; }
plugin->nyx_new_parent = dlsym(handle, "nyx_new_parent");
if (plugin->nyx_new_parent == NULL) { goto fail; }
plugin->nyx_new_child = dlsym(handle, "nyx_new_child");
if (plugin->nyx_new_child == NULL) { goto fail; }
plugin->nyx_shutdown = dlsym(handle, "nyx_shutdown");
if (plugin->nyx_shutdown == NULL) { goto fail; }
plugin->nyx_option_set_reload_mode =
dlsym(handle, "nyx_option_set_reload_mode");
if (plugin->nyx_option_set_reload_mode == NULL) { goto fail; }
plugin->nyx_option_set_timeout = dlsym(handle, "nyx_option_set_timeout");
if (plugin->nyx_option_set_timeout == NULL) { goto fail; }
plugin->nyx_option_apply = dlsym(handle, "nyx_option_apply");
if (plugin->nyx_option_apply == NULL) { goto fail; }
plugin->nyx_set_afl_input = dlsym(handle, "nyx_set_afl_input");
if (plugin->nyx_set_afl_input == NULL) { goto fail; }
plugin->nyx_exec = dlsym(handle, "nyx_exec");
if (plugin->nyx_exec == NULL) { goto fail; }
plugin->nyx_get_bitmap_buffer = dlsym(handle, "nyx_get_bitmap_buffer");
if (plugin->nyx_get_bitmap_buffer == NULL) { goto fail; }
plugin->nyx_get_bitmap_buffer_size =
dlsym(handle, "nyx_get_bitmap_buffer_size");
if (plugin->nyx_get_bitmap_buffer_size == NULL) { goto fail; }
plugin->nyx_get_aux_string = dlsym(handle, "nyx_get_aux_string");
if (plugin->nyx_get_aux_string == NULL) { goto fail; }
OKF("libnyx plugin is ready!");
return plugin;
fail:
FATAL("failed to load libnyx: %s\n", dlerror());
free(plugin);
return NULL;
}
#endif
/* Main entry point */
int main(int argc, char **argv_orig, char **envp) {
@ -1383,16 +1324,16 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->fsrv.mem_limit && afl->shm.cmplog_mode) afl->fsrv.mem_limit += 260;
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
"Eißfeldt, Andrea Fioraldi and Dominik Maier");
OKF("afl++ is open source, get it at "
OKF("AFL++ is maintained by Marc \"van Hauser\" Heuse, Dominik Maier, Andrea "
"Fioraldi and Heiko \"hexcoder\" Eißfeldt");
OKF("AFL++ is open source, get it at "
"https://github.com/AFLplusplus/AFLplusplus");
OKF("NOTE: afl++ >= v3 has changed defaults and behaviours - see README.md");
OKF("NOTE: AFL++ >= v3 has changed defaults and behaviours - see README.md");
#ifdef __linux__
if (afl->fsrv.nyx_mode) {
OKF("afl++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
OKF("AFL++ Nyx mode is enabled (developed and mainted by Sergej Schumilo)");
OKF("Nyx is open source, get it at https://github.com/Nyx-Fuzz");
}
@ -1632,29 +1573,6 @@ int main(int argc, char **argv_orig, char **envp) {
}
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
if (afl->custom_only) {
FATAL("Custom mutators are incompatible with MOpt (-L)");
}
u32 custom_fuzz = 0;
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if (el->afl_custom_fuzz) { custom_fuzz = 1; }
});
if (custom_fuzz) {
WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
}
}
if (afl->afl_env.afl_max_det_extras) {
s32 max_det_extras = atoi(afl->afl_env.afl_max_det_extras);
@ -1871,16 +1789,6 @@ int main(int argc, char **argv_orig, char **envp) {
check_if_tty(afl);
if (afl->afl_env.afl_force_ui) { afl->not_on_tty = 0; }
if (afl->afl_env.afl_custom_mutator_only) {
/* This ensures we don't proceed to havoc/splice */
afl->custom_only = 1;
/* Ensure we also skip all deterministic steps */
afl->skip_deterministic = 1;
}
get_core_count(afl);
atexit(at_exit);
@ -1929,8 +1837,107 @@ int main(int argc, char **argv_orig, char **envp) {
printf("DEBUG: rand %06d is %u\n", counter, rand_below(afl, 65536));
#endif
if (!getenv("AFL_CUSTOM_INFO_PROGRAM")) {
setenv("AFL_CUSTOM_INFO_PROGRAM", argv[optind], 1);
}
if (!getenv("AFL_CUSTOM_INFO_PROGRAM_INPUT") && afl->fsrv.out_file) {
setenv("AFL_CUSTOM_INFO_PROGRAM_INPUT", afl->fsrv.out_file, 1);
}
if (!getenv("AFL_CUSTOM_INFO_PROGRAM_ARGV")) {
u8 envbuf[8096] = "", tmpbuf[8096] = "";
for (s32 i = optind + 1; i < argc; ++i) {
strcpy(tmpbuf, envbuf);
if (strchr(argv[i], ' ') && !strchr(argv[i], '"') &&
!strchr(argv[i], '\'')) {
if (!strchr(argv[i], '\'')) {
snprintf(envbuf, sizeof(tmpbuf), "%s '%s'", tmpbuf, argv[i]);
} else {
snprintf(envbuf, sizeof(tmpbuf), "%s \"%s\"", tmpbuf, argv[i]);
}
} else {
snprintf(envbuf, sizeof(tmpbuf), "%s %s", tmpbuf, argv[i]);
}
}
setenv("AFL_CUSTOM_INFO_PROGRAM_ARGV", envbuf + 1, 1);
}
if (!getenv("AFL_CUSTOM_INFO_OUT")) {
setenv("AFL_CUSTOM_INFO_OUT", afl->out_dir, 1); // same as __AFL_OUT_DIR
}
setup_custom_mutators(afl);
if (afl->afl_env.afl_custom_mutator_only) {
if (!afl->custom_mutators_count) {
if (afl->shm.cmplog_mode) {
WARNF(
"No custom mutator loaded, using AFL_CUSTOM_MUTATOR_ONLY is "
"pointless and only allowed now to allow experiments with CMPLOG.");
} else {
FATAL(
"No custom mutator loaded but AFL_CUSTOM_MUTATOR_ONLY specified.");
}
}
/* This ensures we don't proceed to havoc/splice */
afl->custom_only = 1;
/* Ensure we also skip all deterministic steps */
afl->skip_deterministic = 1;
}
if (afl->limit_time_sig > 0 && afl->custom_mutators_count) {
if (afl->custom_only) {
FATAL("Custom mutators are incompatible with MOpt (-L)");
}
u32 custom_fuzz = 0;
LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, {
if (el->afl_custom_fuzz) { custom_fuzz = 1; }
});
if (custom_fuzz) {
WARNF("afl_custom_fuzz is incompatible with MOpt (-L)");
}
}
write_setup_file(afl, argc, argv);
setup_cmdline_file(afl, argv + optind);
@ -2082,6 +2089,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->non_instrumented_mode || afl->fsrv.qemu_mode ||
afl->fsrv.frida_mode || afl->fsrv.cs_mode || afl->unicorn_mode) {
u32 old_map_size = map_size;
map_size = afl->fsrv.real_map_size = afl->fsrv.map_size = MAP_SIZE;
afl->virgin_bits = ck_realloc(afl->virgin_bits, map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, map_size);
@ -2093,6 +2101,18 @@ int main(int argc, char **argv_orig, char **envp) {
afl->first_trace = ck_realloc(afl->first_trace, map_size);
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, map_size);
if (old_map_size < map_size) {
memset(afl->var_bytes + old_map_size, 0, map_size - old_map_size);
memset(afl->top_rated + old_map_size, 0, map_size - old_map_size);
memset(afl->clean_trace + old_map_size, 0, map_size - old_map_size);
memset(afl->clean_trace_custom + old_map_size, 0,
map_size - old_map_size);
memset(afl->first_trace + old_map_size, 0, map_size - old_map_size);
memset(afl->map_tmp_buf + old_map_size, 0, map_size - old_map_size);
}
}
afl->argv = use_argv;
@ -2120,6 +2140,7 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Re-initializing maps to %u bytes", new_map_size);
u32 old_map_size = map_size;
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
@ -2132,6 +2153,18 @@ int main(int argc, char **argv_orig, char **envp) {
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
if (old_map_size < new_map_size) {
memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
memset(afl->clean_trace_custom + old_map_size, 0,
new_map_size - old_map_size);
memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
}
afl_fsrv_kill(&afl->fsrv);
afl_shm_deinit(&afl->shm);
afl->fsrv.map_size = new_map_size;
@ -2182,6 +2215,7 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Re-initializing maps to %u bytes due cmplog", new_map_size);
u32 old_map_size = map_size;
afl->virgin_bits = ck_realloc(afl->virgin_bits, new_map_size);
afl->virgin_tmout = ck_realloc(afl->virgin_tmout, new_map_size);
afl->virgin_crash = ck_realloc(afl->virgin_crash, new_map_size);
@ -2194,6 +2228,18 @@ int main(int argc, char **argv_orig, char **envp) {
afl->first_trace = ck_realloc(afl->first_trace, new_map_size);
afl->map_tmp_buf = ck_realloc(afl->map_tmp_buf, new_map_size);
if (old_map_size < new_map_size) {
memset(afl->var_bytes + old_map_size, 0, new_map_size - old_map_size);
memset(afl->top_rated + old_map_size, 0, new_map_size - old_map_size);
memset(afl->clean_trace + old_map_size, 0, new_map_size - old_map_size);
memset(afl->clean_trace_custom + old_map_size, 0,
new_map_size - old_map_size);
memset(afl->first_trace + old_map_size, 0, new_map_size - old_map_size);
memset(afl->map_tmp_buf + old_map_size, 0, new_map_size - old_map_size);
}
afl_fsrv_kill(&afl->fsrv);
afl_fsrv_kill(&afl->cmplog_fsrv);
afl_shm_deinit(&afl->shm);
@ -2293,14 +2339,6 @@ int main(int argc, char **argv_orig, char **envp) {
if (!afl->pending_not_fuzzed || !valid_seeds) {
#ifdef __linux__
if (afl->fsrv.nyx_mode) {
afl->fsrv.nyx_handlers->nyx_shutdown(afl->fsrv.nyx_runner);
}
#endif
FATAL("We need at least one valid input seed that does not crash!");
}