diff options
Diffstat (limited to 'include/afl-fuzz.h')
-rw-r--r-- | include/afl-fuzz.h | 761 |
1 files changed, 390 insertions, 371 deletions
diff --git a/include/afl-fuzz.h b/include/afl-fuzz.h index d5ad4653..c773d085 100644 --- a/include/afl-fuzz.h +++ b/include/afl-fuzz.h @@ -46,6 +46,7 @@ #include "sharedmem.h" #include "forkserver.h" #include "common.h" +#include "list.h" #include <stdio.h> #include <unistd.h> @@ -106,6 +107,11 @@ #define CASE_PREFIX "id_" #endif /* ^!SIMPLE_FILES */ +extern s8 interesting_8[INTERESTING_8_LEN]; +extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN]; +extern s32 interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN]; + + struct queue_entry { u8* fname; /* File name for the test case */ @@ -198,45 +204,10 @@ enum { }; -/* 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. */ -extern 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; - -extern s32 SPLICE_CYCLES_puppet, limit_time_sig, key_puppet, key_module; - -extern double w_init, w_end, w_now; - -extern s32 g_now; -extern s32 g_max; - #define operator_num 16 #define swarm_num 5 #define period_core 500000 -extern u64 tmp_core_time; -extern s32 swarm_now; - -extern 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]; - -extern 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 */ - #define RAND_C (rand() % 1000 * 0.001) #define v_max 1 #define v_min 0.05 @@ -249,37 +220,6 @@ extern u64 stage_finds_puppet[swarm_num][operator_num], /* Patterns found per #define STAGE_OverWrite75 15 #define period_pilot 50000 -extern double period_pilot_tmp; -extern s32 key_lv; - -extern 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 */ - *doc_path, /* Path to documentation dir */ - *infoexec, /* Command to execute on a new crash */ - *out_file; /* File to fuzz, if any */ - -extern u32 exec_tmout; /* Configurable exec timeout (ms) */ -extern u32 hang_tmout; /* Timeout used for hang det (ms) */ - -extern u64 mem_limit; /* Memory cap for child (MB) */ - -extern u8 cal_cycles, /* Calibration cycles defaults */ - cal_cycles_long, /* Calibration cycles defaults */ - no_unlink, /* do not unlink cur_input */ - use_stdin, /* use stdin for sending data */ - debug, /* Debug mode */ - custom_only; /* Custom mutator only mode */ - -extern u32 stats_update_freq; /* Stats update frequency (execs) */ - enum { /* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */ @@ -293,172 +233,316 @@ enum { }; -extern char* power_names[POWER_SCHEDULES_NUM]; +extern u8 *doc_path; /* gath to documentation dir */ + +/* Python stuff */ +#ifdef USE_PYTHON -extern u8 schedule; /* Power schedule (default: EXPLORE)*/ -extern u8 havoc_max_mult; - -extern u8 use_radamsa; -extern size_t (*radamsa_mutate_ptr)(u8*, size_t, u8*, size_t, u32); - -extern 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? */ - autoresume, /* Resume if out_dir exists? */ - 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, /* Time to update bitmap? */ - qemu_mode, /* Running in QEMU mode? */ - unicorn_mode, /* Running in Unicorn mode? */ - use_wine, /* Use WINE with QEMU 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? */ - disable_trim; /* Never trim in fuzz_one */ - -extern s32 out_fd, /* Persistent fd for out_file */ -#ifndef HAVE_ARC4RANDOM - dev_urandom_fd, /* Persistent fd for /dev/urandom */ +// because Python sets stuff it should not ... +#ifdef _POSIX_C_SOURCE +#define _SAVE_POSIX_C_SOURCE _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE #endif - dev_null_fd, /* Persistent fd for /dev/null */ - fsrv_ctl_fd, /* Fork server control pipe (write) */ - fsrv_st_fd; /* Fork server status pipe (read) */ - -extern s32 forksrv_pid, /* PID of the fork server */ - child_pid, /* PID of the fuzzed program */ - out_dir_fd; /* FD of the lock file */ - -extern u8* trace_bits; /* SHM with instrumentation bitmap */ - -extern 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 */ - -extern u8 var_bytes[MAP_SIZE]; /* Bytes that appear to be variable */ - -extern volatile u8 stop_soon, /* Ctrl-C pressed? */ - clear_screen, /* Window resized? */ - child_timed_out; /* Traced process timed out? */ - -extern 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; /* Cycle count divisor for havoc */ - -extern 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 */ - slowest_exec_ms, /* Slowest testcase non hang in ms */ - 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 */ - -extern u32 subseq_tmouts; /* Number of timeouts in a row */ - -extern u8 *stage_name, /* Name of the current fuzz stage */ - *stage_short, /* Short stage name */ - *syncing_party; /* Currently syncing with... */ - -extern s32 stage_cur, stage_max; /* Stage progression */ -extern s32 splicing_with; /* Splicing with which test case? */ - -extern u32 master_id, master_max; /* Master instance job splitting */ - -extern u32 syncing_case; /* Syncing with case #... */ - -extern s32 stage_cur_byte, /* Byte offset of current stage op */ - stage_cur_val; /* Value used for stage op */ - -extern u8 stage_val_type; /* Value type (STAGE_VAL_*) */ - -extern u64 stage_finds[32], /* Patterns found per fuzz stage */ - stage_cycles[32]; /* Execs per fuzz stage */ - -#ifndef HAVE_ARC4RANDOM -extern u32 rand_cnt; /* Random number counter */ +#ifdef _XOPEN_SOURCE +#define _SAVE_XOPEN_SOURCE _XOPEN_SOURCE +#undef _XOPEN_SOURCE #endif -extern u32 rand_seed[2]; -extern s64 init_seed; +#include <Python.h> -extern u64 total_cal_us, /* Total calibration time (us) */ - total_cal_cycles; /* Total calibration cycles */ +#ifdef _SAVE_POSIX_C_SOURCE +#ifdef _POSIX_C_SOURCE +#undef _POSIX_C_SOURCE +#endif +#define _POSIX_C_SOURCE _SAVE_POSIX_C_SOURCE +#endif +#ifdef _SAVE_XOPEN_SOURCE +#ifdef _XOPEN_SOURCE +#undef _XOPEN_SOURCE +#endif +#define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE +#endif -extern u64 total_bitmap_size, /* Total bit count for all bitmaps */ - total_bitmap_entries; /* Number of bitmaps counted */ -extern s32 cpu_core_count; /* CPU core count */ +enum { + + /* 00 */ PY_FUNC_INIT, + /* 01 */ PY_FUNC_FUZZ, + /* 02 */ PY_FUNC_PRE_SAVE, + /* 03 */ PY_FUNC_INIT_TRIM, + /* 04 */ PY_FUNC_POST_TRIM, + /* 05 */ PY_FUNC_TRIM, + /* 06 */ PY_FUNC_HAVOC_MUTATION, + /* 07 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY, + /* 08 */ PY_FUNC_QUEUE_GET, + /* 09 */ PY_FUNC_QUEUE_NEW_ENTRY, + PY_FUNC_COUNT + +}; + +#endif + +typedef struct MOpt_globals { + + u64* finds; + u64* finds_v2; + u64* cycles; + u64* cycles_v2; + u64* cycles_v3; + u32 is_pilot_mode; + u64* pTime; + u64 period; + char* havoc_stagename; + char* splice_stageformat; + char* havoc_stagenameshort; + char* splice_stagenameshort; + +} MOpt_globals_t; + +extern char* power_names[POWER_SCHEDULES_NUM]; + +typedef struct afl_state { + + /* Position of this state in the global states list */ + u32 _id; + + afl_forkserver_t fsrv; + sharedmem_t shm; + + char** argv; /* argv if needed */ + + /* 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; + + MOpt_globals_t mopt_globals_core, mopt_globals_pilot; + + s32 SPLICE_CYCLES_puppet, limit_time_sig, key_puppet, key_module; + + double w_init, w_end, w_now; + + s32 g_now; + s32 g_max; + + 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; + 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 */ + *infoexec; /* Command to execute on a new crash */ + + u32 hang_tmout; /* Timeout used for hang det (ms) */ + + u8 cal_cycles, /* Calibration cycles defaults */ + cal_cycles_long, /* Calibration cycles defaults */ + no_unlink, /* do not unlink cur_input */ + debug, /* Debug mode */ + custom_only, /* Custom mutator only mode */ + python_only; /* Python-only mode */ + + u32 stats_update_freq; /* Stats update frequency (execs) */ + + u8 schedule; /* Power schedule (default: EXPLORE)*/ + u8 havoc_max_mult; + + u8 use_radamsa; + size_t (*radamsa_mutate_ptr)(u8*, size_t, u8*, size_t, u32); + + 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? */ + autoresume, /* Resume if afl->out_dir exists? */ + 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, /* Time to update bitmap? */ + qemu_mode, /* Running in QEMU mode? */ + unicorn_mode, /* Running in Unicorn mode? */ + use_wine, /* Use WINE with QEMU 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? */ + disable_trim; /* Never trim in fuzz_one */ + + 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; /* Window resized? */ + + 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; /* 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 */ + slowest_exec_ms, /* Slowest testcase non hang in ms */ + 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, /* Name of the current fuzz stage */ + *stage_short, /* Short stage name */ + *syncing_party; /* Currently syncing with... */ + + u8 stage_name_buf64[64]; /* A name buf with len 64 if needed */ + + s32 stage_cur, stage_max; /* Stage progression */ + s32 splicing_with; /* 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 + + u32 rand_seed[2]; + s64 init_seed; + + 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; /* Selected CPU core */ +#endif /* HAVE_AFFINITY */ -extern s32 cpu_aff; /* Selected CPU core */ + 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 */ -#endif /* HAVE_AFFINITY */ + struct queue_entry* + top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */ -extern FILE* plot_file; /* Gnuplot output file */ + struct extra_data* extras; /* Extra tokens to fuzz with */ + u32 extras_cnt; /* Total number of tokens read */ -extern 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 extra_data* a_extras; /* Automatically selected extras */ + u32 a_extras_cnt; /* Total number of tokens available */ -extern struct queue_entry* - top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */ + u8* (*post_handler)(u8* buf, u32* len); -extern struct extra_data* extras; /* Extra tokens to fuzz with */ -extern u32 extras_cnt; /* Total number of tokens read */ + /* CmpLog */ -extern struct extra_data* a_extras; /* Automatically selected extras */ -extern u32 a_extras_cnt; /* Total number of tokens available */ + u8* cmplog_binary; + s32 cmplog_child_pid, cmplog_fsrv_pid; -u8* (*post_handler)(u8* buf, u32* len); + /* Custom mutators */ + struct custom_mutator* mutator; -/* CmpLog */ + /* cmplog forkserver ids */ + s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd; -extern u8* cmplog_binary; -extern s32 cmplog_child_pid, cmplog_forksrv_pid; + u8 describe_op_buf_256[256]; /* describe_op will use this to return a string up to 256 */ -/* Custom mutators */ +#ifdef USE_PYTHON + /* Python Mutators */ + PyObject *py_module; + PyObject *py_functions[PY_FUNC_COUNT]; +#endif + +#ifdef _AFL_DOCUMENT_MUTATIONS + u8 do_document; + u32 document_counter; +#endif + +} afl_state_t; + +/* A global pointer to all instances is needed (for now) for signals to arrive */ + +extern list_t afl_states; struct custom_mutator { @@ -474,7 +558,7 @@ struct custom_mutator { * * @param seed Seed used for the mutation. */ - void (*afl_custom_init)(unsigned int seed); + void (*afl_custom_init)(afl_state_t *afl, unsigned int seed); /** * Perform custom mutations on a given input @@ -490,7 +574,7 @@ struct custom_mutator { * not produce data larger than max_size. * @return Size of the mutated output. */ - size_t (*afl_custom_fuzz)(u8** buf, size_t buf_size, u8* add_buf, + size_t (*afl_custom_fuzz)(afl_state_t *afl, u8** buf, size_t buf_size, u8* add_buf, size_t add_buf_size, size_t max_size); /** @@ -507,7 +591,7 @@ struct custom_mutator { * will release the memory after saving the test case. * @return Size of the output buffer after processing */ - size_t (*afl_custom_pre_save)(u8* buf, size_t buf_size, u8** out_buf); + size_t (*afl_custom_pre_save)(afl_state_t *afl, u8* buf, size_t buf_size, u8** out_buf); /** * This method is called at the start of each trimming operation and receives @@ -529,7 +613,7 @@ struct custom_mutator { * @param buf_size Size of the test case * @return The amount of possible iteration steps to trim the input */ - u32 (*afl_custom_init_trim)(u8* buf, size_t buf_size); + u32 (*afl_custom_init_trim)(afl_state_t *afl, u8* buf, size_t buf_size); /** * This method is called for each trimming operation. It doesn't have any @@ -547,7 +631,7 @@ struct custom_mutator { * the memory after saving the test case. * @param[out] out_buf_size Pointer to the size of the trimmed test case */ - void (*afl_custom_trim)(u8** out_buf, size_t* out_buf_size); + void (*afl_custom_trim)(afl_state_t *afl, u8** out_buf, size_t* out_buf_size); /** * This method is called after each trim operation to inform you if your @@ -560,8 +644,8 @@ struct custom_mutator { * @return The next trim iteration index (from 0 to the maximum amount of * steps returned in init_trim) */ - u32 (*afl_custom_post_trim)(u8 success); - + u32 (*afl_custom_post_trim)(afl_state_t *afl, u8 success); + /** * Perform a single custom mutation on a given input. * This mutation is stacked with the other muatations in havoc. @@ -575,9 +659,8 @@ struct custom_mutator { * not produce data larger than max_size. * @return Size of the mutated output. */ - size_t (*afl_custom_havoc_mutation)(u8** buf, size_t buf_size, - size_t max_size); - + size_t (*afl_custom_havoc_mutation)(afl_state_t *afl, u8** buf, size_t buf_size, size_t max_size); + /** * Return the probability (in percentage) that afl_custom_havoc_mutation * is called in havoc. By default it is 6 %. @@ -586,7 +669,7 @@ struct custom_mutator { * * @return The probability (0-100). */ - u8 (*afl_custom_havoc_mutation_probability)(void); + u8 (*afl_custom_havoc_mutation_probability)(afl_state_t *afl); /** * Determine whether the fuzzer should fuzz the current queue entry or not. @@ -597,7 +680,7 @@ struct custom_mutator { * @return Return True(1) if the fuzzer will fuzz the queue entry, and * False(0) otherwise. */ - u8 (*afl_custom_queue_get)(const u8* filename); + u8 (*afl_custom_queue_get)(afl_state_t *afl, const u8* filename); /** * Allow for additional analysis (e.g. calling a different tool that does a @@ -609,112 +692,57 @@ struct custom_mutator { * @param filename_orig_queue File name of the original queue entry. This * argument can be NULL while initializing the fuzzer */ - void (*afl_custom_queue_new_entry)(const u8* filename_new_queue, + void (*afl_custom_queue_new_entry)(afl_state_t *afl, const u8* filename_new_queue, const u8* filename_orig_queue); }; -extern struct custom_mutator* mutator; - -/* Interesting values, as per config.h */ - -extern s8 interesting_8[INTERESTING_8_LEN]; -extern s16 interesting_16[INTERESTING_8_LEN + INTERESTING_16_LEN]; -extern s32 - interesting_32[INTERESTING_8_LEN + INTERESTING_16_LEN + INTERESTING_32_LEN]; - -/* Python stuff */ -#ifdef USE_PYTHON - -// because Python sets stuff it should not ... -#ifdef _POSIX_C_SOURCE -#define _SAVE_POSIX_C_SOURCE _POSIX_C_SOURCE -#undef _POSIX_C_SOURCE -#endif -#ifdef _XOPEN_SOURCE -#define _SAVE_XOPEN_SOURCE _XOPEN_SOURCE -#undef _XOPEN_SOURCE -#endif - -#include <Python.h> - -#ifdef _SAVE_POSIX_C_SOURCE -#ifdef _POSIX_C_SOURCE -#undef _POSIX_C_SOURCE -#endif -#define _POSIX_C_SOURCE _SAVE_POSIX_C_SOURCE -#endif -#ifdef _SAVE_XOPEN_SOURCE -#ifdef _XOPEN_SOURCE -#undef _XOPEN_SOURCE -#endif -#define _XOPEN_SOURCE _SAVE_XOPEN_SOURCE -#endif - -extern PyObject* py_module; -enum { - /* 00 */ PY_FUNC_INIT, - /* 01 */ PY_FUNC_FUZZ, - /* 02 */ PY_FUNC_PRE_SAVE, - /* 03 */ PY_FUNC_INIT_TRIM, - /* 04 */ PY_FUNC_POST_TRIM, - /* 05 */ PY_FUNC_TRIM, - /* 06 */ PY_FUNC_HAVOC_MUTATION, - /* 07 */ PY_FUNC_HAVOC_MUTATION_PROBABILITY, - /* 08 */ PY_FUNC_QUEUE_GET, - /* 09 */ PY_FUNC_QUEUE_NEW_ENTRY, - PY_FUNC_COUNT - -}; - -extern PyObject* py_functions[PY_FUNC_COUNT]; - -#endif +void afl_state_init(afl_state_t *); +void afl_state_deinit(afl_state_t*); /**** Prototypes ****/ /* Custom mutators */ -void setup_custom_mutator(void); -void destroy_custom_mutator(void); -u8 trim_case_custom(char** argv, struct queue_entry* q, u8* in_buf); +void setup_custom_mutator(afl_state_t*); +void destroy_custom_mutator(afl_state_t*); +u8 trim_case_custom(afl_state_t *, struct queue_entry* q, u8* in_buf); /* Python */ #ifdef USE_PYTHON -int init_py_module(u8*); -void finalize_py_module(); +int init_py_module(afl_state_t*, u8*); +void finalize_py_module(afl_state_t*); -void init_py(unsigned int); -size_t fuzz_py(u8**, size_t, u8*, size_t, size_t); -size_t pre_save_py(u8*, size_t, u8**); -u32 init_trim_py(u8*, size_t); -u32 post_trim_py(u8); -void trim_py(u8**, size_t*); -size_t havoc_mutation_py(u8**, size_t, size_t); -u8 havoc_mutation_probability_py(void); -u8 queue_get_py(const u8*); -void queue_new_entry_py(const u8*, const u8*); +void init_py(afl_state_t*, unsigned int); +size_t fuzz_py(afl_state_t*, u8**, size_t, u8*, size_t, size_t); +size_t pre_save_py(afl_state_t*, u8*, size_t, u8**); +u32 init_trim_py(afl_state_t*, u8*, size_t); +u32 post_trim_py(afl_state_t*, u8); +void trim_py(afl_state_t*, u8**, size_t*); +size_t havoc_mutation_py(afl_state_t *, u8**, size_t, size_t); +u8 havoc_mutation_probability_py(afl_state_t*); +u8 queue_get_py(afl_state_t*, const u8*); +void queue_new_entry_py(afl_state_t*, const u8*, const u8*); #endif /* Queue */ -void mark_as_det_done(struct queue_entry*); -void mark_as_variable(struct queue_entry*); -void mark_as_redundant(struct queue_entry*, u8); -void add_to_queue(u8*, u32, u8); -void destroy_queue(void); -void update_bitmap_score(struct queue_entry*); -void cull_queue(void); -u32 calculate_score(struct queue_entry*); +void mark_as_det_done(afl_state_t*, struct queue_entry*); +void mark_as_variable(afl_state_t*, struct queue_entry*); +void mark_as_redundant(afl_state_t*, struct queue_entry*, u8); +void add_to_queue(afl_state_t*, u8*, u32, u8); +void destroy_queue(afl_state_t*); +void update_bitmap_score(afl_state_t*, struct queue_entry*); +void cull_queue(afl_state_t*); +u32 calculate_score(afl_state_t*, struct queue_entry*); /* Bitmap */ -void write_bitmap(void); -void read_bitmap(u8*); -u8 has_new_bits(u8*); +void read_bitmap(afl_state_t*, u8*); +void write_bitmap(afl_state_t*); u32 count_bits(u8*); u32 count_bytes(u8*); u32 count_non_255_bytes(u8*); @@ -728,9 +756,10 @@ void classify_counts(u32*); void init_count_class16(void); void minimize_bits(u8*, u8*); #ifndef SIMPLE_FILES -u8* describe_op(u8); +u8* describe_op(afl_state_t*, u8); #endif -u8 save_if_interesting(char**, void*, u32, u8); +u8 save_if_interesting(afl_state_t*, void*, u32, u8); +u8 has_new_bits(afl_state_t *, u8*); /* Misc */ @@ -741,75 +770,71 @@ u8* DTD(u64, u64); /* Extras */ -void load_extras_file(u8*, u32*, u32*, u32); -void load_extras(u8*); -void maybe_add_auto(u8*, u32); -void save_auto(void); -void load_auto(void); -void destroy_extras(void); +void load_extras_file(afl_state_t*, u8*, u32*, u32*, u32); +void load_extras(afl_state_t*, u8*); +void maybe_add_auto(afl_state_t*, u8*, u32); +void save_auto(afl_state_t*); +void load_auto(afl_state_t*); +void destroy_extras(afl_state_t*); /* Stats */ -void write_stats_file(double, double, double); -void maybe_update_plot_file(double, double); -void show_stats(void); -void show_init_stats(void); +void write_stats_file(afl_state_t*, double, double, double); +void maybe_update_plot_file(afl_state_t*, double, double); +void show_stats(afl_state_t*); +void show_init_stats(afl_state_t*); /* Run */ -u8 run_target(char**, u32); -void write_to_testcase(void*, u32); -void write_with_gap(void*, u32, u32, u32); -u8 calibrate_case(char**, struct queue_entry*, u8*, u32, u8); -void sync_fuzzers(char**); -u8 trim_case(char**, struct queue_entry*, u8*); -u8 common_fuzz_stuff(char**, u8*, u32); +u8 run_target(afl_state_t*, u32); +void write_to_testcase(afl_state_t*, void*, u32); +u8 calibrate_case(afl_state_t*, struct queue_entry*, u8*, u32, u8); +void sync_fuzzers(afl_state_t*); +u8 trim_case(afl_state_t*, struct queue_entry*, u8*); +u8 common_fuzz_stuff(afl_state_t*, u8*, u32); /* Fuzz one */ -u8 fuzz_one_original(char**); -u8 pilot_fuzzing(char**); -u8 core_fuzzing(char**); -void pso_updating(void); -u8 fuzz_one(char**); +u8 fuzz_one_original(afl_state_t*); +u8 pilot_fuzzing(afl_state_t*); +u8 core_fuzzing(afl_state_t*); +void pso_updating(afl_state_t*); +u8 fuzz_one(afl_state_t*); /* Init */ #ifdef HAVE_AFFINITY -void bind_to_free_cpu(void); +void bind_to_free_cpu(afl_state_t*); #endif -void setup_post(void); -void read_testcases(void); -void perform_dry_run(char**); -void pivot_inputs(void); -u32 find_start_position(void); -void find_timeout(void); +void setup_post(afl_state_t*); +void read_testcases(afl_state_t*); +void perform_dry_run(afl_state_t*); +void pivot_inputs(afl_state_t*); +u32 find_start_position(afl_state_t*); +void find_timeout(afl_state_t*); double get_runnable_processes(void); -void nuke_resume_dir(void); -void setup_dirs_fds(void); -void setup_cmdline_file(char**); -void setup_stdio_file(void); +void nuke_resume_dir(afl_state_t*); +void setup_dirs_fds(afl_state_t*); +void setup_cmdline_file(afl_state_t*, char**); +void setup_stdio_file(afl_state_t*); void check_crash_handling(void); -void check_cpu_governor(void); -void get_core_count(void); -void fix_up_sync(void); +void check_cpu_governor(afl_state_t*); +void get_core_count(afl_state_t*); +void fix_up_sync(afl_state_t*); void check_asan_opts(void); -void check_binary(u8*); -void fix_up_banner(u8*); -void check_if_tty(void); +void check_binary(afl_state_t*, u8*); +void fix_up_banner(afl_state_t*, u8*); +void check_if_tty(afl_state_t*); void setup_signal_handlers(void); -char** get_qemu_argv(u8*, char**, int); -char** get_wine_argv(u8*, char**, int); -void save_cmdline(u32, char**); +void save_cmdline(afl_state_t*, u32, char**); /* CmpLog */ -void init_cmplog_forkserver(char** argv); -u8 common_fuzz_cmplog_stuff(char** argv, u8* out_buf, u32 len); +void init_cmplog_forkserver(afl_state_t *afl); +u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len); /* RedQueen */ - -u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len, +u8 input_to_state_stage(afl_state_t *afl, u8* orig_buf, u8* buf, u32 len, u32 exec_cksum); /**** Inline routines ****/ @@ -817,20 +842,20 @@ u8 input_to_state_stage(char** argv, u8* orig_buf, u8* buf, u32 len, /* Generate a random number (from 0 to limit - 1). This may have slight bias. */ -static inline u32 UR(u32 limit) { +static inline u32 UR(afl_state_t *afl, u32 limit) { #ifdef HAVE_ARC4RANDOM - if (fixed_seed) { return random() % limit; } + if (afl->fixed_seed) { return random() % limit; } /* The boundary not being necessarily a power of 2, we need to ensure the result uniformity. */ return arc4random_uniform(limit); #else - if (!fixed_seed && unlikely(!rand_cnt--)) { + if (!afl->fixed_seed && unlikely(!afl->rand_cnt--)) { - ck_read(dev_urandom_fd, &rand_seed, sizeof(rand_seed), "/dev/urandom"); - srandom(rand_seed[0]); - rand_cnt = (RESEED_RNG / 2) + (rand_seed[1] % RESEED_RNG); + ck_read(afl->fsrv.dev_urandom_fd, &afl->rand_seed, sizeof(afl->rand_seed), "/dev/urandom"); + srandom(afl->rand_seed[0]); + afl->rand_cnt = (RESEED_RNG / 2) + (afl->rand_seed[1] % RESEED_RNG); } @@ -839,10 +864,10 @@ static inline u32 UR(u32 limit) { } -static inline u32 get_rand_seed() { +static inline u32 get_rand_seed(afl_state_t *afl) { - if (fixed_seed) return (u32)init_seed; - return rand_seed[0]; + if (afl->fixed_seed) return (u32)afl->init_seed; + return afl->rand_seed[0]; } @@ -858,10 +883,4 @@ static u64 next_p2(u64 val) { } -#ifdef _AFL_DOCUMENT_MUTATIONS -extern u8 do_document; -extern u32 document_counter; -#endif - -#endif - +#endif \ No newline at end of file |