mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-12 01:58:17 +00:00
@ -2,9 +2,9 @@
|
|||||||
|
|
||||||
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
|
<img align="right" src="https://raw.githubusercontent.com/AFLplusplus/Website/main/static/aflpp_bg.svg" alt="AFL++ logo" width="250" heigh="250">
|
||||||
|
|
||||||
Release version: [4.20c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
Release version: [4.21c](https://github.com/AFLplusplus/AFLplusplus/releases)
|
||||||
|
|
||||||
GitHub version: 4.21a
|
GitHub version: 4.21c
|
||||||
|
|
||||||
Repository:
|
Repository:
|
||||||
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
[https://github.com/AFLplusplus/AFLplusplus](https://github.com/AFLplusplus/AFLplusplus)
|
||||||
|
3
TODO.md
3
TODO.md
@ -2,6 +2,8 @@
|
|||||||
|
|
||||||
## Must
|
## Must
|
||||||
|
|
||||||
|
- fast restart of afl-fuzz if cmdline + target hash is the same
|
||||||
|
- check for null ptr for xml/curl/g_ string transform functions
|
||||||
- hardened_usercopy=0 page_alloc.shuffle=0
|
- hardened_usercopy=0 page_alloc.shuffle=0
|
||||||
- add value_profile but only enable after 15 minutes without finds
|
- add value_profile but only enable after 15 minutes without finds
|
||||||
- cmplog max items env?
|
- cmplog max items env?
|
||||||
@ -11,7 +13,6 @@
|
|||||||
- afl-showmap -f support
|
- afl-showmap -f support
|
||||||
- afl-fuzz multicore wrapper script
|
- afl-fuzz multicore wrapper script
|
||||||
- when trimming then perform crash detection
|
- when trimming then perform crash detection
|
||||||
- cyclomatic complexity: 2 + calls + edges - blocks
|
|
||||||
|
|
||||||
|
|
||||||
## Should
|
## Should
|
||||||
|
@ -1 +1 @@
|
|||||||
5ed4f8d
|
95a6857
|
||||||
|
Submodule custom_mutators/grammar_mutator/grammar_mutator updated: 5ed4f8d6e6...95a685773e
@ -3,12 +3,16 @@
|
|||||||
This is the list of all noteworthy changes made in every public
|
This is the list of all noteworthy changes made in every public
|
||||||
release of the tool. See README.md for the general instruction manual.
|
release of the tool. See README.md for the general instruction manual.
|
||||||
|
|
||||||
### Version ++4.21a (dev)
|
### Version ++4.21c (release)
|
||||||
* afl-fuzz
|
* afl-fuzz
|
||||||
- fixed a regression in afl-fuzz that resulted in a 5-10% performace loss
|
- fixed a regression in afl-fuzz that resulted in a 5-10% performace loss
|
||||||
do a switch from gettimeofday() to clock_gettime() which should be rather
|
do a switch from gettimeofday() to clock_gettime() which should be rather
|
||||||
three times faster. The reason for this is unknown.
|
three times faster. The reason for this is unknown.
|
||||||
|
- new queue selection algorithm based on 2 core years of queue data
|
||||||
|
analysis. gives a noticable improvement on coverage although the results
|
||||||
|
seem counterintuitive :-)
|
||||||
- added AFL_DISABLE_REDUNDANT for huge queues
|
- added AFL_DISABLE_REDUNDANT for huge queues
|
||||||
|
- added `AFL_NO_SYNC` environment variable that does what you think it does
|
||||||
- fix AFL_PERSISTENT_RECORD
|
- fix AFL_PERSISTENT_RECORD
|
||||||
- run custom_post_process after standard trimming
|
- run custom_post_process after standard trimming
|
||||||
- prevent filenames in the queue that have spaces
|
- prevent filenames in the queue that have spaces
|
||||||
@ -19,6 +23,9 @@
|
|||||||
- -V timing is now accurately the fuzz time (without syncing), before
|
- -V timing is now accurately the fuzz time (without syncing), before
|
||||||
long calibration times and syncing could result in now fuzzing being
|
long calibration times and syncing could result in now fuzzing being
|
||||||
made when the time was already run out until then, thanks to @eqv!
|
made when the time was already run out until then, thanks to @eqv!
|
||||||
|
- fix -n uninstrumented mode when ending fuzzing
|
||||||
|
- enhanced the ASAN configuration
|
||||||
|
- make afl-fuzz use less memory with cmplog and fix a memleak
|
||||||
* afl-cc:
|
* afl-cc:
|
||||||
- re-enable i386 support that was accidently disabled
|
- re-enable i386 support that was accidently disabled
|
||||||
- fixes for LTO and outdated afl-gcc mode for i386
|
- fixes for LTO and outdated afl-gcc mode for i386
|
||||||
@ -32,7 +39,8 @@
|
|||||||
* afl-showmap
|
* afl-showmap
|
||||||
- fix memory leak on shmem testcase usage (thanks to @ndrewh)
|
- fix memory leak on shmem testcase usage (thanks to @ndrewh)
|
||||||
- minor fix to collect coverage -C (thanks to @bet4it)
|
- minor fix to collect coverage -C (thanks to @bet4it)
|
||||||
* enhanced the ASAN configuration
|
* Fixed a shmem mmap bug (that rarely came up on MacOS)
|
||||||
|
* libtokencap: script generate_libtoken_dict.sh added by @a-shvedov
|
||||||
|
|
||||||
|
|
||||||
### Version ++4.20c (release)
|
### Version ++4.20c (release)
|
||||||
|
@ -588,6 +588,9 @@ checks or alter some of the more exotic semantics of the tool:
|
|||||||
between fuzzing instances synchronization. Default sync time is 30 minutes,
|
between fuzzing instances synchronization. Default sync time is 30 minutes,
|
||||||
note that time is halved for -M main nodes.
|
note that time is halved for -M main nodes.
|
||||||
|
|
||||||
|
- `AFL_NO_SYNC` disables any syncing whatsoever and takes priority on all
|
||||||
|
other syncing parameters.
|
||||||
|
|
||||||
- Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables for
|
- Setting `AFL_TARGET_ENV` causes AFL++ to set extra environment variables for
|
||||||
the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz
|
the target binary. Example: `AFL_TARGET_ENV="VAR1=1 VAR2='a b c'" afl-fuzz
|
||||||
... `. This exists mostly for things like `LD_LIBRARY_PATH` but it would
|
... `. This exists mostly for things like `LD_LIBRARY_PATH` but it would
|
||||||
|
@ -49,14 +49,23 @@ void instrument_cache_init(void) {
|
|||||||
|
|
||||||
if (setrlimit(RLIMIT_AS, &data_limit) != 0) {
|
if (setrlimit(RLIMIT_AS, &data_limit) != 0) {
|
||||||
|
|
||||||
FFATAL("Failed to setrlimit: %d", errno);
|
FWARNF("Failed to setrlimit: %d, you may need root or CAP_SYS_RESOURCE",
|
||||||
|
errno);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
map_base =
|
map_base =
|
||||||
gum_memory_allocate(NULL, instrument_cache_size, instrument_cache_size,
|
gum_memory_allocate(NULL, instrument_cache_size, instrument_cache_size,
|
||||||
GUM_PAGE_READ | GUM_PAGE_WRITE);
|
GUM_PAGE_READ | GUM_PAGE_WRITE);
|
||||||
if (map_base == MAP_FAILED) { FFATAL("Failed to map segment: %d", errno); }
|
if (map_base == MAP_FAILED) {
|
||||||
|
|
||||||
|
FFATAL(
|
||||||
|
"Failed to map segment: %d. This can be caused by failure to setrlimit."
|
||||||
|
"Disabling or reducing the size of the allocation using "
|
||||||
|
"AFL_FRIDA_INST_NO_CACHE or AFL_FRIDA_INST_CACHE_SIZE may help",
|
||||||
|
errno);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache addr:" cYEL " [0x%016lX]",
|
FOKF(cBLU "Instrumentation" cRST " - " cGRN "cache addr:" cYEL " [0x%016lX]",
|
||||||
GUM_ADDRESS(map_base));
|
GUM_ADDRESS(map_base));
|
||||||
|
@ -194,8 +194,7 @@ static gboolean print_ranges_callback(const GumRangeDetails *details,
|
|||||||
|
|
||||||
if (details->file == NULL) {
|
if (details->file == NULL) {
|
||||||
|
|
||||||
FVERBOSE("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
|
OKF("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER "X %c%c%c",
|
||||||
"X %c%c%c",
|
|
||||||
details->range->base_address,
|
details->range->base_address,
|
||||||
details->range->base_address + details->range->size,
|
details->range->base_address + details->range->size,
|
||||||
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
||||||
@ -204,14 +203,14 @@ static gboolean print_ranges_callback(const GumRangeDetails *details,
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
FVERBOSE("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
|
OKF("\t0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
|
||||||
"X %c%c%c %s(0x%016" G_GINT64_MODIFIER "x)",
|
"X %c%c%c %s(0x%016" G_GINT64_MODIFIER "x)",
|
||||||
details->range->base_address,
|
details->range->base_address,
|
||||||
details->range->base_address + details->range->size,
|
details->range->base_address + details->range->size,
|
||||||
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
details->protection & GUM_PAGE_READ ? 'R' : '-',
|
||||||
details->protection & GUM_PAGE_WRITE ? 'W' : '-',
|
details->protection & GUM_PAGE_WRITE ? 'W' : '-',
|
||||||
details->protection & GUM_PAGE_EXECUTE ? 'X' : '-',
|
details->protection & GUM_PAGE_EXECUTE ? 'X' : '-', details->file->path,
|
||||||
details->file->path, details->file->offset);
|
details->file->offset);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -581,7 +580,7 @@ static GArray *merge_ranges(GArray *a) {
|
|||||||
|
|
||||||
void ranges_print_debug_maps(void) {
|
void ranges_print_debug_maps(void) {
|
||||||
|
|
||||||
FVERBOSE("Maps");
|
OKF("Maps");
|
||||||
gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL);
|
gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback, NULL);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -457,7 +457,7 @@ typedef struct afl_env_vars {
|
|||||||
afl_no_startup_calibration, afl_no_warn_instability,
|
afl_no_startup_calibration, afl_no_warn_instability,
|
||||||
afl_post_process_keep_original, afl_crashing_seeds_as_new_crash,
|
afl_post_process_keep_original, afl_crashing_seeds_as_new_crash,
|
||||||
afl_final_sync, afl_ignore_seed_problems, afl_disable_redundant,
|
afl_final_sync, afl_ignore_seed_problems, afl_disable_redundant,
|
||||||
afl_sha1_filenames;
|
afl_sha1_filenames, afl_no_sync;
|
||||||
|
|
||||||
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
|
u8 *afl_tmpdir, *afl_custom_mutator_library, *afl_python_module, *afl_path,
|
||||||
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
|
*afl_hang_tmout, *afl_forksrv_init_tmout, *afl_preload,
|
||||||
@ -656,6 +656,7 @@ typedef struct afl_state {
|
|||||||
switch_fuzz_mode, /* auto or fixed fuzz mode */
|
switch_fuzz_mode, /* auto or fixed fuzz mode */
|
||||||
calibration_time_us, /* Time spend on calibration */
|
calibration_time_us, /* Time spend on calibration */
|
||||||
sync_time_us, /* Time spend on sync */
|
sync_time_us, /* Time spend on sync */
|
||||||
|
cmplog_time_us, /* Time spend on cmplog */
|
||||||
trim_time_us; /* Time spend on trimming */
|
trim_time_us; /* Time spend on trimming */
|
||||||
|
|
||||||
u32 slowest_exec_ms, /* Slowest testcase non hang in ms */
|
u32 slowest_exec_ms, /* Slowest testcase non hang in ms */
|
||||||
@ -1226,6 +1227,7 @@ void show_init_stats(afl_state_t *);
|
|||||||
void update_calibration_time(afl_state_t *afl, u64 *time);
|
void update_calibration_time(afl_state_t *afl, u64 *time);
|
||||||
void update_trim_time(afl_state_t *afl, u64 *time);
|
void update_trim_time(afl_state_t *afl, u64 *time);
|
||||||
void update_sync_time(afl_state_t *afl, u64 *time);
|
void update_sync_time(afl_state_t *afl, u64 *time);
|
||||||
|
void update_cmplog_time(afl_state_t *afl, u64 *time);
|
||||||
|
|
||||||
/* StatsD */
|
/* StatsD */
|
||||||
|
|
||||||
@ -1276,6 +1278,7 @@ void get_core_count(afl_state_t *);
|
|||||||
void fix_up_sync(afl_state_t *);
|
void fix_up_sync(afl_state_t *);
|
||||||
void check_asan_opts(afl_state_t *);
|
void check_asan_opts(afl_state_t *);
|
||||||
void check_binary(afl_state_t *, u8 *);
|
void check_binary(afl_state_t *, u8 *);
|
||||||
|
u64 get_binary_hash(u8 *fn);
|
||||||
void check_if_tty(afl_state_t *);
|
void check_if_tty(afl_state_t *);
|
||||||
void save_cmdline(afl_state_t *, u32, char **);
|
void save_cmdline(afl_state_t *, u32, char **);
|
||||||
void read_foreign_testcases(afl_state_t *, int);
|
void read_foreign_testcases(afl_state_t *, int);
|
||||||
|
@ -26,7 +26,7 @@
|
|||||||
/* Version string: */
|
/* Version string: */
|
||||||
|
|
||||||
// c = release, a = volatile github dev, e = experimental branch
|
// c = release, a = volatile github dev, e = experimental branch
|
||||||
#define VERSION "++4.21a"
|
#define VERSION "++4.21c"
|
||||||
|
|
||||||
/******************************************************
|
/******************************************************
|
||||||
* *
|
* *
|
||||||
@ -324,9 +324,9 @@
|
|||||||
#define SYNC_INTERVAL 8
|
#define SYNC_INTERVAL 8
|
||||||
|
|
||||||
/* Sync time (minimum time between syncing in ms, time is halfed for -M main
|
/* Sync time (minimum time between syncing in ms, time is halfed for -M main
|
||||||
nodes) - default is 30 minutes: */
|
nodes) - default is 20 minutes: */
|
||||||
|
|
||||||
#define SYNC_TIME (30 * 60 * 1000)
|
#define SYNC_TIME (20 * 60 * 1000)
|
||||||
|
|
||||||
/* Output directory reuse grace period (minutes): */
|
/* Output directory reuse grace period (minutes): */
|
||||||
|
|
||||||
|
@ -81,14 +81,13 @@ static char *afl_environment_variables[] = {
|
|||||||
"AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE",
|
"AFL_LLVM_MAP_DYNAMIC", "AFL_LLVM_NGRAM_SIZE", "AFL_NGRAM_SIZE",
|
||||||
"AFL_LLVM_NO_RPATH", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_INSTRUMENT_FILE",
|
"AFL_LLVM_NO_RPATH", "AFL_LLVM_NOT_ZERO", "AFL_LLVM_INSTRUMENT_FILE",
|
||||||
"AFL_LLVM_THREADSAFE_INST", "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY",
|
"AFL_LLVM_THREADSAFE_INST", "AFL_LLVM_SKIP_NEVERZERO", "AFL_NO_AFFINITY",
|
||||||
"AFL_TRY_AFFINITY", "AFL_LLVM_LTO_DONTWRITEID",
|
"AFL_TRY_AFFINITY", "AFL_LLVM_LTO_DONTWRITEID", "AFL_LLVM_LTO_SKIPINIT",
|
||||||
"AFL_LLVM_LTO_SKIPINIT"
|
"AFL_LLVM_LTO_STARTID", "AFL_FUZZER_LOOPCOUNT", "AFL_NO_ARITH",
|
||||||
"AFL_LLVM_LTO_STARTID",
|
"AFL_NO_AUTODICT", "AFL_NO_BUILTIN",
|
||||||
"AFL_FUZZER_LOOPCOUNT", "AFL_NO_ARITH", "AFL_NO_AUTODICT", "AFL_NO_BUILTIN",
|
|
||||||
#if defined USE_COLOR && !defined ALWAYS_COLORED
|
#if defined USE_COLOR && !defined ALWAYS_COLORED
|
||||||
"AFL_NO_COLOR", "AFL_NO_COLOUR",
|
"AFL_NO_COLOR", "AFL_NO_COLOUR",
|
||||||
#endif
|
#endif
|
||||||
"AFL_NO_CPU_RED",
|
"AFL_NO_CPU_RED", "AFL_NO_SYNC",
|
||||||
"AFL_NO_CFG_FUZZING", // afl.rs rust crate option
|
"AFL_NO_CFG_FUZZING", // afl.rs rust crate option
|
||||||
"AFL_NO_CRASH_README", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
|
"AFL_NO_CRASH_README", "AFL_NO_FORKSRV", "AFL_NO_UI", "AFL_NO_PYTHON",
|
||||||
"AFL_NO_STARTUP_CALIBRATION", "AFL_NO_WARN_INSTABILITY",
|
"AFL_NO_STARTUP_CALIBRATION", "AFL_NO_WARN_INSTABILITY",
|
||||||
|
@ -1849,7 +1849,7 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
|
|||||||
to avoid duplicate calls (which can happen as an artifact of the underlying
|
to avoid duplicate calls (which can happen as an artifact of the underlying
|
||||||
implementation in LLVM). */
|
implementation in LLVM). */
|
||||||
|
|
||||||
if (__afl_final_loc < 5) __afl_final_loc = 5; // we skip the first 5 entries
|
if (__afl_final_loc < 4) __afl_final_loc = 4; // we skip the first 5 entries
|
||||||
|
|
||||||
*(start++) = ++__afl_final_loc;
|
*(start++) = ++__afl_final_loc;
|
||||||
|
|
||||||
|
@ -1655,7 +1655,8 @@ void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
|||||||
if (fsrv->fsrv_pid > 0) {
|
if (fsrv->fsrv_pid > 0) {
|
||||||
|
|
||||||
kill(fsrv->fsrv_pid, fsrv->fsrv_kill_signal);
|
kill(fsrv->fsrv_pid, fsrv->fsrv_kill_signal);
|
||||||
waitpid(fsrv->fsrv_pid, NULL, 0);
|
usleep(25);
|
||||||
|
waitpid(fsrv->fsrv_pid, NULL, WNOHANG);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -60,32 +60,6 @@ inline u32 select_next_queue_entry(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
double compute_weight(afl_state_t *afl, struct queue_entry *q,
|
|
||||||
double avg_exec_us, double avg_bitmap_size,
|
|
||||||
double avg_top_size) {
|
|
||||||
|
|
||||||
double weight = 1.0;
|
|
||||||
|
|
||||||
if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
|
||||||
|
|
||||||
u32 hits = afl->n_fuzz[q->n_fuzz_entry];
|
|
||||||
if (likely(hits)) { weight /= (log10(hits) + 1); }
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
if (likely(afl->schedule < RARE)) { weight *= (avg_exec_us / q->exec_us); }
|
|
||||||
weight *= (log(q->bitmap_size) / avg_bitmap_size);
|
|
||||||
weight *= (1 + (q->tc_ref / avg_top_size));
|
|
||||||
|
|
||||||
if (unlikely(weight < 0.1)) { weight = 0.1; }
|
|
||||||
if (unlikely(q->favored)) { weight *= 5; }
|
|
||||||
if (unlikely(!q->was_fuzzed)) { weight *= 2; }
|
|
||||||
if (unlikely(q->fs_redundant)) { weight *= 0.8; }
|
|
||||||
|
|
||||||
return weight;
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* create the alias table that allows weighted random selection - expensive */
|
/* create the alias table that allows weighted random selection - expensive */
|
||||||
|
|
||||||
void create_alias_table(afl_state_t *afl) {
|
void create_alias_table(afl_state_t *afl) {
|
||||||
@ -117,7 +91,7 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
|
|
||||||
double avg_exec_us = 0.0;
|
double avg_exec_us = 0.0;
|
||||||
double avg_bitmap_size = 0.0;
|
double avg_bitmap_size = 0.0;
|
||||||
double avg_top_size = 0.0;
|
double avg_len = 0.0;
|
||||||
u32 active = 0;
|
u32 active = 0;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
@ -129,7 +103,7 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
|
|
||||||
avg_exec_us += q->exec_us;
|
avg_exec_us += q->exec_us;
|
||||||
avg_bitmap_size += log(q->bitmap_size);
|
avg_bitmap_size += log(q->bitmap_size);
|
||||||
avg_top_size += q->tc_ref;
|
avg_len += q->len;
|
||||||
++active;
|
++active;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -138,7 +112,7 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
|
|
||||||
avg_exec_us /= active;
|
avg_exec_us /= active;
|
||||||
avg_bitmap_size /= active;
|
avg_bitmap_size /= active;
|
||||||
avg_top_size /= active;
|
avg_len /= active;
|
||||||
|
|
||||||
for (i = 0; i < n; i++) {
|
for (i = 0; i < n; i++) {
|
||||||
|
|
||||||
@ -146,8 +120,59 @@ void create_alias_table(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (likely(!q->disabled)) {
|
if (likely(!q->disabled)) {
|
||||||
|
|
||||||
q->weight =
|
double weight = 1.0;
|
||||||
compute_weight(afl, q, avg_exec_us, avg_bitmap_size, avg_top_size);
|
{ // inline does result in a compile error with LTO, weird
|
||||||
|
|
||||||
|
if (likely(afl->schedule >= FAST && afl->schedule <= RARE)) {
|
||||||
|
|
||||||
|
u32 hits = afl->n_fuzz[q->n_fuzz_entry];
|
||||||
|
if (likely(hits)) { weight /= (log10(hits) + 1); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (likely(afl->schedule < RARE)) {
|
||||||
|
|
||||||
|
double t = q->exec_us / avg_exec_us;
|
||||||
|
if (likely(t < 0.1)) {
|
||||||
|
|
||||||
|
// nothing
|
||||||
|
|
||||||
|
} else if (likely(t <= 0.25))
|
||||||
|
|
||||||
|
weight *= 0.9;
|
||||||
|
else if (likely(t <= 0.5)) {
|
||||||
|
|
||||||
|
// nothing
|
||||||
|
|
||||||
|
} else if (likely(t < 1.0))
|
||||||
|
|
||||||
|
weight *= 1.15;
|
||||||
|
else if (unlikely(t > 2.5 && t < 5.0))
|
||||||
|
weight *= 1.1;
|
||||||
|
// else nothing
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
double l = q->len / avg_len;
|
||||||
|
if (likely(l < 0.1))
|
||||||
|
weight *= 0.75;
|
||||||
|
else if (likely(l < 0.25))
|
||||||
|
weight *= 1.1;
|
||||||
|
else if (unlikely(l >= 10))
|
||||||
|
weight *= 1.1;
|
||||||
|
|
||||||
|
double bms = q->bitmap_size / avg_bitmap_size;
|
||||||
|
if (likely(bms < 0.5))
|
||||||
|
weight *= (1.0 + ((bms - 0.5) / 2));
|
||||||
|
else if (unlikely(bms > 1.33))
|
||||||
|
weight *= 1.1;
|
||||||
|
|
||||||
|
if (unlikely(!q->was_fuzzed)) { weight *= 2.5; }
|
||||||
|
if (unlikely(q->fs_redundant)) { weight *= 0.75; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
q->weight = weight;
|
||||||
q->perf_score = calculate_score(afl, q);
|
q->perf_score = calculate_score(afl, q);
|
||||||
sum += q->weight;
|
sum += q->weight;
|
||||||
|
|
||||||
@ -596,6 +621,8 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
q->trace_mini = NULL;
|
q->trace_mini = NULL;
|
||||||
q->testcase_buf = NULL;
|
q->testcase_buf = NULL;
|
||||||
q->mother = afl->queue_cur;
|
q->mother = afl->queue_cur;
|
||||||
|
q->weight = 1.0;
|
||||||
|
q->perf_score = 100;
|
||||||
|
|
||||||
#ifdef INTROSPECTION
|
#ifdef INTROSPECTION
|
||||||
q->bitsmap_size = afl->bitsmap_size;
|
q->bitsmap_size = afl->bitsmap_size;
|
||||||
@ -1201,9 +1228,11 @@ inline void queue_testcase_retake(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
u32 len = q->len;
|
u32 len = q->len;
|
||||||
|
|
||||||
if (len != old_len) {
|
// only realloc if necessary or useful
|
||||||
|
// (a custom trim can make the testcase larger)
|
||||||
|
if (unlikely(len > old_len || len < old_len + 1024)) {
|
||||||
|
|
||||||
afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len;
|
afl->q_testcase_cache_size += len - old_len;
|
||||||
q->testcase_buf = (u8 *)realloc(q->testcase_buf, len);
|
q->testcase_buf = (u8 *)realloc(q->testcase_buf, len);
|
||||||
|
|
||||||
if (unlikely(!q->testcase_buf)) {
|
if (unlikely(!q->testcase_buf)) {
|
||||||
@ -1232,22 +1261,25 @@ inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
if (likely(q->testcase_buf)) {
|
if (likely(q->testcase_buf)) {
|
||||||
|
|
||||||
u32 is_same = in == q->testcase_buf;
|
if (likely(in != q->testcase_buf)) {
|
||||||
|
|
||||||
if (likely(len != old_len)) {
|
// only realloc if we save memory
|
||||||
|
if (unlikely(len < old_len + 1024)) {
|
||||||
|
|
||||||
u8 *ptr = (u8 *)realloc(q->testcase_buf, len);
|
u8 *ptr = (u8 *)realloc(q->testcase_buf, len);
|
||||||
|
|
||||||
if (likely(ptr)) {
|
if (likely(ptr)) {
|
||||||
|
|
||||||
q->testcase_buf = ptr;
|
q->testcase_buf = ptr;
|
||||||
afl->q_testcase_cache_size = afl->q_testcase_cache_size + len - old_len;
|
afl->q_testcase_cache_size += len - old_len;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!is_same)) { memcpy(q->testcase_buf, in, len); }
|
memcpy(q->testcase_buf, in, len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1258,15 +1290,19 @@ inline void queue_testcase_retake_mem(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
||||||
|
|
||||||
|
if (likely(q->testcase_buf)) { return q->testcase_buf; }
|
||||||
|
|
||||||
u32 len = q->len;
|
u32 len = q->len;
|
||||||
|
double weight = q->weight;
|
||||||
|
|
||||||
/* first handle if no testcase cache is configured */
|
// first handle if no testcase cache is configured, or if the
|
||||||
|
// weighting of the testcase is below average.
|
||||||
|
|
||||||
if (unlikely(!afl->q_testcase_max_cache_size)) {
|
if (unlikely(weight < 1.0 || !afl->q_testcase_max_cache_size)) {
|
||||||
|
|
||||||
u8 *buf;
|
u8 *buf;
|
||||||
|
|
||||||
if (unlikely(q == afl->queue_cur)) {
|
if (likely(q == afl->queue_cur)) {
|
||||||
|
|
||||||
buf = (u8 *)afl_realloc((void **)&afl->testcase_buf, len);
|
buf = (u8 *)afl_realloc((void **)&afl->testcase_buf, len);
|
||||||
|
|
||||||
@ -1292,9 +1328,7 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* now handle the testcase cache */
|
/* now handle the testcase cache and we know it is an interesting one */
|
||||||
|
|
||||||
if (unlikely(!q->testcase_buf)) {
|
|
||||||
|
|
||||||
/* Buf not cached, let's load it */
|
/* Buf not cached, let's load it */
|
||||||
u32 tid = afl->q_testcase_max_cache_count;
|
u32 tid = afl->q_testcase_max_cache_count;
|
||||||
@ -1308,18 +1342,17 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
/* We want a max number of entries to the cache that we learn.
|
/* We want a max number of entries to the cache that we learn.
|
||||||
Very simple: once the cache is filled by size - that is the max. */
|
Very simple: once the cache is filled by size - that is the max. */
|
||||||
|
|
||||||
if (unlikely(afl->q_testcase_cache_size + len >=
|
if (unlikely(
|
||||||
|
afl->q_testcase_cache_size + len >=
|
||||||
afl->q_testcase_max_cache_size &&
|
afl->q_testcase_max_cache_size &&
|
||||||
(afl->q_testcase_cache_count <
|
(afl->q_testcase_cache_count < afl->q_testcase_max_cache_entries &&
|
||||||
afl->q_testcase_max_cache_entries &&
|
|
||||||
afl->q_testcase_max_cache_count <
|
afl->q_testcase_max_cache_count <
|
||||||
afl->q_testcase_max_cache_entries) &&
|
afl->q_testcase_max_cache_entries) &&
|
||||||
!do_once)) {
|
!do_once)) {
|
||||||
|
|
||||||
if (afl->q_testcase_max_cache_count > afl->q_testcase_cache_count) {
|
if (afl->q_testcase_max_cache_count > afl->q_testcase_cache_count) {
|
||||||
|
|
||||||
afl->q_testcase_max_cache_entries =
|
afl->q_testcase_max_cache_entries = afl->q_testcase_max_cache_count + 1;
|
||||||
afl->q_testcase_max_cache_count + 1;
|
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -1405,8 +1438,6 @@ inline u8 *queue_testcase_get(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
return q->testcase_buf;
|
return q->testcase_buf;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -1418,12 +1449,13 @@ inline void queue_testcase_store_mem(afl_state_t *afl, struct queue_entry *q,
|
|||||||
|
|
||||||
u32 len = q->len;
|
u32 len = q->len;
|
||||||
|
|
||||||
if (unlikely(afl->q_testcase_cache_size + len >=
|
if (unlikely(q->weight < 1.0 ||
|
||||||
|
afl->q_testcase_cache_size + len >=
|
||||||
afl->q_testcase_max_cache_size ||
|
afl->q_testcase_max_cache_size ||
|
||||||
afl->q_testcase_cache_count >=
|
afl->q_testcase_cache_count >=
|
||||||
afl->q_testcase_max_cache_entries - 1)) {
|
afl->q_testcase_max_cache_entries - 1)) {
|
||||||
|
|
||||||
// no space? will be loaded regularly later.
|
// no space or uninteresting? will be loaded regularly later.
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -322,7 +322,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
|
|||||||
|
|
||||||
memcpy(backup, buf, len);
|
memcpy(backup, buf, len);
|
||||||
memcpy(changed, buf, len);
|
memcpy(changed, buf, len);
|
||||||
if (afl->cmplog_random_colorization) {
|
if (likely(afl->cmplog_random_colorization)) {
|
||||||
|
|
||||||
random_replace(afl, changed, len);
|
random_replace(afl, changed, len);
|
||||||
|
|
||||||
@ -402,6 +402,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
|
|||||||
|
|
||||||
u32 i = 1;
|
u32 i = 1;
|
||||||
u32 positions = 0;
|
u32 positions = 0;
|
||||||
|
|
||||||
while (i) {
|
while (i) {
|
||||||
|
|
||||||
restart:
|
restart:
|
||||||
@ -2937,6 +2938,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
|
|||||||
// afl->queue_cur->exec_cksum
|
// afl->queue_cur->exec_cksum
|
||||||
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
||||||
|
|
||||||
|
u64 cmplog_start_us = get_cur_time_us();
|
||||||
u8 r = 1;
|
u8 r = 1;
|
||||||
if (unlikely(!afl->pass_stats)) {
|
if (unlikely(!afl->pass_stats)) {
|
||||||
|
|
||||||
@ -2965,7 +2967,12 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) {
|
if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) {
|
||||||
|
|
||||||
if (unlikely(colorization(afl, buf, len, &taint))) { return 1; }
|
if (unlikely(colorization(afl, buf, len, &taint))) {
|
||||||
|
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// no taint? still try, create a dummy to prevent again colorization
|
// no taint? still try, create a dummy to prevent again colorization
|
||||||
if (!taint) {
|
if (!taint) {
|
||||||
@ -2974,6 +2981,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
fprintf(stderr, "TAINT FAILED\n");
|
fprintf(stderr, "TAINT FAILED\n");
|
||||||
#endif
|
#endif
|
||||||
afl->queue_cur->colorized = CMPLOG_LVL_MAX;
|
afl->queue_cur->colorized = CMPLOG_LVL_MAX;
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -2994,17 +3002,20 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
|
|
||||||
struct tainted *t = taint;
|
struct tainted *t = taint;
|
||||||
|
|
||||||
|
#ifdef _DEBUG
|
||||||
while (t) {
|
while (t) {
|
||||||
|
|
||||||
#ifdef _DEBUG
|
|
||||||
fprintf(stderr, "T: idx=%u len=%u\n", t->pos, t->len);
|
fprintf(stderr, "T: idx=%u len=%u\n", t->pos, t->len);
|
||||||
#endif
|
|
||||||
t = t->next;
|
t = t->next;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
|
#if defined(_DEBUG) || defined(CMPLOG_INTROSPECTION)
|
||||||
u64 start_time = get_cur_time();
|
u64 start_time = get_cur_time();
|
||||||
u32 cmp_locations = 0;
|
u32 cmp_locations = 0;
|
||||||
@ -3025,6 +3036,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3048,6 +3060,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -3066,6 +3079,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
u64 orig_hit_cnt, new_hit_cnt;
|
u64 orig_hit_cnt, new_hit_cnt;
|
||||||
u64 orig_execs = afl->fsrv.total_execs;
|
u64 orig_execs = afl->fsrv.total_execs;
|
||||||
orig_hit_cnt = afl->queued_items + afl->saved_crashes;
|
orig_hit_cnt = afl->queued_items + afl->saved_crashes;
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
|
|
||||||
afl->stage_name = "input-to-state";
|
afl->stage_name = "input-to-state";
|
||||||
afl->stage_short = "its";
|
afl->stage_short = "its";
|
||||||
@ -3142,13 +3156,15 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
r = 0;
|
r = 0;
|
||||||
|
|
||||||
exit_its:
|
exit_its:
|
||||||
|
|
||||||
if (afl->cmplog_lvl == CMPLOG_LVL_MAX) {
|
// if (afl->cmplog_lvl == CMPLOG_LVL_MAX) {
|
||||||
|
|
||||||
afl->queue_cur->colorized = CMPLOG_LVL_MAX;
|
afl->queue_cur->colorized = CMPLOG_LVL_MAX;
|
||||||
|
|
||||||
@ -3168,7 +3184,7 @@ exit_its:
|
|||||||
|
|
||||||
afl->queue_cur->taint = NULL;
|
afl->queue_cur->taint = NULL;
|
||||||
|
|
||||||
} else {
|
/*} else {
|
||||||
|
|
||||||
afl->queue_cur->colorized = LVL2;
|
afl->queue_cur->colorized = LVL2;
|
||||||
|
|
||||||
@ -3182,7 +3198,7 @@ exit_its:
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}*/
|
||||||
|
|
||||||
#ifdef CMPLOG_COMBINE
|
#ifdef CMPLOG_COMBINE
|
||||||
if (afl->queued_items + afl->saved_crashes > orig_hit_cnt + 1) {
|
if (afl->queued_items + afl->saved_crashes > orig_hit_cnt + 1) {
|
||||||
@ -3270,6 +3286,7 @@ exit_its:
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
update_cmplog_time(afl, &cmplog_start_us);
|
||||||
return r;
|
return r;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -666,6 +666,8 @@ abort_calibration:
|
|||||||
|
|
||||||
void sync_fuzzers(afl_state_t *afl) {
|
void sync_fuzzers(afl_state_t *afl) {
|
||||||
|
|
||||||
|
if (unlikely(afl->afl_env.afl_no_sync)) { return; }
|
||||||
|
|
||||||
DIR *sd;
|
DIR *sd;
|
||||||
struct dirent *sd_ent;
|
struct dirent *sd_ent;
|
||||||
u32 sync_cnt = 0, synced = 0, entries = 0;
|
u32 sync_cnt = 0, synced = 0, entries = 0;
|
||||||
|
@ -33,15 +33,15 @@ u8 is_det_timeout(u64 cur_ms, u8 is_flip) {
|
|||||||
|
|
||||||
u8 should_det_fuzz(afl_state_t *afl, struct queue_entry *q) {
|
u8 should_det_fuzz(afl_state_t *afl, struct queue_entry *q) {
|
||||||
|
|
||||||
if (!afl->skipdet_g->virgin_det_bits) {
|
if (unlikely(!afl->skipdet_g->virgin_det_bits)) {
|
||||||
|
|
||||||
afl->skipdet_g->virgin_det_bits =
|
afl->skipdet_g->virgin_det_bits =
|
||||||
(u8 *)ck_alloc(sizeof(u8) * afl->fsrv.map_size);
|
(u8 *)ck_alloc(sizeof(u8) * afl->fsrv.map_size);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!q->favored || q->passed_det) return 0;
|
if (likely(!q->favored || q->passed_det)) return 0;
|
||||||
if (!q->trace_mini) return 0;
|
if (unlikely(!q->trace_mini)) return 0;
|
||||||
|
|
||||||
if (!afl->skipdet_g->last_cov_undet)
|
if (!afl->skipdet_g->last_cov_undet)
|
||||||
afl->skipdet_g->last_cov_undet = get_cur_time();
|
afl->skipdet_g->last_cov_undet = get_cur_time();
|
||||||
@ -122,7 +122,8 @@ u8 skip_deterministic_stage(afl_state_t *afl, u8 *orig_buf, u8 *out_buf,
|
|||||||
afl->stage_cur = 0;
|
afl->stage_cur = 0;
|
||||||
orig_hit_cnt = afl->queued_items + afl->saved_crashes;
|
orig_hit_cnt = afl->queued_items + afl->saved_crashes;
|
||||||
|
|
||||||
u8 *inf_eff_map = (u8 *)ck_alloc(sizeof(u8) * len);
|
static u8 *inf_eff_map;
|
||||||
|
inf_eff_map = (u8 *)ck_realloc(inf_eff_map, sizeof(u8) * len);
|
||||||
memset(inf_eff_map, 1, sizeof(u8) * len);
|
memset(inf_eff_map, 1, sizeof(u8) * len);
|
||||||
|
|
||||||
if (common_fuzz_stuff(afl, orig_buf, len)) { return 0; }
|
if (common_fuzz_stuff(afl, orig_buf, len)) { return 0; }
|
||||||
|
@ -279,6 +279,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
afl->afl_env.afl_final_sync =
|
afl->afl_env.afl_final_sync =
|
||||||
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
|
} else if (!strncmp(env, "AFL_NO_SYNC",
|
||||||
|
|
||||||
|
afl_environment_variable_len)) {
|
||||||
|
|
||||||
|
afl->afl_env.afl_no_sync =
|
||||||
|
get_afl_env(afl_environment_variables[i]) ? 1 : 0;
|
||||||
|
|
||||||
} else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_ONLY",
|
} else if (!strncmp(env, "AFL_CUSTOM_MUTATOR_ONLY",
|
||||||
|
|
||||||
afl_environment_variable_len)) {
|
afl_environment_variable_len)) {
|
||||||
@ -762,8 +769,9 @@ void afl_states_stop(void) {
|
|||||||
if (el->fsrv.fsrv_pid > 0) {
|
if (el->fsrv.fsrv_pid > 0) {
|
||||||
|
|
||||||
kill(el->fsrv.fsrv_pid, el->fsrv.fsrv_kill_signal);
|
kill(el->fsrv.fsrv_pid, el->fsrv.fsrv_kill_signal);
|
||||||
|
usleep(100);
|
||||||
/* Make sure the forkserver does not end up as zombie. */
|
/* Make sure the forkserver does not end up as zombie. */
|
||||||
waitpid(el->fsrv.fsrv_pid, NULL, 0);
|
waitpid(el->fsrv.fsrv_pid, NULL, WNOHANG);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -207,6 +207,12 @@ void load_stats_file(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (starts_with("cmplog_time", keystring)) {
|
||||||
|
|
||||||
|
afl->cmplog_time_us = strtoull(lptr, &nptr, 10) * 1000000;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (starts_with("trim_time", keystring)) {
|
if (starts_with("trim_time", keystring)) {
|
||||||
|
|
||||||
afl->trim_time_us = strtoull(lptr, &nptr, 10) * 1000000;
|
afl->trim_time_us = strtoull(lptr, &nptr, 10) * 1000000;
|
||||||
@ -322,8 +328,9 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
|
|||||||
if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
|
if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
|
||||||
#endif
|
#endif
|
||||||
u64 runtime_ms = afl->prev_run_time + cur_time - afl->start_time;
|
u64 runtime_ms = afl->prev_run_time + cur_time - afl->start_time;
|
||||||
u64 overhead_ms =
|
u64 overhead_ms = (afl->calibration_time_us + afl->sync_time_us +
|
||||||
(afl->calibration_time_us + afl->sync_time_us + afl->trim_time_us) / 1000;
|
afl->trim_time_us + afl->cmplog_time_us) /
|
||||||
|
1000;
|
||||||
if (!runtime_ms) { runtime_ms = 1; }
|
if (!runtime_ms) { runtime_ms = 1; }
|
||||||
|
|
||||||
fprintf(
|
fprintf(
|
||||||
@ -337,6 +344,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
|
|||||||
"time_wo_finds : %llu\n"
|
"time_wo_finds : %llu\n"
|
||||||
"fuzz_time : %llu\n"
|
"fuzz_time : %llu\n"
|
||||||
"calibration_time : %llu\n"
|
"calibration_time : %llu\n"
|
||||||
|
"cmplog_time : %llu\n"
|
||||||
"sync_time : %llu\n"
|
"sync_time : %llu\n"
|
||||||
"trim_time : %llu\n"
|
"trim_time : %llu\n"
|
||||||
"execs_done : %llu\n"
|
"execs_done : %llu\n"
|
||||||
@ -385,8 +393,9 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
|
|||||||
? 0
|
? 0
|
||||||
: (cur_time - afl->last_find_time) / 1000),
|
: (cur_time - afl->last_find_time) / 1000),
|
||||||
(runtime_ms - MIN(runtime_ms, overhead_ms)) / 1000,
|
(runtime_ms - MIN(runtime_ms, overhead_ms)) / 1000,
|
||||||
afl->calibration_time_us / 1000000, afl->sync_time_us / 1000000,
|
afl->calibration_time_us / 1000000, afl->cmplog_time_us / 1000000,
|
||||||
afl->trim_time_us / 1000000, afl->fsrv.total_execs,
|
afl->sync_time_us / 1000000, afl->trim_time_us / 1000000,
|
||||||
|
afl->fsrv.total_execs,
|
||||||
afl->fsrv.total_execs / ((double)(runtime_ms) / 1000),
|
afl->fsrv.total_execs / ((double)(runtime_ms) / 1000),
|
||||||
afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored,
|
afl->last_avg_execs_saved, afl->queued_items, afl->queued_favored,
|
||||||
afl->queued_discovered, afl->queued_imported, afl->queued_variable,
|
afl->queued_discovered, afl->queued_imported, afl->queued_variable,
|
||||||
@ -2487,7 +2496,7 @@ void show_init_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_calibration_time(afl_state_t *afl, u64 *time) {
|
inline void update_calibration_time(afl_state_t *afl, u64 *time) {
|
||||||
|
|
||||||
u64 cur = get_cur_time_us();
|
u64 cur = get_cur_time_us();
|
||||||
afl->calibration_time_us += cur - *time;
|
afl->calibration_time_us += cur - *time;
|
||||||
@ -2495,7 +2504,7 @@ void update_calibration_time(afl_state_t *afl, u64 *time) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_trim_time(afl_state_t *afl, u64 *time) {
|
inline void update_trim_time(afl_state_t *afl, u64 *time) {
|
||||||
|
|
||||||
u64 cur = get_cur_time_us();
|
u64 cur = get_cur_time_us();
|
||||||
afl->trim_time_us += cur - *time;
|
afl->trim_time_us += cur - *time;
|
||||||
@ -2503,7 +2512,7 @@ void update_trim_time(afl_state_t *afl, u64 *time) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void update_sync_time(afl_state_t *afl, u64 *time) {
|
inline void update_sync_time(afl_state_t *afl, u64 *time) {
|
||||||
|
|
||||||
u64 cur = get_cur_time_us();
|
u64 cur = get_cur_time_us();
|
||||||
afl->sync_time_us += cur - *time;
|
afl->sync_time_us += cur - *time;
|
||||||
@ -2511,3 +2520,11 @@ void update_sync_time(afl_state_t *afl, u64 *time) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline void update_cmplog_time(afl_state_t *afl, u64 *time) {
|
||||||
|
|
||||||
|
u64 cur = get_cur_time_us();
|
||||||
|
afl->cmplog_time_us += cur - *time;
|
||||||
|
*time = cur;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
@ -335,6 +335,7 @@ static void usage(u8 *argv0, int more_help) {
|
|||||||
"AFL_STATSD_PORT: change default statsd port (default: 8125)\n"
|
"AFL_STATSD_PORT: change default statsd port (default: 8125)\n"
|
||||||
"AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n"
|
"AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n"
|
||||||
" suported formats: dogstatsd, librato, signalfx, influxdb\n"
|
" suported formats: dogstatsd, librato, signalfx, influxdb\n"
|
||||||
|
"AFL_NO_SYNC: disables all syncing\n"
|
||||||
"AFL_SYNC_TIME: sync time between fuzzing instances (in minutes)\n"
|
"AFL_SYNC_TIME: sync time between fuzzing instances (in minutes)\n"
|
||||||
"AFL_FINAL_SYNC: sync a final time when exiting (will delay the exit!)\n"
|
"AFL_FINAL_SYNC: sync a final time when exiting (will delay the exit!)\n"
|
||||||
"AFL_NO_CRASH_README: do not create a README in the crashes directory\n"
|
"AFL_NO_CRASH_README: do not create a README in the crashes directory\n"
|
||||||
@ -914,9 +915,16 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u8 suffix = 'M';
|
u8 suffix = 'M';
|
||||||
|
|
||||||
if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
|
if (mem_limit_given) {
|
||||||
|
|
||||||
|
WARNF("Overriding previous -m option.");
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!optarg) { FATAL("Wrong usage of -m"); }
|
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
@ -1461,9 +1469,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
configure_afl_kill_signals(&afl->fsrv, afl->afl_env.afl_child_kill_signal,
|
configure_afl_kill_signals(
|
||||||
|
&afl->fsrv, afl->afl_env.afl_child_kill_signal,
|
||||||
afl->afl_env.afl_fsrv_kill_signal,
|
afl->afl_env.afl_fsrv_kill_signal,
|
||||||
(afl->fsrv.qemu_mode || afl->unicorn_mode
|
(afl->fsrv.qemu_mode || afl->unicorn_mode || afl->fsrv.use_fauxsrv
|
||||||
#ifdef __linux__
|
#ifdef __linux__
|
||||||
|| afl->fsrv.nyx_mode
|
|| afl->fsrv.nyx_mode
|
||||||
#endif
|
#endif
|
||||||
@ -2586,7 +2595,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
(!afl->queue_cycle && afl->afl_env.afl_import_first)) &&
|
(!afl->queue_cycle && afl->afl_env.afl_import_first)) &&
|
||||||
afl->sync_id)) {
|
afl->sync_id)) {
|
||||||
|
|
||||||
if (!afl->queue_cycle && afl->afl_env.afl_import_first) {
|
if (unlikely(!afl->queue_cycle && afl->afl_env.afl_import_first)) {
|
||||||
|
|
||||||
OKF("Syncing queues from other fuzzer instances first ...");
|
OKF("Syncing queues from other fuzzer instances first ...");
|
||||||
|
|
||||||
@ -2597,6 +2606,12 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
++afl->queue_cycle;
|
++afl->queue_cycle;
|
||||||
|
if (afl->afl_env.afl_no_ui) {
|
||||||
|
|
||||||
|
ACTF("Entering queue cycle %llu\n", afl->queue_cycle);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
runs_in_current_cycle = (u32)-1;
|
runs_in_current_cycle = (u32)-1;
|
||||||
afl->cur_skipped_items = 0;
|
afl->cur_skipped_items = 0;
|
||||||
|
|
||||||
@ -2605,7 +2620,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
// queue is fully cycled.
|
// queue is fully cycled.
|
||||||
time_t cursec = time(NULL);
|
time_t cursec = time(NULL);
|
||||||
struct tm *curdate = localtime(&cursec);
|
struct tm *curdate = localtime(&cursec);
|
||||||
if (likely(!afl->afl_env.afl_pizza_mode)) {
|
if (unlikely(!afl->afl_env.afl_pizza_mode)) {
|
||||||
|
|
||||||
if (unlikely(curdate->tm_mon == 3 && curdate->tm_mday == 1)) {
|
if (unlikely(curdate->tm_mon == 3 && curdate->tm_mday == 1)) {
|
||||||
|
|
||||||
@ -2650,13 +2665,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(afl->not_on_tty)) {
|
|
||||||
|
|
||||||
ACTF("Entering queue cycle %llu.", afl->queue_cycle);
|
|
||||||
fflush(stdout);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
/* If we had a full queue cycle with no new finds, try
|
/* If we had a full queue cycle with no new finds, try
|
||||||
recombination strategies next. */
|
recombination strategies next. */
|
||||||
|
|
||||||
@ -2942,12 +2950,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (likely(!afl->stop_soon && afl->sync_id)) {
|
if (likely(!afl->stop_soon && afl->sync_id)) {
|
||||||
|
|
||||||
if (likely(afl->skip_deterministic)) {
|
|
||||||
|
|
||||||
if (unlikely(afl->is_main_node)) {
|
if (unlikely(afl->is_main_node)) {
|
||||||
|
|
||||||
if (unlikely(cur_time >
|
if (unlikely(cur_time > (afl->sync_time >> 1) + afl->last_sync_time)) {
|
||||||
(afl->sync_time >> 1) + afl->last_sync_time)) {
|
|
||||||
|
|
||||||
if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) {
|
if (!(sync_interval_cnt++ % (SYNC_INTERVAL / 3))) {
|
||||||
|
|
||||||
@ -2967,12 +2972,6 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
|
||||||
|
|
||||||
sync_fuzzers(afl);
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -95,6 +95,24 @@ inline u64 hash64(u8 *key, u32 len, u64 seed) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* Hash a file */
|
||||||
|
|
||||||
|
u64 get_binary_hash(u8 *fn) {
|
||||||
|
|
||||||
|
int fd = open(fn, O_RDONLY);
|
||||||
|
if (fd < 0) { PFATAL("Unable to open '%s'", fn); }
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fd, &st) < 0) { PFATAL("Unable to fstat '%s'", fn); }
|
||||||
|
u32 f_len = st.st_size;
|
||||||
|
u8 *f_data = mmap(0, f_len, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
|
if (f_data == MAP_FAILED) { PFATAL("Unable to mmap file '%s'", fn); }
|
||||||
|
close(fd);
|
||||||
|
u64 hash = hash64(f_data, f_len, 0);
|
||||||
|
if (munmap(f_data, f_len)) { PFATAL("unmap() failed"); }
|
||||||
|
return hash;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// Public domain SHA1 implementation copied from:
|
// Public domain SHA1 implementation copied from:
|
||||||
// https://github.com/x42/liboauth/blob/7001b8256cd654952ec2515b055d2c5b243be600/src/sha1.c
|
// https://github.com/x42/liboauth/blob/7001b8256cd654952ec2515b055d2c5b243be600/src/sha1.c
|
||||||
|
|
||||||
|
@ -239,15 +239,15 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size,
|
|||||||
if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
|
if (shm->cmplog_g_shm_fd == -1) { PFATAL("shm_open() failed"); }
|
||||||
|
|
||||||
/* configure the size of the shared memory segment */
|
/* configure the size of the shared memory segment */
|
||||||
if (ftruncate(shm->cmplog_g_shm_fd, map_size)) {
|
if (ftruncate(shm->cmplog_g_shm_fd, sizeof(struct cmp_map))) {
|
||||||
|
|
||||||
PFATAL("setup_shm(): cmplog ftruncate() failed");
|
PFATAL("setup_shm(): cmplog ftruncate() failed");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* map the shared memory segment to the address space of the process */
|
/* map the shared memory segment to the address space of the process */
|
||||||
shm->cmp_map = mmap(0, map_size, PROT_READ | PROT_WRITE, MAP_SHARED,
|
shm->cmp_map = mmap(0, sizeof(struct cmp_map), PROT_READ | PROT_WRITE,
|
||||||
shm->cmplog_g_shm_fd, 0);
|
MAP_SHARED, shm->cmplog_g_shm_fd, 0);
|
||||||
if (shm->cmp_map == MAP_FAILED) {
|
if (shm->cmp_map == MAP_FAILED) {
|
||||||
|
|
||||||
close(shm->cmplog_g_shm_fd);
|
close(shm->cmplog_g_shm_fd);
|
||||||
|
Submodule unicorn_mode/unicornafl updated: 764b66b21c...4b4fdab161
@ -69,3 +69,21 @@ need to be changed for other OSes.
|
|||||||
|
|
||||||
Current supported OSes are: Linux, Darwin, FreeBSD (thanks to @devnexen)
|
Current supported OSes are: Linux, Darwin, FreeBSD (thanks to @devnexen)
|
||||||
|
|
||||||
|
Also, the following example (generate_libtoken_dict.sh) shows how to use a script to capture tokens from the
|
||||||
|
files in the target output directory,
|
||||||
|
and then generate a dictionary file from those tokens.
|
||||||
|
|
||||||
|
#### usage:
|
||||||
|
```bash
|
||||||
|
./generate_libtoken_dict.sh -p /path/to/libtokencap.so -b /path/to/target/program -o /path/to/target/output -t 5 -- [-program_args]
|
||||||
|
```
|
||||||
|
#### description opts:
|
||||||
|
- ```-o``` : Path to target output directory ;
|
||||||
|
- ```-b``` : Path to target program binary ;
|
||||||
|
- ```-p``` : Path to LD_PRELOAD library ;
|
||||||
|
- ```-t``` : Timeout in seconds ;
|
||||||
|
- ```-- [-program_args]```: Any additional arguments required by the target binary can be specified after ```--```.
|
||||||
|
|
||||||
|
#### output:
|
||||||
|
A sorted and unique token dictionary file with the extension ``*.dict``
|
||||||
|
is created in the same directory as the target output containing tokens captured during the execution of the target binary.
|
||||||
|
55
utils/libtokencap/generate_libtoken_dict.sh
Normal file
55
utils/libtokencap/generate_libtoken_dict.sh
Normal file
@ -0,0 +1,55 @@
|
|||||||
|
#help
|
||||||
|
usage() {
|
||||||
|
echo "Usage: $0 -o <target_output> -b <target_bin> -p <LD_PRELOAD_PATH> [-t <timeout_sec>] -- [target_args]"
|
||||||
|
echo "Options:"
|
||||||
|
echo " -o Path to target output directory"
|
||||||
|
echo " -b Path to target program binary"
|
||||||
|
echo " -p Path to LD_PRELOAD library"
|
||||||
|
echo " -t Timeout in seconds"
|
||||||
|
exit 1
|
||||||
|
}
|
||||||
|
|
||||||
|
#parse cli options
|
||||||
|
while getopts ":o:b:p:t:" opt; do
|
||||||
|
case $opt in
|
||||||
|
o) target_output="$OPTARG" ;;
|
||||||
|
b) target_bin="$OPTARG" ;;
|
||||||
|
p) LD_PRELOAD_PATH="$OPTARG" ;;
|
||||||
|
t) timeout_sec="$OPTARG" ;;
|
||||||
|
\?) echo "Invalid option: -$OPTARG" >&2; usage ;;
|
||||||
|
:) echo "Option -$OPTARG requires an argument." >&2; usage ;;
|
||||||
|
esac
|
||||||
|
done
|
||||||
|
|
||||||
|
#shift away the parsed opts
|
||||||
|
shift $((OPTIND - 1))
|
||||||
|
|
||||||
|
#check options
|
||||||
|
if [ -z "$target_output" ] || [ -z "$target_bin" ] || [ -z "$LD_PRELOAD_PATH" ]; then
|
||||||
|
echo "Error: Missing mandatory opts" >&2
|
||||||
|
usage
|
||||||
|
fi
|
||||||
|
|
||||||
|
# initialize vars
|
||||||
|
AFL_TOKEN_FILE="${PWD}/temp_output.txt"
|
||||||
|
AFL_DICT_FILE="${PWD}/$(basename "$target_bin")_tokens.dict"
|
||||||
|
|
||||||
|
#generate token-file
|
||||||
|
{
|
||||||
|
touch "$AFL_TOKEN_FILE"
|
||||||
|
for i in $(find "$target_output" -type f -name "id*"); do
|
||||||
|
LD_PRELOAD="$LD_PRELOAD_PATH" \
|
||||||
|
timeout -s SIGKILL "$timeout_sec" \
|
||||||
|
"$target_bin" "$@" "$i"
|
||||||
|
done
|
||||||
|
} >"$AFL_TOKEN_FILE"
|
||||||
|
|
||||||
|
# sort & remove duplicates
|
||||||
|
sort -u "$AFL_TOKEN_FILE" >"$AFL_DICT_FILE"
|
||||||
|
|
||||||
|
# delete temp-file
|
||||||
|
rm "$AFL_TOKEN_FILE"
|
||||||
|
|
||||||
|
# print done-message
|
||||||
|
echo "Token dictionary created: $AFL_DICT_FILE"
|
||||||
|
echo "Script completed successfully"
|
Reference in New Issue
Block a user