diff options
author | vanhauser-thc <vh@thc.org> | 2021-03-06 15:48:49 +0100 |
---|---|---|
committer | vanhauser-thc <vh@thc.org> | 2021-03-06 15:48:49 +0100 |
commit | 81442ba3f953c939e2cde9c16b9cd0d5fe7f12b5 (patch) | |
tree | 45be4ebb5401bc2ed32c6ec25ac541f353f09efa | |
parent | 84f0b4f1874a9c3a5f2da4056f974df8273093d9 (diff) | |
download | afl++-81442ba3f953c939e2cde9c16b9cd0d5fe7f12b5.tar.gz |
implementation without testing
-rw-r--r-- | include/forkserver.h | 11 | ||||
-rw-r--r-- | src/afl-forkserver.c | 68 | ||||
-rw-r--r-- | src/afl-fuzz.c | 3 |
3 files changed, 78 insertions, 4 deletions
diff --git a/include/forkserver.h b/include/forkserver.h index a0a60e0f..ddbc36ef 100644 --- a/include/forkserver.h +++ b/include/forkserver.h @@ -55,9 +55,6 @@ typedef struct afl_forkserver { u32 init_tmout; /* Configurable init timeout (ms) */ u32 map_size; /* map size used by the target */ u32 snapshot; /* is snapshot feature used */ - u32 persistent_replay; /* persistent replay setting */ - u32 persistent_replay_idx; /* persistent replay cache ptr */ - u32 persistent_replay_cnt; /* persistent replay counter */ u64 mem_limit; /* Memory cap for child (MB) */ u64 total_execs; /* How often run_target was called */ @@ -97,6 +94,14 @@ typedef struct afl_forkserver { char *cmplog_binary; /* the name of the cmplog binary */ + /* persistent mode replay functionality */ + u32 persistent_replay; /* persistent replay setting */ + u32 persistent_replay_idx; /* persistent replay cache ptr */ + u32 persistent_replay_cnt; /* persistent replay counter */ + u8 * persistent_replay_dir; + u8 ** persistent_replay_data; + u32 **persistent_replay_len; + /* Function to kick off the forkserver child */ void (*init_child_func)(struct afl_forkserver *fsrv, char **argv); diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 7968f69c..05aba2e5 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -364,6 +364,21 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if (!be_quiet) { ACTF("Spinning up the fork server..."); } + if (unlikely(fsrv->persistent_replay)) { + + fsrv->persistent_replay_data = + (u8 **)ck_alloc(fsrv->persistent_replay * sizeof(size_t)); + fsrv->persistent_replay_len = + (u32 **)ck_alloc(fsrv->persistent_replay * sizeof(u32)); + + if (!fsrv->persistent_replay_data || !fsrv->persistent_replay_len) { + + FATAL("Unable to allocate memory for persistent replay."); + + } + + } + if (fsrv->use_fauxsrv) { /* TODO: Come up with some nice way to initialize this all */ @@ -998,6 +1013,29 @@ u32 afl_fsrv_get_mapsize(afl_forkserver_t *fsrv, char **argv, void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) { + if (unlikely(fsrv->persistent_replay)) { + + *fsrv->persistent_replay_len[fsrv->persistent_replay_idx] = len; + fsrv->persistent_replay_data[fsrv->persistent_replay_idx] = afl_realloc( + (void **)&fsrv->persistent_replay_data[fsrv->persistent_replay_idx], + len); + + if (unlikely(!fsrv->persistent_replay_data[fsrv->persistent_replay_idx])) { + + FATAL("allocating replay memory failed."); + + } + + memcpy(fsrv->persistent_replay_data[fsrv->persistent_replay_idx], buf, len); + + if (unlikely(++fsrv->persistent_replay_idx >= fsrv->persistent_replay)) { + + fsrv->persistent_replay_idx = 0; + + } + + } + if (likely(fsrv->use_shmem_fuzz && fsrv->shmem_fuzz)) { if (unlikely(len > MAX_FILE)) len = MAX_FILE; @@ -1208,6 +1246,36 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout, (fsrv->uses_crash_exitcode && WEXITSTATUS(fsrv->child_status) == fsrv->crash_exitcode))) { + if (unlikely(fsrv->persistent_replay)) { + + char fn[4096]; + u32 i, writecnt = 0; + for (i = 0; i < fsrv->persistent_replay; ++i) { + + u32 entry = (i + fsrv->persistent_replay_idx) % fsrv->persistent_replay; + u8 *data = fsrv->persistent_replay_data[entry]; + u32 *len = fsrv->persistent_replay_len[entry]; + if (likely(len && *len && data)) { + + snprintf(fn, sizeof(fn), "%s/replay_%u_%u.bin", + fsrv->persistent_replay_dir, fsrv->persistent_replay_cnt, + writecnt++); + int fd = open(fn, O_WRONLY, 0644); + if (fd >= 0) { + + ck_write(fd, data, *len, fn); + close(fd); + + } + + } + + } + + ++fsrv->persistent_replay_cnt; + + } + /* For a proper crash, set last_kill_signal to WTERMSIG, else set it to 0 */ fsrv->last_kill_signal = WIFSIGNALED(fsrv->child_status) ? WTERMSIG(fsrv->child_status) : 0; diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c index 77e6e2ce..f3aea2c7 100644 --- a/src/afl-fuzz.c +++ b/src/afl-fuzz.c @@ -1239,9 +1239,10 @@ int main(int argc, char **argv_orig, char **envp) { } - if (afl->afl_env.afl_persistent_replay) { + if (unlikely(afl->afl_env.afl_persistent_replay)) { afl->fsrv.persistent_replay = atoi(afl->afl_env.afl_persistent_replay); + afl->fsrv.persistent_replay_dir = alloc_printf("%s/crashes", afl->out_dir); } |