Merge pull request #1141 from AFLplusplus/afl4

cmplog enhancement variant
This commit is contained in:
van Hauser
2021-11-07 14:09:09 +01:00
committed by GitHub
22 changed files with 2892 additions and 1468 deletions

View File

@ -32,7 +32,7 @@ VERSION = $(shell grep '^$(HASH)define VERSION ' ../config.h | cut -d '"' -f
# PROGS intentionally omit afl-as, which gets installed elsewhere.
PROGS = afl-fuzz afl-showmap afl-tmin afl-gotcpu afl-analyze
SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config afl-persistent-config
SH_PROGS = afl-plot afl-cmin afl-cmin.bash afl-whatsup afl-system-config afl-persistent-config afl-cc
MANPAGES=$(foreach p, $(PROGS) $(SH_PROGS), $(p).8) afl-as.8
ASAN_OPTIONS=detect_leaks=0

View File

@ -18,6 +18,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- fix -n dumb mode (nobody should use this)
- fix stability issue with LTO and cmplog
- better banner
- more effective cmplog mode
- more often update the UI when in input2stage mode
- frida_mode: David Carlier added Android support :)
- afl-showmap, afl-tmin and afl-analyze:
- honor persistent mode for more speed. thanks to dloffre-snl for

View File

@ -104,9 +104,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
gsize x0 = ctx_read_reg(context, ARM64_REG_X0);
gsize x1 = ctx_read_reg(context, ARM64_REG_X1);
if (((G_MAXULONG - x0) < 32) || ((G_MAXULONG - x1) < 32)) return;
if (((G_MAXULONG - x0) < 31) || ((G_MAXULONG - x1) < 31)) return;
if (!cmplog_is_readable(x0, 32) || !cmplog_is_readable(x1, 32)) return;
if (!cmplog_is_readable(x0, 31) || !cmplog_is_readable(x1, 31)) return;
void *ptr1 = GSIZE_TO_POINTER(x0);
void *ptr2 = GSIZE_TO_POINTER(x1);
@ -116,18 +116,36 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 0;
}
u32 hits = 0;
if (__afl_cmp_map->headers[k].hits == 0) {
__afl_cmp_map->headers[k].shape = 30;
} else {
hits = __afl_cmp_map->headers[k].hits;
}
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = 31;
__afl_cmp_map->headers[k].shape = 30;
hits &= CMP_MAP_RTN_H - 1;
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
32);
31);
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
32);
31);
}
@ -193,13 +211,24 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
__afl_cmp_map->headers[k].hits = 0;
u32 hits = 0;
if (__afl_cmp_map->headers[k].hits == 0) {
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = (size - 1);
} else {
hits = __afl_cmp_map->headers[k].hits;
}
__afl_cmp_map->headers[k].hits = hits + 1;
hits &= CMP_MAP_H - 1;
__afl_cmp_map->log[k][hits].v0 = operand1;
__afl_cmp_map->log[k][hits].v1 = operand2;

View File

@ -99,9 +99,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
gsize rdi = ctx_read_reg(context, X86_REG_RDI);
gsize rsi = ctx_read_reg(context, X86_REG_RSI);
if (((G_MAXULONG - rdi) < 32) || ((G_MAXULONG - rsi) < 32)) return;
if (((G_MAXULONG - rdi) < 31) || ((G_MAXULONG - rsi) < 31)) return;
if (!cmplog_is_readable(rdi, 32) || !cmplog_is_readable(rsi, 32)) return;
if (!cmplog_is_readable(rdi, 31) || !cmplog_is_readable(rsi, 31)) return;
void *ptr1 = GSIZE_TO_POINTER(rdi);
void *ptr2 = GSIZE_TO_POINTER(rsi);
@ -111,18 +111,34 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 0;
}
u32 hits = 0;
if (__afl_cmp_map->headers[k].hits == 0) {
__afl_cmp_map->headers[k].shape = 30;
} else {
hits = __afl_cmp_map->headers[k].hits;
}
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = 31;
hits &= CMP_MAP_RTN_H - 1;
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
32);
31);
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
32);
31);
}
@ -179,13 +195,23 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 7;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
__afl_cmp_map->headers[k].hits = 0;
u32 hits = 0;
if (__afl_cmp_map->headers[k].hits == 0) {
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = (size - 1);
} else {
hits = __afl_cmp_map->headers[k].hits;
}
__afl_cmp_map->headers[k].hits = hits + 1;
hits &= CMP_MAP_H - 1;
__afl_cmp_map->log[k][hits].v0 = operand1;
__afl_cmp_map->log[k][hits].v1 = operand2;

View File

@ -104,9 +104,9 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
gsize arg1 = esp[0];
gsize arg2 = esp[1];
if (((G_MAXULONG - arg1) < 32) || ((G_MAXULONG - arg2) < 32)) return;
if (((G_MAXULONG - arg1) < 31) || ((G_MAXULONG - arg2) < 31)) return;
if (!cmplog_is_readable(arg1, 32) || !cmplog_is_readable(arg2, 32)) return;
if (!cmplog_is_readable(arg1, 31) || !cmplog_is_readable(arg2, 31)) return;
void *ptr1 = GSIZE_TO_POINTER(arg1);
void *ptr2 = GSIZE_TO_POINTER(arg2);
@ -116,18 +116,34 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 0;
}
u32 hits = 0;
if (__afl_cmp_map->headers[k].hits == 0) {
__afl_cmp_map->headers[k].shape = 30;
} else {
hits = __afl_cmp_map->headers[k].hits;
}
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = 31;
hits &= CMP_MAP_RTN_H - 1;
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
32);
31);
gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
32);
31);
}
@ -184,13 +200,24 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
__afl_cmp_map->headers[k].hits = 0;
u32 hits = 0;
if (__afl_cmp_map->headers[k].hits == 0) {
__afl_cmp_map->headers[k].type = CMP_TYPE_INS;
u32 hits = __afl_cmp_map->headers[k].hits;
__afl_cmp_map->headers[k].hits = hits + 1;
__afl_cmp_map->headers[k].shape = (size - 1);
} else {
hits = __afl_cmp_map->headers[k].hits;
}
__afl_cmp_map->headers[k].hits = hits + 1;
hits &= CMP_MAP_H - 1;
__afl_cmp_map->log[k][hits].v0 = operand1;
__afl_cmp_map->log[k][hits].v1 = operand2;

View File

@ -1135,6 +1135,7 @@ void setup_signal_handlers(void);
void save_cmdline(afl_state_t *, u32, char **);
void read_foreign_testcases(afl_state_t *, int);
void write_crash_readme(afl_state_t *afl);
u8 check_if_text_buf(u8 *buf, u32 len);
/* CmpLog */

View File

@ -48,7 +48,8 @@ struct cmp_header {
unsigned shape : 5;
unsigned type : 2;
unsigned attribute : 4;
unsigned reserved : 5;
unsigned overflow : 1;
unsigned reserved : 4;
} __attribute__((packed));
@ -59,14 +60,16 @@ struct cmp_operands {
u64 v0_128;
u64 v1_128;
};
} __attribute__((packed));
struct cmpfn_operands {
u8 v0[32];
u8 v1[32];
u8 v0[31];
u8 v0_len;
u8 v1[31];
u8 v1_len;
};
} __attribute__((packed));
typedef struct cmp_operands cmp_map_list[CMP_MAP_H];

View File

@ -267,8 +267,8 @@
(first value), and to keep in memory as candidates. The latter should be much
higher than the former. */
#define USE_AUTO_EXTRAS 128
#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 64)
#define USE_AUTO_EXTRAS 4096
#define MAX_AUTO_EXTRAS (USE_AUTO_EXTRAS * 8)
/* Scaling factor for the effector map used to skip some of the more
expensive deterministic steps. The actual divisor is set to

View File

@ -46,6 +46,8 @@ typedef uint128_t u128;
#define FS_ERROR_SHM_OPEN 4
#define FS_ERROR_SHMAT 8
#define FS_ERROR_MMAP 16
#define FS_ERROR_OLD_CMPLOG 32
#define FS_ERROR_OLD_CMPLOG_QEMU 64
/* Reporting options */
#define FS_OPT_ENABLED 0x80000001
@ -53,6 +55,7 @@ typedef uint128_t u128;
#define FS_OPT_SNAPSHOT 0x20000000
#define FS_OPT_AUTODICT 0x10000000
#define FS_OPT_SHDMEM_FUZZ 0x01000000
#define FS_OPT_NEWCMPLOG 0x02000000
#define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000
// FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 22
#define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1)

File diff suppressed because it is too large Load Diff

View File

@ -22,6 +22,10 @@
#include "cmplog.h"
#include "llvm-alternative-coverage.h"
#define XXH_INLINE_ALL
#include "xxhash.h"
#undef XXH_INLINE_ALL
#include <stdio.h>
#include <stdlib.h>
#include <signal.h>
@ -154,6 +158,8 @@ static void at_exit(int signal) {
}
#define default_hash(a, b) XXH3_64bits(a, b)
/* Uninspired gcc plugin instrumentation */
void __afl_trace(const u32 x) {
@ -669,7 +675,7 @@ static void __afl_start_snapshots(void) {
/* Phone home and tell the parent that we're OK. If parent isn't there,
assume we're not running in forkserver mode and just execute program. */
status |= (FS_OPT_ENABLED | FS_OPT_SNAPSHOT);
status |= (FS_OPT_ENABLED | FS_OPT_SNAPSHOT | FS_OPT_NEWCMPLOG);
if (__afl_sharedmem_fuzzing != 0) status |= FS_OPT_SHDMEM_FUZZ;
if (__afl_map_size <= FS_OPT_MAX_MAPSIZE)
status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE);
@ -935,7 +941,12 @@ static void __afl_start_forkserver(void) {
}
if (__afl_sharedmem_fuzzing != 0) { status_for_fsrv |= FS_OPT_SHDMEM_FUZZ; }
if (status_for_fsrv) { status_for_fsrv |= (FS_OPT_ENABLED); }
if (status_for_fsrv) {
status_for_fsrv |= (FS_OPT_ENABLED | FS_OPT_NEWCMPLOG);
}
memcpy(tmp, &status_for_fsrv, 4);
/* Phone home and tell the parent that we're OK. If parent isn't there,
@ -1499,8 +1510,7 @@ void __cmplog_ins_hook1(uint8_t arg1, uint8_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@ -1530,8 +1540,7 @@ void __cmplog_ins_hook2(uint16_t arg1, uint16_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@ -1569,8 +1578,7 @@ void __cmplog_ins_hook4(uint32_t arg1, uint32_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@ -1608,8 +1616,7 @@ void __cmplog_ins_hook8(uint64_t arg1, uint64_t arg2, uint8_t attr) {
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@ -1652,8 +1659,7 @@ void __cmplog_ins_hookN(uint128_t arg1, uint128_t arg2, uint8_t attr,
if (unlikely(!__afl_cmp_map || arg1 == arg2)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@ -1696,8 +1702,7 @@ void __cmplog_ins_hook16(uint128_t arg1, uint128_t arg2, uint8_t attr) {
if (likely(!__afl_cmp_map)) return;
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@ -1802,8 +1807,8 @@ void __sanitizer_cov_trace_switch(uint64_t val, uint64_t *cases) {
for (uint64_t i = 0; i < cases[0]; i++) {
uintptr_t k = (uintptr_t)__builtin_return_address(0) + i;
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) &
(CMP_MAP_W - 1));
u32 hits;
@ -1880,6 +1885,159 @@ static int area_is_valid(void *ptr, size_t len) {
}
void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
/*
u32 i;
if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
fprintf(stderr, "rtn_n len=%u arg0=", len);
for (i = 0; i < len; i++)
fprintf(stderr, "%02x", ptr1[i]);
fprintf(stderr, " arg1=");
for (i = 0; i < len; i++)
fprintf(stderr, "%02x", ptr2[i]);
fprintf(stderr, "\n");
*/
if (likely(!__afl_cmp_map)) return;
// fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
if (unlikely(!len)) return;
int l = MIN(31, len);
// fprintf(stderr, "RTN2 %u\n", l);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = l - 1;
hits = 0;
} else {
hits = __afl_cmp_map->headers[k].hits++;
if (__afl_cmp_map->headers[k].shape < l) {
__afl_cmp_map->headers[k].shape = l - 1;
}
}
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
cmpfn[hits].v0_len = l;
cmpfn[hits].v1_len = l;
__builtin_memcpy(cmpfn[hits].v0, ptr1, l);
__builtin_memcpy(cmpfn[hits].v1, ptr2, l);
// fprintf(stderr, "RTN3\n");
}
void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
/*
if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
fprintf(stderr, "rtn_strn len=%u arg0=%s arg1=%s\n", len, ptr1, ptr2);
*/
if (likely(!__afl_cmp_map)) return;
// fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
if (unlikely(!len)) return;
int l = MIN(31, len + 1);
// fprintf(stderr, "RTN2 %u\n", l);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = l - 1;
hits = 0;
} else {
hits = __afl_cmp_map->headers[k].hits++;
if (__afl_cmp_map->headers[k].shape < l) {
__afl_cmp_map->headers[k].shape = l - 1;
}
}
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
cmpfn[hits].v0_len = 0x80 + l;
cmpfn[hits].v1_len = 0x80 + l;
__builtin_memcpy(cmpfn[hits].v0, ptr1, l);
__builtin_memcpy(cmpfn[hits].v1, ptr2, l);
// fprintf(stderr, "RTN3\n");
}
void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
/*
if (area_is_valid(ptr1, 32) <= 0 || area_is_valid(ptr2, 32) <= 0) return;
fprintf(stderr, "rtn_str arg0=%s arg1=%s\n", ptr1, ptr2);
*/
if (likely(!__afl_cmp_map)) return;
// fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
if (unlikely(!ptr1 || !ptr2)) return;
int len1 = MIN(31, strlen(ptr1) + 1);
int len2 = MIN(31, strlen(ptr2) + 1);
int l = MIN(MAX(len1, len2), 31);
// fprintf(stderr, "RTN2 %u\n", l);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
__afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
__afl_cmp_map->headers[k].hits = 1;
__afl_cmp_map->headers[k].shape = l - 1;
hits = 0;
} else {
hits = __afl_cmp_map->headers[k].hits++;
if (__afl_cmp_map->headers[k].shape < l) {
__afl_cmp_map->headers[k].shape = l - 1;
}
}
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
cmpfn[hits].v0_len = 0x80 + len1;
cmpfn[hits].v1_len = 0x80 + len2;
__builtin_memcpy(cmpfn[hits].v0, ptr1, len1);
__builtin_memcpy(cmpfn[hits].v1, ptr2, len2);
// fprintf(stderr, "RTN3\n");
}
void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
/*
@ -1900,12 +2058,11 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
if ((l1 = area_is_valid(ptr1, 32)) <= 0 ||
(l2 = area_is_valid(ptr2, 32)) <= 0)
return;
int len = MIN(l1, l2);
int len = MIN(31, MIN(l1, l2));
// fprintf(stderr, "RTN2 %u\n", len);
uintptr_t k = (uintptr_t)__builtin_return_address(0);
k = (k >> 4) ^ (k << 8);
k &= CMP_MAP_W - 1;
k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
u32 hits;
@ -1928,11 +2085,13 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
}
struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
hits &= CMP_MAP_RTN_H - 1;
__builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0,
ptr1, len);
__builtin_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1,
ptr2, len);
cmpfn[hits].v0_len = len;
cmpfn[hits].v1_len = len;
__builtin_memcpy(cmpfn[hits].v0, ptr1, len);
__builtin_memcpy(cmpfn[hits].v1, ptr2, len);
// fprintf(stderr, "RTN3\n");
}

View File

@ -87,12 +87,14 @@ char CmpLogRoutines::ID = 0;
bool CmpLogRoutines::hookRtns(Module &M) {
std::vector<CallInst *> calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC;
LLVMContext & C = M.getContext();
std::vector<CallInst *> calls, llvmStdStd, llvmStdC, gccStdStd, gccStdC,
Memcmp, Strcmp, Strncmp;
LLVMContext &C = M.getContext();
Type *VoidTy = Type::getVoidTy(C);
// PointerType *VoidPtrTy = PointerType::get(VoidTy, 0);
IntegerType *Int8Ty = IntegerType::getInt8Ty(C);
IntegerType *Int64Ty = IntegerType::getInt64Ty(C);
PointerType *i8PtrTy = PointerType::get(Int8Ty, 0);
#if LLVM_VERSION_MAJOR < 9
@ -184,6 +186,60 @@ bool CmpLogRoutines::hookRtns(Module &M) {
FunctionCallee cmplogGccStdC = c4;
#endif
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
FunctionCallee
#endif
c5 = M.getOrInsertFunction("__cmplog_rtn_hook_n", VoidTy, i8PtrTy,
i8PtrTy, Int64Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
#endif
);
#if LLVM_VERSION_MAJOR < 9
Function *cmplogHookFnN = cast<Function>(c5);
#else
FunctionCallee cmplogHookFnN = c5;
#endif
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
FunctionCallee
#endif
c6 = M.getOrInsertFunction("__cmplog_rtn_hook_strn", VoidTy, i8PtrTy,
i8PtrTy, Int64Ty
#if LLVM_VERSION_MAJOR < 5
,
NULL
#endif
);
#if LLVM_VERSION_MAJOR < 9
Function *cmplogHookFnStrN = cast<Function>(c6);
#else
FunctionCallee cmplogHookFnStrN = c6;
#endif
#if LLVM_VERSION_MAJOR < 9
Constant *
#else
FunctionCallee
#endif
c7 = M.getOrInsertFunction("__cmplog_rtn_hook_str", VoidTy, i8PtrTy,
i8PtrTy
#if LLVM_VERSION_MAJOR < 5
,
NULL
#endif
);
#if LLVM_VERSION_MAJOR < 9
Function *cmplogHookFnStr = cast<Function>(c7);
#else
FunctionCallee cmplogHookFnStr = c7;
#endif
GlobalVariable *AFLCmplogPtr = M.getNamedGlobal("__afl_cmp_map");
if (!AFLCmplogPtr) {
@ -214,12 +270,93 @@ bool CmpLogRoutines::hookRtns(Module &M) {
if (callInst->getCallingConv() != llvm::CallingConv::C) continue;
FunctionType *FT = Callee->getFunctionType();
std::string FuncName = Callee->getName().str();
bool isPtrRtn = FT->getNumParams() >= 2 &&
!FT->getReturnType()->isVoidTy() &&
FT->getParamType(0) == FT->getParamType(1) &&
FT->getParamType(0)->isPointerTy();
bool isPtrRtnN = FT->getNumParams() >= 3 &&
!FT->getReturnType()->isVoidTy() &&
FT->getParamType(0) == FT->getParamType(1) &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(2)->isIntegerTy();
if (isPtrRtnN) {
auto intTyOp =
dyn_cast<IntegerType>(callInst->getArgOperand(2)->getType());
if (intTyOp) {
if (intTyOp->getBitWidth() != 32 &&
intTyOp->getBitWidth() != 64) {
isPtrRtnN = false;
}
}
}
bool isMemcmp =
(!FuncName.compare("memcmp") || !FuncName.compare("bcmp") ||
!FuncName.compare("CRYPTO_memcmp") ||
!FuncName.compare("OPENSSL_memcmp") ||
!FuncName.compare("memcmp_const_time") ||
!FuncName.compare("memcmpct"));
isMemcmp &= FT->getNumParams() == 3 &&
FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0)->isPointerTy() &&
FT->getParamType(1)->isPointerTy() &&
FT->getParamType(2)->isIntegerTy();
bool isStrcmp =
(!FuncName.compare("strcmp") || !FuncName.compare("xmlStrcmp") ||
!FuncName.compare("xmlStrEqual") ||
!FuncName.compare("g_strcmp0") ||
!FuncName.compare("curl_strequal") ||
!FuncName.compare("strcsequal") ||
!FuncName.compare("strcasecmp") ||
!FuncName.compare("stricmp") ||
!FuncName.compare("ap_cstr_casecmp") ||
!FuncName.compare("OPENSSL_strcasecmp") ||
!FuncName.compare("xmlStrcasecmp") ||
!FuncName.compare("g_strcasecmp") ||
!FuncName.compare("g_ascii_strcasecmp") ||
!FuncName.compare("Curl_strcasecompare") ||
!FuncName.compare("Curl_safe_strcasecompare") ||
!FuncName.compare("cmsstrcasecmp") ||
!FuncName.compare("strstr") ||
!FuncName.compare("g_strstr_len") ||
!FuncName.compare("ap_strcasestr") ||
!FuncName.compare("xmlStrstr") ||
!FuncName.compare("xmlStrcasestr") ||
!FuncName.compare("g_str_has_prefix") ||
!FuncName.compare("g_str_has_suffix"));
isStrcmp &=
FT->getNumParams() == 2 && FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0) == FT->getParamType(1) &&
FT->getParamType(0) == IntegerType::getInt8PtrTy(M.getContext());
bool isStrncmp = (!FuncName.compare("strncmp") ||
!FuncName.compare("xmlStrncmp") ||
!FuncName.compare("curl_strnequal") ||
!FuncName.compare("strncasecmp") ||
!FuncName.compare("strnicmp") ||
!FuncName.compare("ap_cstr_casecmpn") ||
!FuncName.compare("OPENSSL_strncasecmp") ||
!FuncName.compare("xmlStrncasecmp") ||
!FuncName.compare("g_ascii_strncasecmp") ||
!FuncName.compare("Curl_strncasecompare") ||
!FuncName.compare("g_strncasecmp"));
isStrncmp &= FT->getNumParams() == 3 &&
FT->getReturnType()->isIntegerTy(32) &&
FT->getParamType(0) == FT->getParamType(1) &&
FT->getParamType(0) ==
IntegerType::getInt8PtrTy(M.getContext()) &&
FT->getParamType(2)->isIntegerTy();
bool isGccStdStringStdString =
Callee->getName().find("__is_charIT_EE7__value") !=
std::string::npos &&
@ -267,13 +404,19 @@ bool CmpLogRoutines::hookRtns(Module &M) {
*/
if (isGccStdStringCString || isGccStdStringStdString ||
isLlvmStdStringStdString || isLlvmStdStringCString) {
isLlvmStdStringStdString || isLlvmStdStringCString || isMemcmp ||
isStrcmp || isStrncmp) {
isPtrRtn = false;
isPtrRtnN = isPtrRtn = false;
}
if (isPtrRtnN) { isPtrRtn = false; }
if (isPtrRtn) { calls.push_back(callInst); }
if (isMemcmp || isPtrRtnN) { Memcmp.push_back(callInst); }
if (isStrcmp) { Strcmp.push_back(callInst); }
if (isStrncmp) { Strncmp.push_back(callInst); }
if (isGccStdStringStdString) { gccStdStd.push_back(callInst); }
if (isGccStdStringCString) { gccStdC.push_back(callInst); }
if (isLlvmStdStringStdString) { llvmStdStd.push_back(callInst); }
@ -288,7 +431,8 @@ bool CmpLogRoutines::hookRtns(Module &M) {
}
if (!calls.size() && !gccStdStd.size() && !gccStdC.size() &&
!llvmStdStd.size() && !llvmStdC.size())
!llvmStdStd.size() && !llvmStdC.size() && !Memcmp.size() &&
Strcmp.size() && Strncmp.size())
return false;
/*
@ -323,6 +467,96 @@ bool CmpLogRoutines::hookRtns(Module &M) {
}
for (auto &callInst : Memcmp) {
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
*v3P = callInst->getArgOperand(2);
IRBuilder<> IRB2(callInst->getParent());
IRB2.SetInsertPoint(callInst);
LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr);
CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
IRBuilder<> IRB(ThenTerm);
std::vector<Value *> args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
Value * v3Pbitcast = IRB.CreateBitCast(
v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
Value *v3Pcasted =
IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
IRB.CreateCall(cmplogHookFnN, args);
// errs() << callInst->getCalledFunction()->getName() << "\n";
}
for (auto &callInst : Strcmp) {
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);
IRBuilder<> IRB2(callInst->getParent());
IRB2.SetInsertPoint(callInst);
LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr);
CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
IRBuilder<> IRB(ThenTerm);
std::vector<Value *> args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
IRB.CreateCall(cmplogHookFnStr, args);
// errs() << callInst->getCalledFunction()->getName() << "\n";
}
for (auto &callInst : Strncmp) {
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1),
*v3P = callInst->getArgOperand(2);
IRBuilder<> IRB2(callInst->getParent());
IRB2.SetInsertPoint(callInst);
LoadInst *CmpPtr = IRB2.CreateLoad(AFLCmplogPtr);
CmpPtr->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
auto is_not_null = IRB2.CreateICmpNE(CmpPtr, Null);
auto ThenTerm = SplitBlockAndInsertIfThen(is_not_null, callInst, false);
IRBuilder<> IRB(ThenTerm);
std::vector<Value *> args;
Value * v1Pcasted = IRB.CreatePointerCast(v1P, i8PtrTy);
Value * v2Pcasted = IRB.CreatePointerCast(v2P, i8PtrTy);
Value * v3Pbitcast = IRB.CreateBitCast(
v3P, IntegerType::get(C, v3P->getType()->getPrimitiveSizeInBits()));
Value *v3Pcasted =
IRB.CreateIntCast(v3Pbitcast, IntegerType::get(C, 64), false);
args.push_back(v1Pcasted);
args.push_back(v2Pcasted);
args.push_back(v3Pcasted);
IRB.CreateCall(cmplogHookFnStrN, args);
// errs() << callInst->getCalledFunction()->getName() << "\n";
}
for (auto &callInst : gccStdStd) {
Value *v1P = callInst->getArgOperand(0), *v2P = callInst->getArgOperand(1);

View File

@ -1 +1 @@
71ed0d206f
8809a2b2ebf089d3427dd8f6a0044bcc2e13b389

View File

@ -342,6 +342,16 @@ static void report_error_and_exit(int error) {
"the fuzzing target reports that the mmap() call to the shared "
"memory failed.");
break;
case FS_ERROR_OLD_CMPLOG:
FATAL(
"the -c cmplog target was instrumented with an too old afl++ "
"version, you need to recompile it.");
break;
case FS_ERROR_OLD_CMPLOG_QEMU:
FATAL(
"The AFL++ QEMU/FRIDA loaders are from an older version, for -c you "
"need to recompile it.\n");
break;
default:
FATAL("unknown error code %d from fuzzing target!", error);
@ -663,6 +673,20 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND)
status = (status & 0xf0ffffff);
if ((status & FS_OPT_NEWCMPLOG) == 0 && fsrv->cmplog_binary) {
if (fsrv->qemu_mode || fsrv->frida_mode) {
report_error_and_exit(FS_ERROR_OLD_CMPLOG_QEMU);
} else {
report_error_and_exit(FS_ERROR_OLD_CMPLOG);
}
}
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
fsrv->snapshot = 1;

View File

@ -448,11 +448,11 @@ u8 fuzz_one_original(afl_state_t *afl) {
ACTF(
"Fuzzing test case #%u (%u total, %llu uniq crashes found, "
"perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u)...",
"perf_score=%0.0f, exec_us=%llu, hits=%u, map=%u, ascii=%u)...",
afl->current_entry, afl->queued_paths, afl->unique_crashes,
afl->queue_cur->perf_score, afl->queue_cur->exec_us,
likely(afl->n_fuzz) ? afl->n_fuzz[afl->queue_cur->n_fuzz_entry] : 0,
afl->queue_cur->bitmap_size);
afl->queue_cur->bitmap_size, afl->queue_cur->is_ascii);
fflush(stdout);
}
@ -2003,11 +2003,16 @@ havoc_stage:
where we take the input file and make random stacked tweaks. */
#define MAX_HAVOC_ENTRY 59 /* 55 to 60 */
#define MUTATE_ASCII_DICT 64
u32 r_max, r;
r_max = (MAX_HAVOC_ENTRY + 1) + (afl->extras_cnt ? 4 : 0) +
(afl->a_extras_cnt ? 4 : 0);
(afl->a_extras_cnt
? (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii)
? MUTATE_ASCII_DICT
: 4)
: 0);
if (unlikely(afl->expand_havoc && afl->ready_for_splicing_count > 1)) {
@ -2592,7 +2597,15 @@ havoc_stage:
if (afl->a_extras_cnt) {
if (r < 2) {
u32 r_cmp = 2;
if (unlikely(afl->cmplog_binary && afl->queue_cur->is_ascii)) {
r_cmp = MUTATE_ASCII_DICT >> 1;
}
if (r < r_cmp) {
/* Use the dictionary. */
@ -2612,7 +2625,7 @@ havoc_stage:
break;
} else if (r < 4) {
} else if (r < (r_cmp << 1)) {
u32 use_extra = rand_below(afl, afl->a_extras_cnt);
u32 extra_len = afl->a_extras[use_extra].len;
@ -2641,7 +2654,7 @@ havoc_stage:
} else {
r -= 4;
r -= (r_cmp << 1);
}

View File

@ -315,7 +315,96 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
}
/* check if ascii or UTF-8 */
/* check if pointer is ascii or UTF-8 */
u8 check_if_text_buf(u8 *buf, u32 len) {
u32 offset = 0, ascii = 0, utf8 = 0;
while (offset < len) {
// ASCII: <= 0x7F to allow ASCII control characters
if ((buf[offset + 0] == 0x09 || buf[offset + 0] == 0x0A ||
buf[offset + 0] == 0x0D ||
(0x20 <= buf[offset + 0] && buf[offset + 0] <= 0x7E))) {
offset++;
utf8++;
ascii++;
continue;
}
if (isascii((int)buf[offset]) || isprint((int)buf[offset])) {
ascii++;
// we continue though as it can also be a valid utf8
}
// non-overlong 2-byte
if (len - offset > 1 &&
((0xC2 <= buf[offset + 0] && buf[offset + 0] <= 0xDF) &&
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF))) {
offset += 2;
utf8++;
continue;
}
// excluding overlongs
if ((len - offset > 2) &&
((buf[offset + 0] == 0xE0 &&
(0xA0 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
(0x80 <= buf[offset + 2] &&
buf[offset + 2] <= 0xBF)) || // straight 3-byte
(((0xE1 <= buf[offset + 0] && buf[offset + 0] <= 0xEC) ||
buf[offset + 0] == 0xEE || buf[offset + 0] == 0xEF) &&
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
(0x80 <= buf[offset + 2] &&
buf[offset + 2] <= 0xBF)) || // excluding surrogates
(buf[offset + 0] == 0xED &&
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x9F) &&
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF)))) {
offset += 3;
utf8++;
continue;
}
// planes 1-3
if ((len - offset > 3) &&
((buf[offset + 0] == 0xF0 &&
(0x90 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
(0x80 <= buf[offset + 3] &&
buf[offset + 3] <= 0xBF)) || // planes 4-15
((0xF1 <= buf[offset + 0] && buf[offset + 0] <= 0xF3) &&
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0xBF) &&
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
(0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)) || // plane 16
(buf[offset + 0] == 0xF4 &&
(0x80 <= buf[offset + 1] && buf[offset + 1] <= 0x8F) &&
(0x80 <= buf[offset + 2] && buf[offset + 2] <= 0xBF) &&
(0x80 <= buf[offset + 3] && buf[offset + 3] <= 0xBF)))) {
offset += 4;
utf8++;
continue;
}
offset++;
}
return (utf8 > ascii ? utf8 : ascii);
}
/* check if queue entry is ascii or UTF-8 */
static u8 check_if_text(afl_state_t *afl, struct queue_entry *q) {

View File

@ -45,6 +45,23 @@ enum {
};
// add to dictionary enum
// DEFAULT = 1, notTXT = 2, FOUND = 4, notSAME = 8
enum {
DICT_ADD_NEVER = 0,
DICT_ADD_NOTFOUND_SAME_TXT = 1,
DICT_ADD_NOTFOUND_SAME = 3,
DICT_ADD_FOUND_SAME_TXT = 5,
DICT_ADD_FOUND_SAME = 7,
DICT_ADD_NOTFOUND_TXT = 9,
DICT_ADD_NOTFOUND = 11,
DICT_ADD_FOUND_TXT = 13,
DICT_ADD_FOUND = 15,
DICT_ADD_ANY = DICT_ADD_FOUND
};
// CMPLOG LVL
enum {
@ -54,6 +71,8 @@ enum {
};
#define DICT_ADD_STRATEGY DICT_ADD_FOUND_SAME
struct range {
u32 start;
@ -64,6 +83,10 @@ struct range {
};
static u32 hshape;
static u64 screen_update;
static u64 last_update;
static struct range *add_range(struct range *ranges, u32 start, u32 end) {
struct range *r = ck_alloc_nozero(sizeof(struct range));
@ -252,7 +275,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
u64 start_time = get_cur_time();
#endif
u32 screen_update;
u64 orig_hit_cnt, new_hit_cnt, exec_cksum;
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
@ -261,24 +283,6 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
afl->stage_max = (len << 1);
afl->stage_cur = 0;
if (likely(afl->queue_cur->exec_us)) {
if (likely((100000 / 2) >= afl->queue_cur->exec_us)) {
screen_update = 100000 / afl->queue_cur->exec_us;
} else {
screen_update = 1;
}
} else {
screen_update = 100000;
}
// in colorization we do not classify counts, hence we have to calculate
// the original checksum.
if (unlikely(get_exec_checksum(afl, buf, len, &exec_cksum))) {
@ -348,7 +352,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
}
if (++afl->stage_cur % screen_update) { show_stats(afl); };
if (++afl->stage_cur % screen_update == 0) { show_stats(afl); };
}
@ -440,10 +444,10 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len,
fprintf(
f,
"Colorization: fname=%s len=%u ms=%llu result=%u execs=%u found=%llu "
"taint=%u\n",
"taint=%u ascii=%u auto_extra_before=%u\n",
afl->queue_cur->fname, len, get_cur_time() - start_time,
afl->queue_cur->colorized, afl->stage_cur, new_hit_cnt - orig_hit_cnt,
positions);
positions, afl->queue_cur->is_ascii ? 1 : 0, afl->a_extras_cnt);
#ifndef _DEBUG
if (afl->not_on_tty) { fclose(f); }
@ -759,11 +763,18 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u32 its_len = MIN(len - idx, taint_len);
if (afl->fsrv.total_execs - last_update > screen_update) {
show_stats(afl);
last_update = afl->fsrv.total_execs;
}
// 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,
// h->shape + 1, attr);
// hshape, attr);
//#ifdef CMPLOG_SOLVE_TRANSFORM
// reverse atoi()/strnu?toll() is expensive, so we only to it in lvl 3
@ -845,7 +856,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u64 b_val, o_b_val, mask;
u8 bytes;
switch (SHAPE_BYTES(h->shape)) {
switch (hshape) {
case 0:
case 1:
@ -924,7 +935,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
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,
h->shape + 1, o_pattern, o_b_val, o_diff);
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) {
@ -953,7 +964,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
s64 o_diff = o_pattern ^ o_b_val;
/* fprintf(stderr, "DIFF2 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff);
idx, hshape, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF2 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
@ -1002,7 +1013,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
/* fprintf(stderr, "DIFF3 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff);
idx, hshape, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF3 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
@ -1051,7 +1062,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
/* fprintf(stderr, "DIFF4 idx=%03u shape=%02u %llx-%llx=%lx\n",
idx, h->shape + 1, o_pattern, o_b_val, o_diff);
idx, hshape, o_pattern, o_b_val, o_diff);
fprintf(stderr,
"DIFF4 %016llx %llx-%llx=%lx\n", repl, pattern, b_val, diff);
*/
@ -1089,7 +1100,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
if ((lvl & LVL1) || attr >= IS_FP_MOD) {
if (SHAPE_BYTES(h->shape) >= 8 && *status != 1) {
if (hshape >= 8 && *status != 1) {
// if (its_len >= 8)
// fprintf(stderr,
@ -1132,7 +1143,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
if (SHAPE_BYTES(h->shape) >= 4 && *status != 1) {
if (hshape >= 4 && *status != 1) {
// if (its_len >= 4 && (attr <= 1 || attr >= 8))
// fprintf(stderr,
@ -1173,7 +1184,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
if (SHAPE_BYTES(h->shape) >= 2 && *status != 1) {
if (hshape >= 2 && *status != 1) {
if (its_len >= 2 &&
((*buf_16 == (u16)pattern && *o_buf_16 == (u16)o_pattern) ||
@ -1244,11 +1255,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
if (!(attr & (IS_GREATER | IS_LESSER)) || SHAPE_BYTES(h->shape) < 4) {
return 0;
}
if (!(attr & (IS_GREATER | IS_LESSER)) || hshape < 4) { return 0; }
// transform >= to < and <= to >
if ((attr & IS_EQUAL) && (attr & (IS_GREATER | IS_LESSER))) {
@ -1272,7 +1279,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
if (attr & IS_GREATER) {
if (SHAPE_BYTES(h->shape) == 4 && its_len >= 4) {
if (hshape == 4 && its_len >= 4) {
float *f = (float *)&repl;
float g = *f;
@ -1280,7 +1287,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u32 *r = (u32 *)&g;
repl_new = (u32)*r;
} else if (SHAPE_BYTES(h->shape) == 8 && its_len >= 8) {
} else if (hshape == 8 && its_len >= 8) {
double *f = (double *)&repl;
double g = *f;
@ -1307,7 +1314,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
} else {
if (SHAPE_BYTES(h->shape) == 4) {
if (hshape == 4) {
float *f = (float *)&repl;
float g = *f;
@ -1315,7 +1322,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
u32 *r = (u32 *)&g;
repl_new = (u32)*r;
} else if (SHAPE_BYTES(h->shape) == 8) {
} else if (hshape == 8) {
double *f = (double *)&repl;
double g = *f;
@ -1342,7 +1349,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
}
// transform double to float, llvm likes to do that internally ...
if (SHAPE_BYTES(h->shape) == 8 && its_len >= 4) {
if (hshape == 8 && its_len >= 4) {
double *f = (double *)&repl;
float g = (float)*f;
@ -1353,7 +1360,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
memcpy(((char *)&repl_new) + 4, (char *)&g, 4);
#endif
changed_val = repl_new;
h->shape = 3; // modify shape
hshape = 4; // modify shape
// fprintf(stderr, "DOUBLE2FLOAT %llx\n", repl_new);
@ -1361,12 +1368,12 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
afl, h, pattern, repl_new, o_pattern, changed_val, 16, idx,
taint_len, orig_buf, buf, cbuf, len, 1, lvl, status))) {
h->shape = 7; // recover shape
hshape = 8; // recover shape
return 1;
}
h->shape = 7; // recover shape
hshape = 8; // recover shape
}
@ -1421,6 +1428,13 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf,
u32 len, u8 do_reverse, u8 lvl, u8 *status) {
if (afl->fsrv.total_execs - last_update > screen_update) {
show_stats(afl);
last_update = afl->fsrv.total_execs;
}
u8 *ptr = (u8 *)&buf[idx];
u8 *o_ptr = (u8 *)&orig_buf[idx];
u8 *p = (u8 *)&pattern;
@ -1428,52 +1442,51 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
u8 *r = (u8 *)&repl;
u8 backup[16];
u32 its_len = MIN(len - idx, taint_len);
u32 shape = h->shape + 1;
#if (__BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__)
size_t off = 0;
#else
size_t off = 16 - shape;
size_t off = 16 - hshape;
#endif
if (its_len >= shape) {
if (its_len >= hshape) {
#ifdef _DEBUG
fprintf(stderr, "TestUN: %u>=%u (len=%u idx=%u attr=%u off=%lu) (%u) ",
its_len, shape, len, idx, attr, off, do_reverse);
its_len, hshape, len, idx, attr, off, do_reverse);
u32 i;
u8 *o_r = (u8 *)&changed_val;
for (i = 0; i < shape; i++)
for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", ptr[i]);
fprintf(stderr, "==");
for (i = 0; i < shape; i++)
for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", p[off + i]);
fprintf(stderr, " ");
for (i = 0; i < shape; i++)
for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", o_ptr[i]);
fprintf(stderr, "==");
for (i = 0; i < shape; i++)
for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", o_p[off + i]);
fprintf(stderr, " <= ");
for (i = 0; i < shape; i++)
for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", r[off + i]);
fprintf(stderr, "<-");
for (i = 0; i < shape; i++)
for (i = 0; i < hshape; i++)
fprintf(stderr, "%02x", o_r[off + i]);
fprintf(stderr, "\n");
#endif
if (!memcmp(ptr, p + off, shape) && !memcmp(o_ptr, o_p + off, shape)) {
if (!memcmp(ptr, p + off, hshape) && !memcmp(o_ptr, o_p + off, hshape)) {
memcpy(backup, ptr, shape);
memcpy(ptr, r + off, shape);
memcpy(backup, ptr, hshape);
memcpy(ptr, r + off, hshape);
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
#ifdef CMPLOG_COMBINE
if (*status == 1) { memcpy(cbuf + idx, r, shape); }
if (*status == 1) { memcpy(cbuf + idx, r, hshape); }
#endif
memcpy(ptr, backup, shape);
memcpy(ptr, backup, hshape);
#ifdef _DEBUG
fprintf(stderr, "Status=%u\n", *status);
@ -1485,10 +1498,10 @@ static u8 cmp_extend_encodingN(afl_state_t *afl, struct cmp_header *h,
if (do_reverse && *status != 1) {
if (unlikely(cmp_extend_encodingN(
afl, h, SWAPN(pattern, (shape << 3)), SWAPN(repl, (shape << 3)),
SWAPN(o_pattern, (shape << 3)), SWAPN(changed_val, (shape << 3)),
attr, idx, taint_len, orig_buf, buf, cbuf, len, 0, lvl,
status))) {
afl, h, SWAPN(pattern, (hshape << 3)), SWAPN(repl, (hshape << 3)),
SWAPN(o_pattern, (hshape << 3)),
SWAPN(changed_val, (hshape << 3)), attr, idx, taint_len, orig_buf,
buf, cbuf, len, 0, lvl, status))) {
return 1;
@ -1615,6 +1628,8 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
u8 s_v0_inc = 1, s_v1_inc = 1;
u8 s_v0_dec = 1, s_v1_dec = 1;
hshape = SHAPE_BYTES(h->shape);
if (h->hits > CMP_MAP_H) {
loggeds = CMP_MAP_H;
@ -1626,7 +1641,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
#ifdef WORD_SIZE_64
switch (SHAPE_BYTES(h->shape)) {
switch (hshape) {
case 1:
case 2:
@ -1679,8 +1694,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#ifdef _DEBUG
fprintf(stderr, "Handling: %llx->%llx vs %llx->%llx attr=%u shape=%u\n",
orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute,
SHAPE_BYTES(h->shape));
orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, hshape);
#endif
t = taint;
@ -1830,18 +1844,24 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
"END: %llx->%llx vs %llx->%llx attr=%u i=%u found=%u "
"isN=%u size=%u\n",
orig_o->v0, o->v0, orig_o->v1, o->v1, h->attribute, i, found_one,
is_n, SHAPE_BYTES(h->shape));
is_n, hshape);
#endif
// If failed, add to dictionary
if (!found_one) {
// we only learn 16 bit +
if (hshape > 1) {
if (afl->pass_stats[key].total == 0) {
if (!found_one || afl->queue_cur->is_ascii) {
#ifdef WORD_SIZE_64
if (unlikely(is_n)) {
if (!found_one ||
check_if_text_buf((u8 *)&s128_v0, SHAPE_BYTES(h->shape)) ==
SHAPE_BYTES(h->shape))
try_to_add_to_dictN(afl, s128_v0, SHAPE_BYTES(h->shape));
if (!found_one ||
check_if_text_buf((u8 *)&s128_v1, SHAPE_BYTES(h->shape)) ==
SHAPE_BYTES(h->shape))
try_to_add_to_dictN(afl, s128_v1, SHAPE_BYTES(h->shape));
} else
@ -1849,7 +1869,15 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#endif
{
if (!memcmp((u8 *)&o->v0, (u8 *)&orig_o->v0, SHAPE_BYTES(h->shape)) &&
(!found_one ||
check_if_text_buf((u8 *)&o->v0, SHAPE_BYTES(h->shape)) ==
SHAPE_BYTES(h->shape)))
try_to_add_to_dict(afl, o->v0, SHAPE_BYTES(h->shape));
if (!memcmp((u8 *)&o->v1, (u8 *)&orig_o->v1, SHAPE_BYTES(h->shape)) &&
(!found_one ||
check_if_text_buf((u8 *)&o->v1, SHAPE_BYTES(h->shape)) ==
SHAPE_BYTES(h->shape)))
try_to_add_to_dict(afl, o->v1, SHAPE_BYTES(h->shape));
}
@ -1882,8 +1910,9 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
u8 *o_pattern, u8 *changed_val, u8 plen, u32 idx,
static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry,
struct cmpfn_operands *o,
struct cmpfn_operands *orig_o, u32 idx,
u32 taint_len, u8 *orig_buf, u8 *buf, u8 *cbuf,
u32 len, u8 lvl, u8 *status) {
@ -1894,9 +1923,60 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
// (void)(changed_val);
//#endif
if (afl->fsrv.total_execs - last_update > screen_update) {
show_stats(afl);
last_update = afl->fsrv.total_execs;
}
u8 *pattern, *repl, *o_pattern, *changed_val;
u8 l0, l1, ol0, ol1;
if (entry == 0) {
pattern = o->v0;
repl = o->v1;
o_pattern = orig_o->v0;
changed_val = orig_o->v1;
l0 = o->v0_len;
ol0 = orig_o->v0_len;
l1 = o->v1_len;
ol1 = orig_o->v1_len;
} else {
pattern = o->v1;
repl = o->v0;
o_pattern = orig_o->v1;
changed_val = orig_o->v0;
l0 = o->v1_len;
ol0 = orig_o->v1_len;
l1 = o->v0_len;
ol1 = orig_o->v0_len;
}
if (l0 >= 0x80 || ol0 >= 0x80) {
l0 -= 0x80;
l1 -= 0x80;
ol0 -= 0x80;
ol1 -= 0x80;
}
if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 ||
ol0 > 31 || ol1 > 31) {
l0 = l1 = ol0 = ol1 = hshape;
}
u8 lmax = MAX(l0, ol0);
u8 save[40];
u32 saved_idx = idx, pre, from = 0, to = 0, i, j;
u32 its_len = MIN((u32)plen, len - idx);
u32 its_len = MIN(MIN(lmax, hshape), len - idx);
its_len = MIN(its_len, taint_len);
u32 saved_its_len = its_len;
@ -1912,7 +1992,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
(void)(j);
#ifdef _DEBUG
fprintf(stderr, "RTN T idx=%u lvl=%02x ", idx, lvl);
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, " -> ");
@ -1972,10 +2053,10 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 *pattern, u8 *repl,
}
//#ifdef CMPLOG_SOLVE_TRANSFORM
if (*status == 1) return 0;
// transform solving
if (afl->cmplog_enable_transform && (lvl & LVL3)) {
u32 toupper = 0, tolower = 0, xor = 0, arith = 0, tohex = 0, fromhex = 0;
@ -2322,6 +2403,8 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
u32 i, j, idx, have_taint = 1, taint_len, loggeds;
u8 status = 0, found_one = 0;
hshape = SHAPE_BYTES(h->shape);
if (h->hits > CMP_MAP_RTN_H) {
loggeds = CMP_MAP_RTN_H;
@ -2354,16 +2437,20 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
/*
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, h->shape, h->attribute);
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v0[j]);
fprintf(stderr, "RTN N hits=%u id=%u shape=%u attr=%u v0=", h->hits, h->id,
hshape, h->attribute);
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", o->v0[j]);
fprintf(stderr, " v1=");
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", o->v1[j]);
fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u o0=",
hh->hits, hh->id, hh->shape, hh->attribute);
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v0[j]);
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", o->v1[j]);
fprintf(stderr, "\nRTN O hits=%u id=%u shape=%u attr=%u o0=", hh->hits,
hh->id, hshape, hh->attribute);
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", orig_o->v0[j]);
fprintf(stderr, " o1=");
for (j = 0; j < 8; j++) fprintf(stderr, "%02x", orig_o->v1[j]);
for (j = 0; j < 8; j++)
fprintf(stderr, "%02x", orig_o->v1[j]);
fprintf(stderr, "\n");
*/
@ -2400,25 +2487,24 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
#ifdef _DEBUG
int w;
fprintf(stderr, "key=%u idx=%u len=%u o0=", key, idx,
SHAPE_BYTES(h->shape));
for (w = 0; w < SHAPE_BYTES(h->shape); ++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]);
fprintf(stderr, " v0=");
for (w = 0; w < SHAPE_BYTES(h->shape); ++w)
for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", o->v0[w]);
fprintf(stderr, " o1=");
for (w = 0; w < SHAPE_BYTES(h->shape); ++w)
for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", orig_o->v1[w]);
fprintf(stderr, " v1=");
for (w = 0; w < SHAPE_BYTES(h->shape); ++w)
for (w = 0; w < hshape; ++w)
fprintf(stderr, "%02x", o->v1[w]);
fprintf(stderr, "\n");
#endif
if (unlikely(rtn_extend_encoding(
afl, o->v0, o->v1, orig_o->v0, orig_o->v1, SHAPE_BYTES(h->shape),
idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) {
if (unlikely(rtn_extend_encoding(afl, 0, o, orig_o, idx, taint_len,
orig_buf, buf, cbuf, len, lvl,
&status))) {
return 1;
@ -2433,9 +2519,9 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
status = 0;
if (unlikely(rtn_extend_encoding(
afl, o->v1, o->v0, orig_o->v1, orig_o->v0, SHAPE_BYTES(h->shape),
idx, taint_len, orig_buf, buf, cbuf, len, lvl, &status))) {
if (unlikely(rtn_extend_encoding(afl, 1, o, orig_o, idx, taint_len,
orig_buf, buf, cbuf, len, lvl,
&status))) {
return 1;
@ -2450,16 +2536,42 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u8 *cbuf,
}
// If failed, add to dictionary
if (!found_one && (lvl & LVL1)) {
// if (unlikely(!afl->pass_stats[key].total)) {
if (unlikely(!afl->pass_stats[key].total)) {
if ((!found_one && (lvl & LVL1)) || afl->queue_cur->is_ascii) {
maybe_add_auto(afl, o->v0, SHAPE_BYTES(h->shape));
maybe_add_auto(afl, o->v1, SHAPE_BYTES(h->shape));
// if (unlikely(!afl->pass_stats[key].total)) {
u32 shape_len = SHAPE_BYTES(h->shape);
u32 v0_len = shape_len, v1_len = shape_len;
if (afl->queue_cur->is_ascii ||
check_if_text_buf((u8 *)&o->v0, shape_len) == shape_len) {
if (strlen(o->v0)) v0_len = strlen(o->v0);
}
if (afl->queue_cur->is_ascii ||
check_if_text_buf((u8 *)&o->v1, shape_len) == shape_len) {
if (strlen(o->v1)) v1_len = strlen(o->v1);
}
// fprintf(stderr, "SHOULD: found:%u ascii:%u text?%u:%u %u:%s %u:%s \n",
// found_one, afl->queue_cur->is_ascii, check_if_text_buf((u8 *)&o->v0,
// shape_len), check_if_text_buf((u8 *)&o->v1, shape_len), v0_len,
// o->v0, v1_len, o->v1);
if (!memcmp(o->v0, orig_o->v0, v0_len) ||
(!found_one || check_if_text_buf((u8 *)&o->v0, v0_len) == v0_len))
maybe_add_auto(afl, o->v0, v0_len);
if (!memcmp(o->v1, orig_o->v1, v1_len) ||
(!found_one || check_if_text_buf((u8 *)&o->v1, v1_len) == v1_len))
maybe_add_auto(afl, o->v1, v1_len);
//}
}
rtn_fuzz_next_iter:
@ -2492,6 +2604,23 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
}
struct tainted *taint = NULL;
if (likely(afl->queue_cur->exec_us)) {
if (likely((100000 / 2) >= afl->queue_cur->exec_us)) {
screen_update = 100000 / afl->queue_cur->exec_us;
} else {
screen_update = 1;
}
} else {
screen_update = 100000;
}
if (!afl->queue_cur->taint || !afl->queue_cur->cmplog_colorinput) {
@ -2592,8 +2721,6 @@ 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_execs = afl->fsrv.total_execs;
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
u64 screen_update = 100000 / afl->queue_cur->exec_us,
execs = afl->fsrv.total_execs;
afl->stage_name = "input-to-state";
afl->stage_short = "its";
@ -2630,11 +2757,13 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) {
// fprintf(stderr, "INS %u\n", k);
afl->stage_max +=
MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_H);
} else {
// fprintf(stderr, "RTN %u\n", k);
afl->stage_max +=
MIN((u32)(afl->shm.cmp_map->headers[k].hits), (u32)CMP_MAP_RTN_H);
@ -2673,13 +2802,6 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len) {
}
if (afl->fsrv.total_execs - execs > screen_update) {
execs = afl->fsrv.total_execs;
show_stats(afl);
}
}
r = 0;
@ -2795,9 +2917,10 @@ exit_its:
if (f) {
fprintf(f,
"Cmplog: fname=%s len=%u ms=%llu result=%u finds=%llu entries=%u\n",
"Cmplog: fname=%s len=%u ms=%llu result=%u finds=%llu entries=%u "
"auto_extra_after=%u\n",
afl->queue_cur->fname, len, get_cur_time() - start_time, r,
new_hit_cnt - orig_hit_cnt, cmp_locations);
new_hit_cnt - orig_hit_cnt, cmp_locations, afl->a_extras_cnt);
#ifndef _DEBUG
if (afl->not_on_tty) { fclose(f); }

View File

@ -278,6 +278,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
"total_edges : %u\n"
"var_byte_count : %u\n"
"havoc_expansion : %u\n"
"auto_dict_entries : %u\n"
"testcache_size : %llu\n"
"testcache_count : %u\n"
"testcache_evict : %u\n"
@ -316,7 +317,7 @@ void write_stats_file(afl_state_t *afl, u32 t_bytes, double bitmap_cvg,
-1,
#endif
t_bytes, afl->fsrv.real_map_size, afl->var_byte_count,
afl->expand_havoc, afl->q_testcase_cache_size,
afl->expand_havoc, afl->a_extras_cnt, afl->q_testcase_cache_size,
afl->q_testcase_cache_count, afl->q_testcase_evictions,
afl->use_banner, afl->unicorn_mode ? "unicorn" : "",
afl->fsrv.qemu_mode ? "qemu " : "",

View File

@ -2235,13 +2235,12 @@ int main(int argc, char **argv_orig, char **envp) {
}
write_bitmap(afl);
save_auto(afl);
stop_fuzzing:
afl->force_ui_update = 1; // ensure the screen is reprinted
show_stats(afl); // print the screen one last time
write_bitmap(afl);
save_auto(afl);
SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
afl->stop_soon == 2 ? "programmatically" : "by user");
@ -2270,6 +2269,20 @@ stop_fuzzing:
}
if (afl->not_on_tty) {
u32 t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
u8 time_tmp[64];
u_stringify_time_diff(time_tmp, get_cur_time(), afl->start_time);
ACTF(
"Statistics: %u new paths found, %.02f%% coverage achieved, %llu "
"crashes found, %llu timeouts found, total runtime %s",
afl->queued_discovered,
((double)t_bytes * 100) / afl->fsrv.real_map_size, afl->unique_crashes,
afl->unique_hangs, time_tmp);
}
#ifdef PROFILING
SAYF(cYEL "[!] " cRST
"Profiling information: %llu ms total work, %llu ns/run\n",

View File

@ -90,7 +90,8 @@ inline u32 hash32(u8 *key, u32 len, u32 seed) {
#endif
return (u32)XXH64(key, len, seed);
(void)seed;
return (u32)XXH3_64bits(key, len);
}
@ -102,7 +103,8 @@ inline u64 hash64(u8 *key, u32 len, u64 seed) {
#endif
return XXH64(key, len, seed);
(void)seed;
return XXH3_64bits(key, len);
}

View File

@ -1,15 +1,13 @@
#include <stdio.h>
#include <string.h>
#include <stdint.h>
#include <stdarg.h>
#include <stdlib.h>
#include <stdint.h>
#include <unistd.h>
int main(int argc, char *argv[]) {
char buf[1024];
ssize_t i;
if ((i = read(0, buf, sizeof(buf) - 1)) < 24) return 0;
buf[i] = 0;
int LLVMFuzzerTestOneInput(const uint8_t *buf, size_t i) {
if (i < 24) return 0;
if (buf[0] != 'A') return 0;
if (buf[1] != 'B') return 0;
if (buf[2] != 'C') return 0;
@ -18,6 +16,17 @@ int main(int argc, char *argv[]) {
if (strncmp(buf + 12, "IJKL", 4) == 0 && strcmp(buf + 16, "DEADBEEF") == 0)
abort();
return 0;
}
#ifdef __AFL_COMPILER
int main(int argc, char *argv[]) {
unsigned char buf[1024];
ssize_t i;
while(__AFL_LOOP(1000)) {
i = read(0, (char*)buf, sizeof(buf) - 1);
if (i > 0) buf[i] = 0;
LLVMFuzzerTestOneInput(buf, i);
}
return 0;
}
#endif