cmplog is now better

This commit is contained in:
Andrea Fioraldi
2020-04-14 10:09:03 +02:00
parent 0e1d82dd9f
commit 1fbface656
4 changed files with 76 additions and 25 deletions

View File

@ -316,6 +316,10 @@ typedef struct afl_env_vars {
} afl_env_vars_t;
struct afl_pass_stat {
u8 total; u8 faileds;
};
typedef struct afl_state {
/* Position of this state in the global states list */
@ -540,6 +544,8 @@ typedef struct afl_state {
/* cmplog forkserver ids */
s32 cmplog_fsrv_ctl_fd, cmplog_fsrv_st_fd;
struct afl_pass_stat* pass_stats;
u8 describe_op_buf_256[256]; /* describe_op will use this to return a string
up to 256 */

View File

@ -495,7 +495,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (afl->use_radamsa > 1) goto radamsa_stage;
if (afl->shm.cmplog_mode) {
if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
if (input_to_state_stage(afl, in_buf, out_buf, len,
afl->queue_cur->exec_cksum))
@ -2508,6 +2508,28 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
orig_perf = perf_score = calculate_score(afl, afl->queue_cur);
if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
if (input_to_state_stage(afl, in_buf, out_buf, len,
afl->queue_cur->exec_cksum))
goto abandon_entry;
}
/* Go to pacemker fuzzing if MOpt is doing well */
cur_ms_lv = get_cur_time();
if (!(afl->key_puppet == 0 &&
((cur_ms_lv - afl->last_path_time < afl->limit_time_puppet) ||
(afl->last_crash_time != 0 &&
cur_ms_lv - afl->last_crash_time < afl->limit_time_puppet) ||
afl->last_path_time == 0))) {
afl->key_puppet = 1;
goto pacemaker_fuzzing;
}
/* Skip right away if -d is given, if we have done deterministic fuzzing on
this entry ourselves (was_fuzzed), or if it has gone through deterministic
testing in earlier, resumed runs (passed_det). */
@ -2523,17 +2545,6 @@ u8 mopt_common_fuzzing(afl_state_t *afl, MOpt_globals_t MOpt_globals) {
(afl->queue_cur->exec_cksum % afl->master_max) != afl->master_id - 1)
goto havoc_stage;
cur_ms_lv = get_cur_time();
if (!(afl->key_puppet == 0 &&
((cur_ms_lv - afl->last_path_time < afl->limit_time_puppet) ||
(afl->last_crash_time != 0 &&
cur_ms_lv - afl->last_crash_time < afl->limit_time_puppet) ||
afl->last_path_time == 0))) {
afl->key_puppet = 1;
goto pacemaker_fuzzing;
}
doing_det = 1;

View File

@ -127,9 +127,14 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
rand_replace(afl, buf + rng->start, s);
u32 cksum;
u64 start_us = get_cur_time_us();
if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) goto checksum_fail;
u64 stop_us = get_cur_time_us();
if (cksum != exec_cksum) {
/* Discard if the mutations change the paths or if it is too decremental
in speed */
if (cksum != exec_cksum ||
(stop_us - start_us > 2 * afl->queue_cur->exec_us)) {
ranges = add_range(ranges, rng->start, rng->start + s / 2);
ranges = add_range(ranges, rng->start + s / 2 + 1, rng->end);
@ -365,9 +370,12 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
u8 status;
// opt not in the paper
u32 fails = 0;
u32 fails;
u8 found_one = 0;
for (i = 0; i < loggeds; ++i) {
fails = 0;
struct cmp_operands *o = &afl->shm.cmp_map->log[key][i];
@ -396,12 +404,17 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
break;
}
if (status == 1)
found_one = 1;
// If failed, add to dictionary
if (fails == 8) {
try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape));
try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape));
if (afl->pass_stats[key].total == 0) {
try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape));
try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape));
}
}
@ -409,6 +422,11 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
afl->stage_cur++;
}
if (!found_one && afl->pass_stats[key].faileds < 0xff) {
afl->pass_stats[key].faileds++;
}
if (afl->pass_stats[key].total < 0xff) afl->pass_stats[key].total++;
return 0;
@ -450,9 +468,12 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
u8 status;
// opt not in the paper
u32 fails = 0;
u32 fails;
u8 found_one = 0;
for (i = 0; i < loggeds; ++i) {
fails = 0;
struct cmpfn_operands *o =
&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[i];
@ -482,12 +503,17 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
break;
}
if (status == 1)
found_one = 1;
// If failed, add to dictionary
if (fails == 8) {
maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape));
maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape));
if (afl->pass_stats[key].total == 0) {
maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape));
maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape));
}
}
@ -495,6 +521,11 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
afl->stage_cur++;
}
if (!found_one && afl->pass_stats[key].faileds < 0xff) {
afl->pass_stats[key].faileds++;
}
if (afl->pass_stats[key].total < 0xff) afl->pass_stats[key].total++;
return 0;
@ -507,6 +538,9 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
u32 exec_cksum) {
u8 r = 1;
if (afl->pass_stats == NULL)
afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W);
if (unlikely(colorization(afl, buf, len, exec_cksum))) return 1;
@ -528,6 +562,12 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
for (k = 0; k < CMP_MAP_W; ++k) {
if (!afl->shm.cmp_map->headers[k].hits) continue;
if (afl->pass_stats[k].total &&
(UR(afl, afl->pass_stats[k].total) < afl->pass_stats[k].faileds ||
afl->pass_stats[k].total == 0xff))
afl->shm.cmp_map->headers[k].hits = 0;
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS)
afl->stage_max += MIN(afl->shm.cmp_map->headers[k].hits, CMP_MAP_H);
else

View File

@ -966,12 +966,6 @@ int main(int argc, char **argv_orig, char **envp) {
if (afl->cmplog_binary) {
if (afl->limit_time_sig)
FATAL(
"MOpt and CmpLog are mutually exclusive. We accept pull requests "
"that integrates MOpt with the optional mutators "
"(custom/radamsa/redquenn/...).");
if (afl->unicorn_mode)
FATAL("CmpLog and Unicorn mode are not compatible at the moment, sorry");
if (!afl->qemu_mode) check_binary(afl, afl->cmplog_binary);