small improvements to Marcel's patch, fix laf-intel + redqueen crashes

This commit is contained in:
van Hauser
2020-09-29 15:02:57 +02:00
parent fe08482c1b
commit 383cd487a2
12 changed files with 104 additions and 74 deletions

View File

@ -14,6 +14,7 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- all compilers combined to afl-cc which emulates the previous ones
- afl-llvm/gcc-rt.o merged into afl-compiler-rt.o
- afl-fuzz
- Marcel Boehme submitted a patch that improves all AFFast schedules :)
- reading testcases from -i now descends into subdirectories
- allow up to 4 -x command line options
- loaded extras now have a duplicate protection

View File

@ -151,7 +151,8 @@ struct queue_entry {
is_ascii; /* Is the input just ascii text? */
u32 bitmap_size, /* Number of bits set in bitmap */
fuzz_level; /* Number of fuzzing iterations */
fuzz_level, /* Number of fuzzing iterations */
n_fuzz_entry; /* offset in n_fuzz */
u64 exec_us, /* Execution time (us) */
handicap, /* Number of queue cycles behind */
@ -491,7 +492,7 @@ typedef struct afl_state {
u8 *var_bytes; /* Bytes that appear to be variable */
#define n_fuzz_size (1 << 21)
#define N_FUZZ_SIZE (1 << 21)
u32 *n_fuzz;
volatile u8 stop_soon, /* Ctrl-C pressed? */

View File

@ -381,8 +381,9 @@ bool AFLdict2filePass::runOnModule(Module &M) {
if (debug)
fprintf(stderr, "F:%s %p(%s)->\"%s\"(%s) %p(%s)->\"%s\"(%s)\n",
FuncName.c_str(), (void*)Str1P, Str1P->getName().str().c_str(),
Str1.c_str(), HasStr1 == true ? "true" : "false", (void*)Str2P,
FuncName.c_str(), (void *)Str1P,
Str1P->getName().str().c_str(), Str1.c_str(),
HasStr1 == true ? "true" : "false", (void *)Str2P,
Str2P->getName().str().c_str(), Str2.c_str(),
HasStr2 == true ? "true" : "false");
@ -436,7 +437,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
valueMap[Str1P] = new std::string(Str2);
if (debug)
fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(), (void*)Str1P);
fprintf(stderr, "Saved: %s for %p\n", Str2.c_str(),
(void *)Str1P);
continue;
}
@ -455,7 +457,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
Str2 = *strng;
HasStr2 = true;
if (debug)
fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(), (void*)Str2P);
fprintf(stderr, "Filled2: %s for %p\n", strng->c_str(),
(void *)Str2P);
}
@ -497,7 +500,8 @@ bool AFLdict2filePass::runOnModule(Module &M) {
Str1 = *strng;
HasStr1 = true;
if (debug)
fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(), (void*)Str1P);
fprintf(stderr, "Filled1: %s for %p\n", strng->c_str(),
(void *)Str1P);
}

View File

@ -210,7 +210,8 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
}
if (!icomps.size()) return false;
if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp instructions\n";
// if (!be_quiet) errs() << "Hooking " << icomps.size() << " cmp
// instructions\n";
for (auto &selectcmpInst : icomps) {
@ -259,8 +260,7 @@ bool CmpLogInstructions::hookInstrs(Module &M) {
bool CmpLogInstructions::runOnModule(Module &M) {
if (getenv("AFL_QUIET") == NULL)
llvm::errs()
<< "Running cmplog-instructions-pass by andreafioraldi@gmail.com\n";
printf("Running cmplog-instructions-pass by andreafioraldi@gmail.com\n");
else
be_quiet = 1;
hookInstrs(M);

View File

@ -149,9 +149,11 @@ bool CmpLogRoutines::hookRtns(Module &M) {
}
if (!calls.size()) return false;
/*
if (!be_quiet)
errs() << "Hooking " << calls.size()
<< " calls with pointers as arguments\n";
*/
for (auto &callInst : calls) {
@ -179,8 +181,7 @@ bool CmpLogRoutines::hookRtns(Module &M) {
bool CmpLogRoutines::runOnModule(Module &M) {
if (getenv("AFL_QUIET") == NULL)
llvm::errs()
<< "Running cmplog-routines-pass by andreafioraldi@gmail.com\n";
printf("Running cmplog-routines-pass by andreafioraldi@gmail.com\n");
else
be_quiet = 1;
hookRtns(M);

View File

@ -339,8 +339,9 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
if (!calls.size()) return false;
if (!be_quiet)
errs() << "Replacing " << calls.size()
<< " calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n";
printf(
"Replacing %lu calls to strcmp/memcmp/strncmp/strcasecmp/strncasecmp\n",
calls.size());
for (auto &callInst : calls) {
@ -426,11 +427,14 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
else
unrollLen = constStrLen;
/*
if (!be_quiet)
errs() << callInst->getCalledFunction()->getName() << ": unroll len "
<< unrollLen
<< ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ": "
<< ((isSizedcmp && !isConstSized) ? ", variable n" : "") << ":
"
<< ConstStr << "\n";
*/
/* split before the call instruction */
BasicBlock *bb = callInst->getParent();
@ -556,10 +560,12 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
bool CompareTransform::runOnModule(Module &M) {
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
llvm::errs() << "Running compare-transform-pass by laf.intel@gmail.com, "
"extended by heiko@hexco.de\n";
printf(
"Running compare-transform-pass by laf.intel@gmail.com, extended by "
"heiko@hexco.de\n");
else
be_quiet = 1;
transformCmps(M, true, true, true, true, true);
verifyModule(M);

View File

@ -1262,8 +1262,9 @@ bool SplitComparesTransform::runOnModule(Module &M) {
if ((isatty(2) && getenv("AFL_QUIET") == NULL) ||
getenv("AFL_DEBUG") != NULL) {
errs() << "Split-compare-pass by laf.intel@gmail.com, extended by "
"heiko@hexco.de\n";
printf(
"Split-compare-pass by laf.intel@gmail.com, extended by "
"heiko@hexco.de\n");
} else {
@ -1275,6 +1276,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
count = splitFPCompares(M);
/*
if (!be_quiet) {
errs() << "Split-floatingpoint-compare-pass: " << count
@ -1282,6 +1284,7 @@ bool SplitComparesTransform::runOnModule(Module &M) {
}
*/
simplifyFPCompares(M);
}
@ -1294,10 +1297,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
case 64:
count = splitIntCompares(M, bitw);
/*
if (!be_quiet)
errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
count
<< " split\n";
*/
bitw >>= 1;
#if LLVM_VERSION_MAJOR > 3 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7)
@ -1305,10 +1310,12 @@ bool SplitComparesTransform::runOnModule(Module &M) {
#endif
case 32:
count = splitIntCompares(M, bitw);
/*
if (!be_quiet)
errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
count
<< " split\n";
*/
bitw >>= 1;
#if LLVM_VERSION_MAJOR > 3 || \
(LLVM_VERSION_MAJOR == 3 && LLVM_VERSION_MINOR > 7)
@ -1316,15 +1323,17 @@ bool SplitComparesTransform::runOnModule(Module &M) {
#endif
case 16:
count = splitIntCompares(M, bitw);
/*
if (!be_quiet)
errs() << "Split-integer-compare-pass " << bitw << "bit: " << count
errs() << "Split-integer-compare-pass " << bitw << "bit: " <<
count
<< " split\n";
*/
bitw >>= 1;
break;
default:
if (!be_quiet) errs() << "NOT Running split-compare-pass \n";
// if (!be_quiet) errs() << "NOT Running split-compare-pass \n";
return false;
break;

View File

@ -327,10 +327,11 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
}
if (!switches.size()) return false;
/*
if (!be_quiet)
errs() << "Rewriting " << switches.size() << " switch statements "
<< "\n";
*/
for (auto &SI : switches) {
BasicBlock *CurBlock = SI->getParent();
@ -341,15 +342,17 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
BasicBlock *Default = SI->getDefaultDest();
unsigned bitw = Val->getType()->getIntegerBitWidth();
/*
if (!be_quiet)
errs() << "switch: " << SI->getNumCases() << " cases " << bitw
<< " bit\n";
*/
/* If there is only the default destination or the condition checks 8 bit or
* less, don't bother with the code below. */
if (!SI->getNumCases() || bitw <= 8) {
if (!be_quiet) errs() << "skip trivial switch..\n";
// if (!be_quiet) errs() << "skip trivial switch..\n";
continue;
}
@ -415,7 +418,7 @@ bool SplitSwitchesTransform::splitSwitches(Module &M) {
bool SplitSwitchesTransform::runOnModule(Module &M) {
if ((isatty(2) && getenv("AFL_QUIET") == NULL) || getenv("AFL_DEBUG") != NULL)
llvm::errs() << "Running split-switches-pass by laf.intel@gmail.com\n";
printf("Running split-switches-pass by laf.intel@gmail.com\n");
else
be_quiet = 1;
splitSwitches(M);

View File

@ -556,8 +556,8 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
/* Saturated increment */
if (afl->n_fuzz[cksum % n_fuzz_size] < 0xFFFFFFFF)
afl->n_fuzz[cksum % n_fuzz_size]++;
if (afl->n_fuzz[cksum % N_FUZZ_SIZE] < 0xFFFFFFFF)
afl->n_fuzz[cksum % N_FUZZ_SIZE]++;
}
@ -597,10 +597,15 @@ save_if_interesting(afl_state_t *afl, void *mem, u32 len, u8 fault) {
if (cksum)
afl->queue_top->exec_cksum = cksum;
else
afl->queue_top->exec_cksum =
cksum = afl->queue_top->exec_cksum =
hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
afl->n_fuzz[cksum % n_fuzz_size] = 1;
if (afl->schedule >= FAST && afl->schedule <= RARE) {
afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
}
/* Try to calibrate inline; this also calls update_bitmap_score() when
successful. */

View File

@ -732,8 +732,8 @@ void read_testcases(afl_state_t *afl, u8 *directory) {
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE)) {
u64 cksum = hash64(afl->fsrv.trace_bits, afl->fsrv.map_size, HASH_CONST);
afl->n_fuzz[cksum % n_fuzz_size] = 1;
afl->queue_top->n_fuzz_entry = cksum % N_FUZZ_SIZE;
afl->n_fuzz[afl->queue_top->n_fuzz_entry] = 1;
}

View File

@ -310,7 +310,7 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
if (unlikely(afl->schedule >= FAST && afl->schedule < RARE))
fuzz_p2 = 0; // Skip the fuzz_p2 comparison
else if (unlikely(afl->schedule == RARE))
fuzz_p2 = next_pow2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]);
fuzz_p2 = next_pow2(afl->n_fuzz[q->n_fuzz_entry]);
else
fuzz_p2 = q->fuzz_level;
@ -336,7 +336,8 @@ void update_bitmap_score(afl_state_t *afl, struct queue_entry *q) {
u64 top_rated_fav_factor;
u64 top_rated_fuzz_p2;
if (unlikely(afl->schedule >= FAST && afl->schedule <= RARE))
top_rated_fuzz_p2 = next_pow2(afl->n_fuzz[afl->top_rated[i]->exec_cksum % n_fuzz_size]);
top_rated_fuzz_p2 =
next_pow2(afl->n_fuzz[afl->top_rated[i]->n_fuzz_entry]);
else
top_rated_fuzz_p2 = afl->top_rated[i]->fuzz_level;
@ -611,7 +612,6 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
double factor = 1.0;
long double fuzz_mu;
switch (afl->schedule) {
case EXPLORE:
@ -634,7 +634,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
struct queue_entry *queue_it = afl->queue;
while (queue_it) {
fuzz_mu += log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]);
fuzz_mu += log2(afl->n_fuzz[q->n_fuzz_entry]);
n_paths++;
queue_it = queue_it->next;
@ -645,7 +645,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
fuzz_mu = fuzz_mu / n_paths;
if (log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size]) > fuzz_mu) {
if (log2(afl->n_fuzz[q->n_fuzz_entry]) > fuzz_mu) {
/* Never skip favourites */
if (!q->favored) factor = 0;
@ -660,7 +660,7 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
// Don't modify unfuzzed seeds
if (q->fuzz_level == 0) break;
switch ((u32)log2(afl->n_fuzz[q->exec_cksum % n_fuzz_size])) {
switch ((u32)log2(afl->n_fuzz[q->n_fuzz_entry])) {
case 0 ... 1:
factor = 4;
@ -691,17 +691,17 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
}
if (q->favored)
factor *= 1.15;
if (q->favored) factor *= 1.15;
break;
case LIN:
factor = q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1);
factor = q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
break;
case QUAD:
factor = q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->exec_cksum % n_fuzz_size] + 1);
factor =
q->fuzz_level * q->fuzz_level / (afl->n_fuzz[q->n_fuzz_entry] + 1);
break;
case MMOPT:
@ -726,8 +726,8 @@ u32 calculate_score(afl_state_t *afl, struct queue_entry *q) {
perf_score += (q->tc_ref * 10);
// the more often fuzz result paths are equal to this queue entry,
// reduce its value
perf_score *=
(1 - (double)((double)afl->n_fuzz[q->exec_cksum % n_fuzz_size] / (double)afl->fsrv.total_execs));
perf_score *= (1 - (double)((double)afl->n_fuzz[q->n_fuzz_entry] /
(double)afl->fsrv.total_execs));
break;

View File

@ -939,7 +939,7 @@ int main(int argc, char **argv_orig, char **envp) {
/* Dynamically allocate memory for AFLFast schedules */
if (afl->schedule >= FAST && afl->schedule <= RARE) {
afl->n_fuzz = ck_alloc(n_fuzz_size * sizeof(u32));
afl->n_fuzz = ck_alloc(N_FUZZ_SIZE * sizeof(u32));
}