mirror of
https://github.com/AFLplusplus/AFLplusplus.git
synced 2025-06-14 11:08:06 +00:00
clang-tidy readability-braces (#323)
This commit is contained in:
@ -10,7 +10,7 @@ AlignOperands: true
|
|||||||
AlignTrailingComments: true
|
AlignTrailingComments: true
|
||||||
AllowAllParametersOfDeclarationOnNextLine: true
|
AllowAllParametersOfDeclarationOnNextLine: true
|
||||||
AllowShortBlocksOnASingleLine: true
|
AllowShortBlocksOnASingleLine: true
|
||||||
AllowShortCaseLabelsOnASingleLine: true
|
AllowShortCaseLabelsOnASingleLine: false
|
||||||
AllowShortFunctionsOnASingleLine: false
|
AllowShortFunctionsOnASingleLine: false
|
||||||
AllowShortIfStatementsOnASingleLine: true
|
AllowShortIfStatementsOnASingleLine: true
|
||||||
AllowShortLoopsOnASingleLine: false
|
AllowShortLoopsOnASingleLine: false
|
||||||
|
@ -16,7 +16,8 @@ int target_func(unsigned char *buf, int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: break;
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -956,7 +956,7 @@ static inline u32 rand_below(afl_state_t *afl, u32 limit) {
|
|||||||
|
|
||||||
static inline u32 get_rand_seed(afl_state_t *afl) {
|
static inline u32 get_rand_seed(afl_state_t *afl) {
|
||||||
|
|
||||||
if (unlikely(afl->fixed_seed)) return (u32)afl->init_seed;
|
if (unlikely(afl->fixed_seed)) { return (u32)afl->init_seed; }
|
||||||
return afl->rand_seed[0];
|
return afl->rand_seed[0];
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -967,8 +967,12 @@ static inline u32 get_rand_seed(afl_state_t *afl) {
|
|||||||
static inline u64 next_p2(u64 val) {
|
static inline u64 next_p2(u64 val) {
|
||||||
|
|
||||||
u64 ret = 1;
|
u64 ret = 1;
|
||||||
while (val > ret)
|
while (val > ret) {
|
||||||
|
|
||||||
ret <<= 1;
|
ret <<= 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -87,7 +87,7 @@ static inline void *DFL_ck_alloc_nozero(u32 size) {
|
|||||||
|
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if (!size) return NULL;
|
if (!size) { return NULL; }
|
||||||
|
|
||||||
ALLOC_CHECK_SIZE(size);
|
ALLOC_CHECK_SIZE(size);
|
||||||
ret = malloc(size);
|
ret = malloc(size);
|
||||||
@ -103,7 +103,7 @@ static inline void *DFL_ck_alloc(u32 size) {
|
|||||||
|
|
||||||
void *mem;
|
void *mem;
|
||||||
|
|
||||||
if (!size) return NULL;
|
if (!size) { return NULL; }
|
||||||
mem = DFL_ck_alloc_nozero(size);
|
mem = DFL_ck_alloc_nozero(size);
|
||||||
|
|
||||||
return memset(mem, 0, size);
|
return memset(mem, 0, size);
|
||||||
@ -115,7 +115,7 @@ static inline void *DFL_ck_alloc(u32 size) {
|
|||||||
|
|
||||||
static inline void DFL_ck_free(void *mem) {
|
static inline void DFL_ck_free(void *mem) {
|
||||||
|
|
||||||
if (!mem) return;
|
if (!mem) { return; }
|
||||||
|
|
||||||
free(mem);
|
free(mem);
|
||||||
|
|
||||||
@ -165,7 +165,7 @@ static inline u8 *DFL_ck_strdup(u8 *str) {
|
|||||||
u8 *ret;
|
u8 *ret;
|
||||||
u32 size;
|
u32 size;
|
||||||
|
|
||||||
if (!str) return NULL;
|
if (!str) { return NULL; }
|
||||||
|
|
||||||
size = strlen((char *)str) + 1;
|
size = strlen((char *)str) + 1;
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ static inline void *DFL_ck_memdup(void *mem, u32 size) {
|
|||||||
|
|
||||||
void *ret;
|
void *ret;
|
||||||
|
|
||||||
if (!mem || !size) return NULL;
|
if (!mem || !size) { return NULL; }
|
||||||
|
|
||||||
ALLOC_CHECK_SIZE(size);
|
ALLOC_CHECK_SIZE(size);
|
||||||
ret = malloc(size);
|
ret = malloc(size);
|
||||||
@ -201,7 +201,7 @@ static inline u8 *DFL_ck_memdup_str(u8 *mem, u32 size) {
|
|||||||
|
|
||||||
u8 *ret;
|
u8 *ret;
|
||||||
|
|
||||||
if (!mem || !size) return NULL;
|
if (!mem || !size) { return NULL; }
|
||||||
|
|
||||||
ALLOC_CHECK_SIZE(size);
|
ALLOC_CHECK_SIZE(size);
|
||||||
ret = malloc(size + 1);
|
ret = malloc(size + 1);
|
||||||
@ -772,8 +772,12 @@ static inline void TRK_ck_free(void *ptr, const char *file, const char *func,
|
|||||||
*/
|
*/
|
||||||
static inline size_t next_pow2(size_t in) {
|
static inline size_t next_pow2(size_t in) {
|
||||||
|
|
||||||
if (in == 0 || in > (size_t)-1)
|
if (in == 0 || in > (size_t)-1) {
|
||||||
|
|
||||||
return 0; /* avoid undefined behaviour under-/overflow */
|
return 0; /* avoid undefined behaviour under-/overflow */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
size_t out = in - 1;
|
size_t out = in - 1;
|
||||||
out |= out >> 1;
|
out |= out >> 1;
|
||||||
out |= out >> 2;
|
out |= out >> 2;
|
||||||
@ -794,10 +798,10 @@ static inline size_t next_pow2(size_t in) {
|
|||||||
static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) {
|
static inline void *maybe_grow(void **buf, size_t *size, size_t size_needed) {
|
||||||
|
|
||||||
/* No need to realloc */
|
/* No need to realloc */
|
||||||
if (likely(size_needed && *size >= size_needed)) return *buf;
|
if (likely(size_needed && *size >= size_needed)) { return *buf; }
|
||||||
|
|
||||||
/* No initial size was set */
|
/* No initial size was set */
|
||||||
if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE;
|
if (size_needed < INITIAL_GROWTH_SIZE) { size_needed = INITIAL_GROWTH_SIZE; }
|
||||||
|
|
||||||
/* grow exponentially */
|
/* grow exponentially */
|
||||||
size_t next_size = next_pow2(size_needed);
|
size_t next_size = next_pow2(size_needed);
|
||||||
@ -824,13 +828,13 @@ static inline void *ck_maybe_grow(void **buf, size_t *size,
|
|||||||
size_t size_needed) {
|
size_t size_needed) {
|
||||||
|
|
||||||
/* Oops. found a bug? */
|
/* Oops. found a bug? */
|
||||||
if (unlikely(size_needed < 1)) FATAL("cannot grow to non-positive size");
|
if (unlikely(size_needed < 1)) { FATAL("cannot grow to non-positive size"); }
|
||||||
|
|
||||||
/* No need to realloc */
|
/* No need to realloc */
|
||||||
if (likely(*size >= size_needed)) return *buf;
|
if (likely(*size >= size_needed)) { return *buf; }
|
||||||
|
|
||||||
/* No initial size was set */
|
/* No initial size was set */
|
||||||
if (size_needed < INITIAL_GROWTH_SIZE) size_needed = INITIAL_GROWTH_SIZE;
|
if (size_needed < INITIAL_GROWTH_SIZE) { size_needed = INITIAL_GROWTH_SIZE; }
|
||||||
|
|
||||||
/* grow exponentially */
|
/* grow exponentially */
|
||||||
size_t next_size = next_pow2(size_needed);
|
size_t next_size = next_pow2(size_needed);
|
||||||
|
@ -109,3 +109,5 @@ static inline void *shmat(int __shmid, const void *__shmaddr, int __shmflg) {
|
|||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
@ -30,6 +30,7 @@
|
|||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <stdbool.h>
|
#include <stdbool.h>
|
||||||
|
#include "types.h"
|
||||||
|
|
||||||
#include "types.h"
|
#include "types.h"
|
||||||
typedef struct afl_forkserver {
|
typedef struct afl_forkserver {
|
||||||
|
@ -83,7 +83,7 @@ static inline void list_append(list_t *list, void *el) {
|
|||||||
element_t *el_box = NULL;
|
element_t *el_box = NULL;
|
||||||
PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE,
|
PRE_ALLOC(el_box, list->element_prealloc_buf, LIST_PREALLOC_SIZE,
|
||||||
list->element_prealloc_count);
|
list->element_prealloc_count);
|
||||||
if (!el_box) FATAL("failed to allocate list element");
|
if (!el_box) { FATAL("failed to allocate list element"); }
|
||||||
el_box->data = el;
|
el_box->data = el;
|
||||||
el_box->next = head;
|
el_box->next = head;
|
||||||
el_box->prev = head->prev;
|
el_box->prev = head->prev;
|
||||||
|
@ -274,7 +274,8 @@ static void __tokencap_dump(const u8 *ptr, size_t len, u8 is_text) {
|
|||||||
pos += 4;
|
pos += 4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: buf[pos++] = ptr[i];
|
default:
|
||||||
|
buf[pos++] = ptr[i];
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -360,11 +360,20 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
|
|||||||
|
|
||||||
switch (max_size) {
|
switch (max_size) {
|
||||||
|
|
||||||
case 8: IRB.CreateCall(cmplogHookIns1, args, "tmp"); break;
|
case 8:
|
||||||
case 16: IRB.CreateCall(cmplogHookIns2, args, "tmp"); break;
|
IRB.CreateCall(cmplogHookIns1, args, "tmp");
|
||||||
case 32: IRB.CreateCall(cmplogHookIns4, args, "tmp"); break;
|
break;
|
||||||
case 64: IRB.CreateCall(cmplogHookIns8, args, "tmp"); break;
|
case 16:
|
||||||
default: break;
|
IRB.CreateCall(cmplogHookIns2, args, "tmp");
|
||||||
|
break;
|
||||||
|
case 32:
|
||||||
|
IRB.CreateCall(cmplogHookIns4, args, "tmp");
|
||||||
|
break;
|
||||||
|
case 64:
|
||||||
|
IRB.CreateCall(cmplogHookIns8, args, "tmp");
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -318,10 +318,18 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
|
|||||||
CmpInst::Predicate new_pred;
|
CmpInst::Predicate new_pred;
|
||||||
switch (pred) {
|
switch (pred) {
|
||||||
|
|
||||||
case CmpInst::ICMP_UGE: new_pred = CmpInst::ICMP_UGT; break;
|
case CmpInst::ICMP_UGE:
|
||||||
case CmpInst::ICMP_SGE: new_pred = CmpInst::ICMP_SGT; break;
|
new_pred = CmpInst::ICMP_UGT;
|
||||||
case CmpInst::ICMP_ULE: new_pred = CmpInst::ICMP_ULT; break;
|
break;
|
||||||
case CmpInst::ICMP_SLE: new_pred = CmpInst::ICMP_SLT; break;
|
case CmpInst::ICMP_SGE:
|
||||||
|
new_pred = CmpInst::ICMP_SGT;
|
||||||
|
break;
|
||||||
|
case CmpInst::ICMP_ULE:
|
||||||
|
new_pred = CmpInst::ICMP_ULT;
|
||||||
|
break;
|
||||||
|
case CmpInst::ICMP_SLE:
|
||||||
|
new_pred = CmpInst::ICMP_SLT;
|
||||||
|
break;
|
||||||
default: // keep the compiler happy
|
default: // keep the compiler happy
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -384,10 +392,18 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
|
|||||||
CmpInst::Predicate new_pred;
|
CmpInst::Predicate new_pred;
|
||||||
switch (pred) {
|
switch (pred) {
|
||||||
|
|
||||||
case CmpInst::FCMP_UGE: new_pred = CmpInst::FCMP_UGT; break;
|
case CmpInst::FCMP_UGE:
|
||||||
case CmpInst::FCMP_OGE: new_pred = CmpInst::FCMP_OGT; break;
|
new_pred = CmpInst::FCMP_UGT;
|
||||||
case CmpInst::FCMP_ULE: new_pred = CmpInst::FCMP_ULT; break;
|
break;
|
||||||
case CmpInst::FCMP_OLE: new_pred = CmpInst::FCMP_OLT; break;
|
case CmpInst::FCMP_OGE:
|
||||||
|
new_pred = CmpInst::FCMP_OGT;
|
||||||
|
break;
|
||||||
|
case CmpInst::FCMP_ULE:
|
||||||
|
new_pred = CmpInst::FCMP_ULT;
|
||||||
|
break;
|
||||||
|
case CmpInst::FCMP_OLE:
|
||||||
|
new_pred = CmpInst::FCMP_OLT;
|
||||||
|
break;
|
||||||
default: // keep the compiler happy
|
default: // keep the compiler happy
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@ -855,7 +871,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_exponent_result =
|
icmp_exponent_result =
|
||||||
BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
|
BinaryOperator::Create(Instruction::Xor, icmp_exponent, t_s0);
|
||||||
break;
|
break;
|
||||||
default: continue;
|
default:
|
||||||
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -958,7 +975,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
icmp_fraction_result =
|
icmp_fraction_result =
|
||||||
BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
|
BinaryOperator::Create(Instruction::Xor, icmp_fraction, t_s0);
|
||||||
break;
|
break;
|
||||||
default: continue;
|
default:
|
||||||
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1004,7 +1022,8 @@ size_t SplitComparesTransform::splitFPCompares(Module &M) {
|
|||||||
PN->addIncoming(icmp_exponent_result, signequal_bb);
|
PN->addIncoming(icmp_exponent_result, signequal_bb);
|
||||||
PN->addIncoming(icmp_fraction_result, middle_bb);
|
PN->addIncoming(icmp_fraction_result, middle_bb);
|
||||||
break;
|
break;
|
||||||
default: continue;
|
default:
|
||||||
|
continue;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -29,7 +29,9 @@ int target_func(char *buf, int size) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
default: puts("default action"); break;
|
default:
|
||||||
|
puts("default action");
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -51,9 +51,11 @@ int main() {
|
|||||||
|
|
||||||
switch (z) {
|
switch (z) {
|
||||||
|
|
||||||
case 0xBEEF: break;
|
case 0xBEEF:
|
||||||
|
break;
|
||||||
|
|
||||||
default: return 4;
|
default:
|
||||||
|
return 4;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -55,11 +55,20 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv arg1, TCGv arg2,
|
|||||||
|
|
||||||
switch (ot & MO_SIZE) {
|
switch (ot & MO_SIZE) {
|
||||||
|
|
||||||
case MO_64: gen_helper_afl_cmplog_64(cur_loc_v, arg1, arg2); break;
|
case MO_64:
|
||||||
case MO_32: gen_helper_afl_cmplog_32(cur_loc_v, arg1, arg2); break;
|
gen_helper_afl_cmplog_64(cur_loc_v, arg1, arg2);
|
||||||
case MO_16: gen_helper_afl_cmplog_16(cur_loc_v, arg1, arg2); break;
|
break;
|
||||||
case MO_8: gen_helper_afl_cmplog_8(cur_loc_v, arg1, arg2); break;
|
case MO_32:
|
||||||
default: break;
|
gen_helper_afl_cmplog_32(cur_loc_v, arg1, arg2);
|
||||||
|
break;
|
||||||
|
case MO_16:
|
||||||
|
gen_helper_afl_cmplog_16(cur_loc_v, arg1, arg2);
|
||||||
|
break;
|
||||||
|
case MO_8:
|
||||||
|
gen_helper_afl_cmplog_8(cur_loc_v, arg1, arg2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,10 +87,17 @@ static void afl_gen_compcov(target_ulong cur_loc, TCGv arg1, TCGv arg2,
|
|||||||
|
|
||||||
switch (ot & MO_SIZE) {
|
switch (ot & MO_SIZE) {
|
||||||
|
|
||||||
case MO_64: gen_helper_afl_compcov_64(cur_loc_v, arg1, arg2); break;
|
case MO_64:
|
||||||
case MO_32: gen_helper_afl_compcov_32(cur_loc_v, arg1, arg2); break;
|
gen_helper_afl_compcov_64(cur_loc_v, arg1, arg2);
|
||||||
case MO_16: gen_helper_afl_compcov_16(cur_loc_v, arg1, arg2); break;
|
break;
|
||||||
default: break;
|
case MO_32:
|
||||||
|
gen_helper_afl_compcov_32(cur_loc_v, arg1, arg2);
|
||||||
|
break;
|
||||||
|
case MO_16:
|
||||||
|
gen_helper_afl_compcov_16(cur_loc_v, arg1, arg2);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -122,7 +122,7 @@ static void classify_counts(u8 *mem) {
|
|||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
if (*mem) *mem = 1;
|
if (*mem) { *mem = 1; }
|
||||||
mem++;
|
mem++;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -147,8 +147,11 @@ static inline u8 anything_set(void) {
|
|||||||
u32 *ptr = (u32 *)trace_bits;
|
u32 *ptr = (u32 *)trace_bits;
|
||||||
u32 i = (map_size >> 2);
|
u32 i = (map_size >> 2);
|
||||||
|
|
||||||
while (i--)
|
while (i--) {
|
||||||
if (*(ptr++)) return 1;
|
|
||||||
|
if (*(ptr++)) { return 1; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -169,13 +172,16 @@ static void read_initial_file(void) {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
s32 fd = open(in_file, O_RDONLY);
|
s32 fd = open(in_file, O_RDONLY);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", in_file);
|
if (fd < 0) { PFATAL("Unable to open '%s'", in_file); }
|
||||||
|
|
||||||
if (fstat(fd, &st) || !st.st_size) FATAL("Zero-sized input file.");
|
if (fstat(fd, &st) || !st.st_size) { FATAL("Zero-sized input file."); }
|
||||||
|
|
||||||
|
if (st.st_size >= TMIN_MAX_FILE) {
|
||||||
|
|
||||||
if (st.st_size >= TMIN_MAX_FILE)
|
|
||||||
FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);
|
FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
in_len = st.st_size;
|
in_len = st.st_size;
|
||||||
in_data = ck_alloc_nozero(in_len);
|
in_data = ck_alloc_nozero(in_len);
|
||||||
|
|
||||||
@ -197,7 +203,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
|
|||||||
|
|
||||||
ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
|
ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
|
|
||||||
if (ret < 0) PFATAL("Unable to create '%s'", path);
|
if (ret < 0) { PFATAL("Unable to create '%s'", path); }
|
||||||
|
|
||||||
ck_write(ret, mem, len, path);
|
ck_write(ret, mem, len, path);
|
||||||
|
|
||||||
@ -225,7 +231,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
|
|
||||||
child_pid = fork();
|
child_pid = fork();
|
||||||
|
|
||||||
if (child_pid < 0) PFATAL("fork() failed");
|
if (child_pid < 0) { PFATAL("fork() failed"); }
|
||||||
|
|
||||||
if (!child_pid) {
|
if (!child_pid) {
|
||||||
|
|
||||||
@ -278,7 +284,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
|
|
||||||
setitimer(ITIMER_REAL, &it, NULL);
|
setitimer(ITIMER_REAL, &it, NULL);
|
||||||
|
|
||||||
if (waitpid(child_pid, &status, 0) <= 0) FATAL("waitpid() failed");
|
if (waitpid(child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); }
|
||||||
|
|
||||||
child_pid = 0;
|
child_pid = 0;
|
||||||
it.it_value.tv_sec = 0;
|
it.it_value.tv_sec = 0;
|
||||||
@ -290,9 +296,12 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
|
|
||||||
/* Clean up bitmap, analyze exit condition, etc. */
|
/* Clean up bitmap, analyze exit condition, etc. */
|
||||||
|
|
||||||
if (*(u32 *)trace_bits == EXEC_FAIL_SIG)
|
if (*(u32 *)trace_bits == EXEC_FAIL_SIG) {
|
||||||
|
|
||||||
FATAL("Unable to execute '%s'", argv[0]);
|
FATAL("Unable to execute '%s'", argv[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
classify_counts(trace_bits);
|
classify_counts(trace_bits);
|
||||||
total_execs++;
|
total_execs++;
|
||||||
|
|
||||||
@ -325,7 +334,7 @@ static u32 analyze_run_target(char **argv, u8 *mem, u32 len, u8 first_run) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (first_run) orig_cksum = cksum;
|
if (first_run) { orig_cksum = cksum; }
|
||||||
|
|
||||||
return cksum;
|
return cksum;
|
||||||
|
|
||||||
@ -340,9 +349,12 @@ static void show_char(u8 val) {
|
|||||||
switch (val) {
|
switch (val) {
|
||||||
|
|
||||||
case 0 ... 32:
|
case 0 ... 32:
|
||||||
case 127 ... 255: SAYF("#%02x", val); break;
|
case 127 ... 255:
|
||||||
|
SAYF("#%02x", val);
|
||||||
|
break;
|
||||||
|
|
||||||
default: SAYF(" %c ", val);
|
default:
|
||||||
|
SAYF(" %c ", val);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +399,12 @@ static void dump_hex(u8 *buf, u32 len, u8 *b_data) {
|
|||||||
|
|
||||||
while (i + rlen < len && (b_data[i] >> 7) == (b_data[i + rlen] >> 7)) {
|
while (i + rlen < len && (b_data[i] >> 7) == (b_data[i + rlen] >> 7)) {
|
||||||
|
|
||||||
if (rtype < (b_data[i + rlen] & 0x0f)) rtype = b_data[i + rlen] & 0x0f;
|
if (rtype < (b_data[i + rlen] & 0x0f)) {
|
||||||
|
|
||||||
|
rtype = b_data[i + rlen] & 0x0f;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
rlen++;
|
rlen++;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -454,9 +471,11 @@ static void dump_hex(u8 *buf, u32 len, u8 *b_data) {
|
|||||||
|
|
||||||
case 1:
|
case 1:
|
||||||
case 3:
|
case 3:
|
||||||
case 5 ... MAX_AUTO_EXTRA - 1: break;
|
case 5 ... MAX_AUTO_EXTRA - 1:
|
||||||
|
break;
|
||||||
|
|
||||||
default: rtype = RESP_SUSPECT;
|
default:
|
||||||
|
rtype = RESP_SUSPECT;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -472,34 +491,58 @@ static void dump_hex(u8 *buf, u32 len, u8 *b_data) {
|
|||||||
|
|
||||||
if (!((i + off) % 16)) {
|
if (!((i + off) % 16)) {
|
||||||
|
|
||||||
if (off) SAYF(cRST cLCY ">");
|
if (off) { SAYF(cRST cLCY ">"); }
|
||||||
|
|
||||||
|
if (use_hex_offsets) {
|
||||||
|
|
||||||
if (use_hex_offsets)
|
|
||||||
SAYF(cRST cGRA "%s[%06x] " cRST, (i + off) ? "\n" : "", i + off);
|
SAYF(cRST cGRA "%s[%06x] " cRST, (i + off) ? "\n" : "", i + off);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
SAYF(cRST cGRA "%s[%06u] " cRST, (i + off) ? "\n" : "", i + off);
|
SAYF(cRST cGRA "%s[%06u] " cRST, (i + off) ? "\n" : "", i + off);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (rtype) {
|
switch (rtype) {
|
||||||
|
|
||||||
case RESP_NONE: SAYF(cLGR bgGRA); break;
|
case RESP_NONE:
|
||||||
case RESP_MINOR: SAYF(cBRI bgGRA); break;
|
SAYF(cLGR bgGRA);
|
||||||
case RESP_VARIABLE: SAYF(cBLK bgCYA); break;
|
break;
|
||||||
case RESP_FIXED: SAYF(cBLK bgMGN); break;
|
case RESP_MINOR:
|
||||||
case RESP_LEN: SAYF(cBLK bgLGN); break;
|
SAYF(cBRI bgGRA);
|
||||||
case RESP_CKSUM: SAYF(cBLK bgYEL); break;
|
break;
|
||||||
case RESP_SUSPECT: SAYF(cBLK bgLRD); break;
|
case RESP_VARIABLE:
|
||||||
|
SAYF(cBLK bgCYA);
|
||||||
|
break;
|
||||||
|
case RESP_FIXED:
|
||||||
|
SAYF(cBLK bgMGN);
|
||||||
|
break;
|
||||||
|
case RESP_LEN:
|
||||||
|
SAYF(cBLK bgLGN);
|
||||||
|
break;
|
||||||
|
case RESP_CKSUM:
|
||||||
|
SAYF(cBLK bgYEL);
|
||||||
|
break;
|
||||||
|
case RESP_SUSPECT:
|
||||||
|
SAYF(cBLK bgLRD);
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
show_char(in_data[i + off]);
|
show_char(in_data[i + off]);
|
||||||
|
|
||||||
if (off != rlen - 1 && (i + off + 1) % 16)
|
if (off != rlen - 1 && (i + off + 1) % 16) {
|
||||||
|
|
||||||
SAYF(" ");
|
SAYF(" ");
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
SAYF(cRST " ");
|
SAYF(cRST " ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
@ -511,13 +554,27 @@ static void dump_hex(u8 *buf, u32 len, u8 *b_data) {
|
|||||||
|
|
||||||
switch (rtype) {
|
switch (rtype) {
|
||||||
|
|
||||||
case RESP_NONE: SAYF("no-op block\n"); break;
|
case RESP_NONE:
|
||||||
case RESP_MINOR: SAYF("superficial content\n"); break;
|
SAYF("no-op block\n");
|
||||||
case RESP_VARIABLE: SAYF("critical stream\n"); break;
|
break;
|
||||||
case RESP_FIXED: SAYF("\"magic value\" section\n"); break;
|
case RESP_MINOR:
|
||||||
case RESP_LEN: SAYF("suspected length field\n"); break;
|
SAYF("superficial content\n");
|
||||||
case RESP_CKSUM: SAYF("suspected cksum or magic int\n"); break;
|
break;
|
||||||
case RESP_SUSPECT: SAYF("suspected checksummed block\n"); break;
|
case RESP_VARIABLE:
|
||||||
|
SAYF("critical stream\n");
|
||||||
|
break;
|
||||||
|
case RESP_FIXED:
|
||||||
|
SAYF("\"magic value\" section\n");
|
||||||
|
break;
|
||||||
|
case RESP_LEN:
|
||||||
|
SAYF("suspected length field\n");
|
||||||
|
break;
|
||||||
|
case RESP_CKSUM:
|
||||||
|
SAYF("suspected cksum or magic int\n");
|
||||||
|
break;
|
||||||
|
case RESP_SUSPECT:
|
||||||
|
SAYF("suspected checksummed block\n");
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -594,16 +651,21 @@ static void analyze(char **argv) {
|
|||||||
|
|
||||||
b_data[i] = RESP_FIXED;
|
b_data[i] = RESP_FIXED;
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
b_data[i] = RESP_VARIABLE;
|
b_data[i] = RESP_VARIABLE;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* When all checksums change, flip most significant bit of b_data. */
|
/* When all checksums change, flip most significant bit of b_data. */
|
||||||
|
|
||||||
if (prev_xff != xor_ff && prev_x01 != xor_01 && prev_s10 != sub_10 &&
|
if (prev_xff != xor_ff && prev_x01 != xor_01 && prev_s10 != sub_10 &&
|
||||||
prev_a10 != add_10)
|
prev_a10 != add_10) {
|
||||||
|
|
||||||
seq_byte ^= 0x80;
|
seq_byte ^= 0x80;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
b_data[i] |= seq_byte;
|
b_data[i] |= seq_byte;
|
||||||
|
|
||||||
prev_xff = xor_ff;
|
prev_xff = xor_ff;
|
||||||
@ -620,10 +682,13 @@ static void analyze(char **argv) {
|
|||||||
OKF("Analysis complete. Interesting bits: %0.02f%% of the input file.",
|
OKF("Analysis complete. Interesting bits: %0.02f%% of the input file.",
|
||||||
100.0 - ((double)boring_len * 100) / in_len);
|
100.0 - ((double)boring_len * 100) / in_len);
|
||||||
|
|
||||||
if (exec_hangs)
|
if (exec_hangs) {
|
||||||
|
|
||||||
WARNF(cLRD "Encountered %u timeouts - results may be skewed." cRST,
|
WARNF(cLRD "Encountered %u timeouts - results may be skewed." cRST,
|
||||||
exec_hangs);
|
exec_hangs);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ck_free(b_data);
|
ck_free(b_data);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -634,7 +699,7 @@ static void handle_stop_sig(int sig) {
|
|||||||
|
|
||||||
stop_soon = 1;
|
stop_soon = 1;
|
||||||
|
|
||||||
if (child_pid > 0) kill(child_pid, SIGKILL);
|
if (child_pid > 0) { kill(child_pid, SIGKILL); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -645,7 +710,7 @@ static void set_up_environment(void) {
|
|||||||
u8 *x;
|
u8 *x;
|
||||||
|
|
||||||
dev_null_fd = open("/dev/null", O_RDWR);
|
dev_null_fd = open("/dev/null", O_RDWR);
|
||||||
if (dev_null_fd < 0) PFATAL("Unable to open /dev/null");
|
if (dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||||
|
|
||||||
if (!prog_in) {
|
if (!prog_in) {
|
||||||
|
|
||||||
@ -654,7 +719,7 @@ static void set_up_environment(void) {
|
|||||||
if (access(use_dir, R_OK | W_OK | X_OK)) {
|
if (access(use_dir, R_OK | W_OK | X_OK)) {
|
||||||
|
|
||||||
use_dir = get_afl_env("TMPDIR");
|
use_dir = get_afl_env("TMPDIR");
|
||||||
if (!use_dir) use_dir = "/tmp";
|
if (!use_dir) { use_dir = "/tmp"; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -668,25 +733,37 @@ static void set_up_environment(void) {
|
|||||||
|
|
||||||
if (x) {
|
if (x) {
|
||||||
|
|
||||||
if (!strstr(x, "abort_on_error=1"))
|
if (!strstr(x, "abort_on_error=1")) {
|
||||||
|
|
||||||
FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!");
|
FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!");
|
||||||
|
|
||||||
if (!strstr(x, "symbolize=0"))
|
}
|
||||||
|
|
||||||
|
if (!strstr(x, "symbolize=0")) {
|
||||||
|
|
||||||
FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!");
|
FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x = get_afl_env("MSAN_OPTIONS");
|
x = get_afl_env("MSAN_OPTIONS");
|
||||||
|
|
||||||
if (x) {
|
if (x) {
|
||||||
|
|
||||||
if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR)))
|
if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR))) {
|
||||||
|
|
||||||
FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY(
|
FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY(
|
||||||
MSAN_ERROR) " - please fix!");
|
MSAN_ERROR) " - please fix!");
|
||||||
|
|
||||||
if (!strstr(x, "symbolize=0"))
|
}
|
||||||
|
|
||||||
|
if (!strstr(x, "symbolize=0")) {
|
||||||
|
|
||||||
FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!");
|
FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setenv("ASAN_OPTIONS",
|
setenv("ASAN_OPTIONS",
|
||||||
@ -713,20 +790,28 @@ static void set_up_environment(void) {
|
|||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',') {
|
||||||
|
|
||||||
PFATAL(
|
PFATAL(
|
||||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
"specified!");
|
"specified!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload) {
|
||||||
|
|
||||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
qemu_preload, afl_preload, afl_preload);
|
qemu_preload, afl_preload, afl_preload);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
afl_preload, afl_preload);
|
afl_preload, afl_preload);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
setenv("QEMU_SET_ENV", buf, 1);
|
setenv("QEMU_SET_ENV", buf, 1);
|
||||||
|
|
||||||
ck_free(buf);
|
ck_free(buf);
|
||||||
@ -820,26 +905,26 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
SAYF(cCYA "afl-analyze" VERSION cRST " by Michal Zalewski\n");
|
SAYF(cCYA "afl-analyze" VERSION cRST " by Michal Zalewski\n");
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "+i:f:m:t:eQUWh")) > 0)
|
while ((opt = getopt(argc, argv, "+i:f:m:t:eQUWh")) > 0) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
|
|
||||||
if (in_file) FATAL("Multiple -i options not supported");
|
if (in_file) { FATAL("Multiple -i options not supported"); }
|
||||||
in_file = optarg;
|
in_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
|
|
||||||
if (prog_in) FATAL("Multiple -f options not supported");
|
if (prog_in) { FATAL("Multiple -f options not supported"); }
|
||||||
use_stdin = 0;
|
use_stdin = 0;
|
||||||
prog_in = optarg;
|
prog_in = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
|
|
||||||
if (edges_only) FATAL("Multiple -e options not supported");
|
if (edges_only) { FATAL("Multiple -e options not supported"); }
|
||||||
edges_only = 1;
|
edges_only = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -847,7 +932,7 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
u8 suffix = 'M';
|
u8 suffix = 'M';
|
||||||
|
|
||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
if (!optarg) { FATAL("Wrong usage of -m"); }
|
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||||
@ -860,66 +945,83 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
|
if (sscanf(optarg, "%llu%c", &mem_limit, &suffix) < 1 ||
|
||||||
optarg[0] == '-')
|
optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -m");
|
FATAL("Bad syntax used for -m");
|
||||||
|
|
||||||
switch (suffix) {
|
|
||||||
|
|
||||||
case 'T': mem_limit *= 1024 * 1024; break;
|
|
||||||
case 'G': mem_limit *= 1024; break;
|
|
||||||
case 'k': mem_limit /= 1024; break;
|
|
||||||
case 'M': break;
|
|
||||||
|
|
||||||
default: FATAL("Unsupported suffix or bad syntax for -m");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (mem_limit < 5) FATAL("Dangerously low value of -m");
|
switch (suffix) {
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
mem_limit *= 1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
mem_limit *= 1024;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
mem_limit /= 1024;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FATAL("Unsupported suffix or bad syntax for -m");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (mem_limit < 5) { FATAL("Dangerously low value of -m"); }
|
||||||
|
|
||||||
|
if (sizeof(rlim_t) == 4 && mem_limit > 2000) {
|
||||||
|
|
||||||
if (sizeof(rlim_t) == 4 && mem_limit > 2000)
|
|
||||||
FATAL("Value of -m out of range on 32-bit systems");
|
FATAL("Value of -m out of range on 32-bit systems");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
|
|
||||||
if (timeout_given) FATAL("Multiple -t options not supported");
|
if (timeout_given) { FATAL("Multiple -t options not supported"); }
|
||||||
timeout_given = 1;
|
timeout_given = 1;
|
||||||
|
|
||||||
if (!optarg) FATAL("Wrong usage of -t");
|
if (!optarg) { FATAL("Wrong usage of -t"); }
|
||||||
|
|
||||||
exec_tmout = atoi(optarg);
|
exec_tmout = atoi(optarg);
|
||||||
|
|
||||||
if (exec_tmout < 10 || optarg[0] == '-')
|
if (exec_tmout < 10 || optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Dangerously low value of -t");
|
FATAL("Dangerously low value of -t");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
|
|
||||||
if (qemu_mode) FATAL("Multiple -Q options not supported");
|
if (qemu_mode) { FATAL("Multiple -Q options not supported"); }
|
||||||
if (!mem_limit_given) mem_limit = MEM_LIMIT_QEMU;
|
if (!mem_limit_given) { mem_limit = MEM_LIMIT_QEMU; }
|
||||||
|
|
||||||
qemu_mode = 1;
|
qemu_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U':
|
case 'U':
|
||||||
|
|
||||||
if (unicorn_mode) FATAL("Multiple -U options not supported");
|
if (unicorn_mode) { FATAL("Multiple -U options not supported"); }
|
||||||
if (!mem_limit_given) mem_limit = MEM_LIMIT_UNICORN;
|
if (!mem_limit_given) { mem_limit = MEM_LIMIT_UNICORN; }
|
||||||
|
|
||||||
unicorn_mode = 1;
|
unicorn_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W': /* Wine+QEMU mode */
|
case 'W': /* Wine+QEMU mode */
|
||||||
|
|
||||||
if (use_wine) FATAL("Multiple -W options not supported");
|
if (use_wine) { FATAL("Multiple -W options not supported"); }
|
||||||
qemu_mode = 1;
|
qemu_mode = 1;
|
||||||
use_wine = 1;
|
use_wine = 1;
|
||||||
|
|
||||||
if (!mem_limit_given) mem_limit = 0;
|
if (!mem_limit_given) { mem_limit = 0; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -928,11 +1030,14 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: usage(argv[0]);
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind == argc || !in_file) usage(argv[0]);
|
}
|
||||||
|
|
||||||
|
if (optind == argc || !in_file) { usage(argv[0]); }
|
||||||
|
|
||||||
map_size = get_map_size();
|
map_size = get_map_size();
|
||||||
|
|
||||||
@ -952,17 +1057,24 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
if (qemu_mode) {
|
if (qemu_mode) {
|
||||||
|
|
||||||
if (use_wine)
|
if (use_wine) {
|
||||||
|
|
||||||
use_argv =
|
use_argv =
|
||||||
get_wine_argv(argv[0], &target_path, argc - optind, argv + optind);
|
get_wine_argv(argv[0], &target_path, argc - optind, argv + optind);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
use_argv =
|
use_argv =
|
||||||
get_qemu_argv(argv[0], &target_path, argc - optind, argv + optind);
|
get_qemu_argv(argv[0], &target_path, argc - optind, argv + optind);
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
use_argv = argv + optind;
|
use_argv = argv + optind;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SAYF("\n");
|
SAYF("\n");
|
||||||
|
|
||||||
read_initial_file();
|
read_initial_file();
|
||||||
@ -972,17 +1084,23 @@ int main(int argc, char **argv, char **envp) {
|
|||||||
|
|
||||||
analyze_run_target(use_argv, in_data, in_len, 1);
|
analyze_run_target(use_argv, in_data, in_len, 1);
|
||||||
|
|
||||||
if (child_timed_out)
|
if (child_timed_out) {
|
||||||
|
|
||||||
FATAL("Target binary times out (adjusting -t may help).");
|
FATAL("Target binary times out (adjusting -t may help).");
|
||||||
|
|
||||||
if (get_afl_env("AFL_SKIP_BIN_CHECK") == NULL && !anything_set())
|
}
|
||||||
|
|
||||||
|
if (get_afl_env("AFL_SKIP_BIN_CHECK") == NULL && !anything_set()) {
|
||||||
|
|
||||||
FATAL("No instrumentation detected.");
|
FATAL("No instrumentation detected.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
analyze(use_argv);
|
analyze(use_argv);
|
||||||
|
|
||||||
OKF("We're done here. Have a nice day!\n");
|
OKF("We're done here. Have a nice day!\n");
|
||||||
|
|
||||||
if (target_path) ck_free(target_path);
|
if (target_path) { ck_free(target_path); }
|
||||||
|
|
||||||
afl_shm_deinit(&shm);
|
afl_shm_deinit(&shm);
|
||||||
|
|
||||||
|
110
src/afl-as.c
110
src/afl-as.c
@ -126,9 +126,9 @@ static void edit_params(int argc, char **argv) {
|
|||||||
is not set. We need to check these non-standard variables to properly
|
is not set. We need to check these non-standard variables to properly
|
||||||
handle the pass_thru logic later on. */
|
handle the pass_thru logic later on. */
|
||||||
|
|
||||||
if (!tmp_dir) tmp_dir = getenv("TEMP");
|
if (!tmp_dir) { tmp_dir = getenv("TEMP"); }
|
||||||
if (!tmp_dir) tmp_dir = getenv("TMP");
|
if (!tmp_dir) { tmp_dir = getenv("TMP"); }
|
||||||
if (!tmp_dir) tmp_dir = "/tmp";
|
if (!tmp_dir) { tmp_dir = "/tmp"; }
|
||||||
|
|
||||||
as_params = ck_alloc((argc + 32) * sizeof(u8 *));
|
as_params = ck_alloc((argc + 32) * sizeof(u8 *));
|
||||||
|
|
||||||
@ -138,11 +138,16 @@ static void edit_params(int argc, char **argv) {
|
|||||||
|
|
||||||
for (i = 1; i < argc - 1; i++) {
|
for (i = 1; i < argc - 1; i++) {
|
||||||
|
|
||||||
if (!strcmp(argv[i], "--64"))
|
if (!strcmp(argv[i], "--64")) {
|
||||||
|
|
||||||
use_64bit = 1;
|
use_64bit = 1;
|
||||||
else if (!strcmp(argv[i], "--32"))
|
|
||||||
|
} else if (!strcmp(argv[i], "--32")) {
|
||||||
|
|
||||||
use_64bit = 0;
|
use_64bit = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef __APPLE__
|
#ifdef __APPLE__
|
||||||
|
|
||||||
/* The Apple case is a bit different... */
|
/* The Apple case is a bit different... */
|
||||||
@ -195,11 +200,16 @@ static void edit_params(int argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (input_file[1])
|
if (input_file[1]) {
|
||||||
|
|
||||||
FATAL("Incorrect use (not called through afl-gcc?)");
|
FATAL("Incorrect use (not called through afl-gcc?)");
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
input_file = NULL;
|
input_file = NULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Check if this looks like a standard invocation as a part of an attempt
|
/* Check if this looks like a standard invocation as a part of an attempt
|
||||||
@ -210,11 +220,16 @@ static void edit_params(int argc, char **argv) {
|
|||||||
if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) &&
|
if (strncmp(input_file, tmp_dir, strlen(tmp_dir)) &&
|
||||||
strncmp(input_file, "/var/tmp/", 9) &&
|
strncmp(input_file, "/var/tmp/", 9) &&
|
||||||
strncmp(input_file, "/tmp/", 5) &&
|
strncmp(input_file, "/tmp/", 5) &&
|
||||||
getenv("AFL_AS_FORCE_INSTRUMENT") == NULL)
|
getenv("AFL_AS_FORCE_INSTRUMENT") == NULL) {
|
||||||
|
|
||||||
pass_thru = 1;
|
pass_thru = 1;
|
||||||
else if (getenv("AFL_AS_FORCE_INSTRUMENT"))
|
|
||||||
|
} else if (getenv("AFL_AS_FORCE_INSTRUMENT")) {
|
||||||
|
|
||||||
unsetenv("AFL_AS_FORCE_INSTRUMENT");
|
unsetenv("AFL_AS_FORCE_INSTRUMENT");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
modified_file =
|
modified_file =
|
||||||
@ -251,19 +266,21 @@ static void add_instrumentation(void) {
|
|||||||
if (input_file) {
|
if (input_file) {
|
||||||
|
|
||||||
inf = fopen(input_file, "r");
|
inf = fopen(input_file, "r");
|
||||||
if (!inf) PFATAL("Unable to read '%s'", input_file);
|
if (!inf) { PFATAL("Unable to read '%s'", input_file); }
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
inf = stdin;
|
inf = stdin;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600);
|
outfd = open(modified_file, O_WRONLY | O_EXCL | O_CREAT, 0600);
|
||||||
|
|
||||||
if (outfd < 0) PFATAL("Unable to write to '%s'", modified_file);
|
if (outfd < 0) { PFATAL("Unable to write to '%s'", modified_file); }
|
||||||
|
|
||||||
outf = fdopen(outfd, "w");
|
outf = fdopen(outfd, "w");
|
||||||
|
|
||||||
if (!outf) PFATAL("fdopen() failed");
|
if (!outf) { PFATAL("fdopen() failed"); }
|
||||||
|
|
||||||
while (fgets(line, MAX_LINE, inf)) {
|
while (fgets(line, MAX_LINE, inf)) {
|
||||||
|
|
||||||
@ -287,7 +304,7 @@ static void add_instrumentation(void) {
|
|||||||
|
|
||||||
fputs(line, outf);
|
fputs(line, outf);
|
||||||
|
|
||||||
if (pass_thru) continue;
|
if (pass_thru) { continue; }
|
||||||
|
|
||||||
/* All right, this is where the actual fun begins. For one, we only want to
|
/* All right, this is where the actual fun begins. For one, we only want to
|
||||||
instrument the .text section. So, let's keep track of that in processed
|
instrument the .text section. So, let's keep track of that in processed
|
||||||
@ -300,9 +317,12 @@ static void add_instrumentation(void) {
|
|||||||
around them, so we use that as a signal. */
|
around them, so we use that as a signal. */
|
||||||
|
|
||||||
if (!clang_mode && instr_ok && !strncmp(line + 2, "p2align ", 8) &&
|
if (!clang_mode && instr_ok && !strncmp(line + 2, "p2align ", 8) &&
|
||||||
isdigit(line[10]) && line[11] == '\n')
|
isdigit(line[10]) && line[11] == '\n') {
|
||||||
|
|
||||||
skip_next_label = 1;
|
skip_next_label = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!strncmp(line + 2, "text\n", 5) ||
|
if (!strncmp(line + 2, "text\n", 5) ||
|
||||||
!strncmp(line + 2, "section\t.text", 13) ||
|
!strncmp(line + 2, "section\t.text", 13) ||
|
||||||
!strncmp(line + 2, "section\t__TEXT,__text", 21) ||
|
!strncmp(line + 2, "section\t__TEXT,__text", 21) ||
|
||||||
@ -330,23 +350,23 @@ static void add_instrumentation(void) {
|
|||||||
|
|
||||||
if (strstr(line, ".code")) {
|
if (strstr(line, ".code")) {
|
||||||
|
|
||||||
if (strstr(line, ".code32")) skip_csect = use_64bit;
|
if (strstr(line, ".code32")) { skip_csect = use_64bit; }
|
||||||
if (strstr(line, ".code64")) skip_csect = !use_64bit;
|
if (strstr(line, ".code64")) { skip_csect = !use_64bit; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Detect syntax changes, as could happen with hand-written assembly.
|
/* Detect syntax changes, as could happen with hand-written assembly.
|
||||||
Skip Intel blocks, resume instrumentation when back to AT&T. */
|
Skip Intel blocks, resume instrumentation when back to AT&T. */
|
||||||
|
|
||||||
if (strstr(line, ".intel_syntax")) skip_intel = 1;
|
if (strstr(line, ".intel_syntax")) { skip_intel = 1; }
|
||||||
if (strstr(line, ".att_syntax")) skip_intel = 0;
|
if (strstr(line, ".att_syntax")) { skip_intel = 0; }
|
||||||
|
|
||||||
/* Detect and skip ad-hoc __asm__ blocks, likewise skipping them. */
|
/* Detect and skip ad-hoc __asm__ blocks, likewise skipping them. */
|
||||||
|
|
||||||
if (line[0] == '#' || line[1] == '#') {
|
if (line[0] == '#' || line[1] == '#') {
|
||||||
|
|
||||||
if (strstr(line, "#APP")) skip_app = 1;
|
if (strstr(line, "#APP")) { skip_app = 1; }
|
||||||
if (strstr(line, "#NO_APP")) skip_app = 0;
|
if (strstr(line, "#NO_APP")) { skip_app = 0; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -375,9 +395,12 @@ static void add_instrumentation(void) {
|
|||||||
*/
|
*/
|
||||||
|
|
||||||
if (skip_intel || skip_app || skip_csect || !instr_ok || line[0] == '#' ||
|
if (skip_intel || skip_app || skip_csect || !instr_ok || line[0] == '#' ||
|
||||||
line[0] == ' ')
|
line[0] == ' ') {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Conditional branch instruction (jnz, etc). We append the instrumentation
|
/* Conditional branch instruction (jnz, etc). We append the instrumentation
|
||||||
right after the branch (to instrument the not-taken path) and at the
|
right after the branch (to instrument the not-taken path) and at the
|
||||||
branch destination label (handled later on). */
|
branch destination label (handled later on). */
|
||||||
@ -449,11 +472,16 @@ static void add_instrumentation(void) {
|
|||||||
.Lfunc_begin0-style exception handling calculations (a problem on
|
.Lfunc_begin0-style exception handling calculations (a problem on
|
||||||
MacOS X). */
|
MacOS X). */
|
||||||
|
|
||||||
if (!skip_next_label)
|
if (!skip_next_label) {
|
||||||
|
|
||||||
instrument_next = 1;
|
instrument_next = 1;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
skip_next_label = 0;
|
skip_next_label = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -468,17 +496,19 @@ static void add_instrumentation(void) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ins_lines) fputs(use_64bit ? main_payload_64 : main_payload_32, outf);
|
if (ins_lines) { fputs(use_64bit ? main_payload_64 : main_payload_32, outf); }
|
||||||
|
|
||||||
if (input_file) fclose(inf);
|
if (input_file) { fclose(inf); }
|
||||||
fclose(outf);
|
fclose(outf);
|
||||||
|
|
||||||
if (!be_quiet) {
|
if (!be_quiet) {
|
||||||
|
|
||||||
if (!ins_lines)
|
if (!ins_lines) {
|
||||||
|
|
||||||
WARNF("No instrumentation targets found%s.",
|
WARNF("No instrumentation targets found%s.",
|
||||||
pass_thru ? " (pass-thru mode)" : "");
|
pass_thru ? " (pass-thru mode)" : "");
|
||||||
else {
|
|
||||||
|
} else {
|
||||||
|
|
||||||
char modeline[100];
|
char modeline[100];
|
||||||
snprintf(modeline, sizeof(modeline), "%s%s%s%s",
|
snprintf(modeline, sizeof(modeline), "%s%s%s%s",
|
||||||
@ -514,10 +544,12 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
SAYF(cCYA "afl-as" VERSION cRST " by Michal Zalewski\n");
|
SAYF(cCYA "afl-as" VERSION cRST " by Michal Zalewski\n");
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
be_quiet = 1;
|
be_quiet = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (argc < 2 || (argc == 2 && strcmp(argv[1], "-h") == 0)) {
|
if (argc < 2 || (argc == 2 && strcmp(argv[1], "-h") == 0)) {
|
||||||
|
|
||||||
fprintf(
|
fprintf(
|
||||||
@ -565,14 +597,20 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
if (inst_ratio_str) {
|
if (inst_ratio_str) {
|
||||||
|
|
||||||
if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || inst_ratio > 100)
|
if (sscanf(inst_ratio_str, "%u", &inst_ratio) != 1 || inst_ratio > 100) {
|
||||||
|
|
||||||
FATAL("Bad value of AFL_INST_RATIO (must be between 0 and 100)");
|
FATAL("Bad value of AFL_INST_RATIO (must be between 0 and 100)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getenv(AS_LOOP_ENV_VAR))
|
if (getenv(AS_LOOP_ENV_VAR)) {
|
||||||
|
|
||||||
FATAL("Endless loop when calling 'as' (remove '.' from your PATH)");
|
FATAL("Endless loop when calling 'as' (remove '.' from your PATH)");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
setenv(AS_LOOP_ENV_VAR, "1", 1);
|
setenv(AS_LOOP_ENV_VAR, "1", 1);
|
||||||
|
|
||||||
/* When compiling with ASAN, we don't have a particularly elegant way to skip
|
/* When compiling with ASAN, we don't have a particularly elegant way to skip
|
||||||
@ -582,11 +620,11 @@ int main(int argc, char **argv) {
|
|||||||
if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) {
|
if (getenv("AFL_USE_ASAN") || getenv("AFL_USE_MSAN")) {
|
||||||
|
|
||||||
sanitizer = 1;
|
sanitizer = 1;
|
||||||
if (!getenv("AFL_INST_RATIO")) inst_ratio /= 3;
|
if (!getenv("AFL_INST_RATIO")) { inst_ratio /= 3; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!just_version) add_instrumentation();
|
if (!just_version) { add_instrumentation(); }
|
||||||
|
|
||||||
if (!(pid = fork())) {
|
if (!(pid = fork())) {
|
||||||
|
|
||||||
@ -595,11 +633,11 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pid < 0) PFATAL("fork() failed");
|
if (pid < 0) { PFATAL("fork() failed"); }
|
||||||
|
|
||||||
if (waitpid(pid, &status, 0) <= 0) PFATAL("waitpid() failed");
|
if (waitpid(pid, &status, 0) <= 0) { PFATAL("waitpid() failed"); }
|
||||||
|
|
||||||
if (!getenv("AFL_KEEP_ASSEMBLY")) unlink(modified_file);
|
if (!getenv("AFL_KEEP_ASSEMBLY")) { unlink(modified_file); }
|
||||||
|
|
||||||
exit(WEXITSTATUS(status));
|
exit(WEXITSTATUS(status));
|
||||||
|
|
||||||
|
@ -101,7 +101,7 @@ void detect_file_args(char **argv, u8 *prog_in, u8 *use_stdin) {
|
|||||||
|
|
||||||
if (aa_loc) {
|
if (aa_loc) {
|
||||||
|
|
||||||
if (!prog_in) FATAL("@@ syntax is not supported by this tool.");
|
if (!prog_in) { FATAL("@@ syntax is not supported by this tool."); }
|
||||||
|
|
||||||
*use_stdin = 0;
|
*use_stdin = 0;
|
||||||
|
|
||||||
@ -198,7 +198,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
|||||||
|
|
||||||
cp = alloc_printf("%s/afl-qemu-trace", tmp);
|
cp = alloc_printf("%s/afl-qemu-trace", tmp);
|
||||||
|
|
||||||
if (access(cp, X_OK)) FATAL("Unable to find '%s'", tmp);
|
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
|
||||||
|
|
||||||
*target_path_p = new_argv[0] = cp;
|
*target_path_p = new_argv[0] = cp;
|
||||||
return new_argv;
|
return new_argv;
|
||||||
@ -230,7 +230,7 @@ char **get_qemu_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
|||||||
|
|
||||||
if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
|
if (!access(BIN_PATH "/afl-qemu-trace", X_OK)) {
|
||||||
|
|
||||||
if (cp) ck_free(cp);
|
if (cp) { ck_free(cp); }
|
||||||
*target_path_p = new_argv[0] = ck_strdup(BIN_PATH "/afl-qemu-trace");
|
*target_path_p = new_argv[0] = ck_strdup(BIN_PATH "/afl-qemu-trace");
|
||||||
|
|
||||||
return new_argv;
|
return new_argv;
|
||||||
@ -277,13 +277,13 @@ char **get_wine_argv(u8 *own_loc, u8 **target_path_p, int argc, char **argv) {
|
|||||||
|
|
||||||
cp = alloc_printf("%s/afl-qemu-trace", tmp);
|
cp = alloc_printf("%s/afl-qemu-trace", tmp);
|
||||||
|
|
||||||
if (access(cp, X_OK)) FATAL("Unable to find '%s'", tmp);
|
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
|
||||||
|
|
||||||
ck_free(cp);
|
ck_free(cp);
|
||||||
|
|
||||||
cp = alloc_printf("%s/afl-wine-trace", tmp);
|
cp = alloc_printf("%s/afl-wine-trace", tmp);
|
||||||
|
|
||||||
if (access(cp, X_OK)) FATAL("Unable to find '%s'", tmp);
|
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", tmp); }
|
||||||
|
|
||||||
*target_path_p = new_argv[0] = cp;
|
*target_path_p = new_argv[0] = cp;
|
||||||
return new_argv;
|
return new_argv;
|
||||||
@ -416,15 +416,22 @@ u8 *find_binary(u8 *fname) {
|
|||||||
ck_free(cur_elem);
|
ck_free(cur_elem);
|
||||||
|
|
||||||
if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
|
if (!stat(target_path, &st) && S_ISREG(st.st_mode) &&
|
||||||
(st.st_mode & 0111) && st.st_size >= 4)
|
(st.st_mode & 0111) && st.st_size >= 4) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ck_free(target_path);
|
ck_free(target_path);
|
||||||
target_path = NULL;
|
target_path = NULL;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!target_path) FATAL("Program '%s' not found or not executable", fname);
|
if (!target_path) {
|
||||||
|
|
||||||
|
FATAL("Program '%s' not found or not executable", fname);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -434,7 +441,7 @@ u8 *find_binary(u8 *fname) {
|
|||||||
|
|
||||||
void check_environment_vars(char **envp) {
|
void check_environment_vars(char **envp) {
|
||||||
|
|
||||||
if (be_quiet) return;
|
if (be_quiet) { return; }
|
||||||
|
|
||||||
int index = 0, found = 0;
|
int index = 0, found = 0;
|
||||||
char *env, *val;
|
char *env, *val;
|
||||||
@ -448,24 +455,30 @@ void check_environment_vars(char **envp) {
|
|||||||
} else if (strncmp(env, "AFL_", 4) == 0) {
|
} else if (strncmp(env, "AFL_", 4) == 0) {
|
||||||
|
|
||||||
int i = 0, match = 0;
|
int i = 0, match = 0;
|
||||||
while (match == 0 && afl_environment_variables[i] != NULL)
|
while (match == 0 && afl_environment_variables[i] != NULL) {
|
||||||
|
|
||||||
if (strncmp(env, afl_environment_variables[i],
|
if (strncmp(env, afl_environment_variables[i],
|
||||||
strlen(afl_environment_variables[i])) == 0 &&
|
strlen(afl_environment_variables[i])) == 0 &&
|
||||||
env[strlen(afl_environment_variables[i])] == '=') {
|
env[strlen(afl_environment_variables[i])] == '=') {
|
||||||
|
|
||||||
match = 1;
|
match = 1;
|
||||||
if ((val = getenv(afl_environment_variables[i])) && !*val)
|
if ((val = getenv(afl_environment_variables[i])) && !*val) {
|
||||||
|
|
||||||
WARNF(
|
WARNF(
|
||||||
"AFL environment variable %s defined but is empty, this can "
|
"AFL environment variable %s defined but is empty, this can "
|
||||||
"lead to unexpected consequences",
|
"lead to unexpected consequences",
|
||||||
afl_environment_variables[i]);
|
afl_environment_variables[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (match == 0) {
|
if (match == 0) {
|
||||||
|
|
||||||
WARNF("Mistyped AFL environment variable: %s", env);
|
WARNF("Mistyped AFL environment variable: %s", env);
|
||||||
@ -477,7 +490,7 @@ void check_environment_vars(char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) sleep(2);
|
if (found) { sleep(2); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -485,10 +498,16 @@ char *get_afl_env(char *env) {
|
|||||||
|
|
||||||
char *val;
|
char *val;
|
||||||
|
|
||||||
if ((val = getenv(env)) != NULL)
|
if ((val = getenv(env)) != NULL) {
|
||||||
if (!be_quiet)
|
|
||||||
|
if (!be_quiet) {
|
||||||
|
|
||||||
OKF("Loaded environment variable %s with value %s", env, val);
|
OKF("Loaded environment variable %s with value %s", env, val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return val;
|
return val;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -499,7 +518,7 @@ void read_bitmap(u8 *fname, u8 *map, size_t len) {
|
|||||||
|
|
||||||
s32 fd = open(fname, O_RDONLY);
|
s32 fd = open(fname, O_RDONLY);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", fname);
|
if (fd < 0) { PFATAL("Unable to open '%s'", fname); }
|
||||||
|
|
||||||
ck_read(fd, map, len, fname);
|
ck_read(fd, map, len, fname);
|
||||||
|
|
||||||
@ -906,9 +925,13 @@ u32 get_map_size() {
|
|||||||
if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
|
if ((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE"))) {
|
||||||
|
|
||||||
map_size = atoi(ptr);
|
map_size = atoi(ptr);
|
||||||
if (map_size < 8 || map_size > (1 << 29))
|
if (map_size < 8 || map_size > (1 << 29)) {
|
||||||
|
|
||||||
FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size);
|
FATAL("illegal AFL_MAP_SIZE %u, must be between 2^3 and 2^30", map_size);
|
||||||
if (map_size % 8) map_size = (((map_size >> 3) + 1) << 3);
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (map_size % 8) { map_size = (((map_size >> 3) + 1) << 3); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -128,12 +128,16 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
unsigned char tmp[4] = {0, 0, 0, 0};
|
unsigned char tmp[4] = {0, 0, 0, 0};
|
||||||
pid_t child_pid = -1;
|
pid_t child_pid = -1;
|
||||||
|
|
||||||
if (!be_quiet) ACTF("Using Fauxserver:");
|
if (!be_quiet) { ACTF("Using Fauxserver:"); }
|
||||||
|
|
||||||
/* Phone home and tell the parent that we're OK. If parent isn't there,
|
/* 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. */
|
assume we're not running in forkserver mode and just execute program. */
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, tmp, 4) != 4) abort(); // TODO: Abort?
|
if (write(FORKSRV_FD + 1, tmp, 4) != 4) {
|
||||||
|
|
||||||
|
abort(); // TODO: Abort?
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
|
void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
|
||||||
|
|
||||||
@ -144,13 +148,13 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
/* Wait for parent by reading from the pipe. Exit if read fails. */
|
/* Wait for parent by reading from the pipe. Exit if read fails. */
|
||||||
|
|
||||||
if (read(FORKSRV_FD, &was_killed, 4) != 4) exit(0);
|
if (read(FORKSRV_FD, &was_killed, 4) != 4) { exit(0); }
|
||||||
|
|
||||||
/* Create a clone of our process. */
|
/* Create a clone of our process. */
|
||||||
|
|
||||||
child_pid = fork();
|
child_pid = fork();
|
||||||
|
|
||||||
if (child_pid < 0) PFATAL("Fork failed");
|
if (child_pid < 0) { PFATAL("Fork failed"); }
|
||||||
|
|
||||||
/* In child process: close fds, resume execution. */
|
/* In child process: close fds, resume execution. */
|
||||||
|
|
||||||
@ -177,7 +181,7 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
/* In parent process: write PID to AFL. */
|
/* In parent process: write PID to AFL. */
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) exit(0);
|
if (write(FORKSRV_FD + 1, &child_pid, 4) != 4) { exit(0); }
|
||||||
|
|
||||||
/* after child exited, get and relay exit status to parent through waitpid.
|
/* after child exited, get and relay exit status to parent through waitpid.
|
||||||
*/
|
*/
|
||||||
@ -191,7 +195,7 @@ static void afl_fauxsrv_execv(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
/* Relay wait status to AFL pipe, then loop back. */
|
/* Relay wait status to AFL pipe, then loop back. */
|
||||||
|
|
||||||
if (write(FORKSRV_FD + 1, &status, 4) != 4) exit(0);
|
if (write(FORKSRV_FD + 1, &status, 4) != 4) { exit(0); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -212,25 +216,28 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
int status;
|
int status;
|
||||||
s32 rlen;
|
s32 rlen;
|
||||||
|
|
||||||
if (!be_quiet) ACTF("Spinning up the fork server...");
|
if (!be_quiet) { ACTF("Spinning up the fork server..."); }
|
||||||
|
|
||||||
if (fsrv->use_fauxsrv) {
|
if (fsrv->use_fauxsrv) {
|
||||||
|
|
||||||
/* TODO: Come up with sone nice way to initalize this all */
|
/* TODO: Come up with sone nice way to initalize this all */
|
||||||
|
|
||||||
if (fsrv->init_child_func != fsrv_exec_child)
|
if (fsrv->init_child_func != fsrv_exec_child) {
|
||||||
|
|
||||||
FATAL("Different forkserver not compatible with fauxserver");
|
FATAL("Different forkserver not compatible with fauxserver");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fsrv->init_child_func = afl_fauxsrv_execv;
|
fsrv->init_child_func = afl_fauxsrv_execv;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (pipe(st_pipe) || pipe(ctl_pipe)) PFATAL("pipe() failed");
|
if (pipe(st_pipe) || pipe(ctl_pipe)) { PFATAL("pipe() failed"); }
|
||||||
|
|
||||||
fsrv->last_run_timed_out = 0;
|
fsrv->last_run_timed_out = 0;
|
||||||
fsrv->fsrv_pid = fork();
|
fsrv->fsrv_pid = fork();
|
||||||
|
|
||||||
if (fsrv->fsrv_pid < 0) PFATAL("fork() failed");
|
if (fsrv->fsrv_pid < 0) { PFATAL("fork() failed"); }
|
||||||
|
|
||||||
if (!fsrv->fsrv_pid) {
|
if (!fsrv->fsrv_pid) {
|
||||||
|
|
||||||
@ -295,8 +302,8 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
/* Set up control and status pipes, close the unneeded original fds. */
|
/* Set up control and status pipes, close the unneeded original fds. */
|
||||||
|
|
||||||
if (dup2(ctl_pipe[0], FORKSRV_FD) < 0) PFATAL("dup2() failed");
|
if (dup2(ctl_pipe[0], FORKSRV_FD) < 0) { PFATAL("dup2() failed"); }
|
||||||
if (dup2(st_pipe[1], FORKSRV_FD + 1) < 0) PFATAL("dup2() failed");
|
if (dup2(st_pipe[1], FORKSRV_FD + 1) < 0) { PFATAL("dup2() failed"); }
|
||||||
|
|
||||||
close(ctl_pipe[0]);
|
close(ctl_pipe[0]);
|
||||||
close(ctl_pipe[1]);
|
close(ctl_pipe[1]);
|
||||||
@ -308,12 +315,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
#ifndef HAVE_ARC4RANDOM
|
#ifndef HAVE_ARC4RANDOM
|
||||||
close(fsrv->dev_urandom_fd);
|
close(fsrv->dev_urandom_fd);
|
||||||
#endif
|
#endif
|
||||||
if (fsrv->plot_file != NULL) fclose(fsrv->plot_file);
|
if (fsrv->plot_file != NULL) { fclose(fsrv->plot_file); }
|
||||||
|
|
||||||
/* This should improve performance a bit, since it stops the linker from
|
/* This should improve performance a bit, since it stops the linker from
|
||||||
doing extra work post-fork(). */
|
doing extra work post-fork(). */
|
||||||
|
|
||||||
if (!getenv("LD_BIND_LAZY")) setenv("LD_BIND_NOW", "1", 0);
|
if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 0); }
|
||||||
|
|
||||||
/* Set sane defaults for ASAN if nothing else specified. */
|
/* Set sane defaults for ASAN if nothing else specified. */
|
||||||
|
|
||||||
@ -391,17 +398,20 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
if (rlen == 4) {
|
if (rlen == 4) {
|
||||||
|
|
||||||
if (!be_quiet) OKF("All right - fork server is up.");
|
if (!be_quiet) { OKF("All right - fork server is up."); }
|
||||||
|
|
||||||
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
|
if ((status & FS_OPT_ENABLED) == FS_OPT_ENABLED) {
|
||||||
|
|
||||||
if (!be_quiet && getenv("AFL_DEBUG"))
|
if (!be_quiet && getenv("AFL_DEBUG")) {
|
||||||
|
|
||||||
ACTF("Extended forkserver functions received (%08x).", status);
|
ACTF("Extended forkserver functions received (%08x).", status);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
|
if ((status & FS_OPT_SNAPSHOT) == FS_OPT_SNAPSHOT) {
|
||||||
|
|
||||||
fsrv->snapshot = 1;
|
fsrv->snapshot = 1;
|
||||||
if (!be_quiet) ACTF("Using SNAPSHOT feature.");
|
if (!be_quiet) { ACTF("Using SNAPSHOT feature."); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -409,7 +419,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status);
|
u32 tmp_map_size = FS_OPT_GET_MAPSIZE(status);
|
||||||
|
|
||||||
if (!fsrv->map_size) fsrv->map_size = MAP_SIZE;
|
if (!fsrv->map_size) { fsrv->map_size = MAP_SIZE; }
|
||||||
|
|
||||||
if (unlikely(tmp_map_size % 8)) {
|
if (unlikely(tmp_map_size % 8)) {
|
||||||
|
|
||||||
@ -419,13 +429,17 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!be_quiet) ACTF("Target map size: %u", tmp_map_size);
|
if (!be_quiet) { ACTF("Target map size: %u", tmp_map_size); }
|
||||||
if (tmp_map_size > fsrv->map_size)
|
if (tmp_map_size > fsrv->map_size) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"Target's coverage map size of %u is larger than the one this "
|
"Target's coverage map size of %u is larger than the one this "
|
||||||
"afl++ is set with (%u) (change MAP_SIZE_POW2 in config.h and "
|
"afl++ is set with (%u) (change MAP_SIZE_POW2 in config.h and "
|
||||||
"recompile or set AFL_MAP_SIZE)\n",
|
"recompile or set AFL_MAP_SIZE)\n",
|
||||||
tmp_map_size, fsrv->map_size);
|
tmp_map_size, fsrv->map_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fsrv->map_size = tmp_map_size;
|
fsrv->map_size = tmp_map_size;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -436,27 +450,44 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
// this is not afl-fuzz - we deny and return
|
// this is not afl-fuzz - we deny and return
|
||||||
status = (0xffffffff ^ (FS_OPT_ENABLED | FS_OPT_AUTODICT));
|
status = (0xffffffff ^ (FS_OPT_ENABLED | FS_OPT_AUTODICT));
|
||||||
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4)
|
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
|
||||||
|
|
||||||
FATAL("Writing to forkserver failed.");
|
FATAL("Writing to forkserver failed.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!be_quiet) ACTF("Using AUTODICT feature.");
|
if (!be_quiet) { ACTF("Using AUTODICT feature."); }
|
||||||
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
|
status = (FS_OPT_ENABLED | FS_OPT_AUTODICT);
|
||||||
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4)
|
if (write(fsrv->fsrv_ctl_fd, &status, 4) != 4) {
|
||||||
|
|
||||||
FATAL("Writing to forkserver failed.");
|
FATAL("Writing to forkserver failed.");
|
||||||
if (read(fsrv->fsrv_st_fd, &status, 4) != 4)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (read(fsrv->fsrv_st_fd, &status, 4) != 4) {
|
||||||
|
|
||||||
FATAL("Reading from forkserver failed.");
|
FATAL("Reading from forkserver failed.");
|
||||||
|
|
||||||
if (status < 2 || (u32)status > 0xffffff)
|
}
|
||||||
|
|
||||||
|
if (status < 2 || (u32)status > 0xffffff) {
|
||||||
|
|
||||||
FATAL("Dictionary has an illegal size: %d", status);
|
FATAL("Dictionary has an illegal size: %d", status);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
u32 len = status, offset = 0, count = 0;
|
u32 len = status, offset = 0, count = 0;
|
||||||
u8 *dict = ck_alloc(len);
|
u8 *dict = ck_alloc(len);
|
||||||
if (dict == NULL)
|
if (dict == NULL) {
|
||||||
|
|
||||||
FATAL("Could not allocate %u bytes of autodictionary memory", len);
|
FATAL("Could not allocate %u bytes of autodictionary memory", len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
while (len != 0) {
|
while (len != 0) {
|
||||||
|
|
||||||
rlen = read(fsrv->fsrv_st_fd, dict + offset, len);
|
rlen = read(fsrv->fsrv_st_fd, dict + offset, len);
|
||||||
@ -486,7 +517,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!be_quiet) ACTF("Loaded %u autodictionary entries", count);
|
if (!be_quiet) { ACTF("Loaded %u autodictionary entries", count); }
|
||||||
ck_free(dict);
|
ck_free(dict);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -497,10 +528,13 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsrv->last_run_timed_out)
|
if (fsrv->last_run_timed_out) {
|
||||||
|
|
||||||
FATAL("Timeout while initializing fork server (adjusting -t may help)");
|
FATAL("Timeout while initializing fork server (adjusting -t may help)");
|
||||||
|
|
||||||
if (waitpid(fsrv->fsrv_pid, &status, 0) <= 0) PFATAL("waitpid() failed");
|
}
|
||||||
|
|
||||||
|
if (waitpid(fsrv->fsrv_pid, &status, 0) <= 0) { PFATAL("waitpid() failed"); }
|
||||||
|
|
||||||
if (WIFSIGNALED(status)) {
|
if (WIFSIGNALED(status)) {
|
||||||
|
|
||||||
@ -580,9 +614,12 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG)
|
if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) {
|
||||||
|
|
||||||
FATAL("Unable to execute target application ('%s')", argv[0]);
|
FATAL("Unable to execute target application ('%s')", argv[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (fsrv->mem_limit && fsrv->mem_limit < 500 && fsrv->uses_asan) {
|
if (fsrv->mem_limit && fsrv->mem_limit < 500 && fsrv->uses_asan) {
|
||||||
|
|
||||||
SAYF("\n" cLRD "[-] " cRST
|
SAYF("\n" cLRD "[-] " cRST
|
||||||
@ -651,7 +688,7 @@ void afl_fsrv_start(afl_forkserver_t *fsrv, char **argv,
|
|||||||
|
|
||||||
static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
static void afl_fsrv_kill(afl_forkserver_t *fsrv) {
|
||||||
|
|
||||||
if (fsrv->child_pid > 0) kill(fsrv->child_pid, SIGKILL);
|
if (fsrv->child_pid > 0) { kill(fsrv->child_pid, SIGKILL); }
|
||||||
if (fsrv->fsrv_pid > 0) {
|
if (fsrv->fsrv_pid > 0) {
|
||||||
|
|
||||||
kill(fsrv->fsrv_pid, SIGKILL);
|
kill(fsrv->fsrv_pid, SIGKILL);
|
||||||
@ -680,7 +717,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", fsrv->out_file);
|
if (fd < 0) { PFATAL("Unable to create '%s'", fsrv->out_file); }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -692,7 +729,7 @@ void afl_fsrv_write_to_testcase(afl_forkserver_t *fsrv, u8 *buf, size_t len) {
|
|||||||
|
|
||||||
if (!fsrv->out_file) {
|
if (!fsrv->out_file) {
|
||||||
|
|
||||||
if (ftruncate(fd, len)) PFATAL("ftruncate() failed");
|
if (ftruncate(fd, len)) { PFATAL("ftruncate() failed"); }
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -727,7 +764,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
|
|
||||||
if ((res = write(fsrv->fsrv_ctl_fd, &fsrv->last_run_timed_out, 4)) != 4) {
|
if ((res = write(fsrv->fsrv_ctl_fd, &fsrv->last_run_timed_out, 4)) != 4) {
|
||||||
|
|
||||||
if (*stop_soon_p) return 0;
|
if (*stop_soon_p) { return 0; }
|
||||||
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
|
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -736,12 +773,12 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
|
|
||||||
if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) {
|
if ((res = read(fsrv->fsrv_st_fd, &fsrv->child_pid, 4)) != 4) {
|
||||||
|
|
||||||
if (*stop_soon_p) return 0;
|
if (*stop_soon_p) { return 0; }
|
||||||
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
|
RPFATAL(res, "Unable to request new process from fork server (OOM?)");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsrv->child_pid <= 0) FATAL("Fork server is misbehaving (OOM?)");
|
if (fsrv->child_pid <= 0) { FATAL("Fork server is misbehaving (OOM?)"); }
|
||||||
|
|
||||||
exec_ms = read_timed(fsrv->fsrv_st_fd, &status, 4, timeout, stop_soon_p);
|
exec_ms = read_timed(fsrv->fsrv_st_fd, &status, 4, timeout, stop_soon_p);
|
||||||
|
|
||||||
@ -752,13 +789,13 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
|
|
||||||
kill(fsrv->child_pid, SIGKILL);
|
kill(fsrv->child_pid, SIGKILL);
|
||||||
fsrv->last_run_timed_out = 1;
|
fsrv->last_run_timed_out = 1;
|
||||||
if (read(fsrv->fsrv_st_fd, &status, 4) < 4) exec_ms = 0;
|
if (read(fsrv->fsrv_st_fd, &status, 4) < 4) { exec_ms = 0; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!exec_ms) {
|
if (!exec_ms) {
|
||||||
|
|
||||||
if (*stop_soon_p) return 0;
|
if (*stop_soon_p) { return 0; }
|
||||||
SAYF("\n" cLRD "[-] " cRST
|
SAYF("\n" cLRD "[-] " cRST
|
||||||
"Unable to communicate with fork server. Some possible reasons:\n\n"
|
"Unable to communicate with fork server. Some possible reasons:\n\n"
|
||||||
" - You've run out of memory. Use -m to increase the the memory "
|
" - You've run out of memory. Use -m to increase the the memory "
|
||||||
@ -784,7 +821,7 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!WIFSTOPPED(status)) fsrv->child_pid = 0;
|
if (!WIFSTOPPED(status)) { fsrv->child_pid = 0; }
|
||||||
|
|
||||||
fsrv->total_execs++;
|
fsrv->total_execs++;
|
||||||
|
|
||||||
@ -800,9 +837,12 @@ fsrv_run_result_t afl_fsrv_run_target(afl_forkserver_t *fsrv, u32 timeout,
|
|||||||
|
|
||||||
fsrv->last_kill_signal = WTERMSIG(status);
|
fsrv->last_kill_signal = WTERMSIG(status);
|
||||||
|
|
||||||
if (fsrv->last_run_timed_out && fsrv->last_kill_signal == SIGKILL)
|
if (fsrv->last_run_timed_out && fsrv->last_kill_signal == SIGKILL) {
|
||||||
|
|
||||||
return FSRV_RUN_TMOUT;
|
return FSRV_RUN_TMOUT;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return FSRV_RUN_CRASH;
|
return FSRV_RUN_CRASH;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -35,13 +35,13 @@ void write_bitmap(afl_state_t *afl) {
|
|||||||
u8 fname[PATH_MAX];
|
u8 fname[PATH_MAX];
|
||||||
s32 fd;
|
s32 fd;
|
||||||
|
|
||||||
if (!afl->bitmap_changed) return;
|
if (!afl->bitmap_changed) { return; }
|
||||||
afl->bitmap_changed = 0;
|
afl->bitmap_changed = 0;
|
||||||
|
|
||||||
snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir);
|
snprintf(fname, PATH_MAX, "%s/fuzz_bitmap", afl->out_dir);
|
||||||
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
fd = open(fname, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", fname);
|
if (fd < 0) { PFATAL("Unable to open '%s'", fname); }
|
||||||
|
|
||||||
ck_write(fd, afl->virgin_bits, afl->fsrv.map_size, fname);
|
ck_write(fd, afl->virgin_bits, afl->fsrv.map_size, fname);
|
||||||
|
|
||||||
@ -102,11 +102,16 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
|
|||||||
(cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
|
(cur[1] && vir[1] == 0xff) || (cur[2] && vir[2] == 0xff) ||
|
||||||
(cur[3] && vir[3] == 0xff) || (cur[4] && vir[4] == 0xff) ||
|
(cur[3] && vir[3] == 0xff) || (cur[4] && vir[4] == 0xff) ||
|
||||||
(cur[5] && vir[5] == 0xff) || (cur[6] && vir[6] == 0xff) ||
|
(cur[5] && vir[5] == 0xff) || (cur[6] && vir[6] == 0xff) ||
|
||||||
(cur[7] && vir[7] == 0xff))
|
(cur[7] && vir[7] == 0xff)) {
|
||||||
|
|
||||||
ret = 2;
|
ret = 2;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
ret = 1;
|
ret = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#else
|
#else
|
||||||
|
|
||||||
if (*virgin == 0xffffffff || (cur[0] && vir[0] == 0xff) ||
|
if (*virgin == 0xffffffff || (cur[0] && vir[0] == 0xff) ||
|
||||||
@ -129,9 +134,12 @@ u8 has_new_bits(afl_state_t *afl, u8 *virgin_map) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(ret) && likely(virgin_map == afl->virgin_bits))
|
if (unlikely(ret) && likely(virgin_map == afl->virgin_bits)) {
|
||||||
|
|
||||||
afl->bitmap_changed = 1;
|
afl->bitmap_changed = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -183,11 +191,11 @@ u32 count_bytes(afl_state_t *afl, u8 *mem) {
|
|||||||
|
|
||||||
u32 v = *(ptr++);
|
u32 v = *(ptr++);
|
||||||
|
|
||||||
if (!v) continue;
|
if (!v) { continue; }
|
||||||
if (v & 0x000000ff) ++ret;
|
if (v & 0x000000ff) { ++ret; }
|
||||||
if (v & 0x0000ff00) ++ret;
|
if (v & 0x0000ff00) { ++ret; }
|
||||||
if (v & 0x00ff0000) ++ret;
|
if (v & 0x00ff0000) { ++ret; }
|
||||||
if (v & 0xff000000) ++ret;
|
if (v & 0xff000000) { ++ret; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -211,11 +219,11 @@ u32 count_non_255_bytes(afl_state_t *afl, u8 *mem) {
|
|||||||
/* This is called on the virgin bitmap, so optimize for the most likely
|
/* This is called on the virgin bitmap, so optimize for the most likely
|
||||||
case. */
|
case. */
|
||||||
|
|
||||||
if (v == 0xffffffff) continue;
|
if (v == 0xffffffff) { continue; }
|
||||||
if ((v & 0x000000ff) != 0x000000ff) ++ret;
|
if ((v & 0x000000ff) != 0x000000ff) { ++ret; }
|
||||||
if ((v & 0x0000ff00) != 0x0000ff00) ++ret;
|
if ((v & 0x0000ff00) != 0x0000ff00) { ++ret; }
|
||||||
if ((v & 0x00ff0000) != 0x00ff0000) ++ret;
|
if ((v & 0x00ff0000) != 0x00ff0000) { ++ret; }
|
||||||
if ((v & 0xff000000) != 0xff000000) ++ret;
|
if ((v & 0xff000000) != 0xff000000) { ++ret; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -257,10 +265,12 @@ void simplify_trace(afl_state_t *afl, u64 *mem) {
|
|||||||
mem8[6] = simplify_lookup[mem8[6]];
|
mem8[6] = simplify_lookup[mem8[6]];
|
||||||
mem8[7] = simplify_lookup[mem8[7]];
|
mem8[7] = simplify_lookup[mem8[7]];
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
*mem = 0x0101010101010101ULL;
|
*mem = 0x0101010101010101ULL;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
++mem;
|
++mem;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -322,11 +332,17 @@ void init_count_class16(void) {
|
|||||||
|
|
||||||
u32 b1, b2;
|
u32 b1, b2;
|
||||||
|
|
||||||
for (b1 = 0; b1 < 256; b1++)
|
for (b1 = 0; b1 < 256; b1++) {
|
||||||
for (b2 = 0; b2 < 256; b2++)
|
|
||||||
|
for (b2 = 0; b2 < 256; b2++) {
|
||||||
|
|
||||||
count_class_lookup16[(b1 << 8) + b2] =
|
count_class_lookup16[(b1 << 8) + b2] =
|
||||||
(count_class_lookup8[b1] << 8) | count_class_lookup8[b2];
|
(count_class_lookup8[b1] << 8) | count_class_lookup8[b2];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef WORD_SIZE_64
|
#ifdef WORD_SIZE_64
|
||||||
@ -397,7 +413,7 @@ void minimize_bits(afl_state_t *afl, u8 *dst, u8 *src) {
|
|||||||
|
|
||||||
while (i < afl->fsrv.map_size) {
|
while (i < afl->fsrv.map_size) {
|
||||||
|
|
||||||
if (*(src++)) dst[i >> 3] |= 1 << (i & 7);
|
if (*(src++)) { dst[i >> 3] |= 1 << (i & 7); }
|
||||||
++i;
|
++i;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -423,27 +439,35 @@ u8 *describe_op(afl_state_t *afl, u8 hnb) {
|
|||||||
|
|
||||||
sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time);
|
sprintf(ret + strlen(ret), ",time:%llu", get_cur_time() - afl->start_time);
|
||||||
|
|
||||||
if (afl->splicing_with >= 0)
|
if (afl->splicing_with >= 0) {
|
||||||
|
|
||||||
sprintf(ret + strlen(ret), "+%06d", afl->splicing_with);
|
sprintf(ret + strlen(ret), "+%06d", afl->splicing_with);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sprintf(ret + strlen(ret), ",op:%s", afl->stage_short);
|
sprintf(ret + strlen(ret), ",op:%s", afl->stage_short);
|
||||||
|
|
||||||
if (afl->stage_cur_byte >= 0) {
|
if (afl->stage_cur_byte >= 0) {
|
||||||
|
|
||||||
sprintf(ret + strlen(ret), ",pos:%d", afl->stage_cur_byte);
|
sprintf(ret + strlen(ret), ",pos:%d", afl->stage_cur_byte);
|
||||||
|
|
||||||
if (afl->stage_val_type != STAGE_VAL_NONE)
|
if (afl->stage_val_type != STAGE_VAL_NONE) {
|
||||||
|
|
||||||
sprintf(ret + strlen(ret), ",val:%s%+d",
|
sprintf(ret + strlen(ret), ",val:%s%+d",
|
||||||
(afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "",
|
(afl->stage_val_type == STAGE_VAL_BE) ? "be:" : "",
|
||||||
afl->stage_cur_val);
|
afl->stage_cur_val);
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
sprintf(ret + strlen(ret), ",rep:%d", afl->stage_cur_val);
|
sprintf(ret + strlen(ret), ",rep:%d", afl->stage_cur_val);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (hnb == 2) strcat(ret, ",+cov");
|
if (hnb == 2) { strcat(ret, ",+cov"); }
|
||||||
|
|
||||||
return ret;
|
return ret;
|
||||||
|
|
||||||
@ -467,7 +491,7 @@ static void write_crash_readme(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Do not die on errors here - that would be impolite. */
|
/* Do not die on errors here - that would be impolite. */
|
||||||
|
|
||||||
if (unlikely(fd < 0)) return;
|
if (unlikely(fd < 0)) { return; }
|
||||||
|
|
||||||
f = fdopen(fd, "w");
|
f = fdopen(fd, "w");
|
||||||
|
|
||||||
@ -512,7 +536,7 @@ static void write_crash_readme(afl_state_t *afl) {
|
|||||||
|
|
||||||
u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
||||||
|
|
||||||
if (unlikely(len == 0)) return 0;
|
if (unlikely(len == 0)) { return 0; }
|
||||||
|
|
||||||
u8 *queue_fn = "";
|
u8 *queue_fn = "";
|
||||||
u8 hnb = '\0';
|
u8 hnb = '\0';
|
||||||
@ -545,7 +569,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
if (!(hnb = has_new_bits(afl, afl->virgin_bits))) {
|
if (!(hnb = has_new_bits(afl, afl->virgin_bits))) {
|
||||||
|
|
||||||
if (unlikely(afl->crash_mode)) ++afl->total_crashes;
|
if (unlikely(afl->crash_mode)) { ++afl->total_crashes; }
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -578,11 +602,14 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
res = calibrate_case(afl, afl->queue_top, mem, afl->queue_cycle - 1, 0);
|
res = calibrate_case(afl, afl->queue_top, mem, afl->queue_cycle - 1, 0);
|
||||||
|
|
||||||
if (unlikely(res == FSRV_RUN_ERROR))
|
if (unlikely(res == FSRV_RUN_ERROR)) {
|
||||||
|
|
||||||
FATAL("Unable to execute target application");
|
FATAL("Unable to execute target application");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
fd = open(queue_fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", queue_fn);
|
if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", queue_fn); }
|
||||||
ck_write(fd, mem, len, queue_fn);
|
ck_write(fd, mem, len, queue_fn);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
@ -601,7 +628,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
++afl->total_tmouts;
|
++afl->total_tmouts;
|
||||||
|
|
||||||
if (afl->unique_hangs >= KEEP_UNIQUE_HANG) return keeping;
|
if (afl->unique_hangs >= KEEP_UNIQUE_HANG) { return keeping; }
|
||||||
|
|
||||||
if (likely(!afl->dumb_mode)) {
|
if (likely(!afl->dumb_mode)) {
|
||||||
|
|
||||||
@ -611,7 +638,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
simplify_trace(afl, (u32 *)afl->fsrv.trace_bits);
|
simplify_trace(afl, (u32 *)afl->fsrv.trace_bits);
|
||||||
#endif /* ^WORD_SIZE_64 */
|
#endif /* ^WORD_SIZE_64 */
|
||||||
|
|
||||||
if (!has_new_bits(afl, afl->virgin_tmout)) return keeping;
|
if (!has_new_bits(afl, afl->virgin_tmout)) { return keeping; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -631,9 +658,13 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
timeout actually uncovers a crash. Make sure we don't discard it if
|
timeout actually uncovers a crash. Make sure we don't discard it if
|
||||||
so. */
|
so. */
|
||||||
|
|
||||||
if (!afl->stop_soon && new_fault == FSRV_RUN_CRASH) goto keep_as_crash;
|
if (!afl->stop_soon && new_fault == FSRV_RUN_CRASH) {
|
||||||
|
|
||||||
if (afl->stop_soon || new_fault != FSRV_RUN_TMOUT) return keeping;
|
goto keep_as_crash;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (afl->stop_soon || new_fault != FSRV_RUN_TMOUT) { return keeping; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -665,7 +696,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
++afl->total_crashes;
|
++afl->total_crashes;
|
||||||
|
|
||||||
if (afl->unique_crashes >= KEEP_UNIQUE_CRASH) return keeping;
|
if (afl->unique_crashes >= KEEP_UNIQUE_CRASH) { return keeping; }
|
||||||
|
|
||||||
if (likely(!afl->dumb_mode)) {
|
if (likely(!afl->dumb_mode)) {
|
||||||
|
|
||||||
@ -675,11 +706,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
simplify_trace(afl, (u32 *)afl->fsrv.trace_bits);
|
simplify_trace(afl, (u32 *)afl->fsrv.trace_bits);
|
||||||
#endif /* ^WORD_SIZE_64 */
|
#endif /* ^WORD_SIZE_64 */
|
||||||
|
|
||||||
if (!has_new_bits(afl, afl->virgin_crash)) return keeping;
|
if (!has_new_bits(afl, afl->virgin_crash)) { return keeping; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!afl->unique_crashes)) write_crash_readme(afl);
|
if (unlikely(!afl->unique_crashes)) { write_crash_readme(afl); }
|
||||||
|
|
||||||
#ifndef SIMPLE_FILES
|
#ifndef SIMPLE_FILES
|
||||||
|
|
||||||
@ -715,9 +746,11 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case FSRV_RUN_ERROR: FATAL("Unable to execute target application");
|
case FSRV_RUN_ERROR:
|
||||||
|
FATAL("Unable to execute target application");
|
||||||
|
|
||||||
default: return keeping;
|
default:
|
||||||
|
return keeping;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -725,7 +758,7 @@ u8 save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
|
|||||||
test case, too. */
|
test case, too. */
|
||||||
|
|
||||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
if (unlikely(fd < 0)) PFATAL("Unable to create '%s'", fn);
|
if (unlikely(fd < 0)) { PFATAL("Unable to create '%s'", fn); }
|
||||||
ck_write(fd, mem, len, fn);
|
ck_write(fd, mem, len, fn);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
@ -37,9 +37,12 @@ void cmplog_exec_child(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
|
setenv("___AFL_EINS_ZWEI_POLIZEI___", "1", 1);
|
||||||
|
|
||||||
if (!fsrv->qemu_mode && argv[0] != fsrv->cmplog_binary)
|
if (!fsrv->qemu_mode && argv[0] != fsrv->cmplog_binary) {
|
||||||
|
|
||||||
argv[0] = fsrv->cmplog_binary;
|
argv[0] = fsrv->cmplog_binary;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
execv(argv[0], argv);
|
execv(argv[0], argv);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -54,7 +57,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
size_t post_len =
|
size_t post_len =
|
||||||
afl->post_handler(afl->post_data, out_buf, len, &post_buf);
|
afl->post_handler(afl->post_data, out_buf, len, &post_buf);
|
||||||
if (!post_buf || !post_len) return 0;
|
if (!post_buf || !post_len) { return 0; }
|
||||||
out_buf = post_buf;
|
out_buf = post_buf;
|
||||||
len = post_len;
|
len = post_len;
|
||||||
|
|
||||||
@ -64,7 +67,7 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->cmplog_fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
if (afl->stop_soon) return 1;
|
if (afl->stop_soon) { return 1; }
|
||||||
|
|
||||||
if (fault == FSRV_RUN_TMOUT) {
|
if (fault == FSRV_RUN_TMOUT) {
|
||||||
|
|
||||||
@ -75,10 +78,12 @@ u8 common_fuzz_cmplog_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
afl->subseq_tmouts = 0;
|
afl->subseq_tmouts = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Users can hit us with SIGUSR1 to request the current input
|
/* Users can hit us with SIGUSR1 to request the current input
|
||||||
to be abandoned. */
|
to be abandoned. */
|
||||||
|
|
||||||
|
@ -59,7 +59,7 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
|
|||||||
|
|
||||||
f = fopen(fname, "r");
|
f = fopen(fname, "r");
|
||||||
|
|
||||||
if (!f) PFATAL("Unable to open '%s'", fname);
|
if (!f) { PFATAL("Unable to open '%s'", fname); }
|
||||||
|
|
||||||
while ((lptr = fgets(buf, MAX_LINE, f))) {
|
while ((lptr = fgets(buf, MAX_LINE, f))) {
|
||||||
|
|
||||||
@ -70,57 +70,79 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
|
|||||||
|
|
||||||
/* Trim on left and right. */
|
/* Trim on left and right. */
|
||||||
|
|
||||||
while (isspace(*lptr))
|
while (isspace(*lptr)) {
|
||||||
|
|
||||||
++lptr;
|
++lptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
rptr = lptr + strlen(lptr) - 1;
|
rptr = lptr + strlen(lptr) - 1;
|
||||||
while (rptr >= lptr && isspace(*rptr))
|
while (rptr >= lptr && isspace(*rptr)) {
|
||||||
|
|
||||||
--rptr;
|
--rptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
++rptr;
|
++rptr;
|
||||||
*rptr = 0;
|
*rptr = 0;
|
||||||
|
|
||||||
/* Skip empty lines and comments. */
|
/* Skip empty lines and comments. */
|
||||||
|
|
||||||
if (!*lptr || *lptr == '#') continue;
|
if (!*lptr || *lptr == '#') { continue; }
|
||||||
|
|
||||||
/* All other lines must end with '"', which we can consume. */
|
/* All other lines must end with '"', which we can consume. */
|
||||||
|
|
||||||
--rptr;
|
--rptr;
|
||||||
|
|
||||||
if (rptr < lptr || *rptr != '"')
|
if (rptr < lptr || *rptr != '"') {
|
||||||
|
|
||||||
FATAL("Malformed name=\"value\" pair in line %u.", cur_line);
|
FATAL("Malformed name=\"value\" pair in line %u.", cur_line);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
*rptr = 0;
|
*rptr = 0;
|
||||||
|
|
||||||
/* Skip alphanumerics and dashes (label). */
|
/* Skip alphanumerics and dashes (label). */
|
||||||
|
|
||||||
while (isalnum(*lptr) || *lptr == '_')
|
while (isalnum(*lptr) || *lptr == '_') {
|
||||||
|
|
||||||
++lptr;
|
++lptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If @number follows, parse that. */
|
/* If @number follows, parse that. */
|
||||||
|
|
||||||
if (*lptr == '@') {
|
if (*lptr == '@') {
|
||||||
|
|
||||||
++lptr;
|
++lptr;
|
||||||
if (atoi(lptr) > dict_level) continue;
|
if (atoi(lptr) > dict_level) { continue; }
|
||||||
while (isdigit(*lptr))
|
while (isdigit(*lptr)) {
|
||||||
|
|
||||||
++lptr;
|
++lptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Skip whitespace and = signs. */
|
/* Skip whitespace and = signs. */
|
||||||
|
|
||||||
while (isspace(*lptr) || *lptr == '=')
|
while (isspace(*lptr) || *lptr == '=') {
|
||||||
|
|
||||||
++lptr;
|
++lptr;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Consume opening '"'. */
|
/* Consume opening '"'. */
|
||||||
|
|
||||||
if (*lptr != '"')
|
if (*lptr != '"') {
|
||||||
|
|
||||||
FATAL("Malformed name=\"keyword\" pair in line %u.", cur_line);
|
FATAL("Malformed name=\"keyword\" pair in line %u.", cur_line);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
++lptr;
|
++lptr;
|
||||||
|
|
||||||
if (!*lptr) FATAL("Empty keyword in line %u.", cur_line);
|
if (!*lptr) { FATAL("Empty keyword in line %u.", cur_line); }
|
||||||
|
|
||||||
/* Okay, let's allocate memory and copy data between "...", handling
|
/* Okay, let's allocate memory and copy data between "...", handling
|
||||||
\xNN escaping, \\, and \". */
|
\xNN escaping, \\, and \". */
|
||||||
@ -130,7 +152,7 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
|
|||||||
|
|
||||||
wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr);
|
wptr = afl->extras[afl->extras_cnt].data = ck_alloc(rptr - lptr);
|
||||||
|
|
||||||
if (!wptr) PFATAL("no mem for data");
|
if (!wptr) { PFATAL("no mem for data"); }
|
||||||
|
|
||||||
while (*lptr) {
|
while (*lptr) {
|
||||||
|
|
||||||
@ -154,9 +176,12 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2]))
|
if (*lptr != 'x' || !isxdigit(lptr[1]) || !isxdigit(lptr[2])) {
|
||||||
|
|
||||||
FATAL("Invalid escaping (not \\xNN) in line %u.", cur_line);
|
FATAL("Invalid escaping (not \\xNN) in line %u.", cur_line);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
*(wptr++) = ((strchr(hexdigits, tolower(lptr[1])) - hexdigits) << 4) |
|
*(wptr++) = ((strchr(hexdigits, tolower(lptr[1])) - hexdigits) << 4) |
|
||||||
(strchr(hexdigits, tolower(lptr[2])) - hexdigits);
|
(strchr(hexdigits, tolower(lptr[2])) - hexdigits);
|
||||||
|
|
||||||
@ -165,7 +190,9 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: *(wptr++) = *(lptr++); ++klen;
|
default:
|
||||||
|
*(wptr++) = *(lptr++);
|
||||||
|
++klen;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -173,14 +200,17 @@ void load_extras_file(afl_state_t *afl, u8 *fname, u32 *min_len, u32 *max_len,
|
|||||||
|
|
||||||
afl->extras[afl->extras_cnt].len = klen;
|
afl->extras[afl->extras_cnt].len = klen;
|
||||||
|
|
||||||
if (afl->extras[afl->extras_cnt].len > MAX_DICT_FILE)
|
if (afl->extras[afl->extras_cnt].len > MAX_DICT_FILE) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"Keyword too big in line %u (%s, limit is %s)", cur_line,
|
"Keyword too big in line %u (%s, limit is %s)", cur_line,
|
||||||
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), klen),
|
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), klen),
|
||||||
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
||||||
|
|
||||||
if (*min_len > klen) *min_len = klen;
|
}
|
||||||
if (*max_len < klen) *max_len = klen;
|
|
||||||
|
if (*min_len > klen) { *min_len = klen; }
|
||||||
|
if (*max_len < klen) { *max_len = klen; }
|
||||||
|
|
||||||
++afl->extras_cnt;
|
++afl->extras_cnt;
|
||||||
|
|
||||||
@ -227,7 +257,7 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (x) FATAL("Dictionary levels not supported for directories.");
|
if (x) { FATAL("Dictionary levels not supported for directories."); }
|
||||||
|
|
||||||
while ((de = readdir(d))) {
|
while ((de = readdir(d))) {
|
||||||
|
|
||||||
@ -235,7 +265,11 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
|||||||
u8 * fn = alloc_printf("%s/%s", dir, de->d_name);
|
u8 * fn = alloc_printf("%s/%s", dir, de->d_name);
|
||||||
s32 fd;
|
s32 fd;
|
||||||
|
|
||||||
if (lstat(fn, &st) || access(fn, R_OK)) PFATAL("Unable to access '%s'", fn);
|
if (lstat(fn, &st) || access(fn, R_OK)) {
|
||||||
|
|
||||||
|
PFATAL("Unable to access '%s'", fn);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* This also takes care of . and .. */
|
/* This also takes care of . and .. */
|
||||||
if (!S_ISREG(st.st_mode) || !st.st_size) {
|
if (!S_ISREG(st.st_mode) || !st.st_size) {
|
||||||
@ -245,14 +279,17 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (st.st_size > MAX_DICT_FILE)
|
if (st.st_size > MAX_DICT_FILE) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"Extra '%s' is too big (%s, limit is %s)", fn,
|
"Extra '%s' is too big (%s, limit is %s)", fn,
|
||||||
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
|
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), st.st_size),
|
||||||
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), MAX_DICT_FILE));
|
||||||
|
|
||||||
if (min_len > st.st_size) min_len = st.st_size;
|
}
|
||||||
if (max_len < st.st_size) max_len = st.st_size;
|
|
||||||
|
if (min_len > st.st_size) { min_len = st.st_size; }
|
||||||
|
if (max_len < st.st_size) { max_len = st.st_size; }
|
||||||
|
|
||||||
afl->extras = ck_realloc_block(
|
afl->extras = ck_realloc_block(
|
||||||
afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data));
|
afl->extras, (afl->extras_cnt + 1) * sizeof(struct extra_data));
|
||||||
@ -262,7 +299,7 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
|||||||
|
|
||||||
fd = open(fn, O_RDONLY);
|
fd = open(fn, O_RDONLY);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", fn);
|
if (fd < 0) { PFATAL("Unable to open '%s'", fn); }
|
||||||
|
|
||||||
ck_read(fd, afl->extras[afl->extras_cnt].data, st.st_size, fn);
|
ck_read(fd, afl->extras[afl->extras_cnt].data, st.st_size, fn);
|
||||||
|
|
||||||
@ -277,7 +314,7 @@ void load_extras(afl_state_t *afl, u8 *dir) {
|
|||||||
|
|
||||||
check_and_sort:
|
check_and_sort:
|
||||||
|
|
||||||
if (!afl->extras_cnt) FATAL("No usable files in '%s'", dir);
|
if (!afl->extras_cnt) { FATAL("No usable files in '%s'", dir); }
|
||||||
|
|
||||||
qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
|
qsort(afl->extras, afl->extras_cnt, sizeof(struct extra_data),
|
||||||
compare_extras_len);
|
compare_extras_len);
|
||||||
@ -286,22 +323,32 @@ check_and_sort:
|
|||||||
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len),
|
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), min_len),
|
||||||
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len));
|
stringify_mem_size(val_bufs[1], sizeof(val_bufs[1]), max_len));
|
||||||
|
|
||||||
if (max_len > 32)
|
if (max_len > 32) {
|
||||||
|
|
||||||
WARNF("Some tokens are relatively large (%s) - consider trimming.",
|
WARNF("Some tokens are relatively large (%s) - consider trimming.",
|
||||||
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), max_len));
|
stringify_mem_size(val_bufs[0], sizeof(val_bufs[0]), max_len));
|
||||||
|
|
||||||
if (afl->extras_cnt > MAX_DET_EXTRAS)
|
}
|
||||||
|
|
||||||
|
if (afl->extras_cnt > MAX_DET_EXTRAS) {
|
||||||
|
|
||||||
WARNF("More than %d tokens - will use them probabilistically.",
|
WARNF("More than %d tokens - will use them probabilistically.",
|
||||||
MAX_DET_EXTRAS);
|
MAX_DET_EXTRAS);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Helper function for maybe_add_auto(afl, ) */
|
/* Helper function for maybe_add_auto(afl, ) */
|
||||||
|
|
||||||
static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) {
|
static inline u8 memcmp_nocase(u8 *m1, u8 *m2, u32 len) {
|
||||||
|
|
||||||
while (len--)
|
while (len--) {
|
||||||
if (tolower(*(m1++)) ^ tolower(*(m2++))) return 1;
|
|
||||||
|
if (tolower(*(m1++)) ^ tolower(*(m2++))) { return 1; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -318,14 +365,17 @@ void maybe_add_auto(void *afl_tmp, u8 *mem, u32 len) {
|
|||||||
|
|
||||||
/* Allow users to specify that they don't want auto dictionaries. */
|
/* Allow users to specify that they don't want auto dictionaries. */
|
||||||
|
|
||||||
if (!MAX_AUTO_EXTRAS || !USE_AUTO_EXTRAS) return;
|
if (!MAX_AUTO_EXTRAS || !USE_AUTO_EXTRAS) { return; }
|
||||||
|
|
||||||
/* Skip runs of identical bytes. */
|
/* Skip runs of identical bytes. */
|
||||||
|
|
||||||
for (i = 1; i < len; ++i)
|
for (i = 1; i < len; ++i) {
|
||||||
if (mem[0] ^ mem[i]) break;
|
|
||||||
|
|
||||||
if (i == len) return;
|
if (mem[0] ^ mem[i]) { break; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i == len) { return; }
|
||||||
|
|
||||||
/* Reject builtin interesting values. */
|
/* Reject builtin interesting values. */
|
||||||
|
|
||||||
@ -333,33 +383,51 @@ void maybe_add_auto(void *afl_tmp, u8 *mem, u32 len) {
|
|||||||
|
|
||||||
i = sizeof(interesting_16) >> 1;
|
i = sizeof(interesting_16) >> 1;
|
||||||
|
|
||||||
while (i--)
|
while (i--) {
|
||||||
|
|
||||||
if (*((u16 *)mem) == interesting_16[i] ||
|
if (*((u16 *)mem) == interesting_16[i] ||
|
||||||
*((u16 *)mem) == SWAP16(interesting_16[i]))
|
*((u16 *)mem) == SWAP16(interesting_16[i])) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (len == 4) {
|
if (len == 4) {
|
||||||
|
|
||||||
i = sizeof(interesting_32) >> 2;
|
i = sizeof(interesting_32) >> 2;
|
||||||
|
|
||||||
while (i--)
|
while (i--) {
|
||||||
|
|
||||||
if (*((u32 *)mem) == interesting_32[i] ||
|
if (*((u32 *)mem) == interesting_32[i] ||
|
||||||
*((u32 *)mem) == SWAP32(interesting_32[i]))
|
*((u32 *)mem) == SWAP32(interesting_32[i])) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Reject anything that matches existing extras. Do a case-insensitive
|
/* Reject anything that matches existing extras. Do a case-insensitive
|
||||||
match. We optimize by exploiting the fact that extras[] are sorted
|
match. We optimize by exploiting the fact that extras[] are sorted
|
||||||
by size. */
|
by size. */
|
||||||
|
|
||||||
for (i = 0; i < afl->extras_cnt; ++i)
|
for (i = 0; i < afl->extras_cnt; ++i) {
|
||||||
if (afl->extras[i].len >= len) break;
|
|
||||||
|
|
||||||
for (; i < afl->extras_cnt && afl->extras[i].len == len; ++i)
|
if (afl->extras[i].len >= len) { break; }
|
||||||
if (!memcmp_nocase(afl->extras[i].data, mem, len)) return;
|
|
||||||
|
}
|
||||||
|
|
||||||
|
for (; i < afl->extras_cnt && afl->extras[i].len == len; ++i) {
|
||||||
|
|
||||||
|
if (!memcmp_nocase(afl->extras[i].data, mem, len)) { return; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Last but not least, check afl->a_extras[] for matches. There are no
|
/* Last but not least, check afl->a_extras[] for matches. There are no
|
||||||
guarantees of a particular sort order. */
|
guarantees of a particular sort order. */
|
||||||
@ -423,7 +491,7 @@ void save_auto(afl_state_t *afl) {
|
|||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
if (!afl->auto_changed) return;
|
if (!afl->auto_changed) { return; }
|
||||||
afl->auto_changed = 0;
|
afl->auto_changed = 0;
|
||||||
|
|
||||||
for (i = 0; i < MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) {
|
for (i = 0; i < MIN(USE_AUTO_EXTRAS, afl->a_extras_cnt); ++i) {
|
||||||
@ -434,7 +502,7 @@ void save_auto(afl_state_t *afl) {
|
|||||||
|
|
||||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", fn);
|
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||||
|
|
||||||
ck_write(fd, afl->a_extras[i].data, afl->a_extras[i].len, fn);
|
ck_write(fd, afl->a_extras[i].data, afl->a_extras[i].len, fn);
|
||||||
|
|
||||||
@ -461,7 +529,7 @@ void load_auto(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (fd < 0) {
|
if (fd < 0) {
|
||||||
|
|
||||||
if (errno != ENOENT) PFATAL("Unable to open '%s'", fn);
|
if (errno != ENOENT) { PFATAL("Unable to open '%s'", fn); }
|
||||||
ck_free(fn);
|
ck_free(fn);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -472,21 +540,29 @@ void load_auto(afl_state_t *afl) {
|
|||||||
|
|
||||||
len = read(fd, tmp, MAX_AUTO_EXTRA + 1);
|
len = read(fd, tmp, MAX_AUTO_EXTRA + 1);
|
||||||
|
|
||||||
if (len < 0) PFATAL("Unable to read from '%s'", fn);
|
if (len < 0) { PFATAL("Unable to read from '%s'", fn); }
|
||||||
|
|
||||||
|
if (len >= MIN_AUTO_EXTRA && len <= MAX_AUTO_EXTRA) {
|
||||||
|
|
||||||
if (len >= MIN_AUTO_EXTRA && len <= MAX_AUTO_EXTRA)
|
|
||||||
maybe_add_auto((u8 *)afl, tmp, len);
|
maybe_add_auto((u8 *)afl, tmp, len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
ck_free(fn);
|
ck_free(fn);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i)
|
if (i) {
|
||||||
|
|
||||||
OKF("Loaded %u auto-discovered dictionary tokens.", i);
|
OKF("Loaded %u auto-discovered dictionary tokens.", i);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
OKF("No auto-generated dictionary tokens to reuse.");
|
OKF("No auto-generated dictionary tokens to reuse.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Destroy extras. */
|
/* Destroy extras. */
|
||||||
@ -495,14 +571,20 @@ void destroy_extras(afl_state_t *afl) {
|
|||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
|
|
||||||
for (i = 0; i < afl->extras_cnt; ++i)
|
for (i = 0; i < afl->extras_cnt; ++i) {
|
||||||
|
|
||||||
ck_free(afl->extras[i].data);
|
ck_free(afl->extras[i].data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ck_free(afl->extras);
|
ck_free(afl->extras);
|
||||||
|
|
||||||
for (i = 0; i < afl->a_extras_cnt; ++i)
|
for (i = 0; i < afl->a_extras_cnt; ++i) {
|
||||||
|
|
||||||
ck_free(afl->a_extras[i].data);
|
ck_free(afl->a_extras[i].data);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ck_free(afl->a_extras);
|
ck_free(afl->a_extras);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -35,12 +35,15 @@ void setup_custom_mutator(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (fn) {
|
if (fn) {
|
||||||
|
|
||||||
if (afl->limit_time_sig)
|
if (afl->limit_time_sig) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"MOpt and custom mutator are mutually exclusive. We accept pull "
|
"MOpt and custom mutator are mutually exclusive. We accept pull "
|
||||||
"requests that integrates MOpt with the optional mutators "
|
"requests that integrates MOpt with the optional mutators "
|
||||||
"(custom/radamsa/redquenn/...).");
|
"(custom/radamsa/redquenn/...).");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
load_custom_mutator(afl, fn);
|
load_custom_mutator(afl, fn);
|
||||||
|
|
||||||
return;
|
return;
|
||||||
@ -53,12 +56,15 @@ void setup_custom_mutator(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (module_name) {
|
if (module_name) {
|
||||||
|
|
||||||
if (afl->limit_time_sig)
|
if (afl->limit_time_sig) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"MOpt and Python mutator are mutually exclusive. We accept pull "
|
"MOpt and Python mutator are mutually exclusive. We accept pull "
|
||||||
"requests that integrates MOpt with the optional mutators "
|
"requests that integrates MOpt with the optional mutators "
|
||||||
"(custom/radamsa/redqueen/...).");
|
"(custom/radamsa/redqueen/...).");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
load_custom_mutator_py(afl, module_name);
|
load_custom_mutator_py(afl, module_name);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -76,7 +82,7 @@ void destroy_custom_mutator(afl_state_t *afl) {
|
|||||||
|
|
||||||
afl->mutator->afl_custom_deinit(afl->mutator->data);
|
afl->mutator->afl_custom_deinit(afl->mutator->data);
|
||||||
|
|
||||||
if (afl->mutator->dh) dlclose(afl->mutator->dh);
|
if (afl->mutator->dh) { dlclose(afl->mutator->dh); }
|
||||||
|
|
||||||
if (afl->mutator->pre_save_buf) {
|
if (afl->mutator->pre_save_buf) {
|
||||||
|
|
||||||
@ -104,20 +110,26 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
ACTF("Loading custom mutator library from '%s'...", fn);
|
ACTF("Loading custom mutator library from '%s'...", fn);
|
||||||
|
|
||||||
dh = dlopen(fn, RTLD_NOW);
|
dh = dlopen(fn, RTLD_NOW);
|
||||||
if (!dh) FATAL("%s", dlerror());
|
if (!dh) { FATAL("%s", dlerror()); }
|
||||||
afl->mutator->dh = dh;
|
afl->mutator->dh = dh;
|
||||||
|
|
||||||
/* Mutator */
|
/* Mutator */
|
||||||
/* "afl_custom_init", required */
|
/* "afl_custom_init", required */
|
||||||
afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
|
afl->mutator->afl_custom_init = dlsym(dh, "afl_custom_init");
|
||||||
if (!afl->mutator->afl_custom_init)
|
if (!afl->mutator->afl_custom_init) {
|
||||||
|
|
||||||
FATAL("Symbol 'afl_custom_init' not found.");
|
FATAL("Symbol 'afl_custom_init' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_deinit", required */
|
/* "afl_custom_deinit", required */
|
||||||
afl->mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
|
afl->mutator->afl_custom_deinit = dlsym(dh, "afl_custom_deinit");
|
||||||
if (!afl->mutator->afl_custom_deinit)
|
if (!afl->mutator->afl_custom_deinit) {
|
||||||
|
|
||||||
FATAL("Symbol 'afl_custom_deinit' not found.");
|
FATAL("Symbol 'afl_custom_deinit' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_fuzz" or "afl_custom_mutator", required */
|
/* "afl_custom_fuzz" or "afl_custom_mutator", required */
|
||||||
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
|
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_fuzz");
|
||||||
if (!afl->mutator->afl_custom_fuzz) {
|
if (!afl->mutator->afl_custom_fuzz) {
|
||||||
@ -126,32 +138,47 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'.");
|
WARNF("Symbol 'afl_custom_fuzz' not found. Try 'afl_custom_mutator'.");
|
||||||
|
|
||||||
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator");
|
afl->mutator->afl_custom_fuzz = dlsym(dh, "afl_custom_mutator");
|
||||||
if (!afl->mutator->afl_custom_fuzz)
|
if (!afl->mutator->afl_custom_fuzz) {
|
||||||
|
|
||||||
FATAL("Symbol 'afl_custom_mutator' not found.");
|
FATAL("Symbol 'afl_custom_mutator' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* "afl_custom_pre_save", optional */
|
/* "afl_custom_pre_save", optional */
|
||||||
afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
|
afl->mutator->afl_custom_pre_save = dlsym(dh, "afl_custom_pre_save");
|
||||||
if (!afl->mutator->afl_custom_pre_save)
|
if (!afl->mutator->afl_custom_pre_save) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_pre_save' not found.");
|
WARNF("Symbol 'afl_custom_pre_save' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
u8 notrim = 0;
|
u8 notrim = 0;
|
||||||
/* "afl_custom_init_trim", optional */
|
/* "afl_custom_init_trim", optional */
|
||||||
afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
|
afl->mutator->afl_custom_init_trim = dlsym(dh, "afl_custom_init_trim");
|
||||||
if (!afl->mutator->afl_custom_init_trim)
|
if (!afl->mutator->afl_custom_init_trim) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_init_trim' not found.");
|
WARNF("Symbol 'afl_custom_init_trim' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_trim", optional */
|
/* "afl_custom_trim", optional */
|
||||||
afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
|
afl->mutator->afl_custom_trim = dlsym(dh, "afl_custom_trim");
|
||||||
if (!afl->mutator->afl_custom_trim)
|
if (!afl->mutator->afl_custom_trim) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_trim' not found.");
|
WARNF("Symbol 'afl_custom_trim' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_post_trim", optional */
|
/* "afl_custom_post_trim", optional */
|
||||||
afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
|
afl->mutator->afl_custom_post_trim = dlsym(dh, "afl_custom_post_trim");
|
||||||
if (!afl->mutator->afl_custom_post_trim)
|
if (!afl->mutator->afl_custom_post_trim) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_post_trim' not found.");
|
WARNF("Symbol 'afl_custom_post_trim' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (notrim) {
|
if (notrim) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_init_trim = NULL;
|
afl->mutator->afl_custom_init_trim = NULL;
|
||||||
@ -166,33 +193,48 @@ void load_custom_mutator(afl_state_t *afl, const char *fn) {
|
|||||||
/* "afl_custom_havoc_mutation", optional */
|
/* "afl_custom_havoc_mutation", optional */
|
||||||
afl->mutator->afl_custom_havoc_mutation =
|
afl->mutator->afl_custom_havoc_mutation =
|
||||||
dlsym(dh, "afl_custom_havoc_mutation");
|
dlsym(dh, "afl_custom_havoc_mutation");
|
||||||
if (!afl->mutator->afl_custom_havoc_mutation)
|
if (!afl->mutator->afl_custom_havoc_mutation) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
|
WARNF("Symbol 'afl_custom_havoc_mutation' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_havoc_mutation", optional */
|
/* "afl_custom_havoc_mutation", optional */
|
||||||
afl->mutator->afl_custom_havoc_mutation_probability =
|
afl->mutator->afl_custom_havoc_mutation_probability =
|
||||||
dlsym(dh, "afl_custom_havoc_mutation_probability");
|
dlsym(dh, "afl_custom_havoc_mutation_probability");
|
||||||
if (!afl->mutator->afl_custom_havoc_mutation_probability)
|
if (!afl->mutator->afl_custom_havoc_mutation_probability) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found.");
|
WARNF("Symbol 'afl_custom_havoc_mutation_probability' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_queue_get", optional */
|
/* "afl_custom_queue_get", optional */
|
||||||
afl->mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
|
afl->mutator->afl_custom_queue_get = dlsym(dh, "afl_custom_queue_get");
|
||||||
if (!afl->mutator->afl_custom_queue_get)
|
if (!afl->mutator->afl_custom_queue_get) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_queue_get' not found.");
|
WARNF("Symbol 'afl_custom_queue_get' not found.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_queue_new_entry", optional */
|
/* "afl_custom_queue_new_entry", optional */
|
||||||
afl->mutator->afl_custom_queue_new_entry =
|
afl->mutator->afl_custom_queue_new_entry =
|
||||||
dlsym(dh, "afl_custom_queue_new_entry");
|
dlsym(dh, "afl_custom_queue_new_entry");
|
||||||
if (!afl->mutator->afl_custom_queue_new_entry)
|
if (!afl->mutator->afl_custom_queue_new_entry) {
|
||||||
|
|
||||||
WARNF("Symbol 'afl_custom_queue_new_entry' not found");
|
WARNF("Symbol 'afl_custom_queue_new_entry' not found");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OKF("Custom mutator '%s' installed successfully.", fn);
|
OKF("Custom mutator '%s' installed successfully.", fn);
|
||||||
|
|
||||||
/* Initialize the custom mutator */
|
/* Initialize the custom mutator */
|
||||||
if (afl->mutator->afl_custom_init)
|
if (afl->mutator->afl_custom_init) {
|
||||||
|
|
||||||
afl->mutator->data =
|
afl->mutator->data =
|
||||||
afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
|
afl->mutator->afl_custom_init(afl, rand_below(afl, 0xFFFFFFFF));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||||
@ -210,12 +252,19 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
afl->stage_cur = 0;
|
afl->stage_cur = 0;
|
||||||
afl->stage_max =
|
afl->stage_max =
|
||||||
afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len);
|
afl->mutator->afl_custom_init_trim(afl->mutator->data, in_buf, q->len);
|
||||||
if (unlikely(afl->stage_max) < 0)
|
if (unlikely(afl->stage_max) < 0) {
|
||||||
|
|
||||||
FATAL("custom_init_trim error ret: %d", afl->stage_max);
|
FATAL("custom_init_trim error ret: %d", afl->stage_max);
|
||||||
if (afl->not_on_tty && afl->debug)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max,
|
SAYF("[Custom Trimming] START: Max %d iterations, %u bytes", afl->stage_max,
|
||||||
q->len);
|
q->len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
while (afl->stage_cur < afl->stage_max) {
|
while (afl->stage_cur < afl->stage_max) {
|
||||||
|
|
||||||
u8 *retbuf = NULL;
|
u8 *retbuf = NULL;
|
||||||
@ -227,13 +276,18 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf);
|
size_t retlen = afl->mutator->afl_custom_trim(afl->mutator->data, &retbuf);
|
||||||
|
|
||||||
if (unlikely(!retbuf))
|
if (unlikely(!retbuf)) {
|
||||||
|
|
||||||
FATAL("custom_trim failed (ret %zd)", retlen);
|
FATAL("custom_trim failed (ret %zd)", retlen);
|
||||||
else if (unlikely(retlen > orig_len))
|
|
||||||
|
} else if (unlikely(retlen > orig_len)) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"Trimmed data returned by custom mutator is larger than original "
|
"Trimmed data returned by custom mutator is larger than original "
|
||||||
"data");
|
"data");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
write_to_testcase(afl, retbuf, retlen);
|
write_to_testcase(afl, retbuf, retlen);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
@ -263,32 +317,45 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
afl->stage_cur =
|
afl->stage_cur =
|
||||||
afl->mutator->afl_custom_post_trim(afl->mutator->data, 1);
|
afl->mutator->afl_custom_post_trim(afl->mutator->data, 1);
|
||||||
|
|
||||||
if (afl->not_on_tty && afl->debug)
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)",
|
SAYF("[Custom Trimming] SUCCESS: %d/%d iterations (now at %u bytes)",
|
||||||
afl->stage_cur, afl->stage_max, q->len);
|
afl->stage_cur, afl->stage_max, q->len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
/* Tell the custom mutator that the trimming was unsuccessful */
|
/* Tell the custom mutator that the trimming was unsuccessful */
|
||||||
afl->stage_cur =
|
afl->stage_cur =
|
||||||
afl->mutator->afl_custom_post_trim(afl->mutator->data, 0);
|
afl->mutator->afl_custom_post_trim(afl->mutator->data, 0);
|
||||||
if (unlikely(afl->stage_cur < 0))
|
if (unlikely(afl->stage_cur < 0)) {
|
||||||
|
|
||||||
FATAL("Error ret in custom_post_trim: %d", afl->stage_cur);
|
FATAL("Error ret in custom_post_trim: %d", afl->stage_cur);
|
||||||
if (afl->not_on_tty && afl->debug)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur,
|
SAYF("[Custom Trimming] FAILURE: %d/%d iterations", afl->stage_cur,
|
||||||
afl->stage_max);
|
afl->stage_max);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Since this can be slow, update the screen every now and then. */
|
/* Since this can be slow, update the screen every now and then. */
|
||||||
|
|
||||||
if (!(trim_exec++ % afl->stats_update_freq)) show_stats(afl);
|
if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->not_on_tty && afl->debug)
|
if (afl->not_on_tty && afl->debug) {
|
||||||
|
|
||||||
SAYF("[Custom Trimming] DONE: %u bytes -> %u bytes", orig_len, q->len);
|
SAYF("[Custom Trimming] DONE: %u bytes -> %u bytes", orig_len, q->len);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If we have made changes to in_buf, we also need to update the on-disk
|
/* If we have made changes to in_buf, we also need to update the on-disk
|
||||||
version of the test case. */
|
version of the test case. */
|
||||||
|
|
||||||
@ -300,7 +367,7 @@ u8 trim_case_custom(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
fd = open(q->fname, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", q->fname);
|
if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
|
||||||
|
|
||||||
ck_write(fd, in_buf, q->len, q->fname);
|
ck_write(fd, in_buf, q->len, q->fname);
|
||||||
close(fd);
|
close(fd);
|
||||||
|
File diff suppressed because it is too large
Load Diff
@ -111,10 +111,10 @@ static size_t fuzz_py(void *py_mutator, u8 *buf, size_t buf_size, u8 **out_buf,
|
|||||||
|
|
||||||
static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
||||||
|
|
||||||
if (!module_name) return NULL;
|
if (!module_name) { return NULL; }
|
||||||
|
|
||||||
py_mutator_t *py = calloc(1, sizeof(py_mutator_t));
|
py_mutator_t *py = calloc(1, sizeof(py_mutator_t));
|
||||||
if (!py) PFATAL("Could not allocate memory for python mutator!");
|
if (!py) { PFATAL("Could not allocate memory for python mutator!"); }
|
||||||
|
|
||||||
Py_Initialize();
|
Py_Initialize();
|
||||||
|
|
||||||
@ -160,12 +160,12 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
|||||||
if (py_idx == PY_FUNC_PRE_SAVE) {
|
if (py_idx == PY_FUNC_PRE_SAVE) {
|
||||||
|
|
||||||
// Implenting the pre_save API is optional for now
|
// Implenting the pre_save API is optional for now
|
||||||
if (PyErr_Occurred()) PyErr_Print();
|
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||||
|
|
||||||
} else if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) {
|
} else if (py_idx >= PY_FUNC_INIT_TRIM && py_idx <= PY_FUNC_TRIM) {
|
||||||
|
|
||||||
// Implementing the trim API is optional for now
|
// Implementing the trim API is optional for now
|
||||||
if (PyErr_Occurred()) PyErr_Print();
|
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||||
py_notrim = 1;
|
py_notrim = 1;
|
||||||
|
|
||||||
} else if ((py_idx >= PY_FUNC_HAVOC_MUTATION) &&
|
} else if ((py_idx >= PY_FUNC_HAVOC_MUTATION) &&
|
||||||
@ -173,11 +173,11 @@ static py_mutator_t *init_py_module(afl_state_t *afl, u8 *module_name) {
|
|||||||
(py_idx <= PY_FUNC_QUEUE_NEW_ENTRY)) {
|
(py_idx <= PY_FUNC_QUEUE_NEW_ENTRY)) {
|
||||||
|
|
||||||
// Implenting the havoc and queue API is optional for now
|
// Implenting the havoc and queue API is optional for now
|
||||||
if (PyErr_Occurred()) PyErr_Print();
|
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (PyErr_Occurred()) PyErr_Print();
|
if (PyErr_Occurred()) { PyErr_Print(); }
|
||||||
fprintf(stderr,
|
fprintf(stderr,
|
||||||
"Cannot find/call function with index %d in external "
|
"Cannot find/call function with index %d in external "
|
||||||
"Python module.\n",
|
"Python module.\n",
|
||||||
@ -222,9 +222,12 @@ void finalize_py_module(void *py_mutator) {
|
|||||||
deinit_py(py_mutator);
|
deinit_py(py_mutator);
|
||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
for (i = 0; i < PY_FUNC_COUNT; ++i)
|
for (i = 0; i < PY_FUNC_COUNT; ++i) {
|
||||||
|
|
||||||
Py_XDECREF(py->py_functions[i]);
|
Py_XDECREF(py->py_functions[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
Py_DECREF(py->py_module);
|
Py_DECREF(py->py_module);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -308,38 +311,67 @@ void load_custom_mutator_py(afl_state_t *afl, char *module_name) {
|
|||||||
|
|
||||||
PyObject **py_functions = py_mutator->py_functions;
|
PyObject **py_functions = py_mutator->py_functions;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_INIT]) afl->mutator->afl_custom_init = unsupported;
|
if (py_functions[PY_FUNC_INIT]) {
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_DEINIT]) afl->mutator->afl_custom_deinit = deinit_py;
|
afl->mutator->afl_custom_init = unsupported;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_DEINIT]) {
|
||||||
|
|
||||||
|
afl->mutator->afl_custom_deinit = deinit_py;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
|
/* "afl_custom_fuzz" should not be NULL, but the interface of Python mutator
|
||||||
is quite different from the custom mutator. */
|
is quite different from the custom mutator. */
|
||||||
afl->mutator->afl_custom_fuzz = fuzz_py;
|
afl->mutator->afl_custom_fuzz = fuzz_py;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_PRE_SAVE])
|
if (py_functions[PY_FUNC_PRE_SAVE]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_pre_save = pre_save_py;
|
afl->mutator->afl_custom_pre_save = pre_save_py;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_INIT_TRIM])
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_INIT_TRIM]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_init_trim = init_trim_py;
|
afl->mutator->afl_custom_init_trim = init_trim_py;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_POST_TRIM])
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_POST_TRIM]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_post_trim = post_trim_py;
|
afl->mutator->afl_custom_post_trim = post_trim_py;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_TRIM]) afl->mutator->afl_custom_trim = trim_py;
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_TRIM]) { afl->mutator->afl_custom_trim = trim_py; }
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_HAVOC_MUTATION]) {
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_HAVOC_MUTATION])
|
|
||||||
afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py;
|
afl->mutator->afl_custom_havoc_mutation = havoc_mutation_py;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY])
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_HAVOC_MUTATION_PROBABILITY]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_havoc_mutation_probability =
|
afl->mutator->afl_custom_havoc_mutation_probability =
|
||||||
havoc_mutation_probability_py;
|
havoc_mutation_probability_py;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_QUEUE_GET])
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_QUEUE_GET]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_queue_get = queue_get_py;
|
afl->mutator->afl_custom_queue_get = queue_get_py;
|
||||||
|
|
||||||
if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY])
|
}
|
||||||
|
|
||||||
|
if (py_functions[PY_FUNC_QUEUE_NEW_ENTRY]) {
|
||||||
|
|
||||||
afl->mutator->afl_custom_queue_new_entry = queue_new_entry_py;
|
afl->mutator->afl_custom_queue_new_entry = queue_new_entry_py;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OKF("Python mutator '%s' installed successfully.", module_name);
|
OKF("Python mutator '%s' installed successfully.", module_name);
|
||||||
|
|
||||||
/* Initialize the custom mutator */
|
/* Initialize the custom mutator */
|
||||||
|
@ -38,7 +38,7 @@ void mark_as_det_done(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
strrchr(q->fname, '/') + 1);
|
strrchr(q->fname, '/') + 1);
|
||||||
|
|
||||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", fn);
|
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
q->passed_det = 1;
|
q->passed_det = 1;
|
||||||
@ -61,7 +61,7 @@ void mark_as_variable(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
if (symlink(ldest, fn)) {
|
if (symlink(ldest, fn)) {
|
||||||
|
|
||||||
s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
s32 fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", fn);
|
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -77,7 +77,7 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
|
|||||||
|
|
||||||
u8 fn[PATH_MAX];
|
u8 fn[PATH_MAX];
|
||||||
|
|
||||||
if (state == q->fs_redundant) return;
|
if (state == q->fs_redundant) { return; }
|
||||||
|
|
||||||
q->fs_redundant = state;
|
q->fs_redundant = state;
|
||||||
|
|
||||||
@ -89,12 +89,12 @@ void mark_as_redundant(afl_state_t *afl, struct queue_entry *q, u8 state) {
|
|||||||
s32 fd;
|
s32 fd;
|
||||||
|
|
||||||
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
fd = open(fn, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", fn);
|
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (unlink(fn)) PFATAL("Unable to remove '%s'", fn);
|
if (unlink(fn)) { PFATAL("Unable to remove '%s'", fn); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -113,17 +113,19 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
q->n_fuzz = 1;
|
q->n_fuzz = 1;
|
||||||
q->trace_mini = NULL;
|
q->trace_mini = NULL;
|
||||||
|
|
||||||
if (q->depth > afl->max_depth) afl->max_depth = q->depth;
|
if (q->depth > afl->max_depth) { afl->max_depth = q->depth; }
|
||||||
|
|
||||||
if (afl->queue_top) {
|
if (afl->queue_top) {
|
||||||
|
|
||||||
afl->queue_top->next = q;
|
afl->queue_top->next = q;
|
||||||
afl->queue_top = q;
|
afl->queue_top = q;
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
afl->q_prev100 = afl->queue = afl->queue_top = q;
|
afl->q_prev100 = afl->queue = afl->queue_top = q;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
++afl->queued_paths;
|
++afl->queued_paths;
|
||||||
++afl->pending_not_fuzzed;
|
++afl->pending_not_fuzzed;
|
||||||
|
|
||||||
@ -143,7 +145,7 @@ void add_to_queue(afl_state_t *afl, u8 *fname, u32 len, u8 passed_det) {
|
|||||||
u8 *fname_orig = NULL;
|
u8 *fname_orig = NULL;
|
||||||
|
|
||||||
/* At the initialization stage, queue_cur is NULL */
|
/* At the initialization stage, queue_cur is NULL */
|
||||||
if (afl->queue_cur) fname_orig = afl->queue_cur->fname;
|
if (afl->queue_cur) { fname_orig = afl->queue_cur->fname; }
|
||||||
|
|
||||||
afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname,
|
afl->mutator->afl_custom_queue_new_entry(afl->mutator->data, fname,
|
||||||
fname_orig);
|
fname_orig);
|
||||||
@ -188,14 +190,19 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
u64 fuzz_p2 = next_pow2(q->n_fuzz);
|
u64 fuzz_p2 = next_pow2(q->n_fuzz);
|
||||||
|
|
||||||
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
||||||
unlikely(afl->fixed_seed))
|
unlikely(afl->fixed_seed)) {
|
||||||
|
|
||||||
fav_factor = q->len << 2;
|
fav_factor = q->len << 2;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
fav_factor = q->exec_us * q->len;
|
fav_factor = q->exec_us * q->len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
|
/* For every byte set in afl->fsrv.trace_bits[], see if there is a previous
|
||||||
winner, and how it compares to us. */
|
winner, and how it compares to us. */
|
||||||
for (i = 0; i < afl->fsrv.map_size; ++i)
|
for (i = 0; i < afl->fsrv.map_size; ++i) {
|
||||||
|
|
||||||
if (afl->fsrv.trace_bits[i]) {
|
if (afl->fsrv.trace_bits[i]) {
|
||||||
|
|
||||||
@ -206,27 +213,41 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
|
u64 top_rated_fuzz_p2 = next_pow2(afl->top_rated[i]->n_fuzz);
|
||||||
|
|
||||||
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
||||||
unlikely(afl->fixed_seed))
|
unlikely(afl->fixed_seed)) {
|
||||||
|
|
||||||
top_rated_fav_factor = afl->top_rated[i]->len << 2;
|
top_rated_fav_factor = afl->top_rated[i]->len << 2;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
top_rated_fav_factor =
|
top_rated_fav_factor =
|
||||||
afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
|
afl->top_rated[i]->exec_us * afl->top_rated[i]->len;
|
||||||
|
|
||||||
if (fuzz_p2 > top_rated_fuzz_p2)
|
}
|
||||||
|
|
||||||
|
if (fuzz_p2 > top_rated_fuzz_p2) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
else if (fuzz_p2 == top_rated_fuzz_p2)
|
|
||||||
if (fav_factor > top_rated_fav_factor) continue;
|
} else if (fuzz_p2 == top_rated_fuzz_p2) {
|
||||||
|
|
||||||
|
if (fav_factor > top_rated_fav_factor) { continue; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
if (afl->schedule == MMOPT || afl->schedule == RARE ||
|
||||||
unlikely(afl->fixed_seed)) {
|
unlikely(afl->fixed_seed)) {
|
||||||
|
|
||||||
if (fav_factor > afl->top_rated[i]->len << 2) continue;
|
if (fav_factor > afl->top_rated[i]->len << 2) { continue; }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (fav_factor > afl->top_rated[i]->exec_us * afl->top_rated[i]->len)
|
if (fav_factor >
|
||||||
|
afl->top_rated[i]->exec_us * afl->top_rated[i]->len) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Looks like we're going to win. Decrease ref count for the
|
/* Looks like we're going to win. Decrease ref count for the
|
||||||
@ -258,6 +279,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* The second part of the mechanism discussed above is a routine that
|
/* The second part of the mechanism discussed above is a routine that
|
||||||
@ -273,7 +296,7 @@ void cull_queue(afl_state_t *afl) {
|
|||||||
u32 i;
|
u32 i;
|
||||||
u8 * temp_v = afl->map_tmp_buf;
|
u8 * temp_v = afl->map_tmp_buf;
|
||||||
|
|
||||||
if (afl->dumb_mode || !afl->score_changed) return;
|
if (afl->dumb_mode || !afl->score_changed) { return; }
|
||||||
|
|
||||||
afl->score_changed = 0;
|
afl->score_changed = 0;
|
||||||
|
|
||||||
@ -294,25 +317,38 @@ void cull_queue(afl_state_t *afl) {
|
|||||||
/* Let's see if anything in the bitmap isn't captured in temp_v.
|
/* Let's see if anything in the bitmap isn't captured in temp_v.
|
||||||
If yes, and if it has a afl->top_rated[] contender, let's use it. */
|
If yes, and if it has a afl->top_rated[] contender, let's use it. */
|
||||||
|
|
||||||
for (i = 0; i < afl->fsrv.map_size; ++i)
|
for (i = 0; i < afl->fsrv.map_size; ++i) {
|
||||||
|
|
||||||
if (afl->top_rated[i] && (temp_v[i >> 3] & (1 << (i & 7)))) {
|
if (afl->top_rated[i] && (temp_v[i >> 3] & (1 << (i & 7)))) {
|
||||||
|
|
||||||
u32 j = len;
|
u32 j = len;
|
||||||
|
|
||||||
/* Remove all bits belonging to the current entry from temp_v. */
|
/* Remove all bits belonging to the current entry from temp_v. */
|
||||||
|
|
||||||
while (j--)
|
while (j--) {
|
||||||
if (afl->top_rated[i]->trace_mini[j])
|
|
||||||
|
if (afl->top_rated[i]->trace_mini[j]) {
|
||||||
|
|
||||||
temp_v[j] &= ~afl->top_rated[i]->trace_mini[j];
|
temp_v[j] &= ~afl->top_rated[i]->trace_mini[j];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->top_rated[i]->favored = 1;
|
afl->top_rated[i]->favored = 1;
|
||||||
++afl->queued_favored;
|
++afl->queued_favored;
|
||||||
|
|
||||||
if (afl->top_rated[i]->fuzz_level == 0 || !afl->top_rated[i]->was_fuzzed)
|
if (afl->top_rated[i]->fuzz_level == 0 ||
|
||||||
|
!afl->top_rated[i]->was_fuzzed) {
|
||||||
|
|
||||||
++afl->pending_favored;
|
++afl->pending_favored;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
q = afl->queue;
|
q = afl->queue;
|
||||||
|
|
||||||
while (q) {
|
while (q) {
|
||||||
@ -347,39 +383,67 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
if (afl->schedule != MMOPT && afl->schedule != RARE &&
|
if (afl->schedule != MMOPT && afl->schedule != RARE &&
|
||||||
likely(!afl->fixed_seed)) {
|
likely(!afl->fixed_seed)) {
|
||||||
|
|
||||||
if (q->exec_us * 0.1 > avg_exec_us)
|
if (q->exec_us * 0.1 > avg_exec_us) {
|
||||||
|
|
||||||
perf_score = 10;
|
perf_score = 10;
|
||||||
else if (q->exec_us * 0.25 > avg_exec_us)
|
|
||||||
|
} else if (q->exec_us * 0.25 > avg_exec_us) {
|
||||||
|
|
||||||
perf_score = 25;
|
perf_score = 25;
|
||||||
else if (q->exec_us * 0.5 > avg_exec_us)
|
|
||||||
|
} else if (q->exec_us * 0.5 > avg_exec_us) {
|
||||||
|
|
||||||
perf_score = 50;
|
perf_score = 50;
|
||||||
else if (q->exec_us * 0.75 > avg_exec_us)
|
|
||||||
|
} else if (q->exec_us * 0.75 > avg_exec_us) {
|
||||||
|
|
||||||
perf_score = 75;
|
perf_score = 75;
|
||||||
else if (q->exec_us * 4 < avg_exec_us)
|
|
||||||
|
} else if (q->exec_us * 4 < avg_exec_us) {
|
||||||
|
|
||||||
perf_score = 300;
|
perf_score = 300;
|
||||||
else if (q->exec_us * 3 < avg_exec_us)
|
|
||||||
|
} else if (q->exec_us * 3 < avg_exec_us) {
|
||||||
|
|
||||||
perf_score = 200;
|
perf_score = 200;
|
||||||
else if (q->exec_us * 2 < avg_exec_us)
|
|
||||||
|
} else if (q->exec_us * 2 < avg_exec_us) {
|
||||||
|
|
||||||
perf_score = 150;
|
perf_score = 150;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Adjust score based on bitmap size. The working theory is that better
|
/* Adjust score based on bitmap size. The working theory is that better
|
||||||
coverage translates to better targets. Multiplier from 0.25x to 3x. */
|
coverage translates to better targets. Multiplier from 0.25x to 3x. */
|
||||||
|
|
||||||
if (q->bitmap_size * 0.3 > avg_bitmap_size)
|
if (q->bitmap_size * 0.3 > avg_bitmap_size) {
|
||||||
|
|
||||||
perf_score *= 3;
|
perf_score *= 3;
|
||||||
else if (q->bitmap_size * 0.5 > avg_bitmap_size)
|
|
||||||
|
} else if (q->bitmap_size * 0.5 > avg_bitmap_size) {
|
||||||
|
|
||||||
perf_score *= 2;
|
perf_score *= 2;
|
||||||
else if (q->bitmap_size * 0.75 > avg_bitmap_size)
|
|
||||||
|
} else if (q->bitmap_size * 0.75 > avg_bitmap_size) {
|
||||||
|
|
||||||
perf_score *= 1.5;
|
perf_score *= 1.5;
|
||||||
else if (q->bitmap_size * 3 < avg_bitmap_size)
|
|
||||||
|
} else if (q->bitmap_size * 3 < avg_bitmap_size) {
|
||||||
|
|
||||||
perf_score *= 0.25;
|
perf_score *= 0.25;
|
||||||
else if (q->bitmap_size * 2 < avg_bitmap_size)
|
|
||||||
|
} else if (q->bitmap_size * 2 < avg_bitmap_size) {
|
||||||
|
|
||||||
perf_score *= 0.5;
|
perf_score *= 0.5;
|
||||||
else if (q->bitmap_size * 1.5 < avg_bitmap_size)
|
|
||||||
|
} else if (q->bitmap_size * 1.5 < avg_bitmap_size) {
|
||||||
|
|
||||||
perf_score *= 0.75;
|
perf_score *= 0.75;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Adjust score based on handicap. Handicap is proportional to how late
|
/* Adjust score based on handicap. Handicap is proportional to how late
|
||||||
in the game we learned about this path. Latecomers are allowed to run
|
in the game we learned about this path. Latecomers are allowed to run
|
||||||
for a bit longer until they catch up with the rest. */
|
for a bit longer until they catch up with the rest. */
|
||||||
@ -402,11 +466,19 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
switch (q->depth) {
|
switch (q->depth) {
|
||||||
|
|
||||||
case 0 ... 3: break;
|
case 0 ... 3:
|
||||||
case 4 ... 7: perf_score *= 2; break;
|
break;
|
||||||
case 8 ... 13: perf_score *= 3; break;
|
case 4 ... 7:
|
||||||
case 14 ... 25: perf_score *= 4; break;
|
perf_score *= 2;
|
||||||
default: perf_score *= 5;
|
break;
|
||||||
|
case 8 ... 13:
|
||||||
|
perf_score *= 3;
|
||||||
|
break;
|
||||||
|
case 14 ... 25:
|
||||||
|
perf_score *= 4;
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
perf_score *= 5;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -418,9 +490,12 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
switch (afl->schedule) {
|
switch (afl->schedule) {
|
||||||
|
|
||||||
case EXPLORE: break;
|
case EXPLORE:
|
||||||
|
break;
|
||||||
|
|
||||||
case EXPLOIT: factor = MAX_FACTOR; break;
|
case EXPLOIT:
|
||||||
|
factor = MAX_FACTOR;
|
||||||
|
break;
|
||||||
|
|
||||||
case COE:
|
case COE:
|
||||||
fuzz_total = 0;
|
fuzz_total = 0;
|
||||||
@ -435,16 +510,21 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (unlikely(!n_paths)) FATAL("Queue state corrupt");
|
if (unlikely(!n_paths)) { FATAL("Queue state corrupt"); }
|
||||||
|
|
||||||
fuzz_mu = fuzz_total / n_paths;
|
fuzz_mu = fuzz_total / n_paths;
|
||||||
if (fuzz <= fuzz_mu) {
|
if (fuzz <= fuzz_mu) {
|
||||||
|
|
||||||
if (q->fuzz_level < 16)
|
if (q->fuzz_level < 16) {
|
||||||
|
|
||||||
factor = ((u32)(1 << q->fuzz_level));
|
factor = ((u32)(1 << q->fuzz_level));
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
factor = MAX_FACTOR;
|
factor = MAX_FACTOR;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
factor = 0;
|
factor = 0;
|
||||||
@ -454,13 +534,21 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case FAST:
|
case FAST:
|
||||||
if (q->fuzz_level < 16)
|
if (q->fuzz_level < 16) {
|
||||||
|
|
||||||
factor = ((u32)(1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz);
|
factor = ((u32)(1 << q->fuzz_level)) / (fuzz == 0 ? 1 : fuzz);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_pow2(fuzz));
|
factor = MAX_FACTOR / (fuzz == 0 ? 1 : next_pow2(fuzz));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case LIN: factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz); break;
|
case LIN:
|
||||||
|
factor = q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
|
||||||
|
break;
|
||||||
|
|
||||||
case QUAD:
|
case QUAD:
|
||||||
factor = q->fuzz_level * q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
|
factor = q->fuzz_level * q->fuzz_level / (fuzz == 0 ? 1 : fuzz);
|
||||||
@ -477,7 +565,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
(afl->max_depth - q->depth)) / 5));
|
(afl->max_depth - q->depth)) / 5));
|
||||||
*/
|
*/
|
||||||
// put focus on the last 5 entries
|
// put focus on the last 5 entries
|
||||||
if (afl->max_depth - q->depth < 5) perf_score *= 2;
|
if (afl->max_depth - q->depth < 5) { perf_score *= 2; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -493,26 +581,35 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: PFATAL("Unknown Power Schedule");
|
default:
|
||||||
|
PFATAL("Unknown Power Schedule");
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (factor > MAX_FACTOR) factor = MAX_FACTOR;
|
if (factor > MAX_FACTOR) { factor = MAX_FACTOR; }
|
||||||
|
|
||||||
perf_score *= factor / POWER_BETA;
|
perf_score *= factor / POWER_BETA;
|
||||||
|
|
||||||
// MOpt mode
|
// MOpt mode
|
||||||
if (afl->limit_time_sig != 0 && afl->max_depth - q->depth < 3)
|
if (afl->limit_time_sig != 0 && afl->max_depth - q->depth < 3) {
|
||||||
|
|
||||||
perf_score *= 2;
|
perf_score *= 2;
|
||||||
else if (perf_score < 1)
|
|
||||||
|
} else if (perf_score < 1) {
|
||||||
|
|
||||||
// Add a lower bound to AFLFast's energy assignment strategies
|
// Add a lower bound to AFLFast's energy assignment strategies
|
||||||
perf_score = 1;
|
perf_score = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Make sure that we don't go over limit. */
|
/* Make sure that we don't go over limit. */
|
||||||
|
|
||||||
if (perf_score > afl->havoc_max_mult * 100)
|
if (perf_score > afl->havoc_max_mult * 100) {
|
||||||
|
|
||||||
perf_score = afl->havoc_max_mult * 100;
|
perf_score = afl->havoc_max_mult * 100;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return perf_score;
|
return perf_score;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -73,11 +73,16 @@ static struct range *pop_biggest_range(struct range **ranges) {
|
|||||||
|
|
||||||
if (rmax) {
|
if (rmax) {
|
||||||
|
|
||||||
if (prev_rmax)
|
if (prev_rmax) {
|
||||||
|
|
||||||
prev_rmax->next = rmax->next;
|
prev_rmax->next = rmax->next;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
*ranges = rmax->next;
|
*ranges = rmax->next;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return rmax;
|
return rmax;
|
||||||
@ -86,7 +91,7 @@ static struct range *pop_biggest_range(struct range **ranges) {
|
|||||||
|
|
||||||
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u32 *cksum) {
|
static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u32 *cksum) {
|
||||||
|
|
||||||
if (unlikely(common_fuzz_stuff(afl, buf, len))) return 1;
|
if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
|
||||||
|
|
||||||
*cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
*cksum = hash32(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
|
||||||
return 0;
|
return 0;
|
||||||
@ -96,9 +101,12 @@ static u8 get_exec_checksum(afl_state_t *afl, u8 *buf, u32 len, u32 *cksum) {
|
|||||||
static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) {
|
static void rand_replace(afl_state_t *afl, u8 *buf, u32 len) {
|
||||||
|
|
||||||
u32 i;
|
u32 i;
|
||||||
for (i = 0; i < len; ++i)
|
for (i = 0; i < len; ++i) {
|
||||||
|
|
||||||
buf[i] = rand_below(afl, 256);
|
buf[i] = rand_below(afl, 256);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
||||||
@ -131,9 +139,12 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
|||||||
|
|
||||||
u32 cksum;
|
u32 cksum;
|
||||||
u64 start_us = get_cur_time_us();
|
u64 start_us = get_cur_time_us();
|
||||||
if (unlikely(get_exec_checksum(afl, buf, len, &cksum)))
|
if (unlikely(get_exec_checksum(afl, buf, len, &cksum))) {
|
||||||
|
|
||||||
goto checksum_fail;
|
goto checksum_fail;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
u64 stop_us = get_cur_time_us();
|
u64 stop_us = get_cur_time_us();
|
||||||
|
|
||||||
/* Discard if the mutations change the paths or if it is too decremental
|
/* Discard if the mutations change the paths or if it is too decremental
|
||||||
@ -159,7 +170,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->stage_cur < afl->stage_max) afl->queue_cur->fully_colorized = 1;
|
if (afl->stage_cur < afl->stage_max) { afl->queue_cur->fully_colorized = 1; }
|
||||||
|
|
||||||
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||||
afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt;
|
afl->stage_finds[STAGE_COLORIZATION] += new_hit_cnt - orig_hit_cnt;
|
||||||
@ -192,7 +203,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", afl->queue_cur->fname);
|
if (fd < 0) { PFATAL("Unable to create '%s'", afl->queue_cur->fname); }
|
||||||
|
|
||||||
ck_write(fd, buf, len, afl->queue_cur->fname);
|
ck_write(fd, buf, len, afl->queue_cur->fname);
|
||||||
afl->queue_cur->len = len; // no-op, just to be 100% safe
|
afl->queue_cur->len = len; // no-op, just to be 100% safe
|
||||||
@ -204,7 +215,7 @@ static u8 colorization(afl_state_t *afl, u8 *buf, u32 len, u32 exec_cksum) {
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
checksum_fail:
|
checksum_fail:
|
||||||
if (rng) ck_free(rng);
|
if (rng) { ck_free(rng); }
|
||||||
ck_free(backup);
|
ck_free(backup);
|
||||||
|
|
||||||
while (ranges) {
|
while (ranges) {
|
||||||
@ -230,15 +241,20 @@ static u8 its_fuzz(afl_state_t *afl, u8 *buf, u32 len, u8 *status) {
|
|||||||
|
|
||||||
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
orig_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||||
|
|
||||||
if (unlikely(common_fuzz_stuff(afl, buf, len))) return 1;
|
if (unlikely(common_fuzz_stuff(afl, buf, len))) { return 1; }
|
||||||
|
|
||||||
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
new_hit_cnt = afl->queued_paths + afl->unique_crashes;
|
||||||
|
|
||||||
if (unlikely(new_hit_cnt != orig_hit_cnt))
|
if (unlikely(new_hit_cnt != orig_hit_cnt)) {
|
||||||
|
|
||||||
*status = 1;
|
*status = 1;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
*status = 2;
|
*status = 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -265,18 +281,24 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
|
|||||||
if (its_len >= 8 && *buf_64 == pattern && *o_buf_64 == o_pattern) {
|
if (its_len >= 8 && *buf_64 == pattern && *o_buf_64 == o_pattern) {
|
||||||
|
|
||||||
*buf_64 = repl;
|
*buf_64 = repl;
|
||||||
if (unlikely(its_fuzz(afl, buf, len, status))) return 1;
|
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
|
||||||
*buf_64 = pattern;
|
*buf_64 = pattern;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse encoding
|
// reverse encoding
|
||||||
if (do_reverse)
|
if (do_reverse) {
|
||||||
|
|
||||||
if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl),
|
if (unlikely(cmp_extend_encoding(afl, h, SWAP64(pattern), SWAP64(repl),
|
||||||
SWAP64(o_pattern), idx, orig_buf, buf,
|
SWAP64(o_pattern), idx, orig_buf, buf,
|
||||||
len, 0, status)))
|
len, 0, status))) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SHAPE_BYTES(h->shape) == 4 || *status == 2) {
|
if (SHAPE_BYTES(h->shape) == 4 || *status == 2) {
|
||||||
@ -285,18 +307,24 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
|
|||||||
*o_buf_32 == (u32)o_pattern) {
|
*o_buf_32 == (u32)o_pattern) {
|
||||||
|
|
||||||
*buf_32 = (u32)repl;
|
*buf_32 = (u32)repl;
|
||||||
if (unlikely(its_fuzz(afl, buf, len, status))) return 1;
|
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
|
||||||
*buf_32 = pattern;
|
*buf_32 = pattern;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse encoding
|
// reverse encoding
|
||||||
if (do_reverse)
|
if (do_reverse) {
|
||||||
|
|
||||||
if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl),
|
if (unlikely(cmp_extend_encoding(afl, h, SWAP32(pattern), SWAP32(repl),
|
||||||
SWAP32(o_pattern), idx, orig_buf, buf,
|
SWAP32(o_pattern), idx, orig_buf, buf,
|
||||||
len, 0, status)))
|
len, 0, status))) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SHAPE_BYTES(h->shape) == 2 || *status == 2) {
|
if (SHAPE_BYTES(h->shape) == 2 || *status == 2) {
|
||||||
@ -305,18 +333,24 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
|
|||||||
*o_buf_16 == (u16)o_pattern) {
|
*o_buf_16 == (u16)o_pattern) {
|
||||||
|
|
||||||
*buf_16 = (u16)repl;
|
*buf_16 = (u16)repl;
|
||||||
if (unlikely(its_fuzz(afl, buf, len, status))) return 1;
|
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
|
||||||
*buf_16 = (u16)pattern;
|
*buf_16 = (u16)pattern;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// reverse encoding
|
// reverse encoding
|
||||||
if (do_reverse)
|
if (do_reverse) {
|
||||||
|
|
||||||
if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl),
|
if (unlikely(cmp_extend_encoding(afl, h, SWAP16(pattern), SWAP16(repl),
|
||||||
SWAP16(o_pattern), idx, orig_buf, buf,
|
SWAP16(o_pattern), idx, orig_buf, buf,
|
||||||
len, 0, status)))
|
len, 0, status))) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (SHAPE_BYTES(h->shape) == 1 || *status == 2) {
|
if (SHAPE_BYTES(h->shape) == 1 || *status == 2) {
|
||||||
@ -324,7 +358,7 @@ static u8 cmp_extend_encoding(afl_state_t *afl, struct cmp_header *h,
|
|||||||
if (its_len >= 1 && *buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) {
|
if (its_len >= 1 && *buf_8 == (u8)pattern && *o_buf_8 == (u8)o_pattern) {
|
||||||
|
|
||||||
*buf_8 = (u8)repl;
|
*buf_8 = (u8)repl;
|
||||||
if (unlikely(its_fuzz(afl, buf, len, status))) return 1;
|
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
|
||||||
*buf_8 = (u8)pattern;
|
*buf_8 = (u8)pattern;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -343,14 +377,21 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) {
|
|||||||
u8 cons_ff = 0, cons_0 = 0;
|
u8 cons_ff = 0, cons_0 = 0;
|
||||||
for (k = 0; k < shape; ++k) {
|
for (k = 0; k < shape; ++k) {
|
||||||
|
|
||||||
if (b[k] == 0)
|
if (b[k] == 0) {
|
||||||
|
|
||||||
++cons_0;
|
++cons_0;
|
||||||
else if (b[k] == 0xff)
|
|
||||||
|
} else if (b[k] == 0xff) {
|
||||||
|
|
||||||
++cons_0;
|
++cons_0;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
cons_0 = cons_ff = 0;
|
cons_0 = cons_ff = 0;
|
||||||
|
|
||||||
if (cons_0 > 1 || cons_ff > 1) return;
|
}
|
||||||
|
|
||||||
|
if (cons_0 > 1 || cons_ff > 1) { return; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -359,7 +400,8 @@ static void try_to_add_to_dict(afl_state_t *afl, u64 v, u8 shape) {
|
|||||||
u64 rev;
|
u64 rev;
|
||||||
switch (shape) {
|
switch (shape) {
|
||||||
|
|
||||||
case 1: break;
|
case 1:
|
||||||
|
break;
|
||||||
case 2:
|
case 2:
|
||||||
rev = SWAP16((u16)v);
|
rev = SWAP16((u16)v);
|
||||||
maybe_add_auto((u8 *)afl, (u8 *)&rev, shape);
|
maybe_add_auto((u8 *)afl, (u8 *)&rev, shape);
|
||||||
@ -383,7 +425,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
u32 i, j, idx;
|
u32 i, j, idx;
|
||||||
|
|
||||||
u32 loggeds = h->hits;
|
u32 loggeds = h->hits;
|
||||||
if (h->hits > CMP_MAP_H) loggeds = CMP_MAP_H;
|
if (h->hits > CMP_MAP_H) { loggeds = CMP_MAP_H; }
|
||||||
|
|
||||||
u8 status = 0;
|
u8 status = 0;
|
||||||
// opt not in the paper
|
// opt not in the paper
|
||||||
@ -410,12 +452,12 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (s_v0 != o->v0) s_v0_fixed = 0;
|
if (s_v0 != o->v0) { s_v0_fixed = 0; }
|
||||||
if (s_v1 != o->v1) s_v1_fixed = 0;
|
if (s_v1 != o->v1) { s_v1_fixed = 0; }
|
||||||
if (s_v0 + 1 != o->v0) s_v0_inc = 0;
|
if (s_v0 + 1 != o->v0) { s_v0_inc = 0; }
|
||||||
if (s_v1 + 1 != o->v1) s_v1_inc = 0;
|
if (s_v1 + 1 != o->v1) { s_v1_inc = 0; }
|
||||||
if (s_v0 - 1 != o->v0) s_v0_dec = 0;
|
if (s_v0 - 1 != o->v0) { s_v0_dec = 0; }
|
||||||
if (s_v1 - 1 != o->v1) s_v1_dec = 0;
|
if (s_v1 - 1 != o->v1) { s_v1_dec = 0; }
|
||||||
s_v0 = o->v0;
|
s_v0 = o->v0;
|
||||||
s_v1 = o->v1;
|
s_v1 = o->v1;
|
||||||
|
|
||||||
@ -424,32 +466,56 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
struct cmp_operands *orig_o = &afl->orig_cmp_map->log[key][i];
|
struct cmp_operands *orig_o = &afl->orig_cmp_map->log[key][i];
|
||||||
|
|
||||||
// opt not in the paper
|
// opt not in the paper
|
||||||
for (j = 0; j < i; ++j)
|
for (j = 0; j < i; ++j) {
|
||||||
|
|
||||||
if (afl->shm.cmp_map->log[key][j].v0 == o->v0 &&
|
if (afl->shm.cmp_map->log[key][j].v0 == o->v0 &&
|
||||||
afl->shm.cmp_map->log[key][i].v1 == o->v1)
|
afl->shm.cmp_map->log[key][i].v1 == o->v1) {
|
||||||
|
|
||||||
goto cmp_fuzz_next_iter;
|
goto cmp_fuzz_next_iter;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (idx = 0; idx < len && fails < 8; ++idx) {
|
for (idx = 0; idx < len && fails < 8; ++idx) {
|
||||||
|
|
||||||
if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx,
|
if (unlikely(cmp_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx,
|
||||||
orig_buf, buf, len, 1, &status)))
|
orig_buf, buf, len, 1, &status))) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
if (status == 2)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == 2) {
|
||||||
|
|
||||||
++fails;
|
++fails;
|
||||||
else if (status == 1)
|
|
||||||
|
} else if (status == 1) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx,
|
if (unlikely(cmp_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx,
|
||||||
orig_buf, buf, len, 1, &status)))
|
orig_buf, buf, len, 1, &status))) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
if (status == 2)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == 2) {
|
||||||
|
|
||||||
++fails;
|
++fails;
|
||||||
else if (status == 1)
|
|
||||||
|
} else if (status == 1) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == 1) found_one = 1;
|
if (status == 1) { found_one = 1; }
|
||||||
|
|
||||||
// If failed, add to dictionary
|
// If failed, add to dictionary
|
||||||
if (fails == 8) {
|
if (fails == 8) {
|
||||||
@ -481,7 +547,7 @@ static u8 cmp_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->pass_stats[key].total < 0xff) afl->pass_stats[key].total++;
|
if (afl->pass_stats[key].total < 0xff) { afl->pass_stats[key].total++; }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -502,11 +568,14 @@ static u8 rtn_extend_encoding(afl_state_t *afl, struct cmp_header *h,
|
|||||||
for (i = 0; i < its_len; ++i) {
|
for (i = 0; i < its_len; ++i) {
|
||||||
|
|
||||||
if (pattern[idx + i] != buf[idx + i] ||
|
if (pattern[idx + i] != buf[idx + i] ||
|
||||||
o_pattern[idx + i] != orig_buf[idx + i] || *status == 1)
|
o_pattern[idx + i] != orig_buf[idx + i] || *status == 1) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
buf[idx + i] = repl[idx + i];
|
buf[idx + i] = repl[idx + i];
|
||||||
if (unlikely(its_fuzz(afl, buf, len, status))) return 1;
|
if (unlikely(its_fuzz(afl, buf, len, status))) { return 1; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -521,7 +590,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
u32 i, j, idx;
|
u32 i, j, idx;
|
||||||
|
|
||||||
u32 loggeds = h->hits;
|
u32 loggeds = h->hits;
|
||||||
if (h->hits > CMP_MAP_RTN_H) loggeds = CMP_MAP_RTN_H;
|
if (h->hits > CMP_MAP_RTN_H) { loggeds = CMP_MAP_RTN_H; }
|
||||||
|
|
||||||
u8 status = 0;
|
u8 status = 0;
|
||||||
// opt not in the paper
|
// opt not in the paper
|
||||||
@ -539,32 +608,56 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
&((struct cmpfn_operands *)afl->orig_cmp_map->log[key])[i];
|
&((struct cmpfn_operands *)afl->orig_cmp_map->log[key])[i];
|
||||||
|
|
||||||
// opt not in the paper
|
// opt not in the paper
|
||||||
for (j = 0; j < i; ++j)
|
for (j = 0; j < i; ++j) {
|
||||||
|
|
||||||
if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j], o,
|
if (!memcmp(&((struct cmpfn_operands *)afl->shm.cmp_map->log[key])[j], o,
|
||||||
sizeof(struct cmpfn_operands)))
|
sizeof(struct cmpfn_operands))) {
|
||||||
|
|
||||||
goto rtn_fuzz_next_iter;
|
goto rtn_fuzz_next_iter;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
for (idx = 0; idx < len && fails < 8; ++idx) {
|
for (idx = 0; idx < len && fails < 8; ++idx) {
|
||||||
|
|
||||||
if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx,
|
if (unlikely(rtn_extend_encoding(afl, h, o->v0, o->v1, orig_o->v0, idx,
|
||||||
orig_buf, buf, len, &status)))
|
orig_buf, buf, len, &status))) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
if (status == 2)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == 2) {
|
||||||
|
|
||||||
++fails;
|
++fails;
|
||||||
else if (status == 1)
|
|
||||||
|
} else if (status == 1) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx,
|
if (unlikely(rtn_extend_encoding(afl, h, o->v1, o->v0, orig_o->v1, idx,
|
||||||
orig_buf, buf, len, &status)))
|
orig_buf, buf, len, &status))) {
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
if (status == 2)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status == 2) {
|
||||||
|
|
||||||
++fails;
|
++fails;
|
||||||
else if (status == 1)
|
|
||||||
|
} else if (status == 1) {
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (status == 1) found_one = 1;
|
if (status == 1) { found_one = 1; }
|
||||||
|
|
||||||
// If failed, add to dictionary
|
// If failed, add to dictionary
|
||||||
if (fails == 8) {
|
if (fails == 8) {
|
||||||
@ -589,7 +682,7 @@ static u8 rtn_fuzz(afl_state_t *afl, u32 key, u8 *orig_buf, u8 *buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->pass_stats[key].total < 0xff) afl->pass_stats[key].total++;
|
if (afl->pass_stats[key].total < 0xff) { afl->pass_stats[key].total++; }
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -602,25 +695,31 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
|||||||
u32 exec_cksum) {
|
u32 exec_cksum) {
|
||||||
|
|
||||||
u8 r = 1;
|
u8 r = 1;
|
||||||
if (afl->orig_cmp_map == NULL)
|
if (afl->orig_cmp_map == NULL) {
|
||||||
|
|
||||||
afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map));
|
afl->orig_cmp_map = ck_alloc_nozero(sizeof(struct cmp_map));
|
||||||
|
|
||||||
if (afl->pass_stats == NULL)
|
}
|
||||||
|
|
||||||
|
if (afl->pass_stats == NULL) {
|
||||||
|
|
||||||
afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W);
|
afl->pass_stats = ck_alloc(sizeof(struct afl_pass_stat) * CMP_MAP_W);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
// do it manually, forkserver clear only afl->fsrv.trace_bits
|
// do it manually, forkserver clear only afl->fsrv.trace_bits
|
||||||
memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers));
|
memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers));
|
||||||
|
|
||||||
if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) return 1;
|
if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; }
|
||||||
|
|
||||||
memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map));
|
memcpy(afl->orig_cmp_map, afl->shm.cmp_map, sizeof(struct cmp_map));
|
||||||
|
|
||||||
if (unlikely(colorization(afl, buf, len, exec_cksum))) return 1;
|
if (unlikely(colorization(afl, buf, len, exec_cksum))) { return 1; }
|
||||||
|
|
||||||
// do it manually, forkserver clear only afl->fsrv.trace_bits
|
// do it manually, forkserver clear only afl->fsrv.trace_bits
|
||||||
memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers));
|
memset(afl->shm.cmp_map->headers, 0, sizeof(afl->shm.cmp_map->headers));
|
||||||
|
|
||||||
if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) return 1;
|
if (unlikely(common_fuzz_cmplog_stuff(afl, buf, len))) { return 1; }
|
||||||
|
|
||||||
u64 orig_hit_cnt, new_hit_cnt;
|
u64 orig_hit_cnt, new_hit_cnt;
|
||||||
u64 orig_execs = afl->fsrv.total_execs;
|
u64 orig_execs = afl->fsrv.total_execs;
|
||||||
@ -634,33 +733,41 @@ u8 input_to_state_stage(afl_state_t *afl, u8 *orig_buf, u8 *buf, u32 len,
|
|||||||
u32 k;
|
u32 k;
|
||||||
for (k = 0; k < CMP_MAP_W; ++k) {
|
for (k = 0; k < CMP_MAP_W; ++k) {
|
||||||
|
|
||||||
if (!afl->shm.cmp_map->headers[k].hits) continue;
|
if (!afl->shm.cmp_map->headers[k].hits) { continue; }
|
||||||
|
|
||||||
if (afl->pass_stats[k].total &&
|
if (afl->pass_stats[k].total &&
|
||||||
(rand_below(afl, afl->pass_stats[k].total) >=
|
(rand_below(afl, afl->pass_stats[k].total) >=
|
||||||
afl->pass_stats[k].faileds ||
|
afl->pass_stats[k].faileds ||
|
||||||
afl->pass_stats[k].total == 0xff))
|
afl->pass_stats[k].total == 0xff)) {
|
||||||
|
|
||||||
afl->shm.cmp_map->headers[k].hits = 0; // blacklist this cmp
|
afl->shm.cmp_map->headers[k].hits = 0; // blacklist this cmp
|
||||||
|
|
||||||
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS)
|
}
|
||||||
|
|
||||||
|
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) {
|
||||||
|
|
||||||
afl->stage_max += MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_H);
|
afl->stage_max += MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_H);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->stage_max +=
|
afl->stage_max +=
|
||||||
MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H);
|
MIN((u32)afl->shm.cmp_map->headers[k].hits, CMP_MAP_RTN_H);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (k = 0; k < CMP_MAP_W; ++k) {
|
for (k = 0; k < CMP_MAP_W; ++k) {
|
||||||
|
|
||||||
if (!afl->shm.cmp_map->headers[k].hits) continue;
|
if (!afl->shm.cmp_map->headers[k].hits) { continue; }
|
||||||
|
|
||||||
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) {
|
if (afl->shm.cmp_map->headers[k].type == CMP_TYPE_INS) {
|
||||||
|
|
||||||
if (unlikely(cmp_fuzz(afl, k, orig_buf, buf, len))) goto exit_its;
|
if (unlikely(cmp_fuzz(afl, k, orig_buf, buf, len))) { goto exit_its; }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, len))) goto exit_its;
|
if (unlikely(rtn_fuzz(afl, k, orig_buf, buf, len))) { goto exit_its; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -72,9 +72,12 @@ void write_to_testcase(afl_state_t *afl, void *mem, u32 len) {
|
|||||||
size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem,
|
size_t new_size = afl->mutator->afl_custom_pre_save(afl->mutator->data, mem,
|
||||||
len, &new_buf);
|
len, &new_buf);
|
||||||
|
|
||||||
if (unlikely(!new_buf))
|
if (unlikely(!new_buf)) {
|
||||||
|
|
||||||
FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
|
FATAL("Custom_pre_save failed (ret: %lu)", (long unsigned)new_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* everything as planned. use the new data. */
|
/* everything as planned. use the new data. */
|
||||||
afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size);
|
afl_fsrv_write_to_testcase(&afl->fsrv, new_buf, new_size);
|
||||||
|
|
||||||
@ -108,27 +111,34 @@ static void write_with_gap(afl_state_t *afl, void *mem, u32 len, u32 skip_at,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", afl->fsrv.out_file);
|
if (fd < 0) { PFATAL("Unable to create '%s'", afl->fsrv.out_file); }
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
if (skip_at) ck_write(fd, mem, skip_at, afl->fsrv.out_file);
|
}
|
||||||
|
|
||||||
|
if (skip_at) { ck_write(fd, mem, skip_at, afl->fsrv.out_file); }
|
||||||
|
|
||||||
u8 *memu8 = mem;
|
u8 *memu8 = mem;
|
||||||
if (tail_len)
|
if (tail_len) {
|
||||||
|
|
||||||
ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file);
|
ck_write(fd, memu8 + skip_at + skip_len, tail_len, afl->fsrv.out_file);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!afl->fsrv.out_file) {
|
if (!afl->fsrv.out_file) {
|
||||||
|
|
||||||
if (ftruncate(fd, len - skip_len)) PFATAL("ftruncate() failed");
|
if (ftruncate(fd, len - skip_len)) { PFATAL("ftruncate() failed"); }
|
||||||
lseek(fd, 0, SEEK_SET);
|
lseek(fd, 0, SEEK_SET);
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
close(fd);
|
close(fd);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Calibrate a new test case. This is done when processing the input directory
|
/* Calibrate a new test case. This is done when processing the input directory
|
||||||
@ -151,10 +161,13 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
trying to calibrate already-added finds. This helps avoid trouble due
|
trying to calibrate already-added finds. This helps avoid trouble due
|
||||||
to intermittent latency. */
|
to intermittent latency. */
|
||||||
|
|
||||||
if (!from_queue || afl->resuming_fuzz)
|
if (!from_queue || afl->resuming_fuzz) {
|
||||||
|
|
||||||
use_tmout = MAX(afl->fsrv.exec_tmout + CAL_TMOUT_ADD,
|
use_tmout = MAX(afl->fsrv.exec_tmout + CAL_TMOUT_ADD,
|
||||||
afl->fsrv.exec_tmout * CAL_TMOUT_PERC / 100);
|
afl->fsrv.exec_tmout * CAL_TMOUT_PERC / 100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
++q->cal_failed;
|
++q->cal_failed;
|
||||||
|
|
||||||
afl->stage_name = "calibration";
|
afl->stage_name = "calibration";
|
||||||
@ -177,18 +190,24 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q->exec_cksum)
|
if (q->exec_cksum) {
|
||||||
|
|
||||||
memcpy(afl->first_trace, afl->fsrv.trace_bits, afl->fsrv.map_size);
|
memcpy(afl->first_trace, afl->fsrv.trace_bits, afl->fsrv.map_size);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
start_us = get_cur_time_us();
|
start_us = get_cur_time_us();
|
||||||
|
|
||||||
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
for (afl->stage_cur = 0; afl->stage_cur < afl->stage_max; ++afl->stage_cur) {
|
||||||
|
|
||||||
u32 cksum;
|
u32 cksum;
|
||||||
|
|
||||||
if (!first_run && !(afl->stage_cur % afl->stats_update_freq))
|
if (!first_run && !(afl->stage_cur % afl->stats_update_freq)) {
|
||||||
|
|
||||||
show_stats(afl);
|
show_stats(afl);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
write_to_testcase(afl, use_mem, q->len);
|
write_to_testcase(afl, use_mem, q->len);
|
||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, use_tmout);
|
||||||
@ -196,7 +215,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
/* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
|
/* afl->stop_soon is set by the handler for Ctrl+C. When it's pressed,
|
||||||
we want to bail out quickly. */
|
we want to bail out quickly. */
|
||||||
|
|
||||||
if (afl->stop_soon || fault != afl->crash_mode) goto abort_calibration;
|
if (afl->stop_soon || fault != afl->crash_mode) { goto abort_calibration; }
|
||||||
|
|
||||||
if (!afl->dumb_mode && !afl->stage_cur &&
|
if (!afl->dumb_mode && !afl->stage_cur &&
|
||||||
!count_bytes(afl, afl->fsrv.trace_bits)) {
|
!count_bytes(afl, afl->fsrv.trace_bits)) {
|
||||||
@ -211,7 +230,7 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
if (q->exec_cksum != cksum) {
|
if (q->exec_cksum != cksum) {
|
||||||
|
|
||||||
u8 hnb = has_new_bits(afl, afl->virgin_bits);
|
u8 hnb = has_new_bits(afl, afl->virgin_bits);
|
||||||
if (hnb > new_bits) new_bits = hnb;
|
if (hnb > new_bits) { new_bits = hnb; }
|
||||||
|
|
||||||
if (q->exec_cksum) {
|
if (q->exec_cksum) {
|
||||||
|
|
||||||
@ -220,9 +239,12 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
for (i = 0; i < afl->fsrv.map_size; ++i) {
|
for (i = 0; i < afl->fsrv.map_size; ++i) {
|
||||||
|
|
||||||
if (unlikely(!afl->var_bytes[i]) &&
|
if (unlikely(!afl->var_bytes[i]) &&
|
||||||
unlikely(afl->first_trace[i] != afl->fsrv.trace_bits[i]))
|
unlikely(afl->first_trace[i] != afl->fsrv.trace_bits[i])) {
|
||||||
|
|
||||||
afl->var_bytes[i] = 1;
|
afl->var_bytes[i] = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
var_detected = 1;
|
var_detected = 1;
|
||||||
@ -261,9 +283,12 @@ u8 calibrate_case(afl_state_t *afl, struct queue_entry *q, u8 *use_mem,
|
|||||||
parent. This is a non-critical problem, but something to warn the user
|
parent. This is a non-critical problem, but something to warn the user
|
||||||
about. */
|
about. */
|
||||||
|
|
||||||
if (!afl->dumb_mode && first_run && !fault && !new_bits)
|
if (!afl->dumb_mode && first_run && !fault && !new_bits) {
|
||||||
|
|
||||||
fault = FSRV_RUN_NOBITS;
|
fault = FSRV_RUN_NOBITS;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
abort_calibration:
|
abort_calibration:
|
||||||
|
|
||||||
if (new_bits == 2 && !q->has_new_cov) {
|
if (new_bits == 2 && !q->has_new_cov) {
|
||||||
@ -292,7 +317,7 @@ abort_calibration:
|
|||||||
afl->stage_cur = old_sc;
|
afl->stage_cur = old_sc;
|
||||||
afl->stage_max = old_sm;
|
afl->stage_max = old_sm;
|
||||||
|
|
||||||
if (!first_run) show_stats(afl);
|
if (!first_run) { show_stats(afl); }
|
||||||
|
|
||||||
return fault;
|
return fault;
|
||||||
|
|
||||||
@ -307,7 +332,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
u32 sync_cnt = 0;
|
u32 sync_cnt = 0;
|
||||||
|
|
||||||
sd = opendir(afl->sync_dir);
|
sd = opendir(afl->sync_dir);
|
||||||
if (!sd) PFATAL("Unable to open '%s'", afl->sync_dir);
|
if (!sd) { PFATAL("Unable to open '%s'", afl->sync_dir); }
|
||||||
|
|
||||||
afl->stage_max = afl->stage_cur = 0;
|
afl->stage_max = afl->stage_cur = 0;
|
||||||
afl->cur_depth = 0;
|
afl->cur_depth = 0;
|
||||||
@ -326,9 +351,12 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Skip dot files and our own output directory. */
|
/* Skip dot files and our own output directory. */
|
||||||
|
|
||||||
if (sd_ent->d_name[0] == '.' || !strcmp(afl->sync_id, sd_ent->d_name))
|
if (sd_ent->d_name[0] == '.' || !strcmp(afl->sync_id, sd_ent->d_name)) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Skip anything that doesn't have a queue/ subdirectory. */
|
/* Skip anything that doesn't have a queue/ subdirectory. */
|
||||||
|
|
||||||
qd_path = alloc_printf("%s/%s/queue", afl->sync_dir, sd_ent->d_name);
|
qd_path = alloc_printf("%s/%s/queue", afl->sync_dir, sd_ent->d_name);
|
||||||
@ -347,9 +375,13 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
|
|
||||||
id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);
|
id_fd = open(qd_synced_path, O_RDWR | O_CREAT, 0600);
|
||||||
|
|
||||||
if (id_fd < 0) PFATAL("Unable to create '%s'", qd_synced_path);
|
if (id_fd < 0) { PFATAL("Unable to create '%s'", qd_synced_path); }
|
||||||
|
|
||||||
if (read(id_fd, &min_accept, sizeof(u32)) > 0) lseek(id_fd, 0, SEEK_SET);
|
if (read(id_fd, &min_accept, sizeof(u32)) > 0) {
|
||||||
|
|
||||||
|
lseek(id_fd, 0, SEEK_SET);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
next_min_accept = min_accept;
|
next_min_accept = min_accept;
|
||||||
|
|
||||||
@ -372,14 +404,20 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
|
|
||||||
if (qd_ent->d_name[0] == '.' ||
|
if (qd_ent->d_name[0] == '.' ||
|
||||||
sscanf(qd_ent->d_name, CASE_PREFIX "%06u", &afl->syncing_case) != 1 ||
|
sscanf(qd_ent->d_name, CASE_PREFIX "%06u", &afl->syncing_case) != 1 ||
|
||||||
afl->syncing_case < min_accept)
|
afl->syncing_case < min_accept) {
|
||||||
|
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* OK, sounds like a new one. Let's give it a try. */
|
/* OK, sounds like a new one. Let's give it a try. */
|
||||||
|
|
||||||
if (afl->syncing_case >= next_min_accept)
|
if (afl->syncing_case >= next_min_accept) {
|
||||||
|
|
||||||
next_min_accept = afl->syncing_case + 1;
|
next_min_accept = afl->syncing_case + 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
path = alloc_printf("%s/%s", qd_path, qd_ent->d_name);
|
path = alloc_printf("%s/%s", qd_path, qd_ent->d_name);
|
||||||
|
|
||||||
/* Allow this to fail in case the other fuzzer is resuming or so... */
|
/* Allow this to fail in case the other fuzzer is resuming or so... */
|
||||||
@ -393,7 +431,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fstat(fd, &st)) PFATAL("fstat() failed");
|
if (fstat(fd, &st)) { PFATAL("fstat() failed"); }
|
||||||
|
|
||||||
/* Ignore zero-sized or oversized files. */
|
/* Ignore zero-sized or oversized files. */
|
||||||
|
|
||||||
@ -402,7 +440,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
u8 fault;
|
u8 fault;
|
||||||
u8 *mem = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
u8 *mem = mmap(0, st.st_size, PROT_READ, MAP_PRIVATE, fd, 0);
|
||||||
|
|
||||||
if (mem == MAP_FAILED) PFATAL("Unable to mmap '%s'", path);
|
if (mem == MAP_FAILED) { PFATAL("Unable to mmap '%s'", path); }
|
||||||
|
|
||||||
/* See what happens. We rely on save_if_interesting() to catch major
|
/* See what happens. We rely on save_if_interesting() to catch major
|
||||||
errors and save the test case. */
|
errors and save the test case. */
|
||||||
@ -411,7 +449,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
if (afl->stop_soon) goto close_sync;
|
if (afl->stop_soon) { goto close_sync; }
|
||||||
|
|
||||||
afl->syncing_party = sd_ent->d_name;
|
afl->syncing_party = sd_ent->d_name;
|
||||||
afl->queued_imported +=
|
afl->queued_imported +=
|
||||||
@ -420,7 +458,7 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
|
|
||||||
munmap(mem, st.st_size);
|
munmap(mem, st.st_size);
|
||||||
|
|
||||||
if (!(afl->stage_cur++ % afl->stats_update_freq)) show_stats(afl);
|
if (!(afl->stage_cur++ % afl->stats_update_freq)) { show_stats(afl); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -450,9 +488,12 @@ void sync_fuzzers(afl_state_t *afl) {
|
|||||||
u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
||||||
|
|
||||||
/* Custom mutator trimmer */
|
/* Custom mutator trimmer */
|
||||||
if (afl->mutator && afl->mutator->afl_custom_trim)
|
if (afl->mutator && afl->mutator->afl_custom_trim) {
|
||||||
|
|
||||||
return trim_case_custom(afl, q, in_buf);
|
return trim_case_custom(afl, q, in_buf);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
u8 needs_write = 0, fault = 0;
|
u8 needs_write = 0, fault = 0;
|
||||||
u32 trim_exec = 0;
|
u32 trim_exec = 0;
|
||||||
u32 remove_len;
|
u32 remove_len;
|
||||||
@ -464,7 +505,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
detected, it will still work to some extent, so we don't check for
|
detected, it will still work to some extent, so we don't check for
|
||||||
this. */
|
this. */
|
||||||
|
|
||||||
if (q->len < 5) return 0;
|
if (q->len < 5) { return 0; }
|
||||||
|
|
||||||
afl->stage_name = afl->stage_name_buf;
|
afl->stage_name = afl->stage_name_buf;
|
||||||
afl->bytes_trim_in += q->len;
|
afl->bytes_trim_in += q->len;
|
||||||
@ -499,7 +540,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
++afl->trim_execs;
|
++afl->trim_execs;
|
||||||
|
|
||||||
if (afl->stop_soon || fault == FSRV_RUN_ERROR) goto abort_trimming;
|
if (afl->stop_soon || fault == FSRV_RUN_ERROR) { goto abort_trimming; }
|
||||||
|
|
||||||
/* Note that we don't keep track of crashes or hangs here; maybe TODO?
|
/* Note that we don't keep track of crashes or hangs here; maybe TODO?
|
||||||
*/
|
*/
|
||||||
@ -531,13 +572,15 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
remove_pos += remove_len;
|
remove_pos += remove_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Since this can be slow, update the screen every now and then. */
|
/* Since this can be slow, update the screen every now and then. */
|
||||||
|
|
||||||
if (!(trim_exec++ % afl->stats_update_freq)) show_stats(afl);
|
if (!(trim_exec++ % afl->stats_update_freq)) { show_stats(afl); }
|
||||||
++afl->stage_cur;
|
++afl->stage_cur;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -564,7 +607,7 @@ u8 trim_case(afl_state_t *afl, struct queue_entry *q, u8 *in_buf) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", q->fname);
|
if (fd < 0) { PFATAL("Unable to create '%s'", q->fname); }
|
||||||
|
|
||||||
ck_write(fd, in_buf, q->len, q->fname);
|
ck_write(fd, in_buf, q->len, q->fname);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -595,7 +638,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
size_t post_len =
|
size_t post_len =
|
||||||
afl->post_handler(afl->post_data, out_buf, len, &post_buf);
|
afl->post_handler(afl->post_data, out_buf, len, &post_buf);
|
||||||
if (!post_buf || !post_len) return 0;
|
if (!post_buf || !post_len) { return 0; }
|
||||||
out_buf = post_buf;
|
out_buf = post_buf;
|
||||||
len = post_len;
|
len = post_len;
|
||||||
|
|
||||||
@ -605,7 +648,7 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
fault = fuzz_run_target(afl, &afl->fsrv, afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
if (afl->stop_soon) return 1;
|
if (afl->stop_soon) { return 1; }
|
||||||
|
|
||||||
if (fault == FSRV_RUN_TMOUT) {
|
if (fault == FSRV_RUN_TMOUT) {
|
||||||
|
|
||||||
@ -616,10 +659,12 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
afl->subseq_tmouts = 0;
|
afl->subseq_tmouts = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Users can hit us with SIGUSR1 to request the current input
|
/* Users can hit us with SIGUSR1 to request the current input
|
||||||
to be abandoned. */
|
to be abandoned. */
|
||||||
|
|
||||||
@ -636,9 +681,12 @@ u8 common_fuzz_stuff(afl_state_t *afl, u8 *out_buf, u32 len) {
|
|||||||
afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault);
|
afl->queued_discovered += save_if_interesting(afl, out_buf, len, fault);
|
||||||
|
|
||||||
if (!(afl->stage_cur % afl->stats_update_freq) ||
|
if (!(afl->stage_cur % afl->stats_update_freq) ||
|
||||||
afl->stage_cur + 1 == afl->stage_max)
|
afl->stage_cur + 1 == afl->stage_max) {
|
||||||
|
|
||||||
show_stats(afl);
|
show_stats(afl);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
@ -81,7 +81,7 @@ void afl_state_init(afl_state_t *afl, uint32_t map_size) {
|
|||||||
and out_size are NULL/0 by default. */
|
and out_size are NULL/0 by default. */
|
||||||
memset(afl, 0, sizeof(afl_state_t));
|
memset(afl, 0, sizeof(afl_state_t));
|
||||||
|
|
||||||
if (!map_size) afl->shm.map_size = MAP_SIZE;
|
if (!map_size) { afl->shm.map_size = MAP_SIZE; }
|
||||||
|
|
||||||
afl->w_init = 0.9;
|
afl->w_init = 0.9;
|
||||||
afl->w_end = 0.3;
|
afl->w_end = 0.3;
|
||||||
@ -344,10 +344,12 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
i++;
|
i++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (match == 0) {
|
if (match == 0) {
|
||||||
@ -361,7 +363,7 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (found) sleep(2);
|
if (found) { sleep(2); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -369,18 +371,18 @@ void read_afl_environment(afl_state_t *afl, char **envp) {
|
|||||||
|
|
||||||
void afl_state_deinit(afl_state_t *afl) {
|
void afl_state_deinit(afl_state_t *afl) {
|
||||||
|
|
||||||
if (afl->post_deinit) afl->post_deinit(afl->post_data);
|
if (afl->post_deinit) { afl->post_deinit(afl->post_data); }
|
||||||
if (afl->in_place_resume) ck_free(afl->in_dir);
|
if (afl->in_place_resume) { ck_free(afl->in_dir); }
|
||||||
if (afl->sync_id) ck_free(afl->out_dir);
|
if (afl->sync_id) { ck_free(afl->out_dir); }
|
||||||
if (afl->pass_stats) ck_free(afl->pass_stats);
|
if (afl->pass_stats) { ck_free(afl->pass_stats); }
|
||||||
if (afl->orig_cmp_map) ck_free(afl->orig_cmp_map);
|
if (afl->orig_cmp_map) { ck_free(afl->orig_cmp_map); }
|
||||||
|
|
||||||
if (afl->out_buf) free(afl->out_buf);
|
if (afl->out_buf) { free(afl->out_buf); }
|
||||||
if (afl->out_scratch_buf) free(afl->out_scratch_buf);
|
if (afl->out_scratch_buf) { free(afl->out_scratch_buf); }
|
||||||
if (afl->eff_buf) free(afl->eff_buf);
|
if (afl->eff_buf) { free(afl->eff_buf); }
|
||||||
if (afl->in_buf) free(afl->in_buf);
|
if (afl->in_buf) { free(afl->in_buf); }
|
||||||
if (afl->in_scratch_buf) free(afl->in_scratch_buf);
|
if (afl->in_scratch_buf) { free(afl->in_scratch_buf); }
|
||||||
if (afl->ex_buf) free(afl->ex_buf);
|
if (afl->ex_buf) { free(afl->ex_buf); }
|
||||||
|
|
||||||
ck_free(afl->virgin_bits);
|
ck_free(afl->virgin_bits);
|
||||||
ck_free(afl->virgin_tmout);
|
ck_free(afl->virgin_tmout);
|
||||||
|
@ -43,11 +43,11 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
|
|
||||||
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
fd = open(fn, O_WRONLY | O_CREAT | O_TRUNC, 0600);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", fn);
|
if (fd < 0) { PFATAL("Unable to create '%s'", fn); }
|
||||||
|
|
||||||
f = fdopen(fd, "w");
|
f = fdopen(fd, "w");
|
||||||
|
|
||||||
if (!f) PFATAL("fdopen() failed");
|
if (!f) { PFATAL("fdopen() failed"); }
|
||||||
|
|
||||||
/* Keep last values in case we're called from another context
|
/* Keep last values in case we're called from another context
|
||||||
where exec/sec stats and such are not readily available. */
|
where exec/sec stats and such are not readily available. */
|
||||||
@ -65,7 +65,7 @@ void write_stats_file(afl_state_t *afl, double bitmap_cvg, double stability,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getrusage(RUSAGE_CHILDREN, &rus)) rus.ru_maxrss = 0;
|
if (getrusage(RUSAGE_CHILDREN, &rus)) { rus.ru_maxrss = 0; }
|
||||||
|
|
||||||
fprintf(
|
fprintf(
|
||||||
f,
|
f,
|
||||||
@ -153,9 +153,12 @@ void maybe_update_plot_file(afl_state_t *afl, double bitmap_cvg, double eps) {
|
|||||||
afl->plot_prev_uc == afl->unique_crashes &&
|
afl->plot_prev_uc == afl->unique_crashes &&
|
||||||
afl->plot_prev_uh == afl->unique_hangs &&
|
afl->plot_prev_uh == afl->unique_hangs &&
|
||||||
afl->plot_prev_md == afl->max_depth) ||
|
afl->plot_prev_md == afl->max_depth) ||
|
||||||
unlikely(!afl->queue_cycle))
|
unlikely(!afl->queue_cycle)) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->plot_prev_qp = afl->queued_paths;
|
afl->plot_prev_qp = afl->queued_paths;
|
||||||
afl->plot_prev_pf = afl->pending_favored;
|
afl->plot_prev_pf = afl->pending_favored;
|
||||||
afl->plot_prev_pnf = afl->pending_not_fuzzed;
|
afl->plot_prev_pnf = afl->pending_not_fuzzed;
|
||||||
@ -190,10 +193,10 @@ static void check_term_size(afl_state_t *afl) {
|
|||||||
|
|
||||||
afl->term_too_small = 0;
|
afl->term_too_small = 0;
|
||||||
|
|
||||||
if (ioctl(1, TIOCGWINSZ, &ws)) return;
|
if (ioctl(1, TIOCGWINSZ, &ws)) { return; }
|
||||||
|
|
||||||
if (ws.ws_row == 0 || ws.ws_col == 0) return;
|
if (ws.ws_row == 0 || ws.ws_col == 0) { return; }
|
||||||
if (ws.ws_row < 24 || ws.ws_col < 79) afl->term_too_small = 1;
|
if (ws.ws_row < 24 || ws.ws_col < 79) { afl->term_too_small = 1; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -241,12 +244,15 @@ void show_stats(afl_state_t *afl) {
|
|||||||
/* If not enough time has passed since last UI update, bail out. */
|
/* If not enough time has passed since last UI update, bail out. */
|
||||||
|
|
||||||
if (cur_ms - afl->stats_last_ms < 1000 / UI_TARGET_HZ &&
|
if (cur_ms - afl->stats_last_ms < 1000 / UI_TARGET_HZ &&
|
||||||
!afl->force_ui_update)
|
!afl->force_ui_update) {
|
||||||
|
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Check if we're past the 10 minute mark. */
|
/* Check if we're past the 10 minute mark. */
|
||||||
|
|
||||||
if (cur_ms - afl->start_time > 10 * 60 * 1000) afl->run_over10m = 1;
|
if (cur_ms - afl->start_time > 10 * 60 * 1000) { afl->run_over10m = 1; }
|
||||||
|
|
||||||
/* Calculate smoothed exec speed stats. */
|
/* Calculate smoothed exec speed stats. */
|
||||||
|
|
||||||
@ -263,9 +269,13 @@ void show_stats(afl_state_t *afl) {
|
|||||||
/* If there is a dramatic (5x+) jump in speed, reset the indicator
|
/* If there is a dramatic (5x+) jump in speed, reset the indicator
|
||||||
more quickly. */
|
more quickly. */
|
||||||
|
|
||||||
if (cur_avg * 5 < afl->stats_avg_exec || cur_avg / 5 > afl->stats_avg_exec)
|
if (cur_avg * 5 < afl->stats_avg_exec ||
|
||||||
|
cur_avg / 5 > afl->stats_avg_exec) {
|
||||||
|
|
||||||
afl->stats_avg_exec = cur_avg;
|
afl->stats_avg_exec = cur_avg;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->stats_avg_exec = afl->stats_avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) +
|
afl->stats_avg_exec = afl->stats_avg_exec * (1.0 - 1.0 / AVG_SMOOTHING) +
|
||||||
cur_avg * (1.0 / AVG_SMOOTHING);
|
cur_avg * (1.0 / AVG_SMOOTHING);
|
||||||
|
|
||||||
@ -277,18 +287,23 @@ void show_stats(afl_state_t *afl) {
|
|||||||
/* Tell the callers when to contact us (as measured in execs). */
|
/* Tell the callers when to contact us (as measured in execs). */
|
||||||
|
|
||||||
afl->stats_update_freq = afl->stats_avg_exec / (UI_TARGET_HZ * 10);
|
afl->stats_update_freq = afl->stats_avg_exec / (UI_TARGET_HZ * 10);
|
||||||
if (!afl->stats_update_freq) afl->stats_update_freq = 1;
|
if (!afl->stats_update_freq) { afl->stats_update_freq = 1; }
|
||||||
|
|
||||||
/* Do some bitmap stats. */
|
/* Do some bitmap stats. */
|
||||||
|
|
||||||
t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
|
t_bytes = count_non_255_bytes(afl, afl->virgin_bits);
|
||||||
t_byte_ratio = ((double)t_bytes * 100) / afl->fsrv.map_size;
|
t_byte_ratio = ((double)t_bytes * 100) / afl->fsrv.map_size;
|
||||||
|
|
||||||
if (likely(t_bytes) && unlikely(afl->var_byte_count))
|
if (likely(t_bytes) && unlikely(afl->var_byte_count)) {
|
||||||
|
|
||||||
stab_ratio = 100 - (((double)afl->var_byte_count * 100) / t_bytes);
|
stab_ratio = 100 - (((double)afl->var_byte_count * 100) / t_bytes);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
stab_ratio = 100;
|
stab_ratio = 100;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Roughly every minute, update fuzzer stats and save auto tokens. */
|
/* Roughly every minute, update fuzzer stats and save auto tokens. */
|
||||||
|
|
||||||
if (cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000) {
|
if (cur_ms - afl->stats_last_stats_ms > STATS_UPDATE_SEC * 1000) {
|
||||||
@ -312,19 +327,25 @@ void show_stats(afl_state_t *afl) {
|
|||||||
/* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
|
/* Honor AFL_EXIT_WHEN_DONE and AFL_BENCH_UNTIL_CRASH. */
|
||||||
|
|
||||||
if (!afl->dumb_mode && afl->cycles_wo_finds > 100 &&
|
if (!afl->dumb_mode && afl->cycles_wo_finds > 100 &&
|
||||||
!afl->pending_not_fuzzed && afl->afl_env.afl_exit_when_done)
|
!afl->pending_not_fuzzed && afl->afl_env.afl_exit_when_done) {
|
||||||
|
|
||||||
afl->stop_soon = 2;
|
afl->stop_soon = 2;
|
||||||
|
|
||||||
if (afl->total_crashes && afl->afl_env.afl_bench_until_crash)
|
}
|
||||||
|
|
||||||
|
if (afl->total_crashes && afl->afl_env.afl_bench_until_crash) {
|
||||||
|
|
||||||
afl->stop_soon = 2;
|
afl->stop_soon = 2;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If we're not on TTY, bail out. */
|
/* If we're not on TTY, bail out. */
|
||||||
|
|
||||||
if (afl->not_on_tty) return;
|
if (afl->not_on_tty) { return; }
|
||||||
|
|
||||||
/* If we haven't started doing things, bail out. */
|
/* If we haven't started doing things, bail out. */
|
||||||
|
|
||||||
if (!afl->queue_cur) return;
|
if (!afl->queue_cur) { return; }
|
||||||
|
|
||||||
/* Compute some mildly useful bitmap stats. */
|
/* Compute some mildly useful bitmap stats. */
|
||||||
|
|
||||||
@ -389,9 +410,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Lord, forgive me this. */
|
/* Lord, forgive me this. */
|
||||||
|
|
||||||
SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
|
SAYF(SET_G1 bSTG bLT bH bSTOP cCYA
|
||||||
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
|
" process timing " bSTG bH30 bH5 bH bHB bH bSTOP cCYA
|
||||||
" overall results " bSTG bH2 bH2 bRT "\n");
|
" overall results " bSTG bH2 bH2 bRT "\n");
|
||||||
|
|
||||||
if (afl->dumb_mode) {
|
if (afl->dumb_mode) {
|
||||||
|
|
||||||
@ -402,24 +423,33 @@ void show_stats(afl_state_t *afl) {
|
|||||||
u64 min_wo_finds = (cur_ms - afl->last_path_time) / 1000 / 60;
|
u64 min_wo_finds = (cur_ms - afl->last_path_time) / 1000 / 60;
|
||||||
|
|
||||||
/* First queue cycle: don't stop now! */
|
/* First queue cycle: don't stop now! */
|
||||||
if (afl->queue_cycle == 1 || min_wo_finds < 15)
|
if (afl->queue_cycle == 1 || min_wo_finds < 15) {
|
||||||
|
|
||||||
strcpy(tmp, cMGN);
|
strcpy(tmp, cMGN);
|
||||||
else
|
|
||||||
|
} else
|
||||||
|
|
||||||
/* Subsequent cycles, but we're still making finds. */
|
/* Subsequent cycles, but we're still making finds. */
|
||||||
if (afl->cycles_wo_finds < 25 || min_wo_finds < 30)
|
if (afl->cycles_wo_finds < 25 || min_wo_finds < 30) {
|
||||||
|
|
||||||
strcpy(tmp, cYEL);
|
strcpy(tmp, cYEL);
|
||||||
else
|
|
||||||
|
} else
|
||||||
|
|
||||||
/* No finds for a long time and no test cases to try. */
|
/* No finds for a long time and no test cases to try. */
|
||||||
if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed &&
|
if (afl->cycles_wo_finds > 100 && !afl->pending_not_fuzzed &&
|
||||||
min_wo_finds > 120)
|
min_wo_finds > 120) {
|
||||||
|
|
||||||
strcpy(tmp, cLGN);
|
strcpy(tmp, cLGN);
|
||||||
|
|
||||||
/* Default: cautiously OK to stop? */
|
/* Default: cautiously OK to stop? */
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
strcpy(tmp, cLBL);
|
strcpy(tmp, cLBL);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u_stringify_time_diff(time_tmp, cur_ms, afl->start_time);
|
u_stringify_time_diff(time_tmp, cur_ms, afl->start_time);
|
||||||
@ -439,16 +469,18 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
if (afl->dumb_mode)
|
if (afl->dumb_mode) {
|
||||||
|
|
||||||
SAYF(bV bSTOP " last new path : " cPIN "n/a" cRST
|
SAYF(bV bSTOP " last new path : " cPIN "n/a" cRST
|
||||||
" (non-instrumented mode) ");
|
" (non-instrumented mode) ");
|
||||||
|
|
||||||
else
|
} else {
|
||||||
|
|
||||||
SAYF(bV bSTOP " last new path : " cRST "none yet " cLRD
|
SAYF(bV bSTOP " last new path : " cRST "none yet " cLRD
|
||||||
"(odd, check syntax!) ");
|
"(odd, check syntax!) ");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
SAYF(bSTG bV bSTOP " total paths : " cRST "%-5s " bSTG bV "\n",
|
SAYF(bSTG bV bSTOP " total paths : " cRST "%-5s " bSTG bV "\n",
|
||||||
@ -473,9 +505,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
|
" uniq hangs : " cRST "%-6s" bSTG bV "\n",
|
||||||
time_tmp, tmp);
|
time_tmp, tmp);
|
||||||
|
|
||||||
SAYF(bVR bH bSTOP cCYA
|
SAYF(bVR bH bSTOP cCYA
|
||||||
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
|
" cycle progress " bSTG bH10 bH5 bH2 bH2 bHB bH bSTOP cCYA
|
||||||
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
|
" map coverage " bSTG bH bHT bH20 bH2 bVL "\n");
|
||||||
|
|
||||||
/* This gets funny because we want to print several variable-length variables
|
/* This gets funny because we want to print several variable-length variables
|
||||||
together, but then cram them into a fixed-width field - so we need to
|
together, but then cram them into a fixed-width field - so we need to
|
||||||
@ -505,9 +537,9 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
|
SAYF(bSTOP " count coverage : " cRST "%-21s" bSTG bV "\n", tmp);
|
||||||
|
|
||||||
SAYF(bVR bH bSTOP cCYA
|
SAYF(bVR bH bSTOP cCYA
|
||||||
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
|
" stage progress " bSTG bH10 bH5 bH2 bH2 bX bH bSTOP cCYA
|
||||||
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
|
" findings in depth " bSTG bH10 bH5 bH2 bH2 bVL "\n");
|
||||||
|
|
||||||
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
|
sprintf(tmp, "%s (%0.02f%%)", u_stringify_int(IB(0), afl->queued_favored),
|
||||||
((double)afl->queued_favored) * 100 / afl->queued_paths);
|
((double)afl->queued_favored) * 100 / afl->queued_paths);
|
||||||
@ -581,7 +613,7 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* Aaaalmost there... hold on! */
|
/* Aaaalmost there... hold on! */
|
||||||
|
|
||||||
SAYF(bVR bH cCYA bSTOP
|
SAYF(bVR bH cCYA bSTOP
|
||||||
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
|
" fuzzing strategy yields " bSTG bH10 bHT bH10 bH5 bHB bH bSTOP cCYA
|
||||||
" path geometry " bSTG bH5 bH2 bVL "\n");
|
" path geometry " bSTG bH5 bH2 bVL "\n");
|
||||||
|
|
||||||
@ -605,7 +637,8 @@ void show_stats(afl_state_t *afl) {
|
|||||||
" levels : " cRST "%-10s" bSTG bV "\n",
|
" levels : " cRST "%-10s" bSTG bV "\n",
|
||||||
tmp, u_stringify_int(IB(0), afl->max_depth));
|
tmp, u_stringify_int(IB(0), afl->max_depth));
|
||||||
|
|
||||||
if (!afl->skip_deterministic)
|
if (!afl->skip_deterministic) {
|
||||||
|
|
||||||
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
||||||
u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]),
|
u_stringify_int(IB(0), afl->stage_finds[STAGE_FLIP8]),
|
||||||
u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]),
|
u_stringify_int(IB(1), afl->stage_cycles[STAGE_FLIP8]),
|
||||||
@ -614,11 +647,14 @@ void show_stats(afl_state_t *afl) {
|
|||||||
u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]),
|
u_stringify_int(IB(4), afl->stage_finds[STAGE_FLIP32]),
|
||||||
u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32]));
|
u_stringify_int(IB(5), afl->stage_cycles[STAGE_FLIP32]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP
|
SAYF(bV bSTOP " byte flips : " cRST "%-36s " bSTG bV bSTOP
|
||||||
" pending : " cRST "%-10s" bSTG bV "\n",
|
" pending : " cRST "%-10s" bSTG bV "\n",
|
||||||
tmp, u_stringify_int(IB(0), afl->pending_not_fuzzed));
|
tmp, u_stringify_int(IB(0), afl->pending_not_fuzzed));
|
||||||
|
|
||||||
if (!afl->skip_deterministic)
|
if (!afl->skip_deterministic) {
|
||||||
|
|
||||||
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
||||||
u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]),
|
u_stringify_int(IB(0), afl->stage_finds[STAGE_ARITH8]),
|
||||||
u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]),
|
u_stringify_int(IB(1), afl->stage_cycles[STAGE_ARITH8]),
|
||||||
@ -627,11 +663,14 @@ void show_stats(afl_state_t *afl) {
|
|||||||
u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]),
|
u_stringify_int(IB(4), afl->stage_finds[STAGE_ARITH32]),
|
||||||
u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32]));
|
u_stringify_int(IB(5), afl->stage_cycles[STAGE_ARITH32]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP
|
SAYF(bV bSTOP " arithmetics : " cRST "%-36s " bSTG bV bSTOP
|
||||||
" pend fav : " cRST "%-10s" bSTG bV "\n",
|
" pend fav : " cRST "%-10s" bSTG bV "\n",
|
||||||
tmp, u_stringify_int(IB(0), afl->pending_favored));
|
tmp, u_stringify_int(IB(0), afl->pending_favored));
|
||||||
|
|
||||||
if (!afl->skip_deterministic)
|
if (!afl->skip_deterministic) {
|
||||||
|
|
||||||
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
||||||
u_stringify_int(IB(0), afl->stage_finds[STAGE_INTEREST8]),
|
u_stringify_int(IB(0), afl->stage_finds[STAGE_INTEREST8]),
|
||||||
u_stringify_int(IB(1), afl->stage_cycles[STAGE_INTEREST8]),
|
u_stringify_int(IB(1), afl->stage_cycles[STAGE_INTEREST8]),
|
||||||
@ -640,11 +679,14 @@ void show_stats(afl_state_t *afl) {
|
|||||||
u_stringify_int(IB(4), afl->stage_finds[STAGE_INTEREST32]),
|
u_stringify_int(IB(4), afl->stage_finds[STAGE_INTEREST32]),
|
||||||
u_stringify_int(IB(5), afl->stage_cycles[STAGE_INTEREST32]));
|
u_stringify_int(IB(5), afl->stage_cycles[STAGE_INTEREST32]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SAYF(bV bSTOP " known ints : " cRST "%-36s " bSTG bV bSTOP
|
SAYF(bV bSTOP " known ints : " cRST "%-36s " bSTG bV bSTOP
|
||||||
" own finds : " cRST "%-10s" bSTG bV "\n",
|
" own finds : " cRST "%-10s" bSTG bV "\n",
|
||||||
tmp, u_stringify_int(IB(0), afl->queued_discovered));
|
tmp, u_stringify_int(IB(0), afl->queued_discovered));
|
||||||
|
|
||||||
if (!afl->skip_deterministic)
|
if (!afl->skip_deterministic) {
|
||||||
|
|
||||||
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
sprintf(tmp, "%s/%s, %s/%s, %s/%s",
|
||||||
u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
|
u_stringify_int(IB(0), afl->stage_finds[STAGE_EXTRAS_UO]),
|
||||||
u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
|
u_stringify_int(IB(1), afl->stage_cycles[STAGE_EXTRAS_UO]),
|
||||||
@ -653,6 +695,8 @@ void show_stats(afl_state_t *afl) {
|
|||||||
u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
|
u_stringify_int(IB(4), afl->stage_finds[STAGE_EXTRAS_AO]),
|
||||||
u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]));
|
u_stringify_int(IB(5), afl->stage_cycles[STAGE_EXTRAS_AO]));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP
|
SAYF(bV bSTOP " dictionary : " cRST "%-36s " bSTG bV bSTOP
|
||||||
" imported : " cRST "%-10s" bSTG bV "\n",
|
" imported : " cRST "%-10s" bSTG bV "\n",
|
||||||
tmp,
|
tmp,
|
||||||
@ -669,11 +713,16 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
|
SAYF(bV bSTOP " havoc/rad : " cRST "%-36s " bSTG bV bSTOP, tmp);
|
||||||
|
|
||||||
if (t_bytes)
|
if (t_bytes) {
|
||||||
|
|
||||||
sprintf(tmp, "%0.02f%%", stab_ratio);
|
sprintf(tmp, "%0.02f%%", stab_ratio);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
strcpy(tmp, "n/a");
|
strcpy(tmp, "n/a");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SAYF(" stability : %s%-10s" bSTG bV "\n",
|
SAYF(" stability : %s%-10s" bSTG bV "\n",
|
||||||
(stab_ratio < 85 && afl->var_byte_count > 40)
|
(stab_ratio < 85 && afl->var_byte_count > 40)
|
||||||
? cLRD
|
? cLRD
|
||||||
@ -769,14 +818,17 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
/* If we could still run one or more processes, use green. */
|
/* If we could still run one or more processes, use green. */
|
||||||
|
|
||||||
if (afl->cpu_core_count > 1 && cur_runnable + 1 <= afl->cpu_core_count)
|
if (afl->cpu_core_count > 1 && cur_runnable + 1 <= afl->cpu_core_count) {
|
||||||
|
|
||||||
cpu_color = cLGN;
|
cpu_color = cLGN;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If we're clearly oversubscribed, use red. */
|
/* If we're clearly oversubscribed, use red. */
|
||||||
|
|
||||||
if (!afl->no_cpu_meter_red && cur_utilization >= 150) cpu_color = cLRD;
|
if (!afl->no_cpu_meter_red && cur_utilization >= 150) { cpu_color = cLRD; }
|
||||||
|
|
||||||
if (afl->fsrv.snapshot) spacing = snap;
|
if (afl->fsrv.snapshot) { spacing = snap; }
|
||||||
|
|
||||||
#ifdef HAVE_AFFINITY
|
#ifdef HAVE_AFFINITY
|
||||||
|
|
||||||
@ -799,10 +851,12 @@ void show_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
#endif /* ^HAVE_AFFINITY */
|
#endif /* ^HAVE_AFFINITY */
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
SAYF("\r");
|
SAYF("\r");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Last line */
|
/* Last line */
|
||||||
SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1);
|
SAYF(SET_G1 "\n" bSTG bLB bH30 bH20 bH2 bRB bSTOP cRST RESET_G1);
|
||||||
|
|
||||||
@ -829,17 +883,21 @@ void show_init_stats(afl_state_t *afl) {
|
|||||||
u8 val_bufs[4][STRINGIFY_VAL_SIZE_MAX];
|
u8 val_bufs[4][STRINGIFY_VAL_SIZE_MAX];
|
||||||
#define IB(i) val_bufs[(i)], sizeof(val_bufs[(i)])
|
#define IB(i) val_bufs[(i)], sizeof(val_bufs[(i)])
|
||||||
|
|
||||||
if (afl->total_cal_cycles) avg_us = afl->total_cal_us / afl->total_cal_cycles;
|
if (afl->total_cal_cycles) {
|
||||||
|
|
||||||
|
avg_us = afl->total_cal_us / afl->total_cal_cycles;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
while (q) {
|
while (q) {
|
||||||
|
|
||||||
if (!min_us || q->exec_us < min_us) min_us = q->exec_us;
|
if (!min_us || q->exec_us < min_us) { min_us = q->exec_us; }
|
||||||
if (q->exec_us > max_us) max_us = q->exec_us;
|
if (q->exec_us > max_us) { max_us = q->exec_us; }
|
||||||
|
|
||||||
if (!min_bits || q->bitmap_size < min_bits) min_bits = q->bitmap_size;
|
if (!min_bits || q->bitmap_size < min_bits) { min_bits = q->bitmap_size; }
|
||||||
if (q->bitmap_size > max_bits) max_bits = q->bitmap_size;
|
if (q->bitmap_size > max_bits) { max_bits = q->bitmap_size; }
|
||||||
|
|
||||||
if (q->len > max_len) max_len = q->len;
|
if (q->len > max_len) { max_len = q->len; }
|
||||||
|
|
||||||
q = q->next;
|
q = q->next;
|
||||||
|
|
||||||
@ -847,38 +905,61 @@ void show_init_stats(afl_state_t *afl) {
|
|||||||
|
|
||||||
SAYF("\n");
|
SAYF("\n");
|
||||||
|
|
||||||
if (avg_us > ((afl->fsrv.qemu_mode || afl->unicorn_mode) ? 50000 : 10000))
|
if (avg_us > ((afl->fsrv.qemu_mode || afl->unicorn_mode) ? 50000 : 10000)) {
|
||||||
|
|
||||||
WARNF(cLRD "The target binary is pretty slow! See %s/perf_tips.md.",
|
WARNF(cLRD "The target binary is pretty slow! See %s/perf_tips.md.",
|
||||||
doc_path);
|
doc_path);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Let's keep things moving with slow binaries. */
|
/* Let's keep things moving with slow binaries. */
|
||||||
|
|
||||||
if (avg_us > 50000)
|
if (avg_us > 50000) {
|
||||||
|
|
||||||
afl->havoc_div = 10; /* 0-19 execs/sec */
|
afl->havoc_div = 10; /* 0-19 execs/sec */
|
||||||
else if (avg_us > 20000)
|
|
||||||
|
} else if (avg_us > 20000) {
|
||||||
|
|
||||||
afl->havoc_div = 5; /* 20-49 execs/sec */
|
afl->havoc_div = 5; /* 20-49 execs/sec */
|
||||||
else if (avg_us > 10000)
|
|
||||||
|
} else if (avg_us > 10000) {
|
||||||
|
|
||||||
afl->havoc_div = 2; /* 50-100 execs/sec */
|
afl->havoc_div = 2; /* 50-100 execs/sec */
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!afl->resuming_fuzz) {
|
if (!afl->resuming_fuzz) {
|
||||||
|
|
||||||
if (max_len > 50 * 1024)
|
if (max_len > 50 * 1024) {
|
||||||
|
|
||||||
WARNF(cLRD "Some test cases are huge (%s) - see %s/perf_tips.md!",
|
WARNF(cLRD "Some test cases are huge (%s) - see %s/perf_tips.md!",
|
||||||
stringify_mem_size(IB(0), max_len), doc_path);
|
stringify_mem_size(IB(0), max_len), doc_path);
|
||||||
else if (max_len > 10 * 1024)
|
|
||||||
|
} else if (max_len > 10 * 1024) {
|
||||||
|
|
||||||
WARNF("Some test cases are big (%s) - see %s/perf_tips.md.",
|
WARNF("Some test cases are big (%s) - see %s/perf_tips.md.",
|
||||||
stringify_mem_size(IB(0), max_len), doc_path);
|
stringify_mem_size(IB(0), max_len), doc_path);
|
||||||
|
|
||||||
if (afl->useless_at_start && !afl->in_bitmap)
|
}
|
||||||
|
|
||||||
|
if (afl->useless_at_start && !afl->in_bitmap) {
|
||||||
|
|
||||||
WARNF(cLRD "Some test cases look useless. Consider using a smaller set.");
|
WARNF(cLRD "Some test cases look useless. Consider using a smaller set.");
|
||||||
|
|
||||||
if (afl->queued_paths > 100)
|
}
|
||||||
|
|
||||||
|
if (afl->queued_paths > 100) {
|
||||||
|
|
||||||
WARNF(cLRD
|
WARNF(cLRD
|
||||||
"You probably have far too many input files! Consider trimming "
|
"You probably have far too many input files! Consider trimming "
|
||||||
"down.");
|
"down.");
|
||||||
else if (afl->queued_paths > 20)
|
|
||||||
|
} else if (afl->queued_paths > 20) {
|
||||||
|
|
||||||
WARNF("You have lots of input files; try starting small.");
|
WARNF("You have lots of input files; try starting small.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
OKF("Here are some useful stats:\n\n"
|
OKF("Here are some useful stats:\n\n"
|
||||||
@ -903,20 +984,30 @@ void show_init_stats(afl_state_t *afl) {
|
|||||||
random scheduler jitter is less likely to have any impact, and because
|
random scheduler jitter is less likely to have any impact, and because
|
||||||
our patience is wearing thin =) */
|
our patience is wearing thin =) */
|
||||||
|
|
||||||
if (avg_us > 50000)
|
if (avg_us > 50000) {
|
||||||
|
|
||||||
afl->fsrv.exec_tmout = avg_us * 2 / 1000;
|
afl->fsrv.exec_tmout = avg_us * 2 / 1000;
|
||||||
else if (avg_us > 10000)
|
|
||||||
|
} else if (avg_us > 10000) {
|
||||||
|
|
||||||
afl->fsrv.exec_tmout = avg_us * 3 / 1000;
|
afl->fsrv.exec_tmout = avg_us * 3 / 1000;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->fsrv.exec_tmout = avg_us * 5 / 1000;
|
afl->fsrv.exec_tmout = avg_us * 5 / 1000;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->fsrv.exec_tmout = MAX(afl->fsrv.exec_tmout, max_us / 1000);
|
afl->fsrv.exec_tmout = MAX(afl->fsrv.exec_tmout, max_us / 1000);
|
||||||
afl->fsrv.exec_tmout =
|
afl->fsrv.exec_tmout =
|
||||||
(afl->fsrv.exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND;
|
(afl->fsrv.exec_tmout + EXEC_TM_ROUND) / EXEC_TM_ROUND * EXEC_TM_ROUND;
|
||||||
|
|
||||||
if (afl->fsrv.exec_tmout > EXEC_TIMEOUT)
|
if (afl->fsrv.exec_tmout > EXEC_TIMEOUT) {
|
||||||
|
|
||||||
afl->fsrv.exec_tmout = EXEC_TIMEOUT;
|
afl->fsrv.exec_tmout = EXEC_TIMEOUT;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ACTF("No -t option specified, so I'll use exec timeout of %u ms.",
|
ACTF("No -t option specified, so I'll use exec timeout of %u ms.",
|
||||||
afl->fsrv.exec_tmout);
|
afl->fsrv.exec_tmout);
|
||||||
|
|
||||||
@ -932,9 +1023,12 @@ void show_init_stats(afl_state_t *afl) {
|
|||||||
/* In dumb mode, re-running every timing out test case with a generous time
|
/* In dumb mode, re-running every timing out test case with a generous time
|
||||||
limit is very expensive, so let's select a more conservative default. */
|
limit is very expensive, so let's select a more conservative default. */
|
||||||
|
|
||||||
if (afl->dumb_mode && !(afl->afl_env.afl_hang_tmout))
|
if (afl->dumb_mode && !(afl->afl_env.afl_hang_tmout)) {
|
||||||
|
|
||||||
afl->hang_tmout = MIN(EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100);
|
afl->hang_tmout = MIN(EXEC_TIMEOUT, afl->fsrv.exec_tmout * 2 + 100);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OKF("All set and ready to roll!");
|
OKF("All set and ready to roll!");
|
||||||
#undef IB
|
#undef IB
|
||||||
|
|
||||||
|
435
src/afl-fuzz.c
435
src/afl-fuzz.c
@ -37,7 +37,7 @@ static u8 *get_libradamsa_path(u8 *own_loc) {
|
|||||||
|
|
||||||
cp = alloc_printf("%s/libradamsa.so", tmp);
|
cp = alloc_printf("%s/libradamsa.so", tmp);
|
||||||
|
|
||||||
if (access(cp, X_OK)) FATAL("Unable to find '%s'", cp);
|
if (access(cp, X_OK)) { FATAL("Unable to find '%s'", cp); }
|
||||||
|
|
||||||
return cp;
|
return cp;
|
||||||
|
|
||||||
@ -53,12 +53,14 @@ static u8 *get_libradamsa_path(u8 *own_loc) {
|
|||||||
cp = alloc_printf("%s/libradamsa.so", own_copy);
|
cp = alloc_printf("%s/libradamsa.so", own_copy);
|
||||||
ck_free(own_copy);
|
ck_free(own_copy);
|
||||||
|
|
||||||
if (!access(cp, X_OK)) return cp;
|
if (!access(cp, X_OK)) { return cp; }
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
ck_free(own_copy);
|
ck_free(own_copy);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!access(AFL_PATH "/libradamsa.so", X_OK)) {
|
if (!access(AFL_PATH "/libradamsa.so", X_OK)) {
|
||||||
|
|
||||||
return ck_strdup(AFL_PATH "/libradamsa.so");
|
return ck_strdup(AFL_PATH "/libradamsa.so");
|
||||||
@ -148,7 +150,8 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
|||||||
"case\n\n",
|
"case\n\n",
|
||||||
argv0, EXEC_TIMEOUT, MEM_LIMIT);
|
argv0, EXEC_TIMEOUT, MEM_LIMIT);
|
||||||
|
|
||||||
if (more_help > 1)
|
if (more_help > 1) {
|
||||||
|
|
||||||
SAYF(
|
SAYF(
|
||||||
"Environment variables used:\n"
|
"Environment variables used:\n"
|
||||||
"LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
|
"LD_BIND_LAZY: do not set LD_BIND_NOW env var for target\n"
|
||||||
@ -193,11 +196,15 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
|||||||
//"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n"
|
//"AFL_DEFER_FORKSRV: not supported anymore -> no effect, just a warning\n"
|
||||||
"\n"
|
"\n"
|
||||||
);
|
);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
SAYF(
|
SAYF(
|
||||||
"To view also the supported environment variables of afl-fuzz please "
|
"To view also the supported environment variables of afl-fuzz please "
|
||||||
"use \"-hh\".\n\n");
|
"use \"-hh\".\n\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#ifdef USE_PYTHON
|
#ifdef USE_PYTHON
|
||||||
SAYF("Compiled with %s module support, see docs/custom_mutator.md\n",
|
SAYF("Compiled with %s module support, see docs/custom_mutator.md\n",
|
||||||
(char *)PYTHON_VERSION);
|
(char *)PYTHON_VERSION);
|
||||||
@ -216,13 +223,13 @@ static void usage(afl_state_t *afl, u8 *argv0, int more_help) {
|
|||||||
|
|
||||||
static int stricmp(char const *a, char const *b) {
|
static int stricmp(char const *a, char const *b) {
|
||||||
|
|
||||||
if (!a || !b) FATAL("Null reference");
|
if (!a || !b) { FATAL("Null reference"); }
|
||||||
|
|
||||||
for (;; ++a, ++b) {
|
for (;; ++a, ++b) {
|
||||||
|
|
||||||
int d;
|
int d;
|
||||||
d = tolower(*a) - tolower(*b);
|
d = tolower(*a) - tolower(*b);
|
||||||
if (d != 0 || !*a) return d;
|
if (d != 0 || !*a) { return d; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -247,14 +254,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl_state_t *afl = calloc(1, sizeof(afl_state_t));
|
afl_state_t *afl = calloc(1, sizeof(afl_state_t));
|
||||||
if (!afl) { FATAL("Could not create afl state"); }
|
if (!afl) { FATAL("Could not create afl state"); }
|
||||||
|
|
||||||
if (get_afl_env("AFL_DEBUG")) afl->debug = 1;
|
if (get_afl_env("AFL_DEBUG")) { afl->debug = 1; }
|
||||||
|
|
||||||
map_size = get_map_size();
|
map_size = get_map_size();
|
||||||
afl_state_init(afl, map_size);
|
afl_state_init(afl, map_size);
|
||||||
afl_fsrv_init(&afl->fsrv);
|
afl_fsrv_init(&afl->fsrv);
|
||||||
|
|
||||||
read_afl_environment(afl, envp);
|
read_afl_environment(afl, envp);
|
||||||
if (afl->shm.map_size) afl->fsrv.map_size = afl->shm.map_size;
|
if (afl->shm.map_size) { afl->fsrv.map_size = afl->shm.map_size; }
|
||||||
exit_1 = !!afl->afl_env.afl_bench_just_one;
|
exit_1 = !!afl->afl_env.afl_bench_just_one;
|
||||||
|
|
||||||
SAYF(cCYA "afl-fuzz" VERSION cRST
|
SAYF(cCYA "afl-fuzz" VERSION cRST
|
||||||
@ -266,11 +273,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
|
afl->init_seed = tv.tv_sec ^ tv.tv_usec ^ getpid();
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv,
|
while ((opt = getopt(argc, argv,
|
||||||
"+c:i:I:o:f:m:t:T:dnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) > 0)
|
"+c:i:I:o:f:m:t:T:dnCB:S:M:x:QNUWe:p:s:V:E:L:hRP:")) >
|
||||||
|
0) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
case 'I': afl->infoexec = optarg; break;
|
case 'I':
|
||||||
|
afl->infoexec = optarg;
|
||||||
|
break;
|
||||||
|
|
||||||
case 'c': {
|
case 'c': {
|
||||||
|
|
||||||
@ -334,7 +344,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
|
|
||||||
if (afl->file_extension) FATAL("Multiple -e options not supported");
|
if (afl->file_extension) { FATAL("Multiple -e options not supported"); }
|
||||||
|
|
||||||
afl->file_extension = optarg;
|
afl->file_extension = optarg;
|
||||||
|
|
||||||
@ -342,16 +352,16 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
case 'i': /* input dir */
|
case 'i': /* input dir */
|
||||||
|
|
||||||
if (afl->in_dir) FATAL("Multiple -i options not supported");
|
if (afl->in_dir) { FATAL("Multiple -i options not supported"); }
|
||||||
afl->in_dir = optarg;
|
afl->in_dir = optarg;
|
||||||
|
|
||||||
if (!strcmp(afl->in_dir, "-")) afl->in_place_resume = 1;
|
if (!strcmp(afl->in_dir, "-")) { afl->in_place_resume = 1; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o': /* output dir */
|
case 'o': /* output dir */
|
||||||
|
|
||||||
if (afl->out_dir) FATAL("Multiple -o options not supported");
|
if (afl->out_dir) { FATAL("Multiple -o options not supported"); }
|
||||||
afl->out_dir = optarg;
|
afl->out_dir = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -359,7 +369,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u8 *c;
|
u8 *c;
|
||||||
|
|
||||||
if (afl->sync_id) FATAL("Multiple -S or -M options not supported");
|
if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
|
||||||
afl->sync_id = ck_strdup(optarg);
|
afl->sync_id = ck_strdup(optarg);
|
||||||
|
|
||||||
if ((c = strchr(afl->sync_id, ':'))) {
|
if ((c = strchr(afl->sync_id, ':'))) {
|
||||||
@ -368,9 +378,12 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 ||
|
if (sscanf(c + 1, "%u/%u", &afl->master_id, &afl->master_max) != 2 ||
|
||||||
!afl->master_id || !afl->master_max ||
|
!afl->master_id || !afl->master_max ||
|
||||||
afl->master_id > afl->master_max || afl->master_max > 1000000)
|
afl->master_id > afl->master_max || afl->master_max > 1000000) {
|
||||||
|
|
||||||
FATAL("Bogus master ID passed to -M");
|
FATAL("Bogus master ID passed to -M");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
afl->force_deterministic = 1;
|
afl->force_deterministic = 1;
|
||||||
@ -381,20 +394,20 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
|
|
||||||
if (afl->sync_id) FATAL("Multiple -S or -M options not supported");
|
if (afl->sync_id) { FATAL("Multiple -S or -M options not supported"); }
|
||||||
afl->sync_id = ck_strdup(optarg);
|
afl->sync_id = ck_strdup(optarg);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f': /* target file */
|
case 'f': /* target file */
|
||||||
|
|
||||||
if (afl->fsrv.out_file) FATAL("Multiple -f options not supported");
|
if (afl->fsrv.out_file) { FATAL("Multiple -f options not supported"); }
|
||||||
afl->fsrv.out_file = ck_strdup(optarg);
|
afl->fsrv.out_file = ck_strdup(optarg);
|
||||||
afl->fsrv.use_stdin = 0;
|
afl->fsrv.use_stdin = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x': /* dictionary */
|
case 'x': /* dictionary */
|
||||||
|
|
||||||
if (extras_dir) FATAL("Multiple -x options not supported");
|
if (extras_dir) { FATAL("Multiple -x options not supported"); }
|
||||||
extras_dir = optarg;
|
extras_dir = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -402,19 +415,27 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u8 suffix = 0;
|
u8 suffix = 0;
|
||||||
|
|
||||||
if (afl->timeout_given) FATAL("Multiple -t options not supported");
|
if (afl->timeout_given) { FATAL("Multiple -t options not supported"); }
|
||||||
|
|
||||||
if (sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 ||
|
if (sscanf(optarg, "%u%c", &afl->fsrv.exec_tmout, &suffix) < 1 ||
|
||||||
optarg[0] == '-')
|
optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -t");
|
FATAL("Bad syntax used for -t");
|
||||||
|
|
||||||
if (afl->fsrv.exec_tmout < 5) FATAL("Dangerously low value of -t");
|
}
|
||||||
|
|
||||||
|
if (afl->fsrv.exec_tmout < 5) { FATAL("Dangerously low value of -t"); }
|
||||||
|
|
||||||
|
if (suffix == '+') {
|
||||||
|
|
||||||
if (suffix == '+')
|
|
||||||
afl->timeout_given = 2;
|
afl->timeout_given = 2;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->timeout_given = 1;
|
afl->timeout_given = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -423,10 +444,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u8 suffix = 'M';
|
u8 suffix = 'M';
|
||||||
|
|
||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
if (!optarg) FATAL("Wrong usage of -m");
|
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
|
|
||||||
@ -436,32 +457,51 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(optarg, "%llu%c", &afl->fsrv.mem_limit, &suffix) < 1 ||
|
if (sscanf(optarg, "%llu%c", &afl->fsrv.mem_limit, &suffix) < 1 ||
|
||||||
optarg[0] == '-')
|
optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -m");
|
FATAL("Bad syntax used for -m");
|
||||||
|
|
||||||
switch (suffix) {
|
|
||||||
|
|
||||||
case 'T': afl->fsrv.mem_limit *= 1024 * 1024; break;
|
|
||||||
case 'G': afl->fsrv.mem_limit *= 1024; break;
|
|
||||||
case 'k': afl->fsrv.mem_limit /= 1024; break;
|
|
||||||
case 'M': break;
|
|
||||||
|
|
||||||
default: FATAL("Unsupported suffix or bad syntax for -m");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->fsrv.mem_limit < 5) FATAL("Dangerously low value of -m");
|
switch (suffix) {
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
afl->fsrv.mem_limit *= 1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
afl->fsrv.mem_limit *= 1024;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
afl->fsrv.mem_limit /= 1024;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FATAL("Unsupported suffix or bad syntax for -m");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (afl->fsrv.mem_limit < 5) { FATAL("Dangerously low value of -m"); }
|
||||||
|
|
||||||
|
if (sizeof(rlim_t) == 4 && afl->fsrv.mem_limit > 2000) {
|
||||||
|
|
||||||
if (sizeof(rlim_t) == 4 && afl->fsrv.mem_limit > 2000)
|
|
||||||
FATAL("Value of -m out of range on 32-bit systems");
|
FATAL("Value of -m out of range on 32-bit systems");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'd': /* skip deterministic */
|
case 'd': /* skip deterministic */
|
||||||
|
|
||||||
if (afl->skip_deterministic) FATAL("Multiple -d options not supported");
|
if (afl->skip_deterministic) {
|
||||||
|
|
||||||
|
FATAL("Multiple -d options not supported");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->skip_deterministic = 1;
|
afl->skip_deterministic = 1;
|
||||||
afl->use_splicing = 1;
|
afl->use_splicing = 1;
|
||||||
break;
|
break;
|
||||||
@ -479,7 +519,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
I only used this once or twice to get variants of a particular
|
I only used this once or twice to get variants of a particular
|
||||||
file, so I'm not making this an official setting. */
|
file, so I'm not making this an official setting. */
|
||||||
|
|
||||||
if (afl->in_bitmap) FATAL("Multiple -B options not supported");
|
if (afl->in_bitmap) { FATAL("Multiple -B options not supported"); }
|
||||||
|
|
||||||
afl->in_bitmap = optarg;
|
afl->in_bitmap = optarg;
|
||||||
read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size);
|
read_bitmap(afl->in_bitmap, afl->virgin_bits, afl->fsrv.map_size);
|
||||||
@ -487,85 +527,99 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
case 'C': /* crash mode */
|
case 'C': /* crash mode */
|
||||||
|
|
||||||
if (afl->crash_mode) FATAL("Multiple -C options not supported");
|
if (afl->crash_mode) { FATAL("Multiple -C options not supported"); }
|
||||||
afl->crash_mode = FSRV_RUN_CRASH;
|
afl->crash_mode = FSRV_RUN_CRASH;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'n': /* dumb mode */
|
case 'n': /* dumb mode */
|
||||||
|
|
||||||
if (afl->dumb_mode) FATAL("Multiple -n options not supported");
|
if (afl->dumb_mode) { FATAL("Multiple -n options not supported"); }
|
||||||
if (afl->afl_env.afl_dumb_forksrv)
|
if (afl->afl_env.afl_dumb_forksrv) {
|
||||||
|
|
||||||
afl->dumb_mode = 2;
|
afl->dumb_mode = 2;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->dumb_mode = 1;
|
afl->dumb_mode = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'T': /* banner */
|
case 'T': /* banner */
|
||||||
|
|
||||||
if (afl->use_banner) FATAL("Multiple -T options not supported");
|
if (afl->use_banner) { FATAL("Multiple -T options not supported"); }
|
||||||
afl->use_banner = optarg;
|
afl->use_banner = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Q': /* QEMU mode */
|
case 'Q': /* QEMU mode */
|
||||||
|
|
||||||
if (afl->fsrv.qemu_mode) FATAL("Multiple -Q options not supported");
|
if (afl->fsrv.qemu_mode) { FATAL("Multiple -Q options not supported"); }
|
||||||
afl->fsrv.qemu_mode = 1;
|
afl->fsrv.qemu_mode = 1;
|
||||||
|
|
||||||
if (!mem_limit_given) afl->fsrv.mem_limit = MEM_LIMIT_QEMU;
|
if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_QEMU; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'N': /* Unicorn mode */
|
case 'N': /* Unicorn mode */
|
||||||
|
|
||||||
if (afl->no_unlink) FATAL("Multiple -N options not supported");
|
if (afl->no_unlink) { FATAL("Multiple -N options not supported"); }
|
||||||
afl->no_unlink = 1;
|
afl->no_unlink = 1;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U': /* Unicorn mode */
|
case 'U': /* Unicorn mode */
|
||||||
|
|
||||||
if (afl->unicorn_mode) FATAL("Multiple -U options not supported");
|
if (afl->unicorn_mode) { FATAL("Multiple -U options not supported"); }
|
||||||
afl->unicorn_mode = 1;
|
afl->unicorn_mode = 1;
|
||||||
|
|
||||||
if (!mem_limit_given) afl->fsrv.mem_limit = MEM_LIMIT_UNICORN;
|
if (!mem_limit_given) { afl->fsrv.mem_limit = MEM_LIMIT_UNICORN; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W': /* Wine+QEMU mode */
|
case 'W': /* Wine+QEMU mode */
|
||||||
|
|
||||||
if (afl->use_wine) FATAL("Multiple -W options not supported");
|
if (afl->use_wine) { FATAL("Multiple -W options not supported"); }
|
||||||
afl->fsrv.qemu_mode = 1;
|
afl->fsrv.qemu_mode = 1;
|
||||||
afl->use_wine = 1;
|
afl->use_wine = 1;
|
||||||
|
|
||||||
if (!mem_limit_given) afl->fsrv.mem_limit = 0;
|
if (!mem_limit_given) { afl->fsrv.mem_limit = 0; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'V': {
|
case 'V': {
|
||||||
|
|
||||||
afl->most_time_key = 1;
|
afl->most_time_key = 1;
|
||||||
if (sscanf(optarg, "%llu", &afl->most_time) < 1 || optarg[0] == '-')
|
if (sscanf(optarg, "%llu", &afl->most_time) < 1 || optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -V");
|
FATAL("Bad syntax used for -V");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'E': {
|
case 'E': {
|
||||||
|
|
||||||
afl->most_execs_key = 1;
|
afl->most_execs_key = 1;
|
||||||
if (sscanf(optarg, "%llu", &afl->most_execs) < 1 || optarg[0] == '-')
|
if (sscanf(optarg, "%llu", &afl->most_execs) < 1 || optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -E");
|
FATAL("Bad syntax used for -E");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'L': { /* MOpt mode */
|
case 'L': { /* MOpt mode */
|
||||||
|
|
||||||
if (afl->limit_time_sig) FATAL("Multiple -L options not supported");
|
if (afl->limit_time_sig) { FATAL("Multiple -L options not supported"); }
|
||||||
afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT;
|
afl->havoc_max_mult = HAVOC_MAX_MULT_MOPT;
|
||||||
|
|
||||||
if (sscanf(optarg, "%d", &afl->limit_time_puppet) < 1)
|
if (sscanf(optarg, "%d", &afl->limit_time_puppet) < 1) {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -L");
|
FATAL("Bad syntax used for -L");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (afl->limit_time_puppet == -1) {
|
if (afl->limit_time_puppet == -1) {
|
||||||
|
|
||||||
afl->limit_time_sig = -1;
|
afl->limit_time_sig = -1;
|
||||||
@ -583,19 +637,23 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000;
|
u64 limit_time_puppet2 = afl->limit_time_puppet * 60 * 1000;
|
||||||
|
|
||||||
if (limit_time_puppet2 < afl->limit_time_puppet)
|
if (limit_time_puppet2 < afl->limit_time_puppet) {
|
||||||
|
|
||||||
FATAL("limit_time overflow");
|
FATAL("limit_time overflow");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->limit_time_puppet = limit_time_puppet2;
|
afl->limit_time_puppet = limit_time_puppet2;
|
||||||
|
|
||||||
SAYF("limit_time_puppet %d\n", afl->limit_time_puppet);
|
SAYF("limit_time_puppet %d\n", afl->limit_time_puppet);
|
||||||
afl->swarm_now = 0;
|
afl->swarm_now = 0;
|
||||||
|
|
||||||
if (afl->limit_time_puppet == 0) afl->key_puppet = 1;
|
if (afl->limit_time_puppet == 0) { afl->key_puppet = 1; }
|
||||||
|
|
||||||
int i;
|
int i;
|
||||||
int tmp_swarm = 0;
|
int tmp_swarm = 0;
|
||||||
|
|
||||||
if (afl->g_now > afl->g_max) afl->g_now = 0;
|
if (afl->g_now > afl->g_max) { afl->g_now = 0; }
|
||||||
afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) /
|
afl->w_now = (afl->w_init - afl->w_end) * (afl->g_max - afl->g_now) /
|
||||||
(afl->g_max) +
|
(afl->g_max) +
|
||||||
afl->w_end;
|
afl->w_end;
|
||||||
@ -643,11 +701,16 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
afl->x_now[tmp_swarm][i] += afl->v_now[tmp_swarm][i];
|
afl->x_now[tmp_swarm][i] += afl->v_now[tmp_swarm][i];
|
||||||
|
|
||||||
if (afl->x_now[tmp_swarm][i] > v_max)
|
if (afl->x_now[tmp_swarm][i] > v_max) {
|
||||||
|
|
||||||
afl->x_now[tmp_swarm][i] = v_max;
|
afl->x_now[tmp_swarm][i] = v_max;
|
||||||
else if (afl->x_now[tmp_swarm][i] < v_min)
|
|
||||||
|
} else if (afl->x_now[tmp_swarm][i] < v_min) {
|
||||||
|
|
||||||
afl->x_now[tmp_swarm][i] = v_min;
|
afl->x_now[tmp_swarm][i] = v_min;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
x_temp += afl->x_now[tmp_swarm][i];
|
x_temp += afl->x_now[tmp_swarm][i];
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -655,19 +718,27 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
for (i = 0; i < operator_num; ++i) {
|
for (i = 0; i < operator_num; ++i) {
|
||||||
|
|
||||||
afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / x_temp;
|
afl->x_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i] / x_temp;
|
||||||
if (likely(i != 0))
|
if (likely(i != 0)) {
|
||||||
|
|
||||||
afl->probability_now[tmp_swarm][i] =
|
afl->probability_now[tmp_swarm][i] =
|
||||||
afl->probability_now[tmp_swarm][i - 1] +
|
afl->probability_now[tmp_swarm][i - 1] +
|
||||||
afl->x_now[tmp_swarm][i];
|
afl->x_now[tmp_swarm][i];
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->probability_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i];
|
afl->probability_now[tmp_swarm][i] = afl->x_now[tmp_swarm][i];
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->probability_now[tmp_swarm][operator_num - 1] < 0.99 ||
|
if (afl->probability_now[tmp_swarm][operator_num - 1] < 0.99 ||
|
||||||
afl->probability_now[tmp_swarm][operator_num - 1] > 1.01)
|
afl->probability_now[tmp_swarm][operator_num - 1] > 1.01) {
|
||||||
|
|
||||||
FATAL("ERROR probability");
|
FATAL("ERROR probability");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = 0; i < operator_num; ++i) {
|
for (i = 0; i < operator_num; ++i) {
|
||||||
@ -682,25 +753,37 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
} break;
|
} break;
|
||||||
|
|
||||||
case 'h': show_help++; break; // not needed
|
case 'h':
|
||||||
|
show_help++;
|
||||||
|
break; // not needed
|
||||||
|
|
||||||
case 'R':
|
case 'R':
|
||||||
|
|
||||||
if (afl->use_radamsa)
|
if (afl->use_radamsa) {
|
||||||
|
|
||||||
afl->use_radamsa = 2;
|
afl->use_radamsa = 2;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->use_radamsa = 1;
|
afl->use_radamsa = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (!show_help) show_help = 1;
|
if (!show_help) { show_help = 1; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind == argc || !afl->in_dir || !afl->out_dir || show_help)
|
}
|
||||||
|
|
||||||
|
if (optind == argc || !afl->in_dir || !afl->out_dir || show_help) {
|
||||||
|
|
||||||
usage(afl, argv[0], show_help);
|
usage(afl, argv[0], show_help);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
|
OKF("afl++ is maintained by Marc \"van Hauser\" Heuse, Heiko \"hexcoder\" "
|
||||||
"Eißfeldt, Andrea Fioraldi and Dominik Maier");
|
"Eißfeldt, Andrea Fioraldi and Dominik Maier");
|
||||||
OKF("afl++ is open source, get it at "
|
OKF("afl++ is open source, get it at "
|
||||||
@ -711,40 +794,57 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL");
|
OKF("MOpt Mutator from github.com/puppet-meteor/MOpt-AFL");
|
||||||
|
|
||||||
if (afl->sync_id && afl->force_deterministic &&
|
if (afl->sync_id && afl->force_deterministic &&
|
||||||
afl->afl_env.afl_custom_mutator_only)
|
afl->afl_env.afl_custom_mutator_only) {
|
||||||
|
|
||||||
WARNF(
|
WARNF(
|
||||||
"Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will "
|
"Using -M master with the AFL_CUSTOM_MUTATOR_ONLY mutator options will "
|
||||||
"result in no deterministic mutations being done!");
|
"result in no deterministic mutations being done!");
|
||||||
|
|
||||||
if (afl->fixed_seed) OKF("Running with fixed seed: %u", (u32)afl->init_seed);
|
}
|
||||||
|
|
||||||
|
if (afl->fixed_seed) {
|
||||||
|
|
||||||
|
OKF("Running with fixed seed: %u", (u32)afl->init_seed);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
srandom((u32)afl->init_seed);
|
srandom((u32)afl->init_seed);
|
||||||
srand((u32)afl->init_seed); // in case it is a different implementation
|
srand((u32)afl->init_seed); // in case it is a different implementation
|
||||||
|
|
||||||
if (afl->use_radamsa) {
|
if (afl->use_radamsa) {
|
||||||
|
|
||||||
if (afl->limit_time_sig > 0)
|
if (afl->limit_time_sig > 0) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"MOpt and Radamsa are mutually exclusive unless you specify -L -1. "
|
"MOpt and Radamsa are mutually exclusive unless you specify -L -1. "
|
||||||
"We accept pull requests that integrates MOpt with the optional "
|
"We accept pull requests that integrates MOpt with the optional "
|
||||||
"mutators (custom/radamsa/redqueen/...).");
|
"mutators (custom/radamsa/redqueen/...).");
|
||||||
|
|
||||||
if (afl->limit_time_sig && afl->use_radamsa > 1)
|
}
|
||||||
|
|
||||||
|
if (afl->limit_time_sig && afl->use_radamsa > 1) {
|
||||||
|
|
||||||
FATAL("Radamsa in radamsa-only mode can not run together with -L");
|
FATAL("Radamsa in radamsa-only mode can not run together with -L");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
OKF("Using Radamsa add-on");
|
OKF("Using Radamsa add-on");
|
||||||
|
|
||||||
u8 * libradamsa_path = get_libradamsa_path(argv[0]);
|
u8 * libradamsa_path = get_libradamsa_path(argv[0]);
|
||||||
void *handle = dlopen(libradamsa_path, RTLD_NOW);
|
void *handle = dlopen(libradamsa_path, RTLD_NOW);
|
||||||
ck_free(libradamsa_path);
|
ck_free(libradamsa_path);
|
||||||
|
|
||||||
if (!handle) FATAL("Failed to dlopen() libradamsa");
|
if (!handle) { FATAL("Failed to dlopen() libradamsa"); }
|
||||||
|
|
||||||
void (*radamsa_init_ptr)(void) = dlsym(handle, "radamsa_init");
|
void (*radamsa_init_ptr)(void) = dlsym(handle, "radamsa_init");
|
||||||
afl->radamsa_mutate_ptr = dlsym(handle, "radamsa");
|
afl->radamsa_mutate_ptr = dlsym(handle, "radamsa");
|
||||||
|
|
||||||
if (!radamsa_init_ptr || !afl->radamsa_mutate_ptr)
|
if (!radamsa_init_ptr || !afl->radamsa_mutate_ptr) {
|
||||||
|
|
||||||
FATAL("Failed to dlsym() libradamsa");
|
FATAL("Failed to dlsym() libradamsa");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* randamsa_init installs some signal hadlers, call it before
|
/* randamsa_init installs some signal hadlers, call it before
|
||||||
setup_signal_handlers so that AFL++ can then replace those signal
|
setup_signal_handlers so that AFL++ can then replace those signal
|
||||||
handlers */
|
handlers */
|
||||||
@ -767,80 +867,113 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
afl->power_name = power_names[afl->schedule];
|
afl->power_name = power_names[afl->schedule];
|
||||||
|
|
||||||
if (afl->sync_id) fix_up_sync(afl);
|
if (afl->sync_id) { fix_up_sync(afl); }
|
||||||
|
|
||||||
|
if (!strcmp(afl->in_dir, afl->out_dir)) {
|
||||||
|
|
||||||
if (!strcmp(afl->in_dir, afl->out_dir))
|
|
||||||
FATAL("Input and output directories can't be the same");
|
FATAL("Input and output directories can't be the same");
|
||||||
|
|
||||||
if (afl->dumb_mode) {
|
|
||||||
|
|
||||||
if (afl->crash_mode) FATAL("-C and -n are mutually exclusive");
|
|
||||||
if (afl->fsrv.qemu_mode) FATAL("-Q and -n are mutually exclusive");
|
|
||||||
if (afl->unicorn_mode) FATAL("-U and -n are mutually exclusive");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_afl_env("AFL_DISABLE_TRIM")) afl->disable_trim = 1;
|
if (afl->dumb_mode) {
|
||||||
|
|
||||||
|
if (afl->crash_mode) { FATAL("-C and -n are mutually exclusive"); }
|
||||||
|
if (afl->fsrv.qemu_mode) { FATAL("-Q and -n are mutually exclusive"); }
|
||||||
|
if (afl->unicorn_mode) { FATAL("-U and -n are mutually exclusive"); }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (get_afl_env("AFL_DISABLE_TRIM")) { afl->disable_trim = 1; }
|
||||||
|
|
||||||
|
if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI")) {
|
||||||
|
|
||||||
if (getenv("AFL_NO_UI") && getenv("AFL_FORCE_UI"))
|
|
||||||
FATAL("AFL_NO_UI and AFL_FORCE_UI are mutually exclusive");
|
FATAL("AFL_NO_UI and AFL_FORCE_UI are mutually exclusive");
|
||||||
|
|
||||||
if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode)
|
}
|
||||||
|
|
||||||
|
if (strchr(argv[optind], '/') == NULL && !afl->unicorn_mode) {
|
||||||
|
|
||||||
WARNF(cLRD
|
WARNF(cLRD
|
||||||
"Target binary called without a prefixed path, make sure you are "
|
"Target binary called without a prefixed path, make sure you are "
|
||||||
"fuzzing the right binary: " cRST "%s",
|
"fuzzing the right binary: " cRST "%s",
|
||||||
argv[optind]);
|
argv[optind]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ACTF("Getting to work...");
|
ACTF("Getting to work...");
|
||||||
|
|
||||||
switch (afl->schedule) {
|
switch (afl->schedule) {
|
||||||
|
|
||||||
case FAST: OKF("Using exponential power schedule (FAST)"); break;
|
case FAST:
|
||||||
case COE: OKF("Using cut-off exponential power schedule (COE)"); break;
|
OKF("Using exponential power schedule (FAST)");
|
||||||
|
break;
|
||||||
|
case COE:
|
||||||
|
OKF("Using cut-off exponential power schedule (COE)");
|
||||||
|
break;
|
||||||
case EXPLOIT:
|
case EXPLOIT:
|
||||||
OKF("Using exploitation-based constant power schedule (EXPLOIT)");
|
OKF("Using exploitation-based constant power schedule (EXPLOIT)");
|
||||||
break;
|
break;
|
||||||
case LIN: OKF("Using linear power schedule (LIN)"); break;
|
case LIN:
|
||||||
case QUAD: OKF("Using quadratic power schedule (QUAD)"); break;
|
OKF("Using linear power schedule (LIN)");
|
||||||
case MMOPT: OKF("Using modified MOpt power schedule (MMOPT)"); break;
|
break;
|
||||||
case RARE: OKF("Using rare edge focus power schedule (RARE)"); break;
|
case QUAD:
|
||||||
|
OKF("Using quadratic power schedule (QUAD)");
|
||||||
|
break;
|
||||||
|
case MMOPT:
|
||||||
|
OKF("Using modified MOpt power schedule (MMOPT)");
|
||||||
|
break;
|
||||||
|
case RARE:
|
||||||
|
OKF("Using rare edge focus power schedule (RARE)");
|
||||||
|
break;
|
||||||
case EXPLORE:
|
case EXPLORE:
|
||||||
OKF("Using exploration-based constant power schedule (EXPLORE, default)");
|
OKF("Using exploration-based constant power schedule (EXPLORE, default)");
|
||||||
break;
|
break;
|
||||||
default: FATAL("Unknown power schedule"); break;
|
default:
|
||||||
|
FATAL("Unknown power schedule");
|
||||||
|
break;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (get_afl_env("AFL_NO_FORKSRV")) afl->no_forkserver = 1;
|
if (get_afl_env("AFL_NO_FORKSRV")) { afl->no_forkserver = 1; }
|
||||||
if (get_afl_env("AFL_NO_CPU_RED")) afl->no_cpu_meter_red = 1;
|
if (get_afl_env("AFL_NO_CPU_RED")) { afl->no_cpu_meter_red = 1; }
|
||||||
if (get_afl_env("AFL_NO_ARITH")) afl->no_arith = 1;
|
if (get_afl_env("AFL_NO_ARITH")) { afl->no_arith = 1; }
|
||||||
if (get_afl_env("AFL_SHUFFLE_QUEUE")) afl->shuffle_queue = 1;
|
if (get_afl_env("AFL_SHUFFLE_QUEUE")) { afl->shuffle_queue = 1; }
|
||||||
if (get_afl_env("AFL_FAST_CAL")) afl->fast_cal = 1;
|
if (get_afl_env("AFL_FAST_CAL")) { afl->fast_cal = 1; }
|
||||||
|
|
||||||
if (afl->afl_env.afl_autoresume) {
|
if (afl->afl_env.afl_autoresume) {
|
||||||
|
|
||||||
afl->autoresume = 1;
|
afl->autoresume = 1;
|
||||||
if (afl->in_place_resume) SAYF("AFL_AUTORESUME has no effect for '-i -'");
|
if (afl->in_place_resume) {
|
||||||
|
|
||||||
|
SAYF("AFL_AUTORESUME has no effect for '-i -'");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->afl_env.afl_hang_tmout) {
|
if (afl->afl_env.afl_hang_tmout) {
|
||||||
|
|
||||||
afl->hang_tmout = atoi(afl->afl_env.afl_hang_tmout);
|
afl->hang_tmout = atoi(afl->afl_env.afl_hang_tmout);
|
||||||
if (!afl->hang_tmout) FATAL("Invalid value of AFL_HANG_TMOUT");
|
if (!afl->hang_tmout) { FATAL("Invalid value of AFL_HANG_TMOUT"); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (afl->dumb_mode == 2 && afl->no_forkserver)
|
if (afl->dumb_mode == 2 && afl->no_forkserver) {
|
||||||
|
|
||||||
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
|
FATAL("AFL_DUMB_FORKSRV and AFL_NO_FORKSRV are mutually exclusive");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
afl->fsrv.use_fauxsrv = afl->dumb_mode == 1 || afl->no_forkserver;
|
afl->fsrv.use_fauxsrv = afl->dumb_mode == 1 || afl->no_forkserver;
|
||||||
|
|
||||||
if (getenv("LD_PRELOAD"))
|
if (getenv("LD_PRELOAD")) {
|
||||||
|
|
||||||
WARNF(
|
WARNF(
|
||||||
"LD_PRELOAD is set, are you sure that is what to you want to do "
|
"LD_PRELOAD is set, are you sure that is what to you want to do "
|
||||||
"instead of using AFL_PRELOAD?");
|
"instead of using AFL_PRELOAD?");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (afl->afl_env.afl_preload) {
|
if (afl->afl_env.afl_preload) {
|
||||||
|
|
||||||
if (afl->fsrv.qemu_mode) {
|
if (afl->fsrv.qemu_mode) {
|
||||||
@ -852,20 +985,28 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',') {
|
||||||
|
|
||||||
PFATAL(
|
PFATAL(
|
||||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
"specified!");
|
"specified!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload) {
|
||||||
|
|
||||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
qemu_preload, afl_preload, afl_preload);
|
qemu_preload, afl_preload, afl_preload);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
afl_preload, afl_preload);
|
afl_preload, afl_preload);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
setenv("QEMU_SET_ENV", buf, 1);
|
setenv("QEMU_SET_ENV", buf, 1);
|
||||||
|
|
||||||
ck_free(buf);
|
ck_free(buf);
|
||||||
@ -879,15 +1020,18 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (getenv("AFL_LD_PRELOAD"))
|
if (getenv("AFL_LD_PRELOAD")) {
|
||||||
|
|
||||||
FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD");
|
FATAL("Use AFL_PRELOAD instead of AFL_LD_PRELOAD");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
save_cmdline(afl, argc, argv);
|
save_cmdline(afl, argc, argv);
|
||||||
|
|
||||||
fix_up_banner(afl, argv[optind]);
|
fix_up_banner(afl, argv[optind]);
|
||||||
|
|
||||||
check_if_tty(afl);
|
check_if_tty(afl);
|
||||||
if (afl->afl_env.afl_force_ui) afl->not_on_tty = 0;
|
if (afl->afl_env.afl_force_ui) { afl->not_on_tty = 0; }
|
||||||
|
|
||||||
if (afl->afl_env.afl_cal_fast) {
|
if (afl->afl_env.afl_cal_fast) {
|
||||||
|
|
||||||
@ -921,7 +1065,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
setup_post(afl);
|
setup_post(afl);
|
||||||
|
|
||||||
if (!afl->in_bitmap) memset(afl->virgin_bits, 255, afl->fsrv.map_size);
|
if (!afl->in_bitmap) { memset(afl->virgin_bits, 255, afl->fsrv.map_size); }
|
||||||
memset(afl->virgin_tmout, 255, afl->fsrv.map_size);
|
memset(afl->virgin_tmout, 255, afl->fsrv.map_size);
|
||||||
memset(afl->virgin_crash, 255, afl->fsrv.map_size);
|
memset(afl->virgin_crash, 255, afl->fsrv.map_size);
|
||||||
|
|
||||||
@ -938,9 +1082,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
pivot_inputs(afl);
|
pivot_inputs(afl);
|
||||||
|
|
||||||
if (extras_dir) load_extras(afl, extras_dir);
|
if (extras_dir) { load_extras(afl, extras_dir); }
|
||||||
|
|
||||||
if (!afl->timeout_given) find_timeout(afl);
|
if (!afl->timeout_given) { find_timeout(afl); }
|
||||||
|
|
||||||
if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL &&
|
if ((afl->tmp_dir = afl->afl_env.afl_tmpdir) != NULL &&
|
||||||
!afl->in_place_resume) {
|
!afl->in_place_resume) {
|
||||||
@ -959,16 +1103,21 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
/* there is still a race condition here, but well ... */
|
/* there is still a race condition here, but well ... */
|
||||||
if (access(tmpfile, F_OK) != -1)
|
if (access(tmpfile, F_OK) != -1) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"AFL_TMPDIR already has an existing temporary input file: %s - if "
|
"AFL_TMPDIR already has an existing temporary input file: %s - if "
|
||||||
"this is not from another instance, then just remove the file.",
|
"this is not from another instance, then just remove the file.",
|
||||||
tmpfile);
|
tmpfile);
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->tmp_dir = afl->out_dir;
|
afl->tmp_dir = afl->out_dir;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* If we don't have a file name chosen yet, use a safe default. */
|
/* If we don't have a file name chosen yet, use a safe default. */
|
||||||
|
|
||||||
if (!afl->fsrv.out_file) {
|
if (!afl->fsrv.out_file) {
|
||||||
@ -1005,13 +1154,17 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!afl->fsrv.out_file) setup_stdio_file(afl);
|
if (!afl->fsrv.out_file) { setup_stdio_file(afl); }
|
||||||
|
|
||||||
if (afl->cmplog_binary) {
|
if (afl->cmplog_binary) {
|
||||||
|
|
||||||
if (afl->unicorn_mode)
|
if (afl->unicorn_mode) {
|
||||||
|
|
||||||
FATAL("CmpLog and Unicorn mode are not compatible at the moment, sorry");
|
FATAL("CmpLog and Unicorn mode are not compatible at the moment, sorry");
|
||||||
if (!afl->fsrv.qemu_mode) check_binary(afl, afl->cmplog_binary);
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!afl->fsrv.qemu_mode) { check_binary(afl, afl->cmplog_binary); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1021,13 +1174,18 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (afl->fsrv.qemu_mode) {
|
if (afl->fsrv.qemu_mode) {
|
||||||
|
|
||||||
if (afl->use_wine)
|
if (afl->use_wine) {
|
||||||
|
|
||||||
use_argv = get_wine_argv(argv[0], &afl->fsrv.target_path, argc - optind,
|
use_argv = get_wine_argv(argv[0], &afl->fsrv.target_path, argc - optind,
|
||||||
argv + optind);
|
argv + optind);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
use_argv = get_qemu_argv(argv[0], &afl->fsrv.target_path, argc - optind,
|
use_argv = get_qemu_argv(argv[0], &afl->fsrv.target_path, argc - optind,
|
||||||
argv + optind);
|
argv + optind);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
use_argv = argv + optind;
|
use_argv = argv + optind;
|
||||||
@ -1062,7 +1220,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
maybe_update_plot_file(afl, 0, 0);
|
maybe_update_plot_file(afl, 0, 0);
|
||||||
save_auto(afl);
|
save_auto(afl);
|
||||||
|
|
||||||
if (afl->stop_soon) goto stop_fuzzing;
|
if (afl->stop_soon) { goto stop_fuzzing; }
|
||||||
|
|
||||||
/* Woop woop woop */
|
/* Woop woop woop */
|
||||||
|
|
||||||
@ -1070,7 +1228,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
sleep(4);
|
sleep(4);
|
||||||
afl->start_time += 4000;
|
afl->start_time += 4000;
|
||||||
if (afl->stop_soon) goto stop_fuzzing;
|
if (afl->stop_soon) { goto stop_fuzzing; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -1112,34 +1270,44 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (afl->queued_paths == prev_queued) {
|
if (afl->queued_paths == prev_queued) {
|
||||||
|
|
||||||
if (afl->use_splicing)
|
if (afl->use_splicing) {
|
||||||
|
|
||||||
++afl->cycles_wo_finds;
|
++afl->cycles_wo_finds;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->use_splicing = 1;
|
afl->use_splicing = 1;
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
afl->cycles_wo_finds = 0;
|
afl->cycles_wo_finds = 0;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
prev_queued = afl->queued_paths;
|
prev_queued = afl->queued_paths;
|
||||||
|
|
||||||
if (afl->sync_id && afl->queue_cycle == 1 &&
|
if (afl->sync_id && afl->queue_cycle == 1 &&
|
||||||
afl->afl_env.afl_import_first)
|
afl->afl_env.afl_import_first) {
|
||||||
|
|
||||||
sync_fuzzers(afl);
|
sync_fuzzers(afl);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
skipped_fuzz = fuzz_one(afl);
|
skipped_fuzz = fuzz_one(afl);
|
||||||
|
|
||||||
if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) {
|
if (!skipped_fuzz && !afl->stop_soon && afl->sync_id) {
|
||||||
|
|
||||||
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) sync_fuzzers(afl);
|
if (!(sync_interval_cnt++ % SYNC_INTERVAL)) { sync_fuzzers(afl); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!afl->stop_soon && exit_1) afl->stop_soon = 2;
|
if (!afl->stop_soon && exit_1) { afl->stop_soon = 2; }
|
||||||
|
|
||||||
if (afl->stop_soon) break;
|
if (afl->stop_soon) { break; }
|
||||||
|
|
||||||
afl->queue_cur = afl->queue_cur->next;
|
afl->queue_cur = afl->queue_cur->next;
|
||||||
++afl->current_entry;
|
++afl->current_entry;
|
||||||
@ -1159,11 +1327,18 @@ stop_fuzzing:
|
|||||||
SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
|
SAYF(CURSOR_SHOW cLRD "\n\n+++ Testing aborted %s +++\n" cRST,
|
||||||
afl->stop_soon == 2 ? "programmatically" : "by user");
|
afl->stop_soon == 2 ? "programmatically" : "by user");
|
||||||
|
|
||||||
if (afl->most_time_key == 2)
|
if (afl->most_time_key == 2) {
|
||||||
|
|
||||||
SAYF(cYEL "[!] " cRST "Time limit was reached\n");
|
SAYF(cYEL "[!] " cRST "Time limit was reached\n");
|
||||||
if (afl->most_execs_key == 2)
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (afl->most_execs_key == 2) {
|
||||||
|
|
||||||
SAYF(cYEL "[!] " cRST "Execution limit was reached\n");
|
SAYF(cYEL "[!] " cRST "Execution limit was reached\n");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
/* Running for more than 30 minutes but still doing first cycle? */
|
/* Running for more than 30 minutes but still doing first cycle? */
|
||||||
|
|
||||||
if (afl->queue_cycle == 1 &&
|
if (afl->queue_cycle == 1 &&
|
||||||
@ -1182,7 +1357,7 @@ stop_fuzzing:
|
|||||||
destroy_custom_mutator(afl);
|
destroy_custom_mutator(afl);
|
||||||
afl_shm_deinit(&afl->shm);
|
afl_shm_deinit(&afl->shm);
|
||||||
afl_fsrv_deinit(&afl->fsrv);
|
afl_fsrv_deinit(&afl->fsrv);
|
||||||
if (afl->orig_cmdline) ck_free(afl->orig_cmdline);
|
if (afl->orig_cmdline) { ck_free(afl->orig_cmdline); }
|
||||||
ck_free(afl->fsrv.target_path);
|
ck_free(afl->fsrv.target_path);
|
||||||
ck_free(afl->fsrv.out_file);
|
ck_free(afl->fsrv.out_file);
|
||||||
ck_free(afl->sync_id);
|
ck_free(afl->sync_id);
|
||||||
|
@ -128,11 +128,16 @@ static void edit_params(u32 argc, char **argv) {
|
|||||||
cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
|
cc_params = ck_alloc((argc + 128) * sizeof(u8 *));
|
||||||
|
|
||||||
name = strrchr(argv[0], '/');
|
name = strrchr(argv[0], '/');
|
||||||
if (!name)
|
if (!name) {
|
||||||
|
|
||||||
name = argv[0];
|
name = argv[0];
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
++name;
|
++name;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!strncmp(name, "afl-clang", 9)) {
|
if (!strncmp(name, "afl-clang", 9)) {
|
||||||
|
|
||||||
clang_mode = 1;
|
clang_mode = 1;
|
||||||
@ -211,7 +216,7 @@ static void edit_params(u32 argc, char **argv) {
|
|||||||
|
|
||||||
if (!strncmp(cur, "-B", 2)) {
|
if (!strncmp(cur, "-B", 2)) {
|
||||||
|
|
||||||
if (!be_quiet) WARNF("-B is already set, overriding");
|
if (!be_quiet) { WARNF("-B is already set, overriding"); }
|
||||||
|
|
||||||
if (!cur[2] && argc > 1) {
|
if (!cur[2] && argc > 1) {
|
||||||
|
|
||||||
@ -224,18 +229,22 @@ static void edit_params(u32 argc, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!strcmp(cur, "-integrated-as")) continue;
|
if (!strcmp(cur, "-integrated-as")) { continue; }
|
||||||
|
|
||||||
if (!strcmp(cur, "-pipe")) continue;
|
if (!strcmp(cur, "-pipe")) { continue; }
|
||||||
|
|
||||||
#if defined(__FreeBSD__) && defined(WORD_SIZE_64)
|
#if defined(__FreeBSD__) && defined(WORD_SIZE_64)
|
||||||
if (!strcmp(cur, "-m32")) m32_set = 1;
|
if (!strcmp(cur, "-m32")) m32_set = 1;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (!strcmp(cur, "-fsanitize=address") || !strcmp(cur, "-fsanitize=memory"))
|
if (!strcmp(cur, "-fsanitize=address") ||
|
||||||
|
!strcmp(cur, "-fsanitize=memory")) {
|
||||||
|
|
||||||
asan_set = 1;
|
asan_set = 1;
|
||||||
|
|
||||||
if (strstr(cur, "FORTIFY_SOURCE")) fortify_set = 1;
|
}
|
||||||
|
|
||||||
|
if (strstr(cur, "FORTIFY_SOURCE")) { fortify_set = 1; }
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = cur;
|
cc_params[cc_par_cnt++] = cur;
|
||||||
|
|
||||||
@ -244,13 +253,13 @@ static void edit_params(u32 argc, char **argv) {
|
|||||||
cc_params[cc_par_cnt++] = "-B";
|
cc_params[cc_par_cnt++] = "-B";
|
||||||
cc_params[cc_par_cnt++] = as_path;
|
cc_params[cc_par_cnt++] = as_path;
|
||||||
|
|
||||||
if (clang_mode) cc_params[cc_par_cnt++] = "-no-integrated-as";
|
if (clang_mode) { cc_params[cc_par_cnt++] = "-no-integrated-as"; }
|
||||||
|
|
||||||
if (getenv("AFL_HARDEN")) {
|
if (getenv("AFL_HARDEN")) {
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = "-fstack-protector-all";
|
cc_params[cc_par_cnt++] = "-fstack-protector-all";
|
||||||
|
|
||||||
if (!fortify_set) cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2";
|
if (!fortify_set) { cc_params[cc_par_cnt++] = "-D_FORTIFY_SOURCE=2"; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -262,21 +271,35 @@ static void edit_params(u32 argc, char **argv) {
|
|||||||
|
|
||||||
} else if (getenv("AFL_USE_ASAN")) {
|
} else if (getenv("AFL_USE_ASAN")) {
|
||||||
|
|
||||||
if (getenv("AFL_USE_MSAN")) FATAL("ASAN and MSAN are mutually exclusive");
|
if (getenv("AFL_USE_MSAN")) {
|
||||||
|
|
||||||
|
FATAL("ASAN and MSAN are mutually exclusive");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getenv("AFL_HARDEN")) {
|
||||||
|
|
||||||
if (getenv("AFL_HARDEN"))
|
|
||||||
FATAL("ASAN and AFL_HARDEN are mutually exclusive");
|
FATAL("ASAN and AFL_HARDEN are mutually exclusive");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE";
|
cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE";
|
||||||
cc_params[cc_par_cnt++] = "-fsanitize=address";
|
cc_params[cc_par_cnt++] = "-fsanitize=address";
|
||||||
|
|
||||||
} else if (getenv("AFL_USE_MSAN")) {
|
} else if (getenv("AFL_USE_MSAN")) {
|
||||||
|
|
||||||
if (getenv("AFL_USE_ASAN")) FATAL("ASAN and MSAN are mutually exclusive");
|
if (getenv("AFL_USE_ASAN")) {
|
||||||
|
|
||||||
|
FATAL("ASAN and MSAN are mutually exclusive");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (getenv("AFL_HARDEN")) {
|
||||||
|
|
||||||
if (getenv("AFL_HARDEN"))
|
|
||||||
FATAL("MSAN and AFL_HARDEN are mutually exclusive");
|
FATAL("MSAN and AFL_HARDEN are mutually exclusive");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE";
|
cc_params[cc_par_cnt++] = "-U_FORTIFY_SOURCE";
|
||||||
cc_params[cc_par_cnt++] = "-fsanitize=memory";
|
cc_params[cc_par_cnt++] = "-fsanitize=memory";
|
||||||
|
|
||||||
@ -386,10 +409,12 @@ int main(int argc, char **argv) {
|
|||||||
"afl-gcc is deprecated, llvm_mode is much faster and has more "
|
"afl-gcc is deprecated, llvm_mode is much faster and has more "
|
||||||
"options\n");
|
"options\n");
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
be_quiet = 1;
|
be_quiet = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (argc < 2) {
|
if (argc < 2) {
|
||||||
|
|
||||||
SAYF(
|
SAYF(
|
||||||
@ -416,7 +441,11 @@ int main(int argc, char **argv) {
|
|||||||
((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) {
|
((ptr = getenv("AFL_MAP_SIZE")) || (ptr = getenv("AFL_MAPSIZE")))) {
|
||||||
|
|
||||||
u32 map_size = atoi(ptr);
|
u32 map_size = atoi(ptr);
|
||||||
if (map_size != MAP_SIZE) FATAL("AFL_MAP_SIZE is not supported by afl-gcc");
|
if (map_size != MAP_SIZE) {
|
||||||
|
|
||||||
|
FATAL("AFL_MAP_SIZE is not supported by afl-gcc");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -102,8 +102,12 @@ repeat_loop:
|
|||||||
|
|
||||||
v1 = CTEST_BUSY_CYCLES;
|
v1 = CTEST_BUSY_CYCLES;
|
||||||
|
|
||||||
while (v1--)
|
while (v1--) {
|
||||||
|
|
||||||
v2++;
|
v2++;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
sched_yield();
|
sched_yield();
|
||||||
|
|
||||||
en_t = get_cur_time_us();
|
en_t = get_cur_time_us();
|
||||||
@ -154,7 +158,7 @@ int main(int argc, char **argv) {
|
|||||||
|
|
||||||
s32 fr = fork();
|
s32 fr = fork();
|
||||||
|
|
||||||
if (fr < 0) PFATAL("fork failed");
|
if (fr < 0) { PFATAL("fork failed"); }
|
||||||
|
|
||||||
if (!fr) {
|
if (!fr) {
|
||||||
|
|
||||||
@ -192,8 +196,12 @@ int main(int argc, char **argv) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined(__linux__)
|
#if defined(__linux__)
|
||||||
if (sched_setaffinity(0, sizeof(c), &c))
|
if (sched_setaffinity(0, sizeof(c), &c)) {
|
||||||
|
|
||||||
PFATAL("sched_setaffinity failed for cpu %d", i);
|
PFATAL("sched_setaffinity failed for cpu %d", i);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
util_perc = measure_preemption(CTEST_CORE_TRG_MS);
|
util_perc = measure_preemption(CTEST_CORE_TRG_MS);
|
||||||
@ -221,10 +229,10 @@ int main(int argc, char **argv) {
|
|||||||
for (i = 0; i < cpu_cnt; i++) {
|
for (i = 0; i < cpu_cnt; i++) {
|
||||||
|
|
||||||
int ret;
|
int ret;
|
||||||
if (waitpid(-1, &ret, 0) < 0) PFATAL("waitpid failed");
|
if (waitpid(-1, &ret, 0) < 0) { PFATAL("waitpid failed"); }
|
||||||
|
|
||||||
if (WEXITSTATUS(ret) == 0) idle_cpus++;
|
if (WEXITSTATUS(ret) == 0) { idle_cpus++; }
|
||||||
if (WEXITSTATUS(ret) <= 1) maybe_cpus++;
|
if (WEXITSTATUS(ret) <= 1) { maybe_cpus++; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -86,7 +86,7 @@ void afl_shm_deinit(sharedmem_t *shm) {
|
|||||||
|
|
||||||
#else
|
#else
|
||||||
shmctl(shm->shm_id, IPC_RMID, NULL);
|
shmctl(shm->shm_id, IPC_RMID, NULL);
|
||||||
if (shm->cmplog_mode) shmctl(shm->cmplog_shm_id, IPC_RMID, NULL);
|
if (shm->cmplog_mode) { shmctl(shm->cmplog_shm_id, IPC_RMID, NULL); }
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
shm->map = NULL;
|
shm->map = NULL;
|
||||||
@ -152,14 +152,14 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
|
|||||||
|
|
||||||
shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
|
shm->shm_id = shmget(IPC_PRIVATE, map_size, IPC_CREAT | IPC_EXCL | 0600);
|
||||||
|
|
||||||
if (shm->shm_id < 0) PFATAL("shmget() failed");
|
if (shm->shm_id < 0) { PFATAL("shmget() failed"); }
|
||||||
|
|
||||||
if (shm->cmplog_mode) {
|
if (shm->cmplog_mode) {
|
||||||
|
|
||||||
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
|
shm->cmplog_shm_id = shmget(IPC_PRIVATE, sizeof(struct cmp_map),
|
||||||
IPC_CREAT | IPC_EXCL | 0600);
|
IPC_CREAT | IPC_EXCL | 0600);
|
||||||
|
|
||||||
if (shm->cmplog_shm_id < 0) PFATAL("shmget() failed");
|
if (shm->cmplog_shm_id < 0) { PFATAL("shmget() failed"); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -170,7 +170,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
|
|||||||
fork server commands. This should be replaced with better auto-detection
|
fork server commands. This should be replaced with better auto-detection
|
||||||
later on, perhaps? */
|
later on, perhaps? */
|
||||||
|
|
||||||
if (!dumb_mode) setenv(SHM_ENV_VAR, shm_str, 1);
|
if (!dumb_mode) { setenv(SHM_ENV_VAR, shm_str, 1); }
|
||||||
|
|
||||||
ck_free(shm_str);
|
ck_free(shm_str);
|
||||||
|
|
||||||
@ -178,7 +178,7 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
|
|||||||
|
|
||||||
shm_str = alloc_printf("%d", shm->cmplog_shm_id);
|
shm_str = alloc_printf("%d", shm->cmplog_shm_id);
|
||||||
|
|
||||||
if (!dumb_mode) setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1);
|
if (!dumb_mode) { setenv(CMPLOG_SHM_ENV_VAR, shm_str, 1); }
|
||||||
|
|
||||||
ck_free(shm_str);
|
ck_free(shm_str);
|
||||||
|
|
||||||
@ -186,13 +186,17 @@ u8 *afl_shm_init(sharedmem_t *shm, size_t map_size, unsigned char dumb_mode) {
|
|||||||
|
|
||||||
shm->map = shmat(shm->shm_id, NULL, 0);
|
shm->map = shmat(shm->shm_id, NULL, 0);
|
||||||
|
|
||||||
if (shm->map == (void *)-1 || !shm->map) PFATAL("shmat() failed");
|
if (shm->map == (void *)-1 || !shm->map) { PFATAL("shmat() failed"); }
|
||||||
|
|
||||||
if (shm->cmplog_mode) {
|
if (shm->cmplog_mode) {
|
||||||
|
|
||||||
shm->cmp_map = shmat(shm->cmplog_shm_id, NULL, 0);
|
shm->cmp_map = shmat(shm->cmplog_shm_id, NULL, 0);
|
||||||
|
|
||||||
if (shm->cmp_map == (void *)-1 || !shm->cmp_map) PFATAL("shmat() failed");
|
if (shm->cmp_map == (void *)-1 || !shm->cmp_map) {
|
||||||
|
|
||||||
|
PFATAL("shmat() failed");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -121,7 +121,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
if (*mem) *mem = 1;
|
if (*mem) { *mem = 1; }
|
||||||
mem++;
|
mem++;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -143,7 +143,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
static void at_exit_handler(void) {
|
static void at_exit_handler(void) {
|
||||||
|
|
||||||
if (stdin_file) unlink(stdin_file);
|
if (stdin_file) { unlink(stdin_file); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -161,25 +161,28 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
|
|||||||
|
|
||||||
fd = open(outfile, O_WRONLY);
|
fd = open(outfile, O_WRONLY);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", out_file);
|
if (fd < 0) { PFATAL("Unable to open '%s'", out_file); }
|
||||||
|
|
||||||
} else if (!strcmp(outfile, "-")) {
|
} else if (!strcmp(outfile, "-")) {
|
||||||
|
|
||||||
fd = dup(1);
|
fd = dup(1);
|
||||||
if (fd < 0) PFATAL("Unable to open stdout");
|
if (fd < 0) { PFATAL("Unable to open stdout"); }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
unlink(outfile); /* Ignore errors */
|
unlink(outfile); /* Ignore errors */
|
||||||
fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
fd = open(outfile, O_WRONLY | O_CREAT | O_EXCL, 0600);
|
||||||
if (fd < 0) PFATAL("Unable to create '%s'", outfile);
|
if (fd < 0) { PFATAL("Unable to create '%s'", outfile); }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (binary_mode) {
|
if (binary_mode) {
|
||||||
|
|
||||||
for (i = 0; i < map_size; i++)
|
for (i = 0; i < map_size; i++) {
|
||||||
if (fsrv->trace_bits[i]) ret++;
|
|
||||||
|
if (fsrv->trace_bits[i]) { ret++; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
ck_write(fd, fsrv->trace_bits, map_size, outfile);
|
ck_write(fd, fsrv->trace_bits, map_size, outfile);
|
||||||
close(fd);
|
close(fd);
|
||||||
@ -188,27 +191,29 @@ static u32 write_results_to_file(afl_forkserver_t *fsrv, u8 *outfile) {
|
|||||||
|
|
||||||
FILE *f = fdopen(fd, "w");
|
FILE *f = fdopen(fd, "w");
|
||||||
|
|
||||||
if (!f) PFATAL("fdopen() failed");
|
if (!f) { PFATAL("fdopen() failed"); }
|
||||||
|
|
||||||
for (i = 0; i < map_size; i++) {
|
for (i = 0; i < map_size; i++) {
|
||||||
|
|
||||||
if (!fsrv->trace_bits[i]) continue;
|
if (!fsrv->trace_bits[i]) { continue; }
|
||||||
ret++;
|
ret++;
|
||||||
|
|
||||||
total += fsrv->trace_bits[i];
|
total += fsrv->trace_bits[i];
|
||||||
if (highest < fsrv->trace_bits[i]) highest = fsrv->trace_bits[i];
|
if (highest < fsrv->trace_bits[i]) { highest = fsrv->trace_bits[i]; }
|
||||||
|
|
||||||
if (cmin_mode) {
|
if (cmin_mode) {
|
||||||
|
|
||||||
if (fsrv->last_run_timed_out) break;
|
if (fsrv->last_run_timed_out) { break; }
|
||||||
if (!caa && child_crashed != cco) break;
|
if (!caa && child_crashed != cco) { break; }
|
||||||
|
|
||||||
fprintf(f, "%u%u\n", fsrv->trace_bits[i], i);
|
fprintf(f, "%u%u\n", fsrv->trace_bits[i], i);
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
fprintf(f, "%06u:%u\n", i, fsrv->trace_bits[i]);
|
fprintf(f, "%06u:%u\n", i, fsrv->trace_bits[i]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
fclose(f);
|
fclose(f);
|
||||||
@ -251,11 +256,14 @@ static u32 read_file(u8 *in_file) {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
s32 fd = open(in_file, O_RDONLY);
|
s32 fd = open(in_file, O_RDONLY);
|
||||||
|
|
||||||
if (fd < 0) WARNF("Unable to open '%s'", in_file);
|
if (fd < 0) { WARNF("Unable to open '%s'", in_file); }
|
||||||
|
|
||||||
|
if (fstat(fd, &st) || !st.st_size) {
|
||||||
|
|
||||||
if (fstat(fd, &st) || !st.st_size)
|
|
||||||
WARNF("Zero-sized input file '%s'.", in_file);
|
WARNF("Zero-sized input file '%s'.", in_file);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
in_len = st.st_size;
|
in_len = st.st_size;
|
||||||
in_data = ck_alloc_nozero(in_len);
|
in_data = ck_alloc_nozero(in_len);
|
||||||
|
|
||||||
@ -276,13 +284,13 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
static struct itimerval it;
|
static struct itimerval it;
|
||||||
int status = 0;
|
int status = 0;
|
||||||
|
|
||||||
if (!quiet_mode) SAYF("-- Program output begins --\n" cRST);
|
if (!quiet_mode) { SAYF("-- Program output begins --\n" cRST); }
|
||||||
|
|
||||||
MEM_BARRIER();
|
MEM_BARRIER();
|
||||||
|
|
||||||
fsrv->child_pid = fork();
|
fsrv->child_pid = fork();
|
||||||
|
|
||||||
if (fsrv->child_pid < 0) PFATAL("fork() failed");
|
if (fsrv->child_pid < 0) { PFATAL("fork() failed"); }
|
||||||
|
|
||||||
if (!fsrv->child_pid) {
|
if (!fsrv->child_pid) {
|
||||||
|
|
||||||
@ -319,14 +327,19 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!keep_cores)
|
if (!keep_cores) {
|
||||||
|
|
||||||
r.rlim_max = r.rlim_cur = 0;
|
r.rlim_max = r.rlim_cur = 0;
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
r.rlim_max = r.rlim_cur = RLIM_INFINITY;
|
r.rlim_max = r.rlim_cur = RLIM_INFINITY;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
|
setrlimit(RLIMIT_CORE, &r); /* Ignore errors */
|
||||||
|
|
||||||
if (!getenv("LD_BIND_LAZY")) setenv("LD_BIND_NOW", "1", 0);
|
if (!getenv("LD_BIND_LAZY")) { setenv("LD_BIND_NOW", "1", 0); }
|
||||||
|
|
||||||
setsid();
|
setsid();
|
||||||
|
|
||||||
@ -349,7 +362,7 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
setitimer(ITIMER_REAL, &it, NULL);
|
setitimer(ITIMER_REAL, &it, NULL);
|
||||||
|
|
||||||
if (waitpid(fsrv->child_pid, &status, 0) <= 0) FATAL("waitpid() failed");
|
if (waitpid(fsrv->child_pid, &status, 0) <= 0) { FATAL("waitpid() failed"); }
|
||||||
|
|
||||||
fsrv->child_pid = 0;
|
fsrv->child_pid = 0;
|
||||||
it.it_value.tv_sec = 0;
|
it.it_value.tv_sec = 0;
|
||||||
@ -360,26 +373,39 @@ static void showmap_run_target(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
/* Clean up bitmap, analyze exit condition, etc. */
|
/* Clean up bitmap, analyze exit condition, etc. */
|
||||||
|
|
||||||
if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG)
|
if (*(u32 *)fsrv->trace_bits == EXEC_FAIL_SIG) {
|
||||||
|
|
||||||
FATAL("Unable to execute '%s'", argv[0]);
|
FATAL("Unable to execute '%s'", argv[0]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
classify_counts(fsrv);
|
classify_counts(fsrv);
|
||||||
|
|
||||||
if (!quiet_mode) SAYF(cRST "-- Program output ends --\n");
|
if (!quiet_mode) { SAYF(cRST "-- Program output ends --\n"); }
|
||||||
|
|
||||||
|
if (!fsrv->last_run_timed_out && !stop_soon && WIFSIGNALED(status)) {
|
||||||
|
|
||||||
if (!fsrv->last_run_timed_out && !stop_soon && WIFSIGNALED(status))
|
|
||||||
child_crashed = 1;
|
child_crashed = 1;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (!quiet_mode) {
|
if (!quiet_mode) {
|
||||||
|
|
||||||
if (fsrv->last_run_timed_out)
|
if (fsrv->last_run_timed_out) {
|
||||||
|
|
||||||
SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
|
SAYF(cLRD "\n+++ Program timed off +++\n" cRST);
|
||||||
else if (stop_soon)
|
|
||||||
|
} else if (stop_soon) {
|
||||||
|
|
||||||
SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST);
|
SAYF(cLRD "\n+++ Program aborted by user +++\n" cRST);
|
||||||
else if (child_crashed)
|
|
||||||
|
} else if (child_crashed) {
|
||||||
|
|
||||||
SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST,
|
SAYF(cLRD "\n+++ Program killed by signal %u +++\n" cRST,
|
||||||
WTERMSIG(status));
|
WTERMSIG(status));
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -421,20 +447,28 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
|||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',') {
|
||||||
|
|
||||||
PFATAL(
|
PFATAL(
|
||||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
"specified!");
|
"specified!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload) {
|
||||||
|
|
||||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
qemu_preload, afl_preload, afl_preload);
|
qemu_preload, afl_preload, afl_preload);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
afl_preload, afl_preload);
|
afl_preload, afl_preload);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
setenv("QEMU_SET_ENV", buf, 1);
|
setenv("QEMU_SET_ENV", buf, 1);
|
||||||
|
|
||||||
ck_free(buf);
|
ck_free(buf);
|
||||||
@ -549,20 +583,20 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
doc_path = access(DOC_PATH, F_OK) ? "docs" : DOC_PATH;
|
||||||
|
|
||||||
if (getenv("AFL_QUIET") != NULL) be_quiet = 1;
|
if (getenv("AFL_QUIET") != NULL) { be_quiet = 1; }
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqZQUWbcrh")) > 0)
|
while ((opt = getopt(argc, argv, "+i:o:f:m:t:A:eqZQUWbcrh")) > 0) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
if (in_dir) FATAL("Multiple -i options not supported");
|
if (in_dir) { FATAL("Multiple -i options not supported"); }
|
||||||
in_dir = optarg;
|
in_dir = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
|
|
||||||
if (out_file) FATAL("Multiple -o options not supported");
|
if (out_file) { FATAL("Multiple -o options not supported"); }
|
||||||
out_file = optarg;
|
out_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -570,10 +604,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u8 suffix = 'M';
|
u8 suffix = 'M';
|
||||||
|
|
||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
if (!optarg) FATAL("Wrong usage of -m");
|
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
|
|
||||||
@ -583,25 +617,39 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 ||
|
if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 ||
|
||||||
optarg[0] == '-')
|
optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -m");
|
FATAL("Bad syntax used for -m");
|
||||||
|
|
||||||
switch (suffix) {
|
|
||||||
|
|
||||||
case 'T': fsrv->mem_limit *= 1024 * 1024; break;
|
|
||||||
case 'G': fsrv->mem_limit *= 1024; break;
|
|
||||||
case 'k': fsrv->mem_limit /= 1024; break;
|
|
||||||
case 'M': break;
|
|
||||||
|
|
||||||
default: FATAL("Unsupported suffix or bad syntax for -m");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsrv->mem_limit < 5) FATAL("Dangerously low value of -m");
|
switch (suffix) {
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
fsrv->mem_limit *= 1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
fsrv->mem_limit *= 1024;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
fsrv->mem_limit /= 1024;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FATAL("Unsupported suffix or bad syntax for -m");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fsrv->mem_limit < 5) { FATAL("Dangerously low value of -m"); }
|
||||||
|
|
||||||
|
if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000) {
|
||||||
|
|
||||||
if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000)
|
|
||||||
FATAL("Value of -m out of range on 32-bit systems");
|
FATAL("Value of -m out of range on 32-bit systems");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@ -615,32 +663,35 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
|
|
||||||
if (timeout_given) FATAL("Multiple -t options not supported");
|
if (timeout_given) { FATAL("Multiple -t options not supported"); }
|
||||||
timeout_given = 1;
|
timeout_given = 1;
|
||||||
|
|
||||||
if (!optarg) FATAL("Wrong usage of -t");
|
if (!optarg) { FATAL("Wrong usage of -t"); }
|
||||||
|
|
||||||
if (strcmp(optarg, "none")) {
|
if (strcmp(optarg, "none")) {
|
||||||
|
|
||||||
fsrv->exec_tmout = atoi(optarg);
|
fsrv->exec_tmout = atoi(optarg);
|
||||||
|
|
||||||
if (fsrv->exec_tmout < 20 || optarg[0] == '-')
|
if (fsrv->exec_tmout < 20 || optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Dangerously low value of -t");
|
FATAL("Dangerously low value of -t");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
|
|
||||||
if (edges_only) FATAL("Multiple -e options not supported");
|
if (edges_only) { FATAL("Multiple -e options not supported"); }
|
||||||
if (raw_instr_output) FATAL("-e and -r are mutually exclusive");
|
if (raw_instr_output) { FATAL("-e and -r are mutually exclusive"); }
|
||||||
edges_only = 1;
|
edges_only = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'q':
|
case 'q':
|
||||||
|
|
||||||
if (quiet_mode) FATAL("Multiple -q options not supported");
|
if (quiet_mode) { FATAL("Multiple -q options not supported"); }
|
||||||
quiet_mode = 1;
|
quiet_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -660,27 +711,27 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
|
|
||||||
if (fsrv->qemu_mode) FATAL("Multiple -Q options not supported");
|
if (fsrv->qemu_mode) { FATAL("Multiple -Q options not supported"); }
|
||||||
if (!mem_limit_given) fsrv->mem_limit = MEM_LIMIT_QEMU;
|
if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; }
|
||||||
|
|
||||||
fsrv->qemu_mode = 1;
|
fsrv->qemu_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U':
|
case 'U':
|
||||||
|
|
||||||
if (unicorn_mode) FATAL("Multiple -U options not supported");
|
if (unicorn_mode) { FATAL("Multiple -U options not supported"); }
|
||||||
if (!mem_limit_given) fsrv->mem_limit = MEM_LIMIT_UNICORN;
|
if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; }
|
||||||
|
|
||||||
unicorn_mode = 1;
|
unicorn_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W': /* Wine+QEMU mode */
|
case 'W': /* Wine+QEMU mode */
|
||||||
|
|
||||||
if (use_wine) FATAL("Multiple -W options not supported");
|
if (use_wine) { FATAL("Multiple -W options not supported"); }
|
||||||
fsrv->qemu_mode = 1;
|
fsrv->qemu_mode = 1;
|
||||||
use_wine = 1;
|
use_wine = 1;
|
||||||
|
|
||||||
if (!mem_limit_given) fsrv->mem_limit = 0;
|
if (!mem_limit_given) { fsrv->mem_limit = 0; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -694,14 +745,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
case 'c':
|
case 'c':
|
||||||
|
|
||||||
if (keep_cores) FATAL("Multiple -c options not supported");
|
if (keep_cores) { FATAL("Multiple -c options not supported"); }
|
||||||
keep_cores = 1;
|
keep_cores = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'r':
|
case 'r':
|
||||||
|
|
||||||
if (raw_instr_output) FATAL("Multiple -r options not supported");
|
if (raw_instr_output) { FATAL("Multiple -r options not supported"); }
|
||||||
if (edges_only) FATAL("-e and -r are mutually exclusive");
|
if (edges_only) { FATAL("-e and -r are mutually exclusive"); }
|
||||||
raw_instr_output = 1;
|
raw_instr_output = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -710,11 +761,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: usage(argv[0]);
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind == argc || !out_file) usage(argv[0]);
|
}
|
||||||
|
|
||||||
|
if (optind == argc || !out_file) { usage(argv[0]); }
|
||||||
|
|
||||||
check_environment_vars(envp);
|
check_environment_vars(envp);
|
||||||
|
|
||||||
@ -735,7 +789,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (in_dir) {
|
if (in_dir) {
|
||||||
|
|
||||||
if (at_file) PFATAL("Options -A and -i are mutually exclusive");
|
if (at_file) { PFATAL("Options -A and -i are mutually exclusive"); }
|
||||||
detect_file_args(argv + optind, "", &fsrv->use_stdin);
|
detect_file_args(argv + optind, "", &fsrv->use_stdin);
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
@ -744,22 +798,32 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (i = optind; i < argc; i++)
|
for (i = optind; i < argc; i++) {
|
||||||
if (strcmp(argv[i], "@@") == 0) arg_offset = i;
|
|
||||||
|
if (strcmp(argv[i], "@@") == 0) { arg_offset = i; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (fsrv->qemu_mode) {
|
if (fsrv->qemu_mode) {
|
||||||
|
|
||||||
if (use_wine)
|
if (use_wine) {
|
||||||
|
|
||||||
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
|
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
|
||||||
argv + optind);
|
argv + optind);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
|
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
|
||||||
argv + optind);
|
argv + optind);
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
use_argv = argv + optind;
|
use_argv = argv + optind;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (in_dir) {
|
if (in_dir) {
|
||||||
|
|
||||||
DIR * dir_in, *dir_out;
|
DIR * dir_in, *dir_out;
|
||||||
@ -771,20 +835,30 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
||||||
if (fsrv->dev_null_fd < 0) PFATAL("Unable to open /dev/null");
|
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||||
|
|
||||||
if (!(dir_in = opendir(in_dir))) PFATAL("cannot open directory %s", in_dir);
|
if (!(dir_in = opendir(in_dir))) {
|
||||||
|
|
||||||
|
PFATAL("cannot open directory %s", in_dir);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!(dir_out = opendir(out_file))) {
|
||||||
|
|
||||||
|
if (mkdir(out_file, 0700)) {
|
||||||
|
|
||||||
if (!(dir_out = opendir(out_file)))
|
|
||||||
if (mkdir(out_file, 0700))
|
|
||||||
PFATAL("cannot create output directory %s", out_file);
|
PFATAL("cannot create output directory %s", out_file);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
u8 *use_dir = ".";
|
u8 *use_dir = ".";
|
||||||
|
|
||||||
if (access(use_dir, R_OK | W_OK | X_OK)) {
|
if (access(use_dir, R_OK | W_OK | X_OK)) {
|
||||||
|
|
||||||
use_dir = get_afl_env("TMPDIR");
|
use_dir = get_afl_env("TMPDIR");
|
||||||
if (!use_dir) use_dir = "/tmp";
|
if (!use_dir) { use_dir = "/tmp"; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -792,7 +866,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
unlink(stdin_file);
|
unlink(stdin_file);
|
||||||
atexit(at_exit_handler);
|
atexit(at_exit_handler);
|
||||||
fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
fsrv->out_fd = open(stdin_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", out_file);
|
if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
|
||||||
|
|
||||||
if (arg_offset && argv[arg_offset] != stdin_file) {
|
if (arg_offset && argv[arg_offset] != stdin_file) {
|
||||||
|
|
||||||
@ -805,8 +879,12 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
int i = optind;
|
int i = optind;
|
||||||
SAYF(cMGN "[D]" cRST " %s:", fsrv->target_path);
|
SAYF(cMGN "[D]" cRST " %s:", fsrv->target_path);
|
||||||
while (argv[i] != NULL)
|
while (argv[i] != NULL) {
|
||||||
|
|
||||||
SAYF(" \"%s\"", argv[i++]);
|
SAYF(" \"%s\"", argv[i++]);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
SAYF("\n");
|
SAYF("\n");
|
||||||
SAYF(cMGN "[D]" cRST " %d - %d = %d, %s\n", arg_offset, optind,
|
SAYF(cMGN "[D]" cRST " %d - %d = %d, %s\n", arg_offset, optind,
|
||||||
arg_offset - optind, infile);
|
arg_offset - optind, infile);
|
||||||
@ -818,11 +896,19 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
while (done == 0 && (dir_ent = readdir(dir_in))) {
|
while (done == 0 && (dir_ent = readdir(dir_in))) {
|
||||||
|
|
||||||
if (dir_ent->d_name[0] == '.')
|
if (dir_ent->d_name[0] == '.') {
|
||||||
|
|
||||||
continue; // skip anything that starts with '.'
|
continue; // skip anything that starts with '.'
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#if defined(DT_REG) /* Posix and Solaris do not know d_type and DT_REG */
|
#if defined(DT_REG) /* Posix and Solaris do not know d_type and DT_REG */
|
||||||
if (dir_ent->d_type != DT_REG) continue; // only regular files
|
if (dir_ent->d_type != DT_REG) {
|
||||||
|
|
||||||
|
continue; // only regular files
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
snprintf(infile, sizeof(infile), "%s/%s", in_dir, dir_ent->d_name);
|
snprintf(infile, sizeof(infile), "%s/%s", in_dir, dir_ent->d_name);
|
||||||
@ -843,10 +929,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!quiet_mode) OKF("Processed %llu input files.", fsrv->total_execs);
|
if (!quiet_mode) { OKF("Processed %llu input files.", fsrv->total_execs); }
|
||||||
|
|
||||||
closedir(dir_in);
|
closedir(dir_in);
|
||||||
if (dir_out) closedir(dir_out);
|
if (dir_out) { closedir(dir_out); }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -857,7 +943,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (!quiet_mode) {
|
if (!quiet_mode) {
|
||||||
|
|
||||||
if (!tcnt) FATAL("No instrumentation detected" cRST);
|
if (!tcnt) { FATAL("No instrumentation detected" cRST); }
|
||||||
OKF("Captured %u tuples (highest value %u, total values %u) in '%s'." cRST,
|
OKF("Captured %u tuples (highest value %u, total values %u) in '%s'." cRST,
|
||||||
tcnt, highest, total, out_file);
|
tcnt, highest, total, out_file);
|
||||||
|
|
||||||
@ -875,13 +961,13 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u32 ret = child_crashed * 2 + fsrv->last_run_timed_out;
|
u32 ret = child_crashed * 2 + fsrv->last_run_timed_out;
|
||||||
|
|
||||||
if (fsrv->target_path) ck_free(fsrv->target_path);
|
if (fsrv->target_path) { ck_free(fsrv->target_path); }
|
||||||
|
|
||||||
afl_fsrv_deinit(fsrv);
|
afl_fsrv_deinit(fsrv);
|
||||||
if (stdin_file) ck_free(stdin_file);
|
if (stdin_file) { ck_free(stdin_file); }
|
||||||
|
|
||||||
argv_cpy_free(argv);
|
argv_cpy_free(argv);
|
||||||
if (fsrv->qemu_mode) free(use_argv[2]);
|
if (fsrv->qemu_mode) { free(use_argv[2]); }
|
||||||
|
|
||||||
exit(ret);
|
exit(ret);
|
||||||
|
|
||||||
|
266
src/afl-tmin.c
266
src/afl-tmin.c
@ -108,7 +108,7 @@ static void apply_mask(u32 *mem, u32 *mask) {
|
|||||||
|
|
||||||
u32 i = (map_size >> 2);
|
u32 i = (map_size >> 2);
|
||||||
|
|
||||||
if (!mask) return;
|
if (!mask) { return; }
|
||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
@ -129,7 +129,7 @@ static void classify_counts(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
while (i--) {
|
while (i--) {
|
||||||
|
|
||||||
if (*mem) *mem = 1;
|
if (*mem) { *mem = 1; }
|
||||||
mem++;
|
mem++;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -154,8 +154,11 @@ static inline u8 anything_set(afl_forkserver_t *fsrv) {
|
|||||||
u32 *ptr = (u32 *)fsrv->trace_bits;
|
u32 *ptr = (u32 *)fsrv->trace_bits;
|
||||||
u32 i = (map_size >> 2);
|
u32 i = (map_size >> 2);
|
||||||
|
|
||||||
while (i--)
|
while (i--) {
|
||||||
if (*(ptr++)) return 1;
|
|
||||||
|
if (*(ptr++)) { return 1; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
@ -174,13 +177,16 @@ static void read_initial_file(void) {
|
|||||||
struct stat st;
|
struct stat st;
|
||||||
s32 fd = open(in_file, O_RDONLY);
|
s32 fd = open(in_file, O_RDONLY);
|
||||||
|
|
||||||
if (fd < 0) PFATAL("Unable to open '%s'", in_file);
|
if (fd < 0) { PFATAL("Unable to open '%s'", in_file); }
|
||||||
|
|
||||||
if (fstat(fd, &st) || !st.st_size) FATAL("Zero-sized input file.");
|
if (fstat(fd, &st) || !st.st_size) { FATAL("Zero-sized input file."); }
|
||||||
|
|
||||||
|
if (st.st_size >= TMIN_MAX_FILE) {
|
||||||
|
|
||||||
if (st.st_size >= TMIN_MAX_FILE)
|
|
||||||
FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);
|
FATAL("Input file is too large (%u MB max)", TMIN_MAX_FILE / 1024 / 1024);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
in_len = st.st_size;
|
in_len = st.st_size;
|
||||||
in_data = ck_alloc_nozero(in_len);
|
in_data = ck_alloc_nozero(in_len);
|
||||||
|
|
||||||
@ -202,7 +208,7 @@ static s32 write_to_file(u8 *path, u8 *mem, u32 len) {
|
|||||||
|
|
||||||
ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
|
ret = open(path, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
|
|
||||||
if (ret < 0) PFATAL("Unable to create '%s'", path);
|
if (ret < 0) { PFATAL("Unable to create '%s'", path); }
|
||||||
|
|
||||||
ck_write(ret, mem, len, path);
|
ck_write(ret, mem, len, path);
|
||||||
|
|
||||||
@ -223,7 +229,7 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
|||||||
fsrv_run_result_t ret =
|
fsrv_run_result_t ret =
|
||||||
afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon);
|
afl_fsrv_run_target(fsrv, fsrv->exec_tmout, &stop_soon);
|
||||||
|
|
||||||
if (ret == FSRV_RUN_ERROR) FATAL("Couldn't run child");
|
if (ret == FSRV_RUN_ERROR) { FATAL("Couldn't run child"); }
|
||||||
|
|
||||||
if (stop_soon) {
|
if (stop_soon) {
|
||||||
|
|
||||||
@ -239,9 +245,14 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
|||||||
|
|
||||||
switch (ret) {
|
switch (ret) {
|
||||||
|
|
||||||
case FSRV_RUN_TMOUT: return 1;
|
case FSRV_RUN_TMOUT:
|
||||||
case FSRV_RUN_CRASH: missed_crashes++; return 0;
|
return 1;
|
||||||
default: missed_hangs++; return 0;
|
case FSRV_RUN_CRASH:
|
||||||
|
missed_crashes++;
|
||||||
|
return 0;
|
||||||
|
default:
|
||||||
|
missed_hangs++;
|
||||||
|
return 0;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -261,11 +272,11 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
|||||||
|
|
||||||
if (ret == FSRV_RUN_CRASH) {
|
if (ret == FSRV_RUN_CRASH) {
|
||||||
|
|
||||||
if (first_run) crash_mode = 1;
|
if (first_run) { crash_mode = 1; }
|
||||||
|
|
||||||
if (crash_mode) {
|
if (crash_mode) {
|
||||||
|
|
||||||
if (!exact_mode) return 1;
|
if (!exact_mode) { return 1; }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -287,13 +298,13 @@ static u8 tmin_run_target(afl_forkserver_t *fsrv, char **argv, u8 *mem, u32 len,
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (ret == FSRV_RUN_NOINST) FATAL("Binary not instrumented?");
|
if (ret == FSRV_RUN_NOINST) { FATAL("Binary not instrumented?"); }
|
||||||
|
|
||||||
u32 cksum = hash32(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
|
u32 cksum = hash32(fsrv->trace_bits, fsrv->map_size, HASH_CONST);
|
||||||
|
|
||||||
if (first_run) orig_cksum = cksum;
|
if (first_run) { orig_cksum = cksum; }
|
||||||
|
|
||||||
if (orig_cksum == cksum) return 1;
|
if (orig_cksum == cksum) { return 1; }
|
||||||
|
|
||||||
missed_paths++;
|
missed_paths++;
|
||||||
return 0;
|
return 0;
|
||||||
@ -320,7 +331,7 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
set_len = next_pow2(in_len / TMIN_SET_STEPS);
|
set_len = next_pow2(in_len / TMIN_SET_STEPS);
|
||||||
set_pos = 0;
|
set_pos = 0;
|
||||||
|
|
||||||
if (set_len < TMIN_SET_MIN_SIZE) set_len = TMIN_SET_MIN_SIZE;
|
if (set_len < TMIN_SET_MIN_SIZE) { set_len = TMIN_SET_MIN_SIZE; }
|
||||||
|
|
||||||
ACTF(cBRI "Stage #0: " cRST "One-time block normalization...");
|
ACTF(cBRI "Stage #0: " cRST "One-time block normalization...");
|
||||||
|
|
||||||
@ -328,8 +339,11 @@ static void minimize(afl_forkserver_t *fsrv, char **argv) {
|
|||||||
|
|
||||||
u32 use_len = MIN(set_len, in_len - set_pos);
|
u32 use_len = MIN(set_len, in_len - set_pos);
|
||||||
|
|
||||||
for (i = 0; i < use_len; i++)
|
for (i = 0; i < use_len; i++) {
|
||||||
if (in_data[set_pos + i] != '0') break;
|
|
||||||
|
if (in_data[set_pos + i] != '0') { break; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (i != use_len) {
|
if (i != use_len) {
|
||||||
|
|
||||||
@ -374,7 +388,7 @@ next_pass:
|
|||||||
|
|
||||||
next_del_blksize:
|
next_del_blksize:
|
||||||
|
|
||||||
if (!del_len) del_len = 1;
|
if (!del_len) { del_len = 1; }
|
||||||
del_pos = 0;
|
del_pos = 0;
|
||||||
prev_del = 1;
|
prev_del = 1;
|
||||||
|
|
||||||
@ -387,7 +401,7 @@ next_del_blksize:
|
|||||||
s32 tail_len;
|
s32 tail_len;
|
||||||
|
|
||||||
tail_len = in_len - del_pos - del_len;
|
tail_len = in_len - del_pos - del_len;
|
||||||
if (tail_len < 0) tail_len = 0;
|
if (tail_len < 0) { tail_len = 0; }
|
||||||
|
|
||||||
/* If we have processed at least one full block (initially, prev_del == 1),
|
/* If we have processed at least one full block (initially, prev_del == 1),
|
||||||
and we did so without deleting the previous one, and we aren't at the
|
and we did so without deleting the previous one, and we aren't at the
|
||||||
@ -420,10 +434,12 @@ next_del_blksize:
|
|||||||
|
|
||||||
changed_any = 1;
|
changed_any = 1;
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
del_pos += del_len;
|
del_pos += del_len;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (del_len > 1 && in_len >= 1) {
|
if (del_len > 1 && in_len >= 1) {
|
||||||
@ -435,11 +451,14 @@ next_del_blksize:
|
|||||||
|
|
||||||
OKF("Block removal complete, %u bytes deleted.", stage_o_len - in_len);
|
OKF("Block removal complete, %u bytes deleted.", stage_o_len - in_len);
|
||||||
|
|
||||||
if (!in_len && changed_any)
|
if (!in_len && changed_any) {
|
||||||
|
|
||||||
WARNF(cLRD
|
WARNF(cLRD
|
||||||
"Down to zero bytes - check the command line and mem limit!" cRST);
|
"Down to zero bytes - check the command line and mem limit!" cRST);
|
||||||
|
|
||||||
if (cur_pass > 1 && !changed_any) goto finalize_all;
|
}
|
||||||
|
|
||||||
|
if (cur_pass > 1 && !changed_any) { goto finalize_all; }
|
||||||
|
|
||||||
/*************************
|
/*************************
|
||||||
* ALPHABET MINIMIZATION *
|
* ALPHABET MINIMIZATION *
|
||||||
@ -453,7 +472,7 @@ next_del_blksize:
|
|||||||
|
|
||||||
for (i = 0; i < in_len; i++) {
|
for (i = 0; i < in_len; i++) {
|
||||||
|
|
||||||
if (!alpha_map[in_data[i]]) alpha_size++;
|
if (!alpha_map[in_data[i]]) { alpha_size++; }
|
||||||
alpha_map[in_data[i]]++;
|
alpha_map[in_data[i]]++;
|
||||||
|
|
||||||
}
|
}
|
||||||
@ -466,12 +485,15 @@ next_del_blksize:
|
|||||||
u32 r;
|
u32 r;
|
||||||
u8 res;
|
u8 res;
|
||||||
|
|
||||||
if (i == '0' || !alpha_map[i]) continue;
|
if (i == '0' || !alpha_map[i]) { continue; }
|
||||||
|
|
||||||
memcpy(tmp_buf, in_data, in_len);
|
memcpy(tmp_buf, in_data, in_len);
|
||||||
|
|
||||||
for (r = 0; r < in_len; r++)
|
for (r = 0; r < in_len; r++) {
|
||||||
if (tmp_buf[r] == i) tmp_buf[r] = '0';
|
|
||||||
|
if (tmp_buf[r] == i) { tmp_buf[r] = '0'; }
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
|
res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
|
||||||
|
|
||||||
@ -506,7 +528,7 @@ next_del_blksize:
|
|||||||
|
|
||||||
u8 res, orig = tmp_buf[i];
|
u8 res, orig = tmp_buf[i];
|
||||||
|
|
||||||
if (orig == '0') continue;
|
if (orig == '0') { continue; }
|
||||||
tmp_buf[i] = '0';
|
tmp_buf[i] = '0';
|
||||||
|
|
||||||
res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
|
res = tmin_run_target(fsrv, argv, tmp_buf, in_len, 0);
|
||||||
@ -517,10 +539,12 @@ next_del_blksize:
|
|||||||
alpha_del2++;
|
alpha_del2++;
|
||||||
changed_any = 1;
|
changed_any = 1;
|
||||||
|
|
||||||
} else
|
} else {
|
||||||
|
|
||||||
tmp_buf[i] = orig;
|
tmp_buf[i] = orig;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
alpha_d_total += alpha_del2;
|
alpha_d_total += alpha_del2;
|
||||||
@ -528,11 +552,11 @@ next_del_blksize:
|
|||||||
OKF("Character minimization done, %u byte%s replaced.", alpha_del2,
|
OKF("Character minimization done, %u byte%s replaced.", alpha_del2,
|
||||||
alpha_del2 == 1 ? "" : "s");
|
alpha_del2 == 1 ? "" : "s");
|
||||||
|
|
||||||
if (changed_any) goto next_pass;
|
if (changed_any) { goto next_pass; }
|
||||||
|
|
||||||
finalize_all:
|
finalize_all:
|
||||||
|
|
||||||
if (tmp_buf) ck_free(tmp_buf);
|
if (tmp_buf) { ck_free(tmp_buf); }
|
||||||
|
|
||||||
if (hang_mode) {
|
if (hang_mode) {
|
||||||
|
|
||||||
@ -558,9 +582,12 @@ finalize_all:
|
|||||||
missed_hangs ? cLRD : "", missed_hangs);
|
missed_hangs ? cLRD : "", missed_hangs);
|
||||||
|
|
||||||
if (fsrv->total_execs > 50 && missed_hangs * 10 > fsrv->total_execs &&
|
if (fsrv->total_execs > 50 && missed_hangs * 10 > fsrv->total_execs &&
|
||||||
!hang_mode)
|
!hang_mode) {
|
||||||
|
|
||||||
WARNF(cLRD "Frequent timeouts - results may be skewed." cRST);
|
WARNF(cLRD "Frequent timeouts - results may be skewed." cRST);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/* Handle Ctrl-C and the like. */
|
/* Handle Ctrl-C and the like. */
|
||||||
@ -579,7 +606,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
|||||||
u8 *x;
|
u8 *x;
|
||||||
|
|
||||||
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
fsrv->dev_null_fd = open("/dev/null", O_RDWR);
|
||||||
if (fsrv->dev_null_fd < 0) PFATAL("Unable to open /dev/null");
|
if (fsrv->dev_null_fd < 0) { PFATAL("Unable to open /dev/null"); }
|
||||||
|
|
||||||
if (!out_file) {
|
if (!out_file) {
|
||||||
|
|
||||||
@ -588,7 +615,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
|||||||
if (access(use_dir, R_OK | W_OK | X_OK)) {
|
if (access(use_dir, R_OK | W_OK | X_OK)) {
|
||||||
|
|
||||||
use_dir = get_afl_env("TMPDIR");
|
use_dir = get_afl_env("TMPDIR");
|
||||||
if (!use_dir) use_dir = "/tmp";
|
if (!use_dir) { use_dir = "/tmp"; }
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -600,7 +627,7 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
fsrv->out_fd = open(out_file, O_RDWR | O_CREAT | O_EXCL, 0600);
|
||||||
|
|
||||||
if (fsrv->out_fd < 0) PFATAL("Unable to create '%s'", out_file);
|
if (fsrv->out_fd < 0) { PFATAL("Unable to create '%s'", out_file); }
|
||||||
|
|
||||||
/* Set sane defaults... */
|
/* Set sane defaults... */
|
||||||
|
|
||||||
@ -608,25 +635,37 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
|||||||
|
|
||||||
if (x) {
|
if (x) {
|
||||||
|
|
||||||
if (!strstr(x, "abort_on_error=1"))
|
if (!strstr(x, "abort_on_error=1")) {
|
||||||
|
|
||||||
FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!");
|
FATAL("Custom ASAN_OPTIONS set without abort_on_error=1 - please fix!");
|
||||||
|
|
||||||
if (!strstr(x, "symbolize=0"))
|
}
|
||||||
|
|
||||||
|
if (!strstr(x, "symbolize=0")) {
|
||||||
|
|
||||||
FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!");
|
FATAL("Custom ASAN_OPTIONS set without symbolize=0 - please fix!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
x = get_afl_env("MSAN_OPTIONS");
|
x = get_afl_env("MSAN_OPTIONS");
|
||||||
|
|
||||||
if (x) {
|
if (x) {
|
||||||
|
|
||||||
if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR)))
|
if (!strstr(x, "exit_code=" STRINGIFY(MSAN_ERROR))) {
|
||||||
|
|
||||||
FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY(
|
FATAL("Custom MSAN_OPTIONS set without exit_code=" STRINGIFY(
|
||||||
MSAN_ERROR) " - please fix!");
|
MSAN_ERROR) " - please fix!");
|
||||||
|
|
||||||
if (!strstr(x, "symbolize=0"))
|
}
|
||||||
|
|
||||||
|
if (!strstr(x, "symbolize=0")) {
|
||||||
|
|
||||||
FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!");
|
FATAL("Custom MSAN_OPTIONS set without symbolize=0 - please fix!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
setenv("ASAN_OPTIONS",
|
setenv("ASAN_OPTIONS",
|
||||||
@ -653,20 +692,28 @@ static void set_up_environment(afl_forkserver_t *fsrv) {
|
|||||||
s32 i, afl_preload_size = strlen(afl_preload);
|
s32 i, afl_preload_size = strlen(afl_preload);
|
||||||
for (i = 0; i < afl_preload_size; ++i) {
|
for (i = 0; i < afl_preload_size; ++i) {
|
||||||
|
|
||||||
if (afl_preload[i] == ',')
|
if (afl_preload[i] == ',') {
|
||||||
|
|
||||||
PFATAL(
|
PFATAL(
|
||||||
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
"Comma (',') is not allowed in AFL_PRELOAD when -Q is "
|
||||||
"specified!");
|
"specified!");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (qemu_preload)
|
if (qemu_preload) {
|
||||||
|
|
||||||
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("%s,LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
qemu_preload, afl_preload, afl_preload);
|
qemu_preload, afl_preload, afl_preload);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
buf = alloc_printf("LD_PRELOAD=%s,DYLD_INSERT_LIBRARIES=%s",
|
||||||
afl_preload, afl_preload);
|
afl_preload, afl_preload);
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
setenv("QEMU_SET_ENV", buf, 1);
|
setenv("QEMU_SET_ENV", buf, 1);
|
||||||
|
|
||||||
ck_free(buf);
|
ck_free(buf);
|
||||||
@ -772,40 +819,44 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
|
SAYF(cCYA "afl-tmin" VERSION cRST " by Michal Zalewski\n");
|
||||||
|
|
||||||
while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeQUWHh")) > 0)
|
while ((opt = getopt(argc, argv, "+i:o:f:m:t:B:xeQUWHh")) > 0) {
|
||||||
|
|
||||||
switch (opt) {
|
switch (opt) {
|
||||||
|
|
||||||
case 'i':
|
case 'i':
|
||||||
|
|
||||||
if (in_file) FATAL("Multiple -i options not supported");
|
if (in_file) { FATAL("Multiple -i options not supported"); }
|
||||||
in_file = optarg;
|
in_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'o':
|
case 'o':
|
||||||
|
|
||||||
if (output_file) FATAL("Multiple -o options not supported");
|
if (output_file) { FATAL("Multiple -o options not supported"); }
|
||||||
output_file = optarg;
|
output_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'f':
|
case 'f':
|
||||||
|
|
||||||
if (out_file) FATAL("Multiple -f options not supported");
|
if (out_file) { FATAL("Multiple -f options not supported"); }
|
||||||
fsrv->use_stdin = 0;
|
fsrv->use_stdin = 0;
|
||||||
out_file = optarg;
|
out_file = optarg;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'e':
|
case 'e':
|
||||||
|
|
||||||
if (edges_only) FATAL("Multiple -e options not supported");
|
if (edges_only) { FATAL("Multiple -e options not supported"); }
|
||||||
if (hang_mode)
|
if (hang_mode) {
|
||||||
|
|
||||||
FATAL("Edges only and hang mode are mutually exclusive.");
|
FATAL("Edges only and hang mode are mutually exclusive.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
edges_only = 1;
|
edges_only = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'x':
|
case 'x':
|
||||||
|
|
||||||
if (exit_crash) FATAL("Multiple -x options not supported");
|
if (exit_crash) { FATAL("Multiple -x options not supported"); }
|
||||||
exit_crash = 1;
|
exit_crash = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -813,10 +864,10 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
u8 suffix = 'M';
|
u8 suffix = 'M';
|
||||||
|
|
||||||
if (mem_limit_given) FATAL("Multiple -m options not supported");
|
if (mem_limit_given) { FATAL("Multiple -m options not supported"); }
|
||||||
mem_limit_given = 1;
|
mem_limit_given = 1;
|
||||||
|
|
||||||
if (!optarg) FATAL("Wrong usage of -m");
|
if (!optarg) { FATAL("Wrong usage of -m"); }
|
||||||
|
|
||||||
if (!strcmp(optarg, "none")) {
|
if (!strcmp(optarg, "none")) {
|
||||||
|
|
||||||
@ -826,66 +877,83 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 ||
|
if (sscanf(optarg, "%llu%c", &fsrv->mem_limit, &suffix) < 1 ||
|
||||||
optarg[0] == '-')
|
optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Bad syntax used for -m");
|
FATAL("Bad syntax used for -m");
|
||||||
|
|
||||||
switch (suffix) {
|
|
||||||
|
|
||||||
case 'T': fsrv->mem_limit *= 1024 * 1024; break;
|
|
||||||
case 'G': fsrv->mem_limit *= 1024; break;
|
|
||||||
case 'k': fsrv->mem_limit /= 1024; break;
|
|
||||||
case 'M': break;
|
|
||||||
|
|
||||||
default: FATAL("Unsupported suffix or bad syntax for -m");
|
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fsrv->mem_limit < 5) FATAL("Dangerously low value of -m");
|
switch (suffix) {
|
||||||
|
|
||||||
|
case 'T':
|
||||||
|
fsrv->mem_limit *= 1024 * 1024;
|
||||||
|
break;
|
||||||
|
case 'G':
|
||||||
|
fsrv->mem_limit *= 1024;
|
||||||
|
break;
|
||||||
|
case 'k':
|
||||||
|
fsrv->mem_limit /= 1024;
|
||||||
|
break;
|
||||||
|
case 'M':
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
FATAL("Unsupported suffix or bad syntax for -m");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
if (fsrv->mem_limit < 5) { FATAL("Dangerously low value of -m"); }
|
||||||
|
|
||||||
|
if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000) {
|
||||||
|
|
||||||
if (sizeof(rlim_t) == 4 && fsrv->mem_limit > 2000)
|
|
||||||
FATAL("Value of -m out of range on 32-bit systems");
|
FATAL("Value of -m out of range on 32-bit systems");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 't':
|
case 't':
|
||||||
|
|
||||||
if (timeout_given) FATAL("Multiple -t options not supported");
|
if (timeout_given) { FATAL("Multiple -t options not supported"); }
|
||||||
timeout_given = 1;
|
timeout_given = 1;
|
||||||
|
|
||||||
if (!optarg) FATAL("Wrong usage of -t");
|
if (!optarg) { FATAL("Wrong usage of -t"); }
|
||||||
|
|
||||||
fsrv->exec_tmout = atoi(optarg);
|
fsrv->exec_tmout = atoi(optarg);
|
||||||
|
|
||||||
if (fsrv->exec_tmout < 10 || optarg[0] == '-')
|
if (fsrv->exec_tmout < 10 || optarg[0] == '-') {
|
||||||
|
|
||||||
FATAL("Dangerously low value of -t");
|
FATAL("Dangerously low value of -t");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'Q':
|
case 'Q':
|
||||||
|
|
||||||
if (fsrv->qemu_mode) FATAL("Multiple -Q options not supported");
|
if (fsrv->qemu_mode) { FATAL("Multiple -Q options not supported"); }
|
||||||
if (!mem_limit_given) fsrv->mem_limit = MEM_LIMIT_QEMU;
|
if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_QEMU; }
|
||||||
|
|
||||||
fsrv->qemu_mode = 1;
|
fsrv->qemu_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'U':
|
case 'U':
|
||||||
|
|
||||||
if (unicorn_mode) FATAL("Multiple -Q options not supported");
|
if (unicorn_mode) { FATAL("Multiple -Q options not supported"); }
|
||||||
if (!mem_limit_given) fsrv->mem_limit = MEM_LIMIT_UNICORN;
|
if (!mem_limit_given) { fsrv->mem_limit = MEM_LIMIT_UNICORN; }
|
||||||
|
|
||||||
unicorn_mode = 1;
|
unicorn_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'W': /* Wine+QEMU mode */
|
case 'W': /* Wine+QEMU mode */
|
||||||
|
|
||||||
if (use_wine) FATAL("Multiple -W options not supported");
|
if (use_wine) { FATAL("Multiple -W options not supported"); }
|
||||||
fsrv->qemu_mode = 1;
|
fsrv->qemu_mode = 1;
|
||||||
use_wine = 1;
|
use_wine = 1;
|
||||||
|
|
||||||
if (!mem_limit_given) fsrv->mem_limit = 0;
|
if (!mem_limit_given) { fsrv->mem_limit = 0; }
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -893,9 +961,13 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
/* Minimizes a testcase to the minimum that still times out */
|
/* Minimizes a testcase to the minimum that still times out */
|
||||||
|
|
||||||
if (hang_mode) FATAL("Multipe -H options not supported");
|
if (hang_mode) { FATAL("Multipe -H options not supported"); }
|
||||||
if (edges_only)
|
if (edges_only) {
|
||||||
|
|
||||||
FATAL("Edges only and hang mode are mutually exclusive.");
|
FATAL("Edges only and hang mode are mutually exclusive.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
hang_mode = 1;
|
hang_mode = 1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -914,7 +986,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
The option may be extended and made more official if it proves
|
The option may be extended and made more official if it proves
|
||||||
to be useful. */
|
to be useful. */
|
||||||
|
|
||||||
if (mask_bitmap) FATAL("Multiple -B options not supported");
|
if (mask_bitmap) { FATAL("Multiple -B options not supported"); }
|
||||||
mask_bitmap = ck_alloc(map_size);
|
mask_bitmap = ck_alloc(map_size);
|
||||||
read_bitmap(optarg, mask_bitmap, map_size);
|
read_bitmap(optarg, mask_bitmap, map_size);
|
||||||
break;
|
break;
|
||||||
@ -924,11 +996,14 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
return -1;
|
return -1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: usage(argv[0]);
|
default:
|
||||||
|
usage(argv[0]);
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (optind == argc || !in_file || !output_file) usage(argv[0]);
|
}
|
||||||
|
|
||||||
|
if (optind == argc || !in_file || !output_file) { usage(argv[0]); }
|
||||||
|
|
||||||
check_environment_vars(envp);
|
check_environment_vars(envp);
|
||||||
|
|
||||||
@ -945,17 +1020,24 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
if (fsrv->qemu_mode) {
|
if (fsrv->qemu_mode) {
|
||||||
|
|
||||||
if (use_wine)
|
if (use_wine) {
|
||||||
|
|
||||||
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
|
use_argv = get_wine_argv(argv[0], &fsrv->target_path, argc - optind,
|
||||||
argv + optind);
|
argv + optind);
|
||||||
else
|
|
||||||
|
} else {
|
||||||
|
|
||||||
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
|
use_argv = get_qemu_argv(argv[0], &fsrv->target_path, argc - optind,
|
||||||
argv + optind);
|
argv + optind);
|
||||||
|
|
||||||
} else
|
}
|
||||||
|
|
||||||
|
} else {
|
||||||
|
|
||||||
use_argv = argv + optind;
|
use_argv = argv + optind;
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
exact_mode = !!get_afl_env("AFL_TMIN_EXACT");
|
exact_mode = !!get_afl_env("AFL_TMIN_EXACT");
|
||||||
|
|
||||||
if (hang_mode && exact_mode) {
|
if (hang_mode && exact_mode) {
|
||||||
@ -977,17 +1059,23 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
tmin_run_target(fsrv, use_argv, in_data, in_len, 1);
|
tmin_run_target(fsrv, use_argv, in_data, in_len, 1);
|
||||||
|
|
||||||
if (hang_mode && !fsrv->last_run_timed_out)
|
if (hang_mode && !fsrv->last_run_timed_out) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"Target binary did not time out but hang minimization mode "
|
"Target binary did not time out but hang minimization mode "
|
||||||
"(-H) was set (-t %u).",
|
"(-H) was set (-t %u).",
|
||||||
fsrv->exec_tmout);
|
fsrv->exec_tmout);
|
||||||
|
|
||||||
if (fsrv->last_run_timed_out && !hang_mode)
|
}
|
||||||
|
|
||||||
|
if (fsrv->last_run_timed_out && !hang_mode) {
|
||||||
|
|
||||||
FATAL(
|
FATAL(
|
||||||
"Target binary times out (adjusting -t may help). Use -H to minimize a "
|
"Target binary times out (adjusting -t may help). Use -H to minimize a "
|
||||||
"hang.");
|
"hang.");
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
if (hang_mode) {
|
if (hang_mode) {
|
||||||
|
|
||||||
OKF("Program hangs as expected, minimizing in " cCYA "hang" cRST " mode.");
|
OKF("Program hangs as expected, minimizing in " cCYA "hang" cRST " mode.");
|
||||||
@ -997,7 +1085,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
OKF("Program terminates normally, minimizing in " cCYA "instrumented" cRST
|
OKF("Program terminates normally, minimizing in " cCYA "instrumented" cRST
|
||||||
" mode.");
|
" mode.");
|
||||||
|
|
||||||
if (!anything_set(fsrv)) FATAL("No instrumentation detected.");
|
if (!anything_set(fsrv)) { FATAL("No instrumentation detected."); }
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
@ -1012,7 +1100,7 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
ACTF("Writing output to '%s'...", output_file);
|
ACTF("Writing output to '%s'...", output_file);
|
||||||
|
|
||||||
unlink(out_file);
|
unlink(out_file);
|
||||||
if (out_file) ck_free(out_file);
|
if (out_file) { ck_free(out_file); }
|
||||||
out_file = NULL;
|
out_file = NULL;
|
||||||
|
|
||||||
close(write_to_file(output_file, in_data, in_len));
|
close(write_to_file(output_file, in_data, in_len));
|
||||||
@ -1021,9 +1109,9 @@ int main(int argc, char **argv_orig, char **envp) {
|
|||||||
|
|
||||||
afl_shm_deinit(&shm);
|
afl_shm_deinit(&shm);
|
||||||
afl_fsrv_deinit(fsrv);
|
afl_fsrv_deinit(fsrv);
|
||||||
if (fsrv->target_path) ck_free(fsrv->target_path);
|
if (fsrv->target_path) { ck_free(fsrv->target_path); }
|
||||||
if (mask_bitmap) ck_free(mask_bitmap);
|
if (mask_bitmap) { ck_free(mask_bitmap); }
|
||||||
if (in_data) ck_free(in_data);
|
if (in_data) { ck_free(in_data); }
|
||||||
|
|
||||||
argv_cpy_free(argv);
|
argv_cpy_free(argv);
|
||||||
|
|
||||||
|
Reference in New Issue
Block a user