diff --git a/include/cmplog.h b/include/cmplog.h index e4821444..5601beef 100644 --- a/include/cmplog.h +++ b/include/cmplog.h @@ -59,14 +59,15 @@ struct cmp_operands { u64 v1; u64 v0_128; u64 v1_128; + u64 unused; } __attribute__((packed)); struct cmpfn_operands { - u8 v0[31]; + u8 v0[31 + _CMPLOG_EXTRA]; u8 v0_len; - u8 v1[31]; + u8 v1[31 + _CMPLOG_EXTRA]; u8 v1_len; } __attribute__((packed)); diff --git a/include/config.h b/include/config.h index 988e536e..1f9902d4 100644 --- a/include/config.h +++ b/include/config.h @@ -60,6 +60,9 @@ * */ +/* Support 38 byte wide strings (default: off - up to 29 bytes) */ +#define CMPLOG_U256 1 + /* If a redqueen pass finds more than one solution, try to combine them? */ #define CMPLOG_COMBINE @@ -523,5 +526,12 @@ #define AFL_TXT_STRING_MAX_MUTATIONS 6 +/* IGNORE */ +#ifdef CMPLOG_U256 + #define _CMPLOG_EXTRA 8 +#else + #define _CMPLOG_EXTRA 0 +#endif + #endif /* ! _HAVE_CONFIG_H */ diff --git a/include/types.h b/include/types.h index d6476d82..fbd53826 100644 --- a/include/types.h +++ b/include/types.h @@ -48,6 +48,8 @@ typedef uint128_t u128; #define FS_ERROR_MMAP 16 #define FS_ERROR_OLD_CMPLOG 32 #define FS_ERROR_OLD_CMPLOG_QEMU 64 +#define FS_ERROR_U256CMPLOG1 128 +#define FS_ERROR_U256CMPLOG2 256 /* Reporting options */ #define FS_OPT_ENABLED 0x80000001 @@ -56,6 +58,7 @@ typedef uint128_t u128; #define FS_OPT_AUTODICT 0x10000000 #define FS_OPT_SHDMEM_FUZZ 0x01000000 #define FS_OPT_NEWCMPLOG 0x02000000 +#define FS_OPT_U256CMPLOG 0x04000000 #define FS_OPT_OLD_AFLPP_WORKAROUND 0x0f000000 // FS_OPT_MAX_MAPSIZE is 8388608 = 0x800000 = 2^23 = 1 << 23 #define FS_OPT_MAX_MAPSIZE ((0x00fffffeU >> 1) + 1) diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c index 85ee9f71..ace1c9c8 100644 --- a/instrumentation/afl-compiler-rt.o.c +++ b/instrumentation/afl-compiler-rt.o.c @@ -856,6 +856,7 @@ static void __afl_start_snapshots(void) { if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) status |= (FS_OPT_SET_MAPSIZE(__afl_map_size) | FS_OPT_MAPSIZE); if (__afl_dictionary_len && __afl_dictionary) { status |= FS_OPT_AUTODICT; } + if (1 == CMPLOG_U256 && __afl_cmp_map) { status |= FS_OPT_U256CMPLOG; } memcpy(tmp, &status, 4); if (write(FORKSRV_FD + 1, tmp, 4) != 4) { return; } @@ -2290,11 +2291,11 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) { // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len); if (likely(!__afl_cmp_map)) return; if (unlikely(!len)) return; - int len0 = MIN(len, 31); + int len0 = MIN(len, 31 + _CMPLOG_EXTRA); int len1 = strnlen(ptr1, len0); - if (len1 < 31) len1 = area_is_valid(ptr1, len1 + 1); + if (len1 < 31 + _CMPLOG_EXTRA) len1 = area_is_valid(ptr1, len1 + 1); int len2 = strnlen(ptr2, len0); - if (len2 < 31) len2 = area_is_valid(ptr2, len2 + 1); + if (len2 < 31 + _CMPLOG_EXTRA) len2 = area_is_valid(ptr2, len2 + 1); int l = MAX(len1, len2); if (l < 2) return; @@ -2384,7 +2385,7 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { /* u32 i; - if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return; + if (area_is_valid(ptr1, 31 + _CMPLOG_EXTRA) <= 0 || area_is_valid(ptr2, 31 + _CMPLOG_EXTRA) <= 0) return; fprintf(stderr, "rtn arg0="); for (i = 0; i < 32; i++) fprintf(stderr, "%02x", ptr1[i]); @@ -2397,10 +2398,10 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) { // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2); if (likely(!__afl_cmp_map)) return; int l1, l2; - if ((l1 = area_is_valid(ptr1, 31)) <= 0 || - (l2 = area_is_valid(ptr2, 31)) <= 0) + if ((l1 = area_is_valid(ptr1, 31 + _CMPLOG_EXTRA)) <= 0 || + (l2 = area_is_valid(ptr2, 31 + _CMPLOG_EXTRA)) <= 0) return; - int len = MIN(31, MIN(l1, l2)); + int len = MIN(31 + _CMPLOG_EXTRA, MIN(l1, l2)); // fprintf(stderr, "RTN2 %u\n", len); uintptr_t k = (uintptr_t)__builtin_return_address(0); @@ -2449,7 +2450,7 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) { #if 0 /* u32 i; - if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return; + if (area_is_valid(ptr1, 31 + _CMPLOG_EXTRA) <= 0 || area_is_valid(ptr2, 31 + _CMPLOG_EXTRA) <= 0) return; fprintf(stderr, "rtn_n len=%u arg0=", len); for (i = 0; i < len; i++) fprintf(stderr, "%02x", ptr1[i]); @@ -2462,7 +2463,7 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) { // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len); if (likely(!__afl_cmp_map)) return; if (unlikely(!len)) return; - int l = MIN(31, len); + int l = MIN(31 + _CMPLOG_EXTRA, len); if ((l = area_is_valid(ptr1, l)) <= 0 || (l = area_is_valid(ptr2, l)) <= 0) return; diff --git a/src/afl-forkserver.c b/src/afl-forkserver.c index 07f5a1a9..94bca9d0 100644 --- a/src/afl-forkserver.c +++ b/src/afl-forkserver.c @@ -469,6 +469,12 @@ static void report_error_and_exit(int error) { switch (error) { + case FS_ERROR_U256CMPLOG1: + FATAL("afl-fuzz was compiled for CMPLOG_U256, but the target was not"); + break; + case FS_ERROR_U256CMPLOG2: + FATAL("the target was compiled for CMPLOG_U256, but afl-fuzz was not"); + break; case FS_ERROR_MAP_SIZE: FATAL( "AFL_MAP_SIZE is not set and fuzzing target reports that the " @@ -1026,9 +1032,27 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv, if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) { // workaround for recent AFL++ versions - if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == FS_OPT_OLD_AFLPP_WORKAROUND) + if ((status & FS_OPT_OLD_AFLPP_WORKAROUND) == + FS_OPT_OLD_AFLPP_WORKAROUND) { + status = (status & 0xf0ffffff); + } + + if (fsrv->cmplog_binary && CMPLOG_U256 == 1 && + (status & FS_OPT_U256CMPLOG) == 0) { + + report_error_and_exit(FS_ERROR_U256CMPLOG1); + + } + + if (fsrv->cmplog_binary && CMPLOG_U256 == 0 && + (status & FS_OPT_U256CMPLOG)) { + + report_error_and_exit(FS_ERROR_U256CMPLOG2); + + } + if ((status & FS_OPT_NEWCMPLOG) == 0 && fsrv->cmplog_binary) { if (fsrv->qemu_mode || fsrv->frida_mode) { diff --git a/src/afl-fuzz-redqueen.c b/src/afl-fuzz-redqueen.c index db4991db..8ea23daf 100644 --- a/src/afl-fuzz-redqueen.c +++ b/src/afl-fuzz-redqueen.c @@ -2010,8 +2010,9 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, } - if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 || l1 > 31 || - ol0 > 31 || ol1 > 31) { + if (l0 == 0 || l1 == 0 || ol0 == 0 || ol1 == 0 || l0 > 31 + _CMPLOG_EXTRA || + l1 > 31 + _CMPLOG_EXTRA || ol0 > 31 + _CMPLOG_EXTRA || + ol1 > 31 + _CMPLOG_EXTRA) { l0 = ol0 = hshape; @@ -2121,7 +2122,8 @@ static u8 rtn_extend_encoding(afl_state_t *afl, u8 entry, u32 tob64 = 0, fromb64 = 0; u32 from_0 = 0, from_x = 0, from_X = 0, from_slash = 0, from_up = 0; u32 to_0 = 0, to_x = 0, to_slash = 0, to_up = 0; - u8 xor_val[32], arith_val[32], tmp[48]; + u8 xor_val[32 + _CMPLOG_EXTRA], arith_val[32 + _CMPLOG_EXTRA], + tmp[48 + (_CMPLOG_EXTRA << 1)]; idx = saved_idx; its_len = saved_its_len;