mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-16 03:48:08 +00:00
Merge pull request #1141 from AFLplusplus/afl4
cmplog enhancement variant
This commit is contained in:
@ -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
|
||||
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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;
|
||||
|
@ -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 */
|
||||
|
||||
|
@ -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];
|
||||
|
||||
|
@ -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
|
||||
|
@ -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)
|
||||
|
1882
include/xxhash.h
1882
include/xxhash.h
File diff suppressed because it is too large
Load Diff
@ -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");
|
||||
|
||||
}
|
||||
|
@ -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);
|
||||
|
@ -1 +1 @@
|
||||
71ed0d206f
|
||||
8809a2b2ebf089d3427dd8f6a0044bcc2e13b389
|
||||
|
Submodule qemu_mode/qemuafl updated: 71ed0d206f...8809a2b2eb
@ -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;
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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) {
|
||||
|
||||
|
@ -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); }
|
||||
|
@ -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 " : "",
|
||||
|
@ -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",
|
||||
|
@ -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);
|
||||
|
||||
}
|
||||
|
||||
|
@ -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
|
||||
|
Reference in New Issue
Block a user