diff options
author | Andrea Fioraldi <andreafioraldi@gmail.com> | 2019-08-30 13:10:04 +0200 |
---|---|---|
committer | Andrea Fioraldi <andreafioraldi@gmail.com> | 2019-08-30 13:10:04 +0200 |
commit | 4f3c417753c7ff40023fcbb2958eb6109ebdd575 (patch) | |
tree | 8f7f55ec402549fd986117c37669f1272b2493fb /src | |
parent | 113fc168ab02f5241522a74c06bc8fb21fcafc55 (diff) | |
download | afl++-4f3c417753c7ff40023fcbb2958eb6109ebdd575.tar.gz |
remave the afl-fuzz folder to afl-fuzz-src due to gitignore
Diffstat (limited to 'src')
-rw-r--r-- | src/afl-fuzz-src/afl-fuzz.c (renamed from src/afl-fuzz/afl-fuzz.c) | 0 | ||||
-rw-r--r-- | src/afl-fuzz-src/globals.c | 282 | ||||
-rw-r--r-- | src/afl-fuzz-src/python.c | 223 |
3 files changed, 505 insertions, 0 deletions
diff --git a/src/afl-fuzz/afl-fuzz.c b/src/afl-fuzz-src/afl-fuzz.c index b93c17c8..b93c17c8 100644 --- a/src/afl-fuzz/afl-fuzz.c +++ b/src/afl-fuzz-src/afl-fuzz.c diff --git a/src/afl-fuzz-src/globals.c b/src/afl-fuzz-src/globals.c new file mode 100644 index 00000000..127d7609 --- /dev/null +++ b/src/afl-fuzz-src/globals.c @@ -0,0 +1,282 @@ +/* + american fuzzy lop - fuzzer code + -------------------------------- + + Written and maintained by Michal Zalewski <lcamtuf@google.com> + + Forkserver design by Jann Horn <jannhorn@googlemail.com> + + Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This is the real deal: the program takes an instrumented binary and + attempts a variety of basic fuzzing tricks, paying close attention to + how they affect the execution path. + + */ + +#include "afl-fuzz.h" + +/* MOpt: + Lots of globals, but mostly for the status UI and other things where it + really makes no sense to haul them around as function parameters. */ +u64 limit_time_puppet, + orig_hit_cnt_puppet, + last_limit_time_start, + tmp_pilot_time, + total_pacemaker_time, + total_puppet_find, + temp_puppet_find, + most_time_key, + most_time, + most_execs_key, + most_execs, + old_hit_count; + +s32 SPLICE_CYCLES_puppet, + limit_time_sig, + key_puppet, + key_module; + +double w_init = 0.9, + w_end = 0.3, + w_now; + +s32 g_now; +s32 g_max = 5000; + +u64 tmp_core_time; +s32 swarm_now; + +double x_now[swarm_num][operator_num], + L_best[swarm_num][operator_num], + eff_best[swarm_num][operator_num], + G_best[operator_num], + v_now[swarm_num][operator_num], + probability_now[swarm_num][operator_num], + swarm_fitness[swarm_num]; + +u64 stage_finds_puppet[swarm_num][operator_num], /* Patterns found per fuzz stage */ + stage_finds_puppet_v2[swarm_num][operator_num], + stage_cycles_puppet_v2[swarm_num][operator_num], + stage_cycles_puppet_v3[swarm_num][operator_num], + stage_cycles_puppet[swarm_num][operator_num], + operator_finds_puppet[operator_num], + core_operator_finds_puppet[operator_num], + core_operator_finds_puppet_v2[operator_num], + core_operator_cycles_puppet[operator_num], + core_operator_cycles_puppet_v2[operator_num], + core_operator_cycles_puppet_v3[operator_num]; /* Execs per fuzz stage */ + +double period_pilot_tmp = 5000.0; +s32 key_lv; + +u8 *in_dir, /* Input directory with test cases */ + *out_dir, /* Working & output directory */ + *tmp_dir , /* Temporary directory for input */ + *sync_dir, /* Synchronization directory */ + *sync_id, /* Fuzzer ID */ + *power_name, /* Power schedule name */ + *use_banner, /* Display banner */ + *in_bitmap, /* Input bitmap */ + *file_extension, /* File extension */ + *orig_cmdline; /* Original command line */ +u8 *doc_path, /* Path to documentation dir */ + *target_path, /* Path to target binary */ + *out_file; /* File to fuzz, if any */ + +u32 exec_tmout = EXEC_TIMEOUT; /* Configurable exec timeout (ms) */ +u32 hang_tmout = EXEC_TIMEOUT; /* Timeout used for hang det (ms) */ + +u64 mem_limit = MEM_LIMIT; /* Memory cap for child (MB) */ + +u8 cal_cycles = CAL_CYCLES, /* Calibration cycles defaults */ + cal_cycles_long = CAL_CYCLES_LONG, + debug, /* Debug mode */ + python_only; /* Python-only mode */ + +u32 stats_update_freq = 1; /* Stats update frequency (execs) */ + +char *power_names[POWER_SCHEDULES_NUM] = { + "explore", + "fast", + "coe", + "lin", + "quad", + "exploit" +}; + +u8 schedule = EXPLORE; /* Power schedule (default: EXPLORE)*/ +u8 havoc_max_mult = HAVOC_MAX_MULT; + +u8 skip_deterministic, /* Skip deterministic stages? */ + force_deterministic, /* Force deterministic stages? */ + use_splicing, /* Recombine input files? */ + dumb_mode, /* Run in non-instrumented mode? */ + score_changed, /* Scoring for favorites changed? */ + kill_signal, /* Signal that killed the child */ + resuming_fuzz, /* Resuming an older fuzzing job? */ + timeout_given, /* Specific timeout given? */ + not_on_tty, /* stdout is not a tty */ + term_too_small, /* terminal dimensions too small */ + no_forkserver, /* Disable forkserver? */ + crash_mode, /* Crash mode! Yeah! */ + in_place_resume, /* Attempt in-place resume? */ + auto_changed, /* Auto-generated tokens changed? */ + no_cpu_meter_red, /* Feng shui on the status screen */ + no_arith, /* Skip most arithmetic ops */ + shuffle_queue, /* Shuffle input queue? */ + bitmap_changed = 1, /* Time to update bitmap? */ + qemu_mode, /* Running in QEMU mode? */ + unicorn_mode, /* Running in Unicorn mode? */ + skip_requested, /* Skip request, via SIGUSR1 */ + run_over10m, /* Run time over 10 minutes? */ + persistent_mode, /* Running in persistent mode? */ + deferred_mode, /* Deferred forkserver mode? */ + fixed_seed, /* do not reseed */ + fast_cal, /* Try to calibrate faster? */ + uses_asan; /* Target uses ASAN? */ + +s32 out_fd, /* Persistent fd for out_file */ +#ifndef HAVE_ARC4RANDOM + dev_urandom_fd = -1, /* Persistent fd for /dev/urandom */ +#endif + dev_null_fd = -1, /* Persistent fd for /dev/null */ + fsrv_ctl_fd, /* Fork server control pipe (write) */ + fsrv_st_fd; /* Fork server status pipe (read) */ + + s32 forksrv_pid, /* PID of the fork server */ + child_pid = -1, /* PID of the fuzzed program */ + out_dir_fd = -1; /* FD of the lock file */ + + u8* trace_bits; /* SHM with instrumentation bitmap */ + +u8 virgin_bits[MAP_SIZE], /* Regions yet untouched by fuzzing */ + virgin_tmout[MAP_SIZE], /* Bits we haven't seen in tmouts */ + virgin_crash[MAP_SIZE]; /* Bits we haven't seen in crashes */ + +u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */ + +volatile u8 stop_soon, /* Ctrl-C pressed? */ + clear_screen = 1, /* Window resized? */ + child_timed_out; /* Traced process timed out? */ + +u32 queued_paths, /* Total number of queued testcases */ + queued_variable, /* Testcases with variable behavior */ + queued_at_start, /* Total number of initial inputs */ + queued_discovered, /* Items discovered during this run */ + queued_imported, /* Items imported via -S */ + queued_favored, /* Paths deemed favorable */ + queued_with_cov, /* Paths with new coverage bytes */ + pending_not_fuzzed, /* Queued but not done yet */ + pending_favored, /* Pending favored paths */ + cur_skipped_paths, /* Abandoned inputs in cur cycle */ + cur_depth, /* Current path depth */ + max_depth, /* Max path depth */ + useless_at_start, /* Number of useless starting paths */ + var_byte_count, /* Bitmap bytes with var behavior */ + current_entry, /* Current queue entry ID */ + havoc_div = 1; /* Cycle count divisor for havoc */ + +u64 total_crashes, /* Total number of crashes */ + unique_crashes, /* Crashes with unique signatures */ + total_tmouts, /* Total number of timeouts */ + unique_tmouts, /* Timeouts with unique signatures */ + unique_hangs, /* Hangs with unique signatures */ + total_execs, /* Total execve() calls */ + start_time, /* Unix start time (ms) */ + last_path_time, /* Time for most recent path (ms) */ + last_crash_time, /* Time for most recent crash (ms) */ + last_hang_time, /* Time for most recent hang (ms) */ + last_crash_execs, /* Exec counter at last crash */ + queue_cycle, /* Queue round counter */ + cycles_wo_finds, /* Cycles without any new paths */ + trim_execs, /* Execs done to trim input files */ + bytes_trim_in, /* Bytes coming into the trimmer */ + bytes_trim_out, /* Bytes coming outa the trimmer */ + blocks_eff_total, /* Blocks subject to effector maps */ + blocks_eff_select; /* Blocks selected as fuzzable */ + +u32 subseq_tmouts; /* Number of timeouts in a row */ + +u8 *stage_name = "init", /* Name of the current fuzz stage */ + *stage_short, /* Short stage name */ + *syncing_party; /* Currently syncing with... */ + +s32 stage_cur, stage_max; /* Stage progression */ +s32 splicing_with = -1; /* Splicing with which test case? */ + +u32 master_id, master_max; /* Master instance job splitting */ + +u32 syncing_case; /* Syncing with case #... */ + +s32 stage_cur_byte, /* Byte offset of current stage op */ + stage_cur_val; /* Value used for stage op */ + +u8 stage_val_type; /* Value type (STAGE_VAL_*) */ + +u64 stage_finds[32], /* Patterns found per fuzz stage */ + stage_cycles[32]; /* Execs per fuzz stage */ + +#ifndef HAVE_ARC4RANDOM +u32 rand_cnt; /* Random number counter */ +#endif + +u64 total_cal_us, /* Total calibration time (us) */ + total_cal_cycles; /* Total calibration cycles */ + +u64 total_bitmap_size, /* Total bit count for all bitmaps */ + total_bitmap_entries; /* Number of bitmaps counted */ + +s32 cpu_core_count; /* CPU core count */ + +#ifdef HAVE_AFFINITY + +s32 cpu_aff = -1; /* Selected CPU core */ + +#endif /* HAVE_AFFINITY */ + +FILE* plot_file; /* Gnuplot output file */ + + + +struct queue_entry *queue, /* Fuzzing queue (linked list) */ + *queue_cur, /* Current offset within the queue */ + *queue_top, /* Top of the list */ + *q_prev100; /* Previous 100 marker */ + +struct queue_entry* + top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */ + +struct extra_data* extras; /* Extra tokens to fuzz with */ +u32 extras_cnt; /* Total number of tokens read */ + +struct extra_data* a_extras; /* Automatically selected extras */ +u32 a_extras_cnt; /* Total number of tokens available */ + +u8* (*post_handler)(u8* buf, u32* len); + +/* hooks for the custom mutator function */ +size_t (*custom_mutator)(u8 *data, size_t size, u8* mutated_out, size_t max_size, unsigned int seed); +size_t (*pre_save_handler)(u8 *data, size_t size, u8 **new_data); + + +/* Interesting values, as per config.h */ + +s8 interesting_8[] = { INTERESTING_8 }; +s16 interesting_16[] = { INTERESTING_8, INTERESTING_16 }; +s32 interesting_32[] = { INTERESTING_8, INTERESTING_16, INTERESTING_32 }; + +/* Python stuff */ +#ifdef USE_PYTHON + +PyObject *py_module; +PyObject *py_functions[PY_FUNC_COUNT]; + +#endif + diff --git a/src/afl-fuzz-src/python.c b/src/afl-fuzz-src/python.c new file mode 100644 index 00000000..74ffc524 --- /dev/null +++ b/src/afl-fuzz-src/python.c @@ -0,0 +1,223 @@ +/* + american fuzzy lop - fuzzer code + -------------------------------- + + Written and maintained by Michal Zalewski <lcamtuf@google.com> + + Forkserver design by Jann Horn <jannhorn@googlemail.com> + + Copyright 2013, 2014, 2015, 2016, 2017 Google Inc. All rights reserved. + + Licensed under the Apache License, Version 2.0 (the "License"); + you may not use this file except in compliance with the License. + You may obtain a copy of the License at: + + http://www.apache.org/licenses/LICENSE-2.0 + + This is the real deal: the program takes an instrumented binary and + attempts a variety of basic fuzzing tricks, paying close attention to + how they affect the execution path. + + */ + +#include "afl-fuzz.h" + +/* Python stuff */ +#ifdef USE_PYTHON + +int init_py() { + Py_Initialize(); + u8* module_name = getenv("AFL_PYTHON_MODULE"); + + if (module_name) { + PyObject* py_name = PyString_FromString(module_name); + + py_module = PyImport_Import(py_name); + Py_DECREF(py_name); + + if (py_module != NULL) { + u8 py_notrim = 0; + py_functions[PY_FUNC_INIT] = PyObject_GetAttrString(py_module, "init"); + py_functions[PY_FUNC_FUZZ] = PyObject_GetAttrString(py_module, "fuzz"); + py_functions[PY_FUNC_INIT_TRIM] = PyObject_GetAttrString(py_module, "init_trim"); + py_functions[PY_FUNC_POST_TRIM] = PyObject_GetAttrString(py_module, "post_trim"); + py_functions[PY_FUNC_TRIM] = PyObject_GetAttrString(py_module, "trim"); + + for (u8 py_idx = 0; py_idx < PY_FUNC_COUNT; ++py_idx) { + if (!py_functions[py_idx] || !PyCallable_Check(py_functions[py_idx])) { + if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) { + // Implementing the trim API is optional for now + if (PyErr_Occurred()) + PyErr_Print(); + py_notrim = 1; + } else { + if (PyErr_Occurred()) + PyErr_Print(); + fprintf(stderr, "Cannot find/call function with index %d in external Python module.\n", py_idx); + return 1; + } + } + + } + + if (py_notrim) { + py_functions[PY_FUNC_INIT_TRIM] = NULL; + py_functions[PY_FUNC_POST_TRIM] = NULL; + py_functions[PY_FUNC_TRIM] = NULL; + WARNF("Python module does not implement trim API, standard trimming will be used."); + } + + PyObject *py_args, *py_value; + + /* Provide the init function a seed for the Python RNG */ + py_args = PyTuple_New(1); + py_value = PyInt_FromLong(UR(0xFFFFFFFF)); + if (!py_value) { + Py_DECREF(py_args); + fprintf(stderr, "Cannot convert argument\n"); + return 1; + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyObject_CallObject(py_functions[PY_FUNC_INIT], py_args); + + Py_DECREF(py_args); + + if (py_value == NULL) { + PyErr_Print(); + fprintf(stderr,"Call failed\n"); + return 1; + } + } else { + PyErr_Print(); + fprintf(stderr, "Failed to load \"%s\"\n", module_name); + return 1; + } + } + + return 0; +} + +void finalize_py() { + if (py_module != NULL) { + u32 i; + for (i = 0; i < PY_FUNC_COUNT; ++i) + Py_XDECREF(py_functions[i]); + + Py_DECREF(py_module); + } + + Py_Finalize(); +} + +void fuzz_py(char* buf, size_t buflen, char* add_buf, size_t add_buflen, char** ret, size_t* retlen) { + + if (py_module != NULL) { + PyObject *py_args, *py_value; + py_args = PyTuple_New(2); + py_value = PyByteArray_FromStringAndSize(buf, buflen); + if (!py_value) { + Py_DECREF(py_args); + fprintf(stderr, "Cannot convert argument\n"); + return; + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyByteArray_FromStringAndSize(add_buf, add_buflen); + if (!py_value) { + Py_DECREF(py_args); + fprintf(stderr, "Cannot convert argument\n"); + return; + } + + PyTuple_SetItem(py_args, 1, py_value); + + py_value = PyObject_CallObject(py_functions[PY_FUNC_FUZZ], py_args); + + Py_DECREF(py_args); + + if (py_value != NULL) { + *retlen = PyByteArray_Size(py_value); + *ret = malloc(*retlen); + memcpy(*ret, PyByteArray_AsString(py_value), *retlen); + Py_DECREF(py_value); + } else { + PyErr_Print(); + fprintf(stderr,"Call failed\n"); + return; + } + } +} + +u32 init_trim_py(char* buf, size_t buflen) { + PyObject *py_args, *py_value; + + py_args = PyTuple_New(1); + py_value = PyByteArray_FromStringAndSize(buf, buflen); + if (!py_value) { + Py_DECREF(py_args); + FATAL("Failed to convert arguments"); + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyObject_CallObject(py_functions[PY_FUNC_INIT_TRIM], py_args); + Py_DECREF(py_args); + + if (py_value != NULL) { + u32 retcnt = PyInt_AsLong(py_value); + Py_DECREF(py_value); + return retcnt; + } else { + PyErr_Print(); + FATAL("Call failed"); + } +} + +u32 post_trim_py(char success) { + PyObject *py_args, *py_value; + + py_args = PyTuple_New(1); + + py_value = PyBool_FromLong(success); + if (!py_value) { + Py_DECREF(py_args); + FATAL("Failed to convert arguments"); + } + + PyTuple_SetItem(py_args, 0, py_value); + + py_value = PyObject_CallObject(py_functions[PY_FUNC_POST_TRIM], py_args); + Py_DECREF(py_args); + + if (py_value != NULL) { + u32 retcnt = PyInt_AsLong(py_value); + Py_DECREF(py_value); + return retcnt; + } else { + PyErr_Print(); + FATAL("Call failed"); + } +} + +void trim_py(char** ret, size_t* retlen) { + PyObject *py_args, *py_value; + + py_args = PyTuple_New(0); + py_value = PyObject_CallObject(py_functions[PY_FUNC_TRIM], py_args); + Py_DECREF(py_args); + + if (py_value != NULL) { + *retlen = PyByteArray_Size(py_value); + *ret = malloc(*retlen); + memcpy(*ret, PyByteArray_AsString(py_value), *retlen); + Py_DECREF(py_value); + } else { + PyErr_Print(); + FATAL("Call failed"); + } +} + +#endif /* USE_PYTHON */ |