mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-08 08:11:34 +00:00
715 lines
24 KiB
C
715 lines
24 KiB
C
/*
|
|
american fuzzy lop++ - fuzzer header
|
|
------------------------------------
|
|
|
|
Originally written by Michal Zalewski <lcamtuf@google.com>
|
|
|
|
Now maintained by by Marc Heuse <mh@mh-sec.de>,
|
|
Heiko Eißfeldt <heiko.eissfeldt@hexco.de> and
|
|
Andrea Fioraldi <andreafioraldi@gmail.com>
|
|
|
|
Copyright 2016, 2017 Google Inc. All rights reserved.
|
|
Copyright 2019 AFLplusplus Project. 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.
|
|
|
|
*/
|
|
|
|
#ifndef _AFL_FUZZ_H
|
|
#define _AFL_FUZZ_H
|
|
|
|
#define AFL_MAIN
|
|
#define MESSAGES_TO_STDOUT
|
|
|
|
#ifndef _GNU_SOURCE
|
|
#define _GNU_SOURCE 1
|
|
#endif
|
|
#define _FILE_OFFSET_BITS 64
|
|
|
|
#ifdef __ANDROID__
|
|
#include "android-ashmem.h"
|
|
#endif
|
|
|
|
#include "config.h"
|
|
#include "types.h"
|
|
#include "debug.h"
|
|
#include "alloc-inl.h"
|
|
#include "hash.h"
|
|
#include "sharedmem.h"
|
|
#include "forkserver.h"
|
|
#include "common.h"
|
|
|
|
#include <stdio.h>
|
|
#include <unistd.h>
|
|
#include <stdlib.h>
|
|
#include <string.h>
|
|
#include <time.h>
|
|
#include <errno.h>
|
|
#include <signal.h>
|
|
#include <dirent.h>
|
|
#include <ctype.h>
|
|
#include <fcntl.h>
|
|
#include <termios.h>
|
|
#include <dlfcn.h>
|
|
#include <sched.h>
|
|
|
|
#include <sys/wait.h>
|
|
#include <sys/time.h>
|
|
#include <sys/shm.h>
|
|
#include <sys/stat.h>
|
|
#include <sys/types.h>
|
|
#include <sys/resource.h>
|
|
#include <sys/mman.h>
|
|
#include <sys/ioctl.h>
|
|
#include <sys/file.h>
|
|
|
|
#if defined(__APPLE__) || defined(__FreeBSD__) || defined(__OpenBSD__) || \
|
|
defined(__NetBSD__)
|
|
#include <sys/sysctl.h>
|
|
#endif /* __APPLE__ || __FreeBSD__ || __OpenBSD__ */
|
|
|
|
/* For systems that have sched_setaffinity; right now just Linux, but one
|
|
can hope... */
|
|
|
|
#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__)
|
|
#define HAVE_AFFINITY 1
|
|
#if defined(__FreeBSD__)
|
|
#include <sys/cpuset.h>
|
|
#include <sys/user.h>
|
|
#include <pthread.h>
|
|
#include <pthread_np.h>
|
|
#define cpu_set_t cpuset_t
|
|
#elif defined(__NetBSD__)
|
|
#include <pthread.h>
|
|
#endif
|
|
#endif /* __linux__ */
|
|
|
|
#ifndef SIMPLE_FILES
|
|
#define CASE_PREFIX "id:"
|
|
#else
|
|
#define CASE_PREFIX "id_"
|
|
#endif /* ^!SIMPLE_FILES */
|
|
|
|
struct queue_entry {
|
|
|
|
u8* fname; /* File name for the test case */
|
|
u32 len; /* Input length */
|
|
|
|
u8 cal_failed, /* Calibration failed? */
|
|
trim_done, /* Trimmed? */
|
|
was_fuzzed, /* historical, but needed for MOpt */
|
|
passed_det, /* Deterministic stages passed? */
|
|
has_new_cov, /* Triggers new coverage? */
|
|
var_behavior, /* Variable behavior? */
|
|
favored, /* Currently favored? */
|
|
fs_redundant; /* Marked as redundant in the fs? */
|
|
|
|
u32 bitmap_size, /* Number of bits set in bitmap */
|
|
fuzz_level, /* Number of fuzzing iterations */
|
|
exec_cksum; /* Checksum of the execution trace */
|
|
|
|
u64 exec_us, /* Execution time (us) */
|
|
handicap, /* Number of queue cycles behind */
|
|
n_fuzz, /* Number of fuzz, does not overflow */
|
|
depth; /* Path depth */
|
|
|
|
u8* trace_mini; /* Trace bytes, if kept */
|
|
u32 tc_ref; /* Trace bytes ref count */
|
|
|
|
struct queue_entry *next, /* Next element, if any */
|
|
*next_100; /* 100 elements ahead */
|
|
|
|
};
|
|
|
|
struct extra_data {
|
|
|
|
u8* data; /* Dictionary token data */
|
|
u32 len; /* Dictionary token length */
|
|
u32 hit_cnt; /* Use count in the corpus */
|
|
|
|
};
|
|
|
|
/* Fuzzing stages */
|
|
|
|
enum {
|
|
|
|
/* 00 */ STAGE_FLIP1,
|
|
/* 01 */ STAGE_FLIP2,
|
|
/* 02 */ STAGE_FLIP4,
|
|
/* 03 */ STAGE_FLIP8,
|
|
/* 04 */ STAGE_FLIP16,
|
|
/* 05 */ STAGE_FLIP32,
|
|
/* 06 */ STAGE_ARITH8,
|
|
/* 07 */ STAGE_ARITH16,
|
|
/* 08 */ STAGE_ARITH32,
|
|
/* 09 */ STAGE_INTEREST8,
|
|
/* 10 */ STAGE_INTEREST16,
|
|
/* 11 */ STAGE_INTEREST32,
|
|
/* 12 */ STAGE_EXTRAS_UO,
|
|
/* 13 */ STAGE_EXTRAS_UI,
|
|
/* 14 */ STAGE_EXTRAS_AO,
|
|
/* 15 */ STAGE_HAVOC,
|
|
/* 16 */ STAGE_SPLICE,
|
|
/* 17 */ STAGE_PYTHON,
|
|
/* 18 */ STAGE_RADAMSA,
|
|
/* 19 */ STAGE_CUSTOM_MUTATOR
|
|
|
|
};
|
|
|
|
/* Stage value types */
|
|
|
|
enum {
|
|
|
|
/* 00 */ STAGE_VAL_NONE,
|
|
/* 01 */ STAGE_VAL_LE,
|
|
/* 02 */ STAGE_VAL_BE
|
|
|
|
};
|
|
|
|
/* Execution status fault codes */
|
|
|
|
enum {
|
|
|
|
/* 00 */ FAULT_NONE,
|
|
/* 01 */ FAULT_TMOUT,
|
|
/* 02 */ FAULT_CRASH,
|
|
/* 03 */ FAULT_ERROR,
|
|
/* 04 */ FAULT_NOINST,
|
|
/* 05 */ FAULT_NOBITS
|
|
|
|
};
|
|
|
|
/* 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
|
|
#define limit_time_bound 1.1
|
|
#define SPLICE_CYCLES_puppet_up 25
|
|
#define SPLICE_CYCLES_puppet_low 5
|
|
#define STAGE_RANDOMBYTE 12
|
|
#define STAGE_DELETEBYTE 13
|
|
#define STAGE_Clone75 14
|
|
#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, debug, /* Debug mode */
|
|
custom_only, /* Custom mutator only mode */
|
|
python_only; /* Python-only mode */
|
|
|
|
extern u32 stats_update_freq; /* Stats update frequency (execs) */
|
|
|
|
enum {
|
|
|
|
/* 00 */ EXPLORE, /* AFL default, Exploration-based constant schedule */
|
|
/* 01 */ FAST, /* Exponential schedule */
|
|
/* 02 */ COE, /* Cut-Off Exponential schedule */
|
|
/* 03 */ LIN, /* Linear schedule */
|
|
/* 04 */ QUAD, /* Quadratic schedule */
|
|
/* 05 */ EXPLOIT, /* AFL's exploitation-based const. */
|
|
|
|
POWER_SCHEDULES_NUM
|
|
|
|
};
|
|
|
|
extern char* power_names[POWER_SCHEDULES_NUM];
|
|
|
|
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? */
|
|
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? */
|
|
|
|
extern s32 out_fd, /* Persistent fd for out_file */
|
|
#ifndef HAVE_ARC4RANDOM
|
|
dev_urandom_fd, /* Persistent fd for /dev/urandom */
|
|
#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 */
|
|
#endif
|
|
|
|
extern u32 rand_seed[2];
|
|
extern s64 init_seed;
|
|
|
|
extern u64 total_cal_us, /* Total calibration time (us) */
|
|
total_cal_cycles; /* Total calibration cycles */
|
|
|
|
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 */
|
|
|
|
#ifdef HAVE_AFFINITY
|
|
|
|
extern s32 cpu_aff; /* Selected CPU core */
|
|
|
|
#endif /* HAVE_AFFINITY */
|
|
|
|
extern FILE* plot_file; /* Gnuplot output file */
|
|
|
|
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 */
|
|
|
|
extern struct queue_entry*
|
|
top_rated[MAP_SIZE]; /* Top entries for bitmap bytes */
|
|
|
|
extern struct extra_data* extras; /* Extra tokens to fuzz with */
|
|
extern u32 extras_cnt; /* Total number of tokens read */
|
|
|
|
extern struct extra_data* a_extras; /* Automatically selected extras */
|
|
extern u32 a_extras_cnt; /* Total number of tokens available */
|
|
|
|
u8* (*post_handler)(u8* buf, u32* len);
|
|
|
|
/* hooks for the custom mutator function */
|
|
/**
|
|
* Perform custom mutations on a given input
|
|
* @param data Input data to be mutated
|
|
* @param size Size of input data
|
|
* @param mutated_out Buffer to store the mutated input
|
|
* @param max_size Maximum size of the mutated output. The mutation must not
|
|
* produce data larger than max_size.
|
|
* @param seed Seed used for the mutation. The mutation should produce the same
|
|
* output given the same seed.
|
|
* @return Size of the mutated output.
|
|
*/
|
|
size_t (*custom_mutator)(u8* data, size_t size, u8* mutated_out,
|
|
size_t max_size, unsigned int seed);
|
|
/**
|
|
* A post-processing function to use right before AFL writes the test case to
|
|
* disk in order to execute the target. If this functionality is not needed,
|
|
* Simply don't define this function.
|
|
* @param data Buffer containing the test case to be executed.
|
|
* @param size Size of the test case.
|
|
* @param new_data Buffer to store the test case after processing
|
|
* @return Size of data after processing.
|
|
*/
|
|
size_t (*pre_save_handler)(u8* data, size_t size, u8** new_data);
|
|
|
|
/* 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_INIT_TRIM,
|
|
/* 03 */ PY_FUNC_POST_TRIM,
|
|
/* 04 */ PY_FUNC_TRIM,
|
|
PY_FUNC_COUNT
|
|
|
|
};
|
|
|
|
extern PyObject* py_functions[PY_FUNC_COUNT];
|
|
|
|
#endif
|
|
|
|
/**** Prototypes ****/
|
|
|
|
/* Python */
|
|
#ifdef USE_PYTHON
|
|
int init_py();
|
|
void finalize_py();
|
|
void fuzz_py(char*, size_t, char*, size_t, char**, size_t*);
|
|
u32 init_trim_py(char*, size_t);
|
|
u32 post_trim_py(char);
|
|
void trim_py(char**, size_t*);
|
|
u8 trim_case_python(char**, struct queue_entry*, 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*);
|
|
|
|
/* Bitmap */
|
|
|
|
void write_bitmap(void);
|
|
void read_bitmap(u8*);
|
|
u8 has_new_bits(u8*);
|
|
u32 count_bits(u8*);
|
|
u32 count_bytes(u8*);
|
|
u32 count_non_255_bytes(u8*);
|
|
#ifdef __x86_64__
|
|
void simplify_trace(u64*);
|
|
void classify_counts(u64*);
|
|
#else
|
|
void simplify_trace(u32*);
|
|
void classify_counts(u32*);
|
|
#endif
|
|
void init_count_class16(void);
|
|
void minimize_bits(u8*, u8*);
|
|
#ifndef SIMPLE_FILES
|
|
u8* describe_op(u8);
|
|
#endif
|
|
u8 save_if_interesting(char**, void*, u32, u8);
|
|
|
|
/* Misc */
|
|
|
|
u8* DI(u64);
|
|
u8* DF(double);
|
|
u8* DMS(u64);
|
|
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);
|
|
|
|
/* Stats */
|
|
|
|
void write_stats_file(double, double, double);
|
|
void maybe_update_plot_file(double, double);
|
|
void show_stats(void);
|
|
void show_init_stats(void);
|
|
|
|
/* 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);
|
|
|
|
/* Fuzz one */
|
|
|
|
u8 fuzz_one_original(char**);
|
|
u8 pilot_fuzzing(char**);
|
|
u8 core_fuzzing(char**);
|
|
void pso_updating(void);
|
|
u8 fuzz_one(char**);
|
|
|
|
/* Init */
|
|
|
|
#ifdef HAVE_AFFINITY
|
|
void bind_to_free_cpu(void);
|
|
#endif
|
|
void setup_post(void);
|
|
void setup_custom_mutator(void);
|
|
void read_testcases(void);
|
|
void perform_dry_run(char**);
|
|
void pivot_inputs(void);
|
|
u32 find_start_position(void);
|
|
void find_timeout(void);
|
|
double get_runnable_processes(void);
|
|
void nuke_resume_dir(void);
|
|
void maybe_delete_out_dir(void);
|
|
void setup_dirs_fds(void);
|
|
void setup_cmdline_file(char**);
|
|
void setup_stdio_file(void);
|
|
void check_crash_handling(void);
|
|
void check_cpu_governor(void);
|
|
void get_core_count(void);
|
|
void fix_up_sync(void);
|
|
void check_asan_opts(void);
|
|
void check_binary(u8*);
|
|
void fix_up_banner(u8*);
|
|
void check_if_tty(void);
|
|
void setup_signal_handlers(void);
|
|
char** get_qemu_argv(u8*, char**, int);
|
|
char** get_wine_argv(u8*, char**, int);
|
|
void save_cmdline(u32, char**);
|
|
|
|
/**** Inline routines ****/
|
|
|
|
/* Generate a random number (from 0 to limit - 1). This may
|
|
have slight bias. */
|
|
|
|
static inline u32 UR(u32 limit) {
|
|
|
|
#ifdef HAVE_ARC4RANDOM
|
|
if (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--)) {
|
|
|
|
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);
|
|
|
|
}
|
|
|
|
return random() % limit;
|
|
#endif
|
|
|
|
}
|
|
|
|
static inline u32 get_rand_seed() {
|
|
|
|
if (fixed_seed) return (u32)init_seed;
|
|
return rand_seed[0];
|
|
|
|
}
|
|
|
|
/* Find first power of two greater or equal to val (assuming val under
|
|
2^63). */
|
|
|
|
static u64 next_p2(u64 val) {
|
|
|
|
u64 ret = 1;
|
|
while (val > ret)
|
|
ret <<= 1;
|
|
return ret;
|
|
|
|
}
|
|
|
|
/* Get unix time in milliseconds */
|
|
|
|
static u64 get_cur_time(void) {
|
|
|
|
struct timeval tv;
|
|
struct timezone tz;
|
|
|
|
gettimeofday(&tv, &tz);
|
|
|
|
return (tv.tv_sec * 1000ULL) + (tv.tv_usec / 1000);
|
|
|
|
}
|
|
|
|
/* Get unix time in microseconds */
|
|
|
|
static u64 get_cur_time_us(void) {
|
|
|
|
struct timeval tv;
|
|
struct timezone tz;
|
|
|
|
gettimeofday(&tv, &tz);
|
|
|
|
return (tv.tv_sec * 1000000ULL) + tv.tv_usec;
|
|
|
|
}
|
|
|
|
#ifdef _AFL_DOCUMENT_MUTATIONS
|
|
extern u8 do_document;
|
|
extern u32 document_counter;
|
|
#endif
|
|
|
|
#endif
|
|
|