Compare commits

...

20 Commits
3.0c ... taint

Author SHA1 Message Date
9b701605a7 update readme 2020-08-20 14:26:20 +02:00
a6d3b33902 Merge pull request #516 from AFLplusplus/debug
push previous dev to taint
2020-08-20 14:18:37 +02:00
1ef94511eb fix another crash 2020-08-15 20:50:07 +02:00
757beb547e important bugfix for large covmaps 2020-08-15 18:16:09 +02:00
e935c40e1e initial mem changes 2020-08-15 13:43:28 +02:00
c8b066b168 crash fix and more stats 2020-08-15 12:05:08 +02:00
2d279f05dd more stats, force deterministic for taint 2020-08-15 11:51:10 +02:00
befd6b2be4 more stats 2020-08-15 11:33:29 +02:00
982f15d939 fix file naming 2020-08-15 11:27:19 +02:00
e2a3c560dc change strategy 2020-08-15 11:16:52 +02:00
a8346a2412 Merge pull request #506 from AFLplusplus/taint
min length map
2020-08-14 21:31:08 +02:00
0dc2af0ecb min length map 2020-08-14 21:30:09 +02:00
eb85fe7b08 Merge pull request #504 from AFLplusplus/taint
Taint to debug
2020-08-14 13:25:01 +02:00
bf4d01e549 Merge pull request #503 from AFLplusplus/dev
to debug
2020-08-14 13:23:38 +02:00
fa0ce5f51f max 84% of taint for taint mode 2020-08-14 06:25:31 +02:00
4c0212a054 debug attempt 2020-08-13 22:48:02 +02:00
f375b69e26 fix buf 2020-08-13 15:55:39 +02:00
17aa6b942a save stack 2020-08-13 15:44:42 +02:00
5f47ef406a fix crash 2020-08-13 11:32:12 +02:00
10ccd9a97b fix bugs 2020-08-12 09:55:59 +02:00
11 changed files with 336 additions and 192 deletions

View File

@ -1,7 +1,5 @@
# qemu_taint variant.
UPDATE: **WORKS NOW** **PLEASE TEST** **:-)**
## HOWTO
cd qemu_taint && ./build_qemu_taint.sh
@ -10,13 +8,15 @@ afl-fuzz -A ...
## CAVEATS
* llvm shmem persistent mode does not and can not not work
** Tests have shown that taint is rarely helping, in approx 20-30% of cases
and there only slightly, hence this is not further followed-up **
**There is still a bug somewhere which can crash afl-fuzz :-(**
* llvm shmem persistent mode does not and cannot work
* MOpt works but totally ignores the taint information, so disabled here
* custom mutators? dunno if they work or not. depends on how they work.
* not tested with qemu_mode
* there are several debug checks to ensure the data is fine which slows down
fuzzing, if the beta experiment runs fine these will be improved and it
will result in quite a speed gain.
## THE TAINT

View File

@ -106,7 +106,7 @@ If 1, close stdout at startup. If 2 close stderr; if 3 close both.
#error "Support for your platform has not been implemented"
#endif
int __afl_sharedmem_fuzzing = 0;
int __afl_sharedmem_fuzzing = 0;
// libFuzzer interface is thin, so we don't include any libFuzzer headers.
int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
@ -283,11 +283,7 @@ int main(int argc, char **argv) {
printf("WARNING: using the deprecated call style `%s %d`\n", argv[0], N);
else if (argc > 1) {
if (!getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) {
__afl_manual_init();
}
if (!getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) { __afl_manual_init(); }
return ExecuteFilesOnyByOne(argc, argv);

View File

@ -515,7 +515,7 @@ typedef struct afl_state {
var_byte_count, /* Bitmap bytes with var behavior */
current_entry, /* Current queue entry ID */
havoc_div, /* Cycle count divisor for havoc */
taint_len, taint_count;
taint_len, taint_count, taint_runs;
u64 total_crashes, /* Total number of crashes */
unique_crashes, /* Crashes with unique signatures */

View File

@ -70,21 +70,21 @@
#ifndef __NetBSD__
#ifndef WORD_SIZE_64
#define MEM_LIMIT 25
#else
#define MEM_LIMIT 50
#else
#define MEM_LIMIT 75
#endif /* ^!WORD_SIZE_64 */
#else /* NetBSD's kernel needs more space for stack, see discussion for issue \
#165 */
#define MEM_LIMIT 200
#define MEM_LIMIT 250
#endif
/* Default memory limit when running in QEMU mode (MB): */
#define MEM_LIMIT_QEMU 200
#define MEM_LIMIT_QEMU 250
/* Default memory limit when running in Unicorn mode (MB): */
#define MEM_LIMIT_UNICORN 200
#define MEM_LIMIT_UNICORN 250
/* Number of calibration cycles per every new test case (and for test
cases that show variable behavior): */

View File

@ -282,13 +282,14 @@
\
} while (0)
#define ck_read(fd, buf, len, fn) \
do { \
\
s32 _len = (s32)(len); \
s32 _res = read(fd, buf, _len); \
if (_res != _len) RPFATAL(_res, "Short read from %s", fn); \
\
#define ck_read(fd, buf, len, fn) \
do { \
\
s32 _len = (s32)(len); \
s32 _res = read(fd, buf, _len); \
if (_res != _len) \
RPFATAL(_res, "Short read from %s, %d < %d", fn, _res, (s32)_len); \
\
} while (0)
#endif /* ! _HAVE_DEBUG_H */

View File

@ -107,6 +107,10 @@ struct cmp_map *__afl_cmp_map;
static u8 is_persistent;
/* Are we in sancov mode? */
static u8 _is_sancov;
/* Error reporting to forkserver controller */
void send_forkserver_error(int error) {
@ -190,19 +194,10 @@ static void __afl_map_shm(void) {
if (__afl_final_loc) {
if (__afl_area_ptr && __afl_final_loc &&
__afl_final_loc > MAP_INITIAL_SIZE &&
__afl_area_ptr != __afl_area_initial) {
munmap(__afl_area_ptr, __afl_final_loc);
__afl_area_ptr = __afl_area_initial;
}
if (__afl_final_loc % 8)
__afl_final_loc = (((__afl_final_loc + 7) >> 3) << 3);
__afl_map_size = __afl_final_loc;
if (__afl_final_loc > MAP_SIZE) {
char *ptr;
@ -212,10 +207,12 @@ static void __afl_map_shm(void) {
if (__afl_final_loc > FS_OPT_MAX_MAPSIZE) {
fprintf(stderr,
"Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u to "
"be able to run this instrumented program!\n",
__afl_final_loc);
if (!getenv("AFL_QUIET"))
fprintf(stderr,
"Error: AFL++ tools *require* to set AFL_MAP_SIZE to %u "
"to be able to run this instrumented program!\n",
__afl_final_loc);
if (id_str) {
send_forkserver_error(FS_ERROR_MAP_SIZE);
@ -225,10 +222,11 @@ static void __afl_map_shm(void) {
} else {
fprintf(stderr,
"Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u to "
"be able to run this instrumented program!\n",
__afl_final_loc);
if (!getenv("AFL_QUIET"))
fprintf(stderr,
"Warning: AFL++ tools will need to set AFL_MAP_SIZE to %u "
"to be able to run this instrumented program!\n",
__afl_final_loc);
}
@ -251,6 +249,13 @@ static void __afl_map_shm(void) {
if (id_str) {
if (__afl_area_ptr && __afl_area_ptr != __afl_area_initial) {
free(__afl_area_ptr);
__afl_area_ptr = __afl_area_initial;
}
#ifdef USEMMAP
const char * shm_file_path = id_str;
int shm_fd = -1;
@ -332,6 +337,14 @@ static void __afl_map_shm(void) {
}
} else if (_is_sancov && __afl_area_ptr != __afl_area_initial) {
free(__afl_area_ptr);
__afl_area_ptr = NULL;
if (__afl_final_loc > MAP_INITIAL_SIZE)
__afl_area_ptr = malloc(__afl_final_loc);
if (!__afl_area_ptr) __afl_area_ptr = __afl_area_initial;
}
id_str = getenv(CMPLOG_SHM_ENV_VAR);
@ -902,15 +915,10 @@ __attribute__((constructor(0))) void __afl_auto_first(void) {
if (getenv("AFL_DISABLE_LLVM_INSTRUMENTATION")) return;
u8 *ptr;
u32 get_size = __afl_final_loc ? __afl_final_loc : 1024000;
if (__afl_final_loc > MAP_INITIAL_SIZE) {
ptr = (u8 *)mmap(NULL, __afl_final_loc, PROT_READ | PROT_WRITE, MAP_PRIVATE,
-1, 0);
if (ptr && (ssize_t)ptr != -1) { __afl_area_ptr = ptr; }
}
ptr = (u8 *)malloc(get_size);
if (ptr && (ssize_t)ptr != -1) { __afl_area_ptr = ptr; }
}
@ -978,6 +986,8 @@ void __sanitizer_cov_trace_pc_guard_init(uint32_t *start, uint32_t *stop) {
u32 inst_ratio = 100;
char *x;
_is_sancov = 1;
if (getenv("AFL_DEBUG")) {
fprintf(stderr, "Running __sanitizer_cov_trace_pc_guard_init: %p-%p\n",

View File

@ -458,145 +458,182 @@ u8 fuzz_one_original(afl_state_t *afl) {
}
u32 tmp_val = 0;
u32 tmp_val = 0, taint_finds, taint_execs;
if (unlikely(afl->taint_mode)) {
tmp_val = afl->queue_cycle % 2; // starts with 1
ret_val = 0;
afl->taint_needs_splode = 0;
if (unlikely(afl->queue_cur->cal_failed && !tmp_val)) goto abandon_entry;
if (unlikely(!afl->skip_deterministic && !afl->queue_cur->passed_det &&
!tmp_val))
goto abandon_entry;
if ((!afl->queue_cur->taint_bytes_new ||
afl->queue_cur->taint_bytes_new == afl->queue_cur->len) &&
!tmp_val)
goto abandon_entry;
if (!tmp_val) { // sole fuzz tainted new bytes
ret_val = 1;
ret_val = 0;
if (likely(!afl->queue_cur->taint_bytes_new ||
afl->queue_cur->taint_bytes_new == afl->queue_cur->len))
goto abandon_entry;
if (unlikely(afl->queue_cur->cal_failed)) goto abandon_entry;
if (unlikely(!afl->skip_deterministic && !afl->queue_cur->passed_det))
goto abandon_entry;
s32 dst = 0, i;
ret_val = 1;
afl->taint_needs_splode = 1;
taint_finds = afl->queued_paths + afl->unique_crashes;
taint_execs = afl->fsrv.total_execs;
}
}
if (unlikely(afl->taint_needs_splode)) {
// s32 dst = 0, i;
temp_len = len = afl->queue_cur->len;
s32 j = 0; // tmp
// s32 j = 0; // tmp
// if (afl->queue_cur->len < 4) len = 4;
// else len = afl->queue_cur->len;
fd = open(afl->queue_cur->fname, O_RDONLY);
afl->taint_src = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
afl->taint_src =
mmap(0, len < 4 ? 4 : len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)afl->taint_src == -1)
FATAL("unable to open '%s'", afl->queue_cur->fname);
close(fd);
afl->taint_needs_splode = 1;
switch (tmp_val) {
/*
afl->taint_needs_splode = 1;
case 1: // fuzz only tainted bytes
switch (tmp_val) {
// special case: all or nothing tainted. in this case we act like
// nothing is special. this is not the taint you are looking for ...
if (!afl->queue_cur->taint_bytes_all ||
afl->queue_cur->taint_bytes_all == (u32)len) {
case 1: // fuzz only tainted bytes
orig_in = in_buf = afl->taint_src;
afl->taint_needs_splode = 0;
break;
fd = open(afl->taint_input_file, O_RDONLY);
temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all;
orig_in = in_buf =
mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536,
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s'", afl->taint_input_file);
close(fd);
}
fd = open(afl->queue_cur->fname_taint, O_RDONLY);
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ |
PROT_WRITE, MAP_PRIVATE, fd, 0); if (fd < 0) {
fd = open(afl->taint_input_file, O_RDONLY);
temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_all;
orig_in = in_buf =
mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536,
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s'", afl->taint_input_file);
close(fd);
afl->queue_cur->taint_bytes_all = 0;
goto abandon_entry;
fd = open(afl->queue_cur->fname_taint, O_RDONLY);
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s'", afl->queue_cur->fname_taint);
close(fd);
}
for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++)
if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i];
if ((ssize_t)afl->taint_map == -1)
FATAL("unable to mmap '%s'", afl->queue_cur->fname_taint);
close(fd);
// FIXME DEBUG TODO XXX
for (i = 0; i < (s32)afl->queue_cur->len; i++) {
for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++)
if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i];
switch (afl->taint_map[i]) {
// FIXME DEBUG TODO XXX
/ *
for (i = 0; i < (s32)afl->queue_cur->len; i++) {
case 0x0:
break;
case '!':
j++;
break;
default:
FATAL(
"invalid taint map entry byte 0x%02x at position %d "
"(passed_det:%d)\n",
afl->taint_map[i], i, afl->queue_cur->passed_det);
switch (afl->taint_map[i]) {
}
case 0x0:
break;
case '!':
j++;
break;
default:
FATAL(
"invalid taint map entry byte 0x%02x at position
%d "
"(passed_det:%d)\n",
afl->taint_map[i], i, afl->queue_cur->passed_det);
}
}
if (j != len)
FATAL("different taint values in map vs in queue (%d != %d)", j, len);
}
break;
if (j != len)
FATAL("different taint values in map vs in queue (%d !=
%d)", j, len);
* /
break;
case 0: // fuzz only newly tainted bytes
case 0: // fuzz only newly tainted bytes
*/
fd = open(afl->taint_input_file, O_RDONLY);
temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new;
orig_in = in_buf =
mmap(0, len >= MAX_FILE - 65536 ? MAX_FILE : len + 65536,
PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s'", afl->taint_input_file);
close(fd);
u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint);
if (!fn) FATAL("OOM");
fd = open(fn, O_RDWR);
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if (fd < 0) {
u8 *fn = alloc_printf("%s.new", afl->queue_cur->fname_taint);
if (!fn) FATAL("OOM");
fd = open(fn, O_RDWR);
afl->taint_map = mmap(0, afl->queue_cur->len, PROT_READ | PROT_WRITE,
MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s' for %u bytes", fn, len);
close(fd);
ck_free(fn);
for (i = 0; i < (s32)afl->queue_cur->len && dst < len; i++)
if (afl->taint_map[i]) in_buf[dst++] = afl->taint_src[i];
// FIXME DEBUG TODO XXX
for (i = 0; i < (s32)afl->queue_cur->len; i++) {
switch (afl->taint_map[i]) {
case 0x0:
break;
case '!':
j++;
break;
default:
FATAL(
"invalid taint map entry byte 0x%02x at position %d "
"(passed_det:%d)\n",
afl->taint_map[i], i, afl->queue_cur->passed_det);
}
}
if (j != len)
FATAL("different taint values in map vs in queue (%d != %d)", j, len);
break;
ck_free(fn);
afl->queue_cur->taint_bytes_new = 0;
goto abandon_entry;
}
if ((ssize_t)afl->taint_map == -1) FATAL("unable to mmap '%s'", fn);
close(fd);
u8 *fndata = alloc_printf("%s.data", fn);
fd = open(fndata, O_RDONLY);
/*
if (fd < 0) {
ck_free(fn);
afl->queue_cur->taint_bytes_new = 0;
goto abandon_entry;
}
*/
temp_len = len = afl->taint_len = afl->queue_cur->taint_bytes_new;
orig_in = in_buf =
mmap(0, len + 4, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (fd < 0 || (ssize_t)in_buf == -1)
FATAL("unable to open '%s' for %u bytes", fndata, len);
close(fd);
ck_free(fndata);
ck_free(fn);
afl->taint_runs++;
// FIXME DEBUG TODO XXX
/*
for (i = 0; i < (s32)afl->queue_cur->len; i++) {
switch (afl->taint_map[i]) {
case 0x0:
break;
case '!':
j++;
break;
default:
FATAL(
"invalid taint map entry byte 0x%02x at position %d "
"(passed_det:%d)\n",
afl->taint_map[i], i, afl->queue_cur->passed_det);
}
}
if (j != len)
FATAL("different taint values in map vs in queue (%d != %d)",
j, len);
*/
/*
break;
}
*/
} else {
/* Map the test case into memory. */
@ -611,7 +648,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
len = afl->queue_cur->len;
orig_in = in_buf = mmap(0, len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
// if (afl->queue_cur->len < 4) len = 4;
// else len = afl->queue_cur->len;
orig_in = in_buf =
mmap(0, len < 4 ? 4 : len, PROT_READ | PROT_WRITE, MAP_PRIVATE, fd, 0);
if (unlikely(orig_in == MAP_FAILED)) {
@ -637,7 +678,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
* CALIBRATION (only if failed earlier on) *
*******************************************/
if (unlikely(afl->queue_cur->cal_failed)) {
if (unlikely(afl->queue_cur->cal_failed && !afl->taint_needs_splode)) {
u8 res = FSRV_RUN_TMOUT;
@ -699,6 +740,7 @@ u8 fuzz_one_original(afl_state_t *afl) {
}
//fprintf(stderr, "%p[%u] %p[%u] %u (%p %p)\n", out_buf, afl->out_size, in_buf, afl->in_size, len, afl->out_buf, afl->in_buf);
memcpy(out_buf, in_buf, len);
/*********************
@ -709,9 +751,10 @@ u8 fuzz_one_original(afl_state_t *afl) {
if (unlikely(perf_score == 0)) { goto abandon_entry; }
if (afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized) {
if (unlikely(afl->shm.cmplog_mode && !afl->queue_cur->fully_colorized && !afl->taint_needs_splode)) {
int res;
/*
if (unlikely(afl->taint_needs_splode)) {
len = afl->queue_cur->len;
@ -723,12 +766,12 @@ u8 fuzz_one_original(afl_state_t *afl) {
res = 1;
} else {
*/
res = input_to_state_stage(afl, in_buf, out_buf, len,
afl->queue_cur->exec_cksum);
/*
}
*/
if (unlikely(res)) { goto abandon_entry; }
}
@ -738,11 +781,13 @@ u8 fuzz_one_original(afl_state_t *afl) {
if it has gone through deterministic testing in earlier, resumed runs
(passed_det). */
if (likely(afl->queue_cur->passed_det) || likely(afl->skip_deterministic) ||
likely(perf_score <
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
? afl->queue_cur->depth * 30
: afl->havoc_max_mult * 100))) {
if (likely(afl->queue_cur->passed_det) ||
likely(!afl->taint_needs_splode && afl->skip_deterministic) ||
likely(!afl->taint_needs_splode &&
perf_score <
(afl->queue_cur->depth * 30 <= afl->havoc_max_mult * 100
? afl->queue_cur->depth * 30
: afl->havoc_max_mult * 100))) {
goto custom_mutator_stage;
@ -2256,7 +2301,7 @@ havoc_stage:
out_buf[rand_below(afl, temp_len)] ^= 1 + rand_below(afl, 255);
break;
case 11 ... 12: {
case 11: {
/* Delete bytes. We're making this a bit more likely
than insertion (the next option) in hopes of keeping
@ -2281,7 +2326,7 @@ havoc_stage:
}
case 13:
case 12 ... 13:
if (temp_len + HAVOC_BLK_XL < MAX_FILE) {
@ -2343,7 +2388,7 @@ havoc_stage:
/* Tail */
memmove(new_buf + clone_to + clone_len, out_buf + clone_to,
temp_len - clone_to);
temp_len - clone_to);
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = new_buf;
@ -2392,7 +2437,7 @@ havoc_stage:
u8 *new_buf = ck_maybe_grow(BUF_PARAMS(out_scratch),
copy_to + copy_len);
memcpy(new_buf, in_buf, copy_to);
memcpy(new_buf, out_buf, copy_to);
memcpy(new_buf + copy_to, afl->taint_src + copy_from,
copy_len);
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
@ -2600,8 +2645,12 @@ havoc_stage:
memcpy(temp_buf + clone_to, new_buf + clone_from, clone_len);
/* Tail */
memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to,
temp_len - clone_to);
if (unlikely(afl->taint_needs_splode))
memmove(temp_buf + clone_to + clone_len, out_buf + clone_to,
temp_len - clone_to);
else
memcpy(temp_buf + clone_to + clone_len, out_buf + clone_to,
temp_len - clone_to);
swap_bufs(BUF_PARAMS(out), BUF_PARAMS(out_scratch));
out_buf = temp_buf;
@ -2772,6 +2821,15 @@ abandon_entry:
afl->splicing_with = -1;
if (afl->taint_needs_splode) {
afl->stage_finds[STAGE_PYTHON] +=
(afl->queued_paths + afl->unique_crashes - taint_finds);
afl->stage_cycles[STAGE_PYTHON] += (afl->fsrv.total_execs - taint_execs);
afl->stage_finds[STAGE_CUSTOM_MUTATOR]++;
}
/* Update afl->pending_not_fuzzed count if we made it through the calibration
cycle and have not seen this entry before. */

View File

@ -106,6 +106,8 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname,
u8 *mem, u32 len) {
if (q->len < 16) return;
u8 * ptr, *fn = fname;
u32 bytes = 0, plen = len;
struct queue_entry *prev = q->prev;
@ -131,29 +133,34 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname,
fprintf(stderr, "Debug: tainted %u out of %u bytes\n", bytes, len);
/* DEBUG FIXME TODO XXX */
u32 i;
for (i = 0; i < len; i++) {
/*
u32 i;
for (i = 0; i < len; i++) {
if (afl->taint_fsrv.trace_bits[i] &&
afl->taint_fsrv.trace_bits[i] != '!')
FATAL("invalid taint map value %02x at pos %d",
afl->taint_fsrv.trace_bits[i], i);
if (afl->taint_fsrv.trace_bits[i] &&
afl->taint_fsrv.trace_bits[i] != '!')
FATAL("invalid taint map value %02x at pos %d",
afl->taint_fsrv.trace_bits[i], i);
}
}
if (len < plen)
for (i = len; i < plen; i++) {
if (len < plen)
for (i = len; i < plen; i++) {
if (afl->taint_fsrv.trace_bits[i])
FATAL("invalid taint map value %02x in padding at pos %d",
afl->taint_fsrv.trace_bits[i], i);
if (afl->taint_fsrv.trace_bits[i])
FATAL("invalid taint map value %02x in padding at pos %d",
afl->taint_fsrv.trace_bits[i], i);
}
}
*/
}
// if (((bytes * 100) / len) > 85) bytes = len;
// if all is tainted we do not need to write taint data away
if (bytes && bytes < len) {
if (bytes) {
// save the bytes away
int w = open(q->fname_taint, O_CREAT | O_WRONLY, 0644);
@ -168,7 +175,7 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname,
i--;
q->taint_bytes_highest = i;
afl->taint_count++;
// afl->taint_count++;
} else {
@ -207,6 +214,29 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname,
fprintf(stderr, "Debug: %u new taint out of %u bytes\n", bytes,
len);
switch (q->taint_bytes_new) {
case 0:
break;
case 1:
if (len <= 64) q->taint_bytes_new = 0;
break;
case 2:
if (len <= 32) q->taint_bytes_new = 0;
break;
case 3:
if (len <= 16) q->taint_bytes_new = 0;
break;
case 4:
if (len <= 8) q->taint_bytes_new = 0;
break;
default:
if (((q->taint_bytes_new * 100) / len) >= 50)
q->taint_bytes_new = 0;
break;
}
if (q->taint_bytes_new) {
u8 *fnw = alloc_printf("%s.new", q->fname_taint);
@ -217,6 +247,8 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname,
ck_write(w, tmp, plen, fnw);
close(w);
afl->taint_count++;
afl->stage_cycles[STAGE_CUSTOM_MUTATOR]++;
} else {
@ -225,6 +257,38 @@ void perform_taint_run(afl_state_t *afl, struct queue_entry *q, u8 *fname,
}
u8 *fnwdata = alloc_printf("%s.data", fnw);
if (fnwdata) {
u8 *data = ck_maybe_grow(BUF_PARAMS(out_scratch), plen);
if ((ssize_t)data == -1) FATAL("maybegrow failed");
u32 j = 0;
for (i = 0; i < len && j < q->taint_bytes_new; i++)
if (tmp[i] == '!') data[j++] = mem[i];
memset(data + q->taint_bytes_new, 0, 4);
int w = open(fnwdata, O_CREAT | O_WRONLY, 0644);
if (w >= 0) {
ck_write(w, data, q->taint_bytes_new + 4, fnw);
close(w);
} else {
FATAL("count not create '%s'", fnwdata);
q->taint_bytes_new = 0;
}
ck_free(fnwdata);
} else {
q->taint_bytes_new = 0;
}
ck_free(fnw);
} else {
@ -272,12 +336,18 @@ static u8 check_if_text(struct queue_entry *q) {
if (q->len < AFL_TXT_MIN_LEN) return 0;
u8 buf[MAX_FILE];
s32 fd, len = q->len, offset = 0, ascii = 0, utf8 = 0, comp;
if (len >= MAX_FILE) len = MAX_FILE - 1;
if ((fd = open(q->fname, O_RDONLY)) < 0) return 0;
if ((comp = read(fd, buf, len)) != len) return 0;
u8 *buf = ck_alloc(q->len + 32);
if ((comp = read(fd, buf, len)) != len) {
ck_free(buf);
return 0;
}
buf[len] = 0;
close(fd);
@ -363,6 +433,8 @@ static u8 check_if_text(struct queue_entry *q) {
}
ck_free(buf);
u32 percent_utf8 = (utf8 * 100) / comp;
u32 percent_ascii = (ascii * 100) / len;

View File

@ -862,6 +862,12 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
abort_trimming:
afl->bytes_trim_out += q->len;
if (unlikely(afl->taint_mode)) {
if (q->taint_bytes_all > q->len) q->taint_bytes_all = q->len;
if (q->taint_bytes_new > q->len) afl->taint_len = q->taint_bytes_new = q->len;
if (q->taint_bytes_highest > q->len) q->taint_bytes_highest = q->len;
afl->taint_len = q->len;
}
return fault;
}

View File

@ -117,6 +117,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
"var_byte_count : %u\n"
"havoc_expansion : %u\n"
"tainted_inputs : %u\n"
"tainted_runs : %u\n"
"afl_banner : %s\n"
"afl_version : " VERSION
"\n"
@ -151,7 +152,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
-1,
#endif
t_bytes, afl->var_byte_count, afl->expand_havoc, afl->taint_count,
afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->taint_runs, afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->fsrv.qemu_mode ? "qemu " : "",
afl->non_instrumented_mode ? " non_instrumented " : "",
afl->no_forkserver ? "no_fsrv " : "", afl->crash_mode ? "crash " : "",

View File

@ -1318,7 +1318,7 @@ int main(int argc, char **argv_orig, char **envp) {
OKF("Taint forkserver successfully started");
const rlim_t kStackSize = 128L * 1024L * 1024L; // min stack size = 128 Mb
const rlim_t kStackSize = 16L * 1024L * 1024L; // min stack size = 16 Mb
struct rlimit rl;
rl.rlim_cur = kStackSize;
if (getrlimit(RLIMIT_STACK, &rl) != 0)