aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
Diffstat (limited to 'src')
-rw-r--r--src/afl-forkserver.c63
-rw-r--r--src/afl-fuzz-bitmap.c3
-rw-r--r--src/afl-fuzz-init.c105
-rw-r--r--src/afl-fuzz-one.c2
-rw-r--r--src/afl-fuzz-redqueen.c336
-rw-r--r--src/afl-fuzz-state.c7
-rw-r--r--src/afl-fuzz-stats.c9
-rw-r--r--src/afl-fuzz.c60
-rw-r--r--src/afl-showmap.c1
9 files changed, 395 insertions, 191 deletions
diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c
index ba7cdd66..9da096f7 100644
--- a/src/afl-forkserver.c
+++ b/src/afl-forkserver.c
@@ -129,6 +129,10 @@ nyx_plugin_handler_t *afl_load_libnyx_plugin(u8 *libnyx_binary) {
plugin->nyx_remove_work_dir = dlsym(handle, "nyx_remove_work_dir");
if (plugin->nyx_remove_work_dir == NULL) { goto fail; }
+ plugin->nyx_config_set_aux_buffer_size =
+ dlsym(handle, "nyx_config_set_aux_buffer_size");
+ if (plugin->nyx_config_set_aux_buffer_size == NULL) { goto fail; }
+
OKF("libnyx plugin is ready!");
return plugin;
@@ -160,6 +164,8 @@ void afl_nyx_runner_kill(afl_forkserver_t *fsrv) {
}
+ if (fsrv->nyx_log_fd >= 0) { close(fsrv->nyx_log_fd); }
+
}
}
@@ -214,6 +220,7 @@ void afl_fsrv_init(afl_forkserver_t *fsrv) {
fsrv->nyx_bind_cpu_id = 0xFFFFFFFF;
fsrv->nyx_use_tmp_workdir = false;
fsrv->nyx_tmp_workdir_path = NULL;
+ fsrv->nyx_log_fd = -1;
#endif
// this structure needs default so we initialize it if this was not done
@@ -571,6 +578,22 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
fsrv->nyx_handlers->nyx_config_set_input_buffer_write_protection(nyx_config,
true);
+ char *nyx_log_path = getenv("AFL_NYX_LOG");
+ if (nyx_log_path) {
+
+ fsrv->nyx_log_fd =
+ open(nyx_log_path, O_CREAT | O_TRUNC | O_WRONLY, DEFAULT_PERMISSION);
+ if (fsrv->nyx_log_fd < 0) {
+
+ NYX_PRE_FATAL(fsrv, "AFL_NYX_LOG path could not be written");
+
+ }
+
+ fsrv->nyx_handlers->nyx_config_set_hprintf_fd(nyx_config,
+ fsrv->nyx_log_fd);
+
+ }
+
if (fsrv->nyx_standalone) {
fsrv->nyx_handlers->nyx_config_set_process_role(nyx_config, StandAlone);
@@ -589,23 +612,36 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
}
- if (getenv("NYX_REUSE_SNAPSHOT") != NULL) {
+ if (getenv("AFL_NYX_AUX_SIZE") != NULL) {
+
+ if (fsrv->nyx_handlers->nyx_config_set_aux_buffer_size(
+ nyx_config, atoi(getenv("AFL_NYX_AUX_SIZE"))) != 1) {
+
+ NYX_PRE_FATAL(fsrv,
+ "Invalid AFL_NYX_AUX_SIZE value set (must be a multiple "
+ "of 4096) ...");
+
+ }
+
+ }
+
+ if (getenv("AFL_NYX_REUSE_SNAPSHOT") != NULL) {
- if (access(getenv("NYX_REUSE_SNAPSHOT"), F_OK) == -1) {
+ if (access(getenv("AFL_NYX_REUSE_SNAPSHOT"), F_OK) == -1) {
- NYX_PRE_FATAL(fsrv, "NYX_REUSE_SNAPSHOT path does not exist");
+ NYX_PRE_FATAL(fsrv, "AFL_NYX_REUSE_SNAPSHOT path does not exist");
}
/* stupid sanity check to avoid passing an empty or invalid snapshot
* directory */
char *snapshot_file_path =
- alloc_printf("%s/global.state", getenv("NYX_REUSE_SNAPSHOT"));
+ alloc_printf("%s/global.state", getenv("AFL_NYX_REUSE_SNAPSHOT"));
if (access(snapshot_file_path, R_OK) == -1) {
- NYX_PRE_FATAL(
- fsrv,
- "NYX_REUSE_SNAPSHOT path does not contain a valid Nyx snapshot");
+ NYX_PRE_FATAL(fsrv,
+ "AFL_NYX_REUSE_SNAPSHOT path does not contain a valid "
+ "Nyx snapshot");
}
@@ -617,13 +653,14 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
char *workdir_snapshot_path =
alloc_printf("%s/workdir/snapshot", outdir_path_absolute);
char *reuse_snapshot_path_real =
- realpath(getenv("NYX_REUSE_SNAPSHOT"), NULL);
+ realpath(getenv("AFL_NYX_REUSE_SNAPSHOT"), NULL);
if (strcmp(workdir_snapshot_path, reuse_snapshot_path_real) == 0) {
- NYX_PRE_FATAL(fsrv,
- "NYX_REUSE_SNAPSHOT path is located in current workdir "
- "(use another output directory)");
+ NYX_PRE_FATAL(
+ fsrv,
+ "AFL_NYX_REUSE_SNAPSHOT path is located in current workdir "
+ "(use another output directory)");
}
@@ -631,7 +668,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
ck_free(workdir_snapshot_path);
fsrv->nyx_handlers->nyx_config_set_reuse_snapshot_path(
- nyx_config, getenv("NYX_REUSE_SNAPSHOT"));
+ nyx_config, getenv("AFL_NYX_REUSE_SNAPSHOT"));
}
@@ -653,7 +690,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
fsrv->nyx_handlers->nyx_get_bitmap_buffer(fsrv->nyx_runner);
fsrv->nyx_handlers->nyx_option_set_reload_mode(
- fsrv->nyx_runner, getenv("NYX_DISABLE_SNAPSHOT_MODE") == NULL);
+ fsrv->nyx_runner, getenv("AFL_NYX_DISABLE_SNAPSHOT_MODE") == NULL);
fsrv->nyx_handlers->nyx_option_apply(fsrv->nyx_runner);
fsrv->nyx_handlers->nyx_option_set_timeout(fsrv->nyx_runner, 2, 0);
diff --git a/src/afl-fuzz-bitmap.c b/src/afl-fuzz-bitmap.c
index fb8a1d4b..87157cad 100644
--- a/src/afl-fuzz-bitmap.c
+++ b/src/afl-fuzz-bitmap.c
@@ -533,7 +533,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
close(fd);
add_to_queue(afl, queue_fn, len, 0);
- if (unlikely(afl->fuzz_mode) && likely(afl->switch_fuzz_mode)) {
+ if (unlikely(afl->fuzz_mode) &&
+ likely(afl->switch_fuzz_mode && !afl->non_instrumented_mode)) {
if (afl->afl_env.afl_no_ui) {
diff --git a/src/afl-fuzz-init.c b/src/afl-fuzz-init.c
index 24fd7077..5a530821 100644
--- a/src/afl-fuzz-init.c
+++ b/src/afl-fuzz-init.c
@@ -1058,7 +1058,19 @@ void perform_dry_run(afl_state_t *afl) {
} else {
- WARNF("Test case '%s' results in a crash, skipping", fn);
+ if (afl->afl_env.afl_crashing_seeds_as_new_crash) {
+
+ WARNF(
+ "Test case '%s' results in a crash, "
+ "as AFL_CRASHING_SEEDS_AS_NEW_CRASH is set, "
+ "saving as a new crash",
+ fn);
+
+ } else {
+
+ WARNF("Test case '%s' results in a crash, skipping", fn);
+
+ }
}
@@ -1078,36 +1090,95 @@ void perform_dry_run(afl_state_t *afl) {
}
- q->disabled = 1;
- q->perf_score = 0;
+ /* Crashing seeds will be regarded as new crashes on startup */
+ if (afl->afl_env.afl_crashing_seeds_as_new_crash) {
- u32 i = 0;
- while (unlikely(i < afl->queued_items && afl->queue_buf[i] &&
- afl->queue_buf[i]->disabled)) {
+ ++afl->total_crashes;
- ++i;
+ if (likely(!afl->non_instrumented_mode)) {
- }
+ classify_counts(&afl->fsrv);
+
+ simplify_trace(afl, afl->fsrv.trace_bits);
+
+ if (!has_new_bits(afl, afl->virgin_crash)) { break; }
+
+ }
+
+ if (unlikely(!afl->saved_crashes) &&
+ (afl->afl_env.afl_no_crash_readme != 1)) {
+
+ write_crash_readme(afl);
+
+ }
+
+ u8 crash_fn[PATH_MAX];
+ u8 *use_name = strstr(q->fname, ",orig:");
+
+ afl->stage_name = "dry_run";
+ afl->stage_short = "dry_run";
+
+#ifndef SIMPLE_FILES
- if (i < afl->queued_items && afl->queue_buf[i]) {
+ snprintf(crash_fn, PATH_MAX, "%s/crashes/id:%06llu,sig:%02u,%s%s",
+ afl->out_dir, afl->saved_crashes, afl->fsrv.last_kill_signal,
+ describe_op(afl, 0,
+ NAME_MAX - strlen("id:000000,sig:00,") -
+ strlen(use_name)),
+ use_name);
- afl->queue = afl->queue_buf[i];
+#else
+
+ snprintf(crash_fn, PATH_MAX, "%s/crashes/id_%06llu_%02u",
+ afl->out_dir, afl->saved_crashes,
+ afl->fsrv.last_kill_signal);
+
+#endif
+
+ ++afl->saved_crashes;
+
+ fd = open(crash_fn, O_WRONLY | O_CREAT | O_EXCL, DEFAULT_PERMISSION);
+ if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", crash_fn); }
+ ck_write(fd, use_mem, read_len, crash_fn);
+ close(fd);
+
+ afl->last_crash_time = get_cur_time();
+ afl->last_crash_execs = afl->fsrv.total_execs;
} else {
- afl->queue = afl->queue_buf[0];
+ u32 i = 0;
+ while (unlikely(i < afl->queued_items && afl->queue_buf[i] &&
+ afl->queue_buf[i]->disabled)) {
- }
+ ++i;
+
+ }
+
+ if (i < afl->queued_items && afl->queue_buf[i]) {
- afl->max_depth = 0;
- for (i = 0; i < afl->queued_items && likely(afl->queue_buf[i]); i++) {
+ afl->queue = afl->queue_buf[i];
- if (!afl->queue_buf[i]->disabled &&
- afl->queue_buf[i]->depth > afl->max_depth)
- afl->max_depth = afl->queue_buf[i]->depth;
+ } else {
+
+ afl->queue = afl->queue_buf[0];
+
+ }
+
+ afl->max_depth = 0;
+ for (i = 0; i < afl->queued_items && likely(afl->queue_buf[i]); i++) {
+
+ if (!afl->queue_buf[i]->disabled &&
+ afl->queue_buf[i]->depth > afl->max_depth)
+ afl->max_depth = afl->queue_buf[i]->depth;
+
+ }
}
+ q->disabled = 1;
+ q->perf_score = 0;
+
break;
case FSRV_RUN_ERROR:
diff --git a/src/afl-fuzz-one.c b/src/afl-fuzz-one.c
index 8ee50bbf..2ad4697e 100644
--- a/src/afl-fuzz-one.c
+++ b/src/afl-fuzz-one.c
@@ -2995,7 +2995,7 @@ havoc_stage:
// fprintf(stderr, "val: %u-%u = %ld\n", off, off2, val);
char buf[20];
- snprintf(buf, sizeof(buf), "%ld", val);
+ snprintf(buf, sizeof(buf), "%" PRId64, val);
// fprintf(stderr, "BEFORE: %s\n", out_buf);
diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c
index 73e188e7..db4991db 100644
--- a/src/afl-fuzz-redqueen.c
+++ b/src/afl-fuzz-redqueen.c
@@ -129,7 +129,6 @@ static struct range *pop_biggest_range(struct range **ranges) {
}
#ifdef _DEBUG
-// static int logging = 0;
static void dump(char *txt, u8 *buf, u32 len) {
u32 i;
@@ -140,6 +139,7 @@ static void dump(char *txt, u8 *buf, u32 len) {
}
+/*
static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) {
char fn[4096];
@@ -155,6 +155,8 @@ static void dump_file(char *path, char *name, u32 counter, u8 *buf, u32 len) {
}
+*/
+
#endif
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u64 *cksum) {
@@ -571,7 +573,6 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) {
}
-// #ifdef CMPLOG_SOLVE_TRANSFORM
static int strntoll(const char *str, size_t sz, char **end, int base,
long long *out) {
@@ -656,7 +657,6 @@ static int is_hex(const char *str) {
}
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
// tests 4 bytes at location
static int is_base64(const char *str) {
@@ -732,12 +732,14 @@ static u32 from_base64(u8 *src, u8 *dst, u32 dst_len) {
}
-static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
+static u32 to_base64(u8 *src, u8 *dst, u32 dst_len) {
u32 i, j, v;
- u32 len = (dst_len >> 2) * 3;
+ // u32 len = (dst_len >> 2) * 3;
+ u32 len = (dst_len / 3) * 4;
+ if (dst_len % 3) len += 4;
- for (i = 0, j = 0; i < len; i += 3, j += 4) {
+ for (i = 0, j = 0; j < len; i += 3, j += 4) {
v = src[i];
v = i + 1 < len ? v << 8 | src[i + 1] : v << 8;
@@ -745,7 +747,8 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
dst[j] = base64_encode_table[(v >> 18) & 0x3F];
dst[j + 1] = base64_encode_table[(v >> 12) & 0x3F];
- if (i + 1 < len) {
+
+ if (i + 1 < dst_len) {
dst[j + 2] = base64_encode_table[(v >> 6) & 0x3F];
@@ -755,7 +758,7 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
}
- if (i + 2 < len) {
+ if (i + 2 < dst_len) {
dst[j + 3] = base64_encode_table[v & 0x3F];
@@ -767,11 +770,10 @@ static void to_base64(u8 *src, u8 *dst, u32 dst_len) {
}
-}
-
-#endif
+ dst[len] = 0;
+ return len;
-// #endif
+}
static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u64 pattern, u64 repl, u64 o_pattern,
@@ -797,42 +799,54 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
- // fprintf(stderr,
- // "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
- // "taint_len=%u shape=%u attr=%u\n",
- // o_pattern, pattern, repl, changed_val, idx, taint_len,
- // hshape, attr);
+ /*
+ fprintf(stderr,
+ "Encode: %llx->%llx into %llx(<-%llx) at idx=%u "
+ "taint_len=%u shape=%u attr=%u\n",
+ o_pattern, pattern, repl, changed_val, idx, taint_len,
+ hshape, attr);
+ */
- // #ifdef CMPLOG_SOLVE_TRANSFORM
// reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u8 *endptr;
u8 use_num = 0, use_unum = 0;
- unsigned long long unum;
- long long num;
+ unsigned long long unum = 0;
+ long long num = 0;
+
+ // if (afl->queue_cur->is_ascii) {
+
+ // we first check if our input are ascii numbers that are transformed to
+ // an integer and used for comparison:
- if (afl->queue_cur->is_ascii) {
+ endptr = buf_8;
+ if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) {
- endptr = buf_8;
- if (strntoll(buf_8, len - idx, (char **)&endptr, 0, &num)) {
+ if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum)) {
- if (!strntoull(buf_8, len - idx, (char **)&endptr, 0, &unum))
- use_unum = 1;
+ use_unum = 1;
- } else
+ }
+
+ } else {
- use_num = 1;
+ use_num = 1;
}
+ //}
+
#ifdef _DEBUG
if (idx == 0)
- fprintf(stderr, "ASCII is=%u use_num=%u use_unum=%u idx=%u %llx==%llx\n",
- afl->queue_cur->is_ascii, use_num, use_unum, idx, num, pattern);
+ fprintf(stderr,
+ "ASCII is=%u use_num=%u>%lld use_unum=%u>%llu idx=%u "
+ "pattern=0x%llx\n",
+ afl->queue_cur->is_ascii, use_num, num, use_unum, unum, idx,
+ pattern);
#endif
- // num is likely not pattern as atoi("AAA") will be zero...
+ // atoi("AAA") == 0 so !num means we have to investigate
if (use_num && ((u64)num == pattern || !num)) {
u8 tmp_buf[32];
@@ -961,10 +975,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// test for arithmetic, eg. "if ((user_val - 0x1111) == 0x1234) ..."
s64 diff = pattern - b_val;
s64 o_diff = o_pattern - o_b_val;
- /* fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
- hshape, o_pattern, o_b_val, o_diff);
- fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
- b_val, diff); */
+ /*
+ fprintf(stderr, "DIFF1 idx=%03u shape=%02u %llx-%llx=%lx\n", idx,
+ hshape, o_pattern, o_b_val, o_diff);
+ fprintf(stderr, "DIFF1 %016llx %llx-%llx=%lx\n", repl, pattern,
+ b_val, diff);
+ */
if (diff == o_diff && diff) {
// this could be an arithmetic transformation
@@ -1275,7 +1291,6 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
// 16 = modified float, 32 = modified integer (modified = wont match
// in original buffer)
- // #ifdef CMPLOG_SOLVE_ARITHMETIC
if (!afl->cmplog_enable_arith || lvl < LVL3 || attr == IS_TRANSFORM) {
return 0;
@@ -2009,8 +2024,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
+ // fprintf(stderr, "its_len=%u repl=%s\n", its_len, repl);
+
+ if (its_len <= 1) { return 0; }
+
if (lvl & LVL3) {
+ if (memcmp(changed_val, repl, its_len) != 0) { return 0; }
+
u32 max_to = MIN(4U, idx);
if (!(lvl & LVL1) && max_to) { from = 1; }
to = max_to;
@@ -2021,27 +2042,32 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
(void)(j);
#ifdef _DEBUG
- fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl,
- o->v0_len >= 0x80 ? 1 : 0, hshape, l0);
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", orig_buf[idx + j]);
- fprintf(stderr, " -> ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", o_pattern[j]);
- fprintf(stderr, " <= ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", repl[j]);
- fprintf(stderr, "\n");
- fprintf(stderr, " ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", buf[idx + j]);
- fprintf(stderr, " -> ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", pattern[j]);
- fprintf(stderr, " <= ");
- for (j = 0; j < 8; j++)
- fprintf(stderr, "%02x", changed_val[j]);
- fprintf(stderr, "\n");
+ if (idx == 0) {
+
+ fprintf(stderr, "RTN T idx=%u lvl=%02x is_txt=%u shape=%u/%u ", idx, lvl,
+ o->v0_len >= 0x80 ? 1 : 0, hshape, l0);
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", orig_buf[idx + j]);
+ fprintf(stderr, " -> ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", o_pattern[j]);
+ fprintf(stderr, " <= ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", repl[j]);
+ fprintf(stderr, "\n");
+ fprintf(stderr, " ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", buf[idx + j]);
+ fprintf(stderr, " -> ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", pattern[j]);
+ fprintf(stderr, " <= ");
+ for (j = 0; j < 8; j++)
+ fprintf(stderr, "%02x", changed_val[j]);
+ fprintf(stderr, "\n");
+
+ }
+
#endif
// Try to match the replace value up to 4 bytes before the current idx.
@@ -2050,6 +2076,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
// if (memcmp(user_val, "TEST-VALUE") == 0) ...
// We only do this in lvl 3, otherwise we only do direct matching
+ // fprintf(stderr, "XXXX FROMB64 saved_idx=%u its_len=%u from=%u to=%u FROMHEX
+ // repl=%s\n", saved_idx, saved_its_len, from, to, repl);
+
for (pre = from; pre <= to; pre++) {
if (*status != 1 && (!pre || !memcmp(buf + saved_idx - pre, repl, pre))) {
@@ -2089,9 +2118,7 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0;
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
u32 tob64 = 0, fromb64 = 0;
-#endif
u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0;
u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0;
u8 xor_val[32], arith_val[32], tmp[48];
@@ -2144,7 +2171,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if (i < 16 && is_hex(repl + (i << 1))) {
+ if (afl->cmplog_enable_xtreme_transform && i < 16 &&
+ is_hex(repl + (i << 1))) {
++tohex;
@@ -2163,9 +2191,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if ((i % 2)) {
+ if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1) {
- if (len > idx + i + 1 && is_hex(orig_buf + idx + i)) {
+ if (len > idx + i + 1 && is_hex(orig_buf + idx + i - 1)) {
fromhex += 2;
@@ -2187,20 +2215,23 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- if (i % 3 == 2 && i < 24) {
+ if (afl->cmplog_enable_xtreme_transform) {
- if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
+ if (i % 3 == 2 && i < 24) {
- }
+ if (is_base64(repl + ((i / 3) << 2))) tob64 += 3;
- if (i % 4 == 3 && i < 24) {
+ }
- if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
+ // fprintf(stderr, "X FROMB64 idx=%u i=%u repl=%s\n", saved_idx, i,
+ // repl);
+ if (i % 4 == 3 && i < 24) {
- }
+ if (is_base64(orig_buf + idx + i - 3)) fromb64 += 4;
-#endif
+ }
+
+ }
if ((o_pattern[i] ^ orig_buf[idx + i]) == xor_val[i] && xor_val[i]) {
@@ -2229,45 +2260,70 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
#ifdef _DEBUG
- fprintf(stderr,
- "RTN idx=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
- "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
- "from_0=%u from_slash=%u from_x=%u\n",
- idx, i, xor, arith, tolower, toupper, tohex, fromhex, to_0,
- to_slash, to_x, from_0, from_slash, from_x);
- #ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- fprintf(stderr, "RTN idx=%u loop=%u tob64=%u from64=%u\n", tob64,
- fromb64);
- #endif
+ if (idx == 0) {
+
+ fprintf(stderr, "RTN Z %s %s %s %s repl=%s\n", buf, pattern, orig_buf,
+ o_pattern, repl);
+ fprintf(
+ stderr,
+ "RTN Z idx=%u len=%u loop=%u xor=%u arith=%u tolower=%u toupper=%u "
+ "tohex=%u fromhex=%u to_0=%u to_slash=%u to_x=%u "
+ "from_0=%u from_slash=%u from_x=%u\n",
+ idx, its_len, i, xor, arith, tolower, toupper, tohex, fromhex, to_0,
+ to_slash, to_x, from_0, from_slash, from_x);
+ if (afl->cmplog_enable_xtreme_transform) {
+
+ fprintf(stderr, "RTN Z idx=%u loop=%u tob64=%u from64=%u\n", idx, i,
+ tob64, fromb64);
+
+ }
+
+ }
+
#endif
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- // input is base64 and converted to binary? convert repl to base64!
- if ((i % 4) == 3 && i < 24 && fromb64 > i) {
+ if (afl->cmplog_enable_xtreme_transform) {
- to_base64(repl, tmp, i + 1);
- memcpy(buf + idx, tmp, i + 1);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT fromb64 %u result %u\n", fromb64,
- // *status);
+ // input is base64 and converted to binary? convert repl to base64!
+ // fprintf(stderr, "FROMB64 idx=%u i=%u %% 4 == 3 && i < 24 &&
+ // fromb64=%u > i, repl=%s\n", saved_idx, i, fromb64, repl);
+ if ((i % 4) == 3 && i < 24 && fromb64 > i) {
- }
+ for (u32 hlen = i; hlen + saved_idx < len && hlen <= its_len;
+ ++hlen) {
- // input is converted to base64? decode repl with base64!
- if ((i % 3) == 2 && i < 24 && tob64 > i) {
+ u32 res = to_base64(repl, tmp, hlen);
+ // fprintf(stderr, "FROMB64 GOGO! idx=%u repl=%s tmp[%u]=%s
+ // hlen=%u\n", saved_idx, repl, res, tmp, hlen);
+ if (res + saved_idx < len) {
- u32 olen = from_base64(repl, tmp, i + 1);
- memcpy(buf + idx, tmp, olen);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64,
- // idx, *status);
+ memcpy(buf + idx, tmp, res);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ // fprintf(stderr, "RTN ATTEMPT FROMB64 idx=%u fromb64 %u %s %s
+ // result %u\n", saved_idx, fromb64, tmp, repl,
+ // *status);
- }
+ }
-#endif
+ }
+
+ }
+
+ // input is converted to base64? decode repl with base64!
+ if ((i % 3) == 2 && i < 24 && tob64 > i) {
+
+ u32 olen = from_base64(repl, tmp, i + 1);
+ memcpy(buf + idx, tmp, olen);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ // fprintf(stderr, "RTN ATTEMPT tob64 %u idx=%u result %u\n", tob64,
+ // idx, *status);
+
+ }
+
+ }
// input is converted to hex? convert repl to binary!
- if (i < 16 && tohex > i) {
+ if (afl->cmplog_enable_xtreme_transform && i < 16 && tohex > i) {
u32 off;
if (to_slash + to_x + to_0 == 2) {
@@ -2292,8 +2348,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
// input is hex and converted to binary? convert repl to hex!
- if (i && (i % 2) && i < 16 && fromhex &&
- fromhex + from_slash + from_x + from_0 > i) {
+ if (afl->cmplog_enable_xtreme_transform && (i % 2) == 1 && i < 16 &&
+ fromhex && fromhex + from_slash + from_x + from_0 > i) {
u8 off = 0;
if (from_slash && from_x) {
@@ -2328,31 +2384,36 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- if (to_up == 1) {
+ for (u32 hlen = i; hlen <= (i << 1) && hlen + idx < len; hlen += i) {
- for (j = 0; j <= (i >> 1); j++) {
+ if (to_up == 1) {
- tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4];
- tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16];
+ for (j = 0; j <= (hlen >> 1); j++) {
- }
+ tmp[off + (j << 1)] = hex_table_up[repl[j] >> 4];
+ tmp[off + (j << 1) + 1] = hex_table_up[repl[j] % 16];
- } else {
+ }
+
+ } else {
- for (j = 0; j <= (i >> 1); j++) {
+ for (j = 0; j <= (hlen >> 1); j++) {
- tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4];
- tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16];
+ tmp[off + (j << 1)] = hex_table_low[repl[j] >> 4];
+ tmp[off + (j << 1) + 1] = hex_table_low[repl[j] % 16];
+
+ }
}
- }
+ memcpy(buf + idx, tmp, hlen + 1 + off);
+ if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
+ tmp[hlen + 1 + off] = 0;
+ // fprintf(stderr, "RTN ATTEMPT idx=%u len=%u fromhex %u %s %s result
+ // %u\n", idx, len, fromhex, tmp, repl, *status);
+ memcpy(buf + idx, save, hlen + 1 + off);
- memcpy(buf + idx, tmp, i + 1 + off);
- if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
- // fprintf(stderr, "RTN ATTEMPT fromhex %u result %u\n", fromhex,
- // *status);
- memcpy(buf + idx, save, i + 1 + off);
+ }
}
@@ -2401,11 +2462,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
if ((i >= 7 &&
(i >= xor&&i >= arith &&i >= tolower &&i >= toupper &&i > tohex &&i >
- (fromhex + from_0 + from_x + from_slash + 1)
-#ifdef CMPLOG_SOLVE_TRANSFORM_BASE64
- && i > tob64 + 3 && i > fromb64 + 4
-#endif
- )) ||
+ (fromhex + from_0 + from_x + from_slash + 1) &&
+ (afl->cmplog_enable_xtreme_transform && i > tob64 + 3 &&
+ i > fromb64 + 4))) ||
repl[i] != changed_val[i] || *status == 1) {
break;
@@ -2418,8 +2477,6 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
}
- // #endif
-
return 0;
}
@@ -2429,7 +2486,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
struct tainted *t;
struct cmp_header *h = &afl->shm.cmp_map->headers[key];
- u32 i, j, idx, have_taint = 1, taint_len, loggeds;
+ u32 i, idx, have_taint = 1, taint_len, loggeds;
u8 status = 0, found_one = 0;
hshape = SHAPE_BYTES(h->shape);
@@ -2452,19 +2509,23 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
struct cmpfn_operands *orig_o =
&((struct cmpfn_operands *)afl->orig_cmp_map->log[key])[i];
- // opt not in the paper
- for (j = 0; j < i; ++j) {
+ /*
+ // opt not in the paper
+ for (j = 0; j < i; ++j) {
- if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j], o,
- sizeof(struct cmpfn_operands))) {
+ if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j],
+ o, sizeof(struct cmpfn_operands))) {
- goto rtn_fuzz_next_iter;
+ goto rtn_fuzz_next_iter;
- }
+ }
- }
+ }
- /*
+ */
+
+#ifdef _DEBUG
+ u32 j;
struct cmp_header *hh = &afl->orig_cmp_map->headers[key];
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
hshape, h->attribute);
@@ -2481,7 +2542,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", orig_o->v1[j]);
fprintf(stderr, "\n");
- */
+#endif
t = taint;
while (t->next) {
@@ -2515,7 +2576,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
status = 0;
#ifdef _DEBUG
- int w;
+ u32 w;
fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx, hshape);
for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", orig_o->v0[w]);
@@ -2605,7 +2666,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
- rtn_fuzz_next_iter:
+ // rtn_fuzz_next_iter:
afl->stage_cur++;
}
@@ -2818,12 +2879,7 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
}
- } else if ((lvl & LVL1)
-
- // #ifdef CMPLOG_SOLVE_TRANSFORM
- || ((lvl & LVL3) && afl->cmplog_enable_transform)
- // #endif
- ) {
+ } else if ((lvl & LVL1) || ((lvl & LVL3) && afl->cmplog_enable_transform)) {
if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, cbuf, len, lvl, taint))) {
diff --git a/src/afl-fuzz-state.c b/src/afl-fuzz-state.c
index 99f69314..5a6b95cf 100644
--- a/src/afl-fuzz-state.c
+++ b/src/afl-fuzz-state.c
@@ -200,6 +200,13 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
afl->afl_env.afl_exit_on_time =
(u8 *)get_afl_env(afl_environment_variables[i]);
+ } else if (!strncmp(env, "AFL_CRASHING_SEEDS_AS_NEW_CRASH",
+
+ afl_environment_variable_len)) {
+
+ afl->afl_env.afl_crashing_seeds_as_new_crash =
+ atoi((u8 *)get_afl_env(afl_environment_variables[i]));
+
} else if (!strncmp(env, "AFL_NO_AFFINITY",
afl_environment_variable_len)) {
diff --git a/src/afl-fuzz-stats.c b/src/afl-fuzz-stats.c
index 4013370d..3d0a9b9a 100644
--- a/src/afl-fuzz-stats.c
+++ b/src/afl-fuzz-stats.c
@@ -37,8 +37,13 @@ char *get_fuzzing_state(afl_state_t *afl) {
u64 cur_run_time = cur_ms - afl->start_time;
u64 cur_total_run_time = afl->prev_run_time + cur_run_time;
- if (unlikely(cur_run_time < 60 * 3 * 1000 ||
- cur_total_run_time < 60 * 5 * 1000)) {
+ if (unlikely(afl->non_instrumented_mode)) {
+
+ return fuzzing_state[1];
+
+ } else if (unlikely(cur_run_time < 60 * 3 * 1000 ||
+
+ cur_total_run_time < 60 * 5 * 1000)) {
return fuzzing_state[0];
diff --git a/src/afl-fuzz.c b/src/afl-fuzz.c
index 9afece66..cdb3f996 100644
--- a/src/afl-fuzz.c
+++ b/src/afl-fuzz.c
@@ -180,12 +180,14 @@ static void usage(u8 *argv0, int more_help) {
"it.\n"
" if using QEMU/FRIDA or the fuzzing target is "
"compiled\n"
- " for CmpLog then just use -c 0.\n"
+ " for CmpLog then use '-c 0'. To disable Cmplog use '-c "
+ "-'.\n"
" -l cmplog_opts - CmpLog configuration values (e.g. \"2ATR\"):\n"
" 1=small files, 2=larger files (default), 3=all "
"files,\n"
" A=arithmetic solving, T=transformational solving,\n"
- " R=random colorization bytes.\n\n"
+ " X=extreme transform solving, R=random colorization "
+ "bytes.\n\n"
"Fuzzing behavior settings:\n"
" -Z - sequential queue selection instead of weighted "
"random\n"
@@ -277,7 +279,8 @@ static void usage(u8 *argv0, int more_help) {
"AFL_IGNORE_UNKNOWN_ENVS: don't warn on unknown env vars\n"
"AFL_IMPORT_FIRST: sync and import test cases from other fuzzer instances first\n"
"AFL_INPUT_LEN_MIN/AFL_INPUT_LEN_MAX: like -g/-G set min/max fuzz length produced\n"
- "AFL_PIZZA_MODE: 1 - enforce pizza mode, 0 - disable for April 1st\n"
+ "AFL_PIZZA_MODE: 1 - enforce pizza mode, -1 - disable for April 1st,\n"
+ " 0 (default) - activate on April 1st\n"
"AFL_KILL_SIGNAL: Signal ID delivered to child processes on timeout, etc.\n"
" (default: SIGKILL)\n"
"AFL_FORK_SERVER_KILL_SIGNAL: Kill signal for the fork server on termination\n"
@@ -297,7 +300,12 @@ static void usage(u8 *argv0, int more_help) {
"AFL_NO_SNAPSHOT: do not use the snapshot feature (if the snapshot lkm is loaded)\n"
"AFL_NO_STARTUP_CALIBRATION: no initial seed calibration, start fuzzing at once\n"
"AFL_NO_UI: switch status screen off\n"
-
+ "AFL_NYX_AUX_SIZE: size of the Nyx auxiliary buffer. Must be a multiple of 4096.\n"
+ " Increase this value in case the crash reports are truncated.\n"
+ " Default value is 4096.\n"
+ "AFL_NYX_DISABLE_SNAPSHOT_MODE: disable snapshot mode (must be supported by the agent)\n"
+ "AFL_NYX_LOG: output NYX hprintf messages to another file\n"
+ "AFL_NYX_REUSE_SNAPSHOT: reuse an existing Nyx root snapshot\n"
DYN_COLOR
"AFL_PATH: path to AFL support binaries\n"
@@ -306,8 +314,8 @@ static void usage(u8 *argv0, int more_help) {
PERSISTENT_MSG
- "AFL_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to the queue,\n"
- " but execute the post-processed one\n"
+ "AFL_POST_PROCESS_KEEP_ORIGINAL: save the file as it was prior post-processing to\n"
+ " the queue, but execute the post-processed one\n"
"AFL_PRELOAD: LD_PRELOAD / DYLD_INSERT_LIBRARIES settings for target\n"
"AFL_TARGET_ENV: pass extra environment variables to target\n"
"AFL_SHUFFLE_QUEUE: reorder the input queue randomly on startup\n"
@@ -318,18 +326,17 @@ static void usage(u8 *argv0, int more_help) {
"AFL_STATSD_HOST: change default statsd host (default 127.0.0.1)\n"
"AFL_STATSD_PORT: change default statsd port (default: 8125)\n"
"AFL_STATSD_TAGS_FLAVOR: set statsd tags format (default: disable tags)\n"
- " Supported formats are: 'dogstatsd', 'librato',\n"
- " 'signalfx' and 'influxdb'\n"
+ " suported formats: dogstatsd, librato, signalfx, influxdb\n"
"AFL_SYNC_TIME: sync time between fuzzing instances (in minutes)\n"
"AFL_NO_CRASH_README: do not create a README in the crashes directory\n"
"AFL_TESTCACHE_SIZE: use a cache for testcases, improves performance (in MB)\n"
"AFL_TMPDIR: directory to use for input file generation (ramdisk recommended)\n"
"AFL_EARLY_FORKSERVER: force an early forkserver in an afl-clang-fast/\n"
" afl-clang-lto/afl-gcc-fast target\n"
- "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib\n"
- "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a .so)\n"
- "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in seconds, "
- "(default: 60, minimum: 1)\n"
+ "AFL_PERSISTENT: enforce persistent mode (if __AFL_LOOP is in a shared lib)\n"
+ "AFL_DEFER_FORKSRV: enforced deferred forkserver (__AFL_INIT is in a shared lib)\n"
+ "AFL_FUZZER_STATS_UPDATE_INTERVAL: interval to update fuzzer_stats file in\n"
+ " seconds (default: 60, minimum: 1)\n"
"\n"
);
@@ -594,8 +601,23 @@ int main(int argc, char **argv_orig, char **envp) {
case 'c': {
- afl->shm.cmplog_mode = 1;
- afl->cmplog_binary = ck_strdup(optarg);
+ if (strcmp(optarg, "-") == 0) {
+
+ if (afl->shm.cmplog_mode) {
+
+ ACTF("Disabling cmplog again because of '-c -'.");
+ afl->shm.cmplog_mode = 0;
+ afl->cmplog_binary = NULL;
+
+ }
+
+ } else {
+
+ afl->shm.cmplog_mode = 1;
+ afl->cmplog_binary = ck_strdup(optarg);
+
+ }
+
break;
}
@@ -1120,6 +1142,10 @@ int main(int argc, char **argv_orig, char **envp) {
case 'T':
afl->cmplog_enable_transform = 1;
break;
+ case 'x':
+ case 'X':
+ afl->cmplog_enable_xtreme_transform = 1;
+ break;
case 'r':
case 'R':
afl->cmplog_random_colorization = 1;
@@ -1500,8 +1526,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (!afl->use_banner) { afl->use_banner = argv[optind]; }
- if (afl->shm.cmplog_mode &&
- (!strcmp("-", afl->cmplog_binary) || !strcmp("0", afl->cmplog_binary))) {
+ if (afl->shm.cmplog_mode && strcmp("0", afl->cmplog_binary) == 0) {
afl->cmplog_binary = strdup(argv[optind]);
@@ -2755,7 +2780,8 @@ int main(int argc, char **argv_orig, char **envp) {
u64 cur_time = get_cur_time();
- if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0) &&
+ if (likely(afl->switch_fuzz_mode && afl->fuzz_mode == 0 &&
+ !afl->non_instrumented_mode) &&
unlikely(cur_time > afl->last_find_time + afl->switch_fuzz_mode)) {
if (afl->afl_env.afl_no_ui) {
diff --git a/src/afl-showmap.c b/src/afl-showmap.c
index b82bcd72..7a639cf6 100644
--- a/src/afl-showmap.c
+++ b/src/afl-showmap.c
@@ -1611,6 +1611,7 @@ int main(int argc, char **argv_orig, char **envp) {
if (in_dir || in_filelist) {
afl->fsrv.dev_urandom_fd = open("/dev/urandom", O_RDONLY);
+ if (afl->fsrv.dev_urandom_fd < 0) { PFATAL("Unable to open /dev/urandom"); }
afl->afl_env.afl_custom_mutator_library =
getenv("AFL_CUSTOM_MUTATOR_LIBRARY");
afl->afl_env.afl_python_module = getenv("AFL_PYTHON_MODULE");