diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/afl-cc.c | 26 | ||||
-rw-r--r-- | src/afl-fuzz-mutators.c | 66 | ||||
-rw-r--r-- | src/afl-fuzz-python.c | 31 | ||||
-rw-r--r-- | src/afl-fuzz-redqueen.c | 29 | ||||
-rw-r--r-- | src/afl-fuzz-run.c | 50 | ||||
-rw-r--r-- | src/afl-fuzz.c | 9 | ||||
-rw-r--r-- | src/afl-showmap.c | 16 |
7 files changed, 214 insertions, 13 deletions
diff --git a/src/afl-cc.c b/src/afl-cc.c index cd2061e6..1c3b5405 100644 --- a/src/afl-cc.c +++ b/src/afl-cc.c @@ -514,7 +514,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (lto_mode && have_instr_env) { #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf( "-fpass-plugin=%s/afl-llvm-lto-instrumentlist.so", obj_path); #else @@ -530,7 +532,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (getenv("AFL_LLVM_DICT2FILE")) { #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-dict2file.so", obj_path); #else @@ -547,7 +551,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (getenv("LAF_SPLIT_SWITCHES") || getenv("AFL_LLVM_LAF_SPLIT_SWITCHES")) { #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); #else @@ -564,7 +570,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { getenv("AFL_LLVM_LAF_TRANSFORM_COMPARES")) { #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/compare-transform-pass.so", obj_path); #else @@ -581,7 +589,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { getenv("AFL_LLVM_LAF_SPLIT_FLOATS")) { #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/split-compares-pass.so", obj_path); #else @@ -604,10 +614,14 @@ static void edit_params(u32 argc, char **argv, char **envp) { cc_params[cc_par_cnt++] = "-fno-inline"; #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/cmplog-switches-pass.so", obj_path); + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/split-switches-pass.so", obj_path); #else @@ -705,7 +719,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf( "-fpass-plugin=%s/SanitizerCoveragePCGUARD.so", obj_path); #else @@ -743,7 +759,9 @@ static void edit_params(u32 argc, char **argv, char **envp) { } else { #if LLVM_MAJOR >= 11 /* use new pass manager */ + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/afl-llvm-pass.so", obj_path); #else @@ -761,10 +779,14 @@ static void edit_params(u32 argc, char **argv, char **envp) { if (cmplog_mode) { #if LLVM_MAJOR >= 11 + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf( "-fpass-plugin=%s/cmplog-instructions-pass.so", obj_path); + #if LLVM_MAJOR < 16 cc_params[cc_par_cnt++] = "-fexperimental-new-pass-manager"; + #endif cc_params[cc_par_cnt++] = alloc_printf("-fpass-plugin=%s/cmplog-routines-pass.so", obj_path); #else @@ -1144,6 +1166,7 @@ static void edit_params(u32 argc, char **argv, char **envp) { "({ static volatile char *_B __attribute__((used,unused)); " " _B = (char*)\"" PERSIST_SIG "\"; " + "extern int __afl_connected;" #ifdef __APPLE__ "__attribute__((visibility(\"default\"))) " "int _L(unsigned int) __asm__(\"___afl_persistent_loop\"); " @@ -1151,7 +1174,8 @@ static void edit_params(u32 argc, char **argv, char **envp) { "__attribute__((visibility(\"default\"))) " "int _L(unsigned int) __asm__(\"__afl_persistent_loop\"); " #endif /* ^__APPLE__ */ - "_L(_A); })"; + // if afl is connected, we run _A times, else once. + "_L(__afl_connected ? _A : 1); })"; cc_params[cc_par_cnt++] = "-D__AFL_INIT()=" diff --git a/src/afl-fuzz-mutators.c b/src/afl-fuzz-mutators.c index b9daebfa..ef30b993 100644 --- a/src/afl-fuzz-mutators.c +++ b/src/afl-fuzz-mutators.c @@ -211,8 +211,16 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { WARNF("Symbol 'afl_custom_mutator' not found."); + } else { + + OKF("Found 'afl_custom_mutator'."); + } + } else { + + OKF("Found 'afl_custom_mutator'."); + } /* "afl_custom_introspection", optional */ @@ -222,6 +230,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_introspection' not found."); + } else { + + OKF("Found 'afl_custom_introspection'."); + } #endif @@ -232,6 +244,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_fuzz_count' not found."); + } else { + + OKF("Found 'afl_custom_fuzz_count'."); + } /* "afl_custom_deinit", optional for backward compatibility */ @@ -248,6 +264,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_post_process' not found."); + } else { + + OKF("Found 'afl_custom_post_process'."); + } u8 notrim = 0; @@ -258,6 +278,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { notrim = 1; ACTF("optional symbol 'afl_custom_init_trim' not found."); + } else { + + OKF("Found 'afl_custom_init_trim'."); + } /* "afl_custom_trim", optional */ @@ -267,6 +291,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { notrim = 1; ACTF("optional symbol 'afl_custom_trim' not found."); + } else { + + OKF("Found 'afl_custom_trim'."); + } /* "afl_custom_post_trim", optional */ @@ -276,6 +304,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { notrim = 1; ACTF("optional symbol 'afl_custom_post_trim' not found."); + } else { + + OKF("Found 'afl_custom_post_trim'."); + } if (notrim) { @@ -295,6 +327,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_havoc_mutation' not found."); + } else { + + OKF("Found 'afl_custom_havoc_mutation'."); + } /* "afl_custom_havoc_mutation", optional */ @@ -304,6 +340,10 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_havoc_mutation_probability' not found."); + } else { + + OKF("Found 'afl_custom_havoc_mutation_probability'."); + } /* "afl_custom_queue_get", optional */ @@ -312,6 +352,22 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_queue_get' not found."); + } else { + + OKF("Found 'afl_custom_queue_get'."); + + } + + /* "afl_custom_fuzz_send", optional */ + mutator->afl_custom_fuzz_send = dlsym(dh, "afl_custom_fuzz_send"); + if (!mutator->afl_custom_fuzz_send) { + + ACTF("optional symbol 'afl_custom_fuzz_send' not found."); + + } else { + + OKF("Found 'afl_custom_fuzz_send'."); + } /* "afl_custom_queue_new_entry", optional */ @@ -320,13 +376,21 @@ struct custom_mutator *load_custom_mutator(afl_state_t *afl, const char *fn) { ACTF("optional symbol 'afl_custom_queue_new_entry' not found"); + } else { + + OKF("Found 'afl_custom_queue_new_entry'."); + } /* "afl_custom_describe", optional */ mutator->afl_custom_describe = dlsym(dh, "afl_custom_describe"); if (!mutator->afl_custom_describe) { - ACTF("Symbol 'afl_custom_describe' not found."); + ACTF("optional symbol 'afl_custom_describe' not found."); + + } else { + + OKF("Found 'afl_custom_describe'."); } diff --git a/src/afl-fuzz-python.c b/src/afl-fuzz-python.c index a43d80bb..d8aed8c6 100644 --- a/src/afl-fuzz-python.c +++ b/src/afl-fuzz-python.c @@ -246,6 +246,8 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) { PyObject_GetAttrString(py_module, "havoc_mutation_probability"); py_functions[PY_FUNC_QUEUE_GET] = PyObject_GetAttrString(py_module, "queue_get"); + py_functions[PY_FUNC_FUZZ_SEND] = + PyObject_GetAttrString(py_module, "fuzz_send"); py_functions[PY_FUNC_QUEUE_NEW_ENTRY] = PyObject_GetAttrString(py_module, "queue_new_entry"); py_functions[PY_FUNC_INTROSPECTION] = @@ -466,6 +468,12 @@ struct custom_mutator *load_custom_mutator_py(afl_state_t *afl, } + if (py_functions[PY_FUNC_FUZZ_SEND]) { + + mutator->afl_custom_fuzz_send = fuzz_send_py; + + } + if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) { mutator->afl_custom_queue_new_entry = queue_new_entry_py; @@ -893,6 +901,29 @@ u8 queue_get_py(void *py_mutator, const u8 *filename) { } +void fuzz_send_py(void *py_mutator, const u8 *buf, size_t buf_size) { + + PyObject *py_args, *py_value; + + py_args = PyTuple_New(1); + py_value = PyByteArray_FromStringAndSize(buf, buf_size); + if (!py_value) { + + Py_DECREF(py_args); + FATAL("Failed to convert arguments"); + + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyObject_CallObject( + ((py_mutator_t *)py_mutator)->py_functions[PY_FUNC_FUZZ_SEND], py_args); + Py_DECREF(py_args); + + if (py_value != NULL) { Py_DECREF(py_value); } + +} + u8 queue_new_entry_py(void *py_mutator, const u8 *filename_new_queue, const u8 *filename_orig_queue) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index 337f124d..0dae26a3 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -167,6 +167,25 @@ static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) { } +/* replace everything with different values */ +static void random_replace(afl_state_t *afl, u8 *buf, u32 len) { + + for (u32 i = 0; i < len; i++) { + + u8 c; + + do { + + c = rand_below(afl, 256); + + } while (c == buf[i]); + + buf[i] = c; + + } + +} + /* replace everything with different values but stay in the same type */ static void type_replace(afl_state_t *afl, u8 *buf, u32 len) { @@ -293,7 +312,15 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, memcpy(backup, buf, len); memcpy(changed, buf, len); - type_replace(afl, changed, len); + if (afl->cmplog_random_colorization) { + + random_replace(afl, changed, len); + + } else { + + type_replace(afl, changed, len); + + } while ((rng = pop_biggest_range(&ranges)) != NULL && afl->stage_cur < afl->stage_max) { diff --git a/src/afl-fuzz-run.c b/src/afl-fuzz-run.c index ee4a3298..7f9c3bf3 100644 --- a/src/afl-fuzz-run.c +++ b/src/afl-fuzz-run.c @@ -76,6 +76,8 @@ fuzz_run_target(afl_state_t *afl, afl_forkserver_t *fsrv, u32 timeout) { u32 __attribute__((hot)) write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { + u8 sent = 0; + if (unlikely(afl->custom_mutators_count)) { ssize_t new_size = len; @@ -133,9 +135,28 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { if (new_mem != *mem) { *mem = new_mem; } - /* everything as planned. use the potentially new data. */ - afl_fsrv_write_to_testcase(&afl->fsrv, *mem, new_size); - len = new_size; + if (unlikely(afl->custom_mutators_count)) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + el->afl_custom_fuzz_send(el->data, *mem, new_size); + sent = 1; + + } + + }); + + } + + if (likely(!sent)) { + + /* everything as planned. use the potentially new data. */ + afl_fsrv_write_to_testcase(&afl->fsrv, *mem, new_size); + len = new_size; + + } } else { @@ -149,8 +170,27 @@ write_to_testcase(afl_state_t *afl, void **mem, u32 len, u32 fix) { } - /* boring uncustom. */ - afl_fsrv_write_to_testcase(&afl->fsrv, *mem, len); + if (unlikely(afl->custom_mutators_count)) { + + LIST_FOREACH(&afl->custom_mutator_list, struct custom_mutator, { + + if (el->afl_custom_fuzz_send) { + + el->afl_custom_fuzz_send(el->data, *mem, len); + sent = 1; + + } + + }); + + } + + if (likely(!sent)) { + + /* boring uncustom. */ + afl_fsrv_write_to_testcase(&afl->fsrv, *mem, len); + + } } diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index acb0b2ec..a81cab7d 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -171,10 +171,11 @@ static void usage(u8 *argv0, int more_help) { " if using QEMU/FRIDA or the fuzzing target is " "compiled\n" " for CmpLog then just use -c 0.\n" - " -l cmplog_opts - CmpLog configuration values (e.g. \"2AT\"):\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\n" + " A=arithmetic solving, T=transformational solving,\n" + " R=random colorization bytes.\n\n" "Fuzzing behavior settings:\n" " -Z - sequential queue selection instead of weighted " "random\n" @@ -1113,6 +1114,10 @@ int main(int argc, char **argv_orig, char **envp) { case 'T': afl->cmplog_enable_transform = 1; break; + case 'r': + case 'R': + afl->cmplog_random_colorization = 1; + break; default: FATAL("Unknown option value '%c' in -l %s", *c, optarg); diff --git a/src/afl-showmap.c b/src/afl-showmap.c index b1b548e5..93339a8f 100644 --- a/src/afl-showmap.c +++ b/src/afl-showmap.c @@ -515,11 +515,11 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) { it.it_value.tv_sec = (fsrv->exec_tmout / 1000); it.it_value.tv_usec = (fsrv->exec_tmout % 1000) * 1000; - } + signal(SIGALRM, kill_child); - signal(SIGALRM, kill_child); + setitimer(ITIMER_REAL, &it, NULL); - setitimer(ITIMER_REAL, &it, NULL); + } if (waitpid(fsrv->child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); } @@ -1016,6 +1016,16 @@ int main(int argc, char **argv_orig, char **envp) { } + } else { + + // The forkserver code does not have a way to completely + // disable the timeout, so we'll use a very, very long + // timeout instead. + WARNF( + "Setting an execution timeout of 120 seconds ('none' is not " + "allowed)."); + fsrv->exec_tmout = 120 * 1000; + } break; |