final touches

This commit is contained in:
van Hauser
2019-07-05 11:28:08 +02:00
parent 9199967022
commit 7f6aaa5314
5 changed files with 71 additions and 55 deletions

View File

@ -17,6 +17,8 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
Version ++2.52d (tbd):
-----------------------------
- added never zero counters for afl-gcc and optional (because of an
optimization issue in llvm < 9) for llvm_mode (AFL_LLVM_NEVER_ZERO=1)
- added whitelist support for llvm_mode via AFL_LLVM_WHITELIST to allow
only to instrument what is actually interesting. Gives more speed and less
map pollution (originally by choller@mozilla)

View File

@ -108,8 +108,11 @@ Then there are a few specific features that are only available in llvm_mode:
OTHER
=====
- Setting AFL_NZERO_COUNTS=1 during compilation will use counters
that skip zero on overflow.
- Setting export AFL_LLVM_NOT_ZERO=1 during compilation will use counters
that skip zero on overflow. This is the default for llvm >= 9,
however for llvm versions below that this will increase an unnecessary
slowdown due a performance issue that is only fixed in llvm 9+.
This feature increases path discovery by a little bit.
Note that AFL_INST_RATIO will behave a bit differently than for afl-gcc,
because functions are *not* instrumented unconditionally - so low values

View File

@ -25,11 +25,17 @@ VERSION = $(shell grep '^\#define VERSION ' ../config.h | cut -d '"' -f2)
LLVM_CONFIG ?= llvm-config
#LLVM_OK = $(shell $(LLVM_CONFIG) --version | egrep -q '^[5-6]' && echo 0 || echo 1 )
LLVM_UNSUPPORTED = $(shell $(LLVM_CONFIG) --version | egrep -q '^9|3.0' && echo 1 || echo 0 )
LLVM_MAJOR = ($shell $(LLVM_CONFIG) --version | sed 's/\..*//')
ifeq "$(LLVM_UNSUPPORTED)" "1"
$(warn llvm_mode only supports versions 3.8.0 up to 8.x )
endif
# this is not visible yet:
ifeq "$(LLVM_MAJOR)" "9"
$(info llvm_mode deteted llvm 9, enabling neverZero implementation)
endif
CFLAGS ?= -O3 -funroll-loops
CFLAGS += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign \
-DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \

View File

@ -0,0 +1,22 @@
Usage
=====
In larger, complex or reiterative programs the map that collects the edge pairs
can easily fill up and wrap.
This is not that much of an issue - unless by chance it wraps just to a 0
when the program execution ends.
In this case afl-fuzz is not able to see that the pair has been accessed and
will ignore it.
NeverZero prevents this behaviour. If a counter wraps, it jumps over the 0
directly to a 1. This improves path discovery (by a very little amount)
at a very little cost (one instruction per edge).
This is implemented in afl-gcc, however for llvm_mode this is optional if
the llvm version is below 9 - as there is a perfomance bug that is only fixed
in version 9 and onwards.
If you want to enable this for llvm < 9 then set
export AFL_LLVM_NOT_ZERO=1

View File

@ -118,7 +118,9 @@ bool AFLCoverage::runOnModule(Module &M) {
}
char* neverZero_counters_str = getenv("AFL_NZERO_COUNTS");
#if LLVM_VERSION_MAJOR < 9
char* neverZero_counters_str = getenv("AFL_LLVM_NOT_ZERO");
#endif
/* Get globals for the SHM region and the previous location. Note that
__afl_prev_loc is thread-local. */
@ -236,75 +238,56 @@ bool AFLCoverage::runOnModule(Module &M) {
LoadInst *Counter = IRB.CreateLoad(MapPtrIdx);
Counter->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
Value *Incr;
// if (neverZero_counters_str == NULL || neverZero_counters_str[0] != '4')
Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
Value *Incr = IRB.CreateAdd(Counter, ConstantInt::get(Int8Ty, 1));
if (neverZero_counters_str != NULL) {
/* hexcoder: Realize a counter that skips zero during overflow.
* Once this counter reaches its maximum value, it next increments to 1
*
* Instead of
* Counter + 1 -> Counter
* we inject now this
* Counter + 1 -> {Counter, OverflowFlag}
* Counter + OverflowFlag -> Counter
*/
// Solution #1 - creates
//mov ecx,edx
//add cl,0x1
//adc dl,0x1
/*
if (neverZero_counters_str[0] == '1') {
CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, ConstantInt::get(Int8Ty, 1));
AddOv->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
Value *SumWithOverflowBit = AddOv;
Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0), // sum
IRB.CreateZExt( // convert from one bit type to 8 bits type
IRB.CreateExtractValue(SumWithOverflowBit, 1), // overflow
Int8Ty));
// Solution #2 - creates the same code as #1
#if LLVM_VERSION_MAJOR < 9
if (neverZero_counters_str != NULL) { // with llvm 9 we make this the default as the bug in llvm is then fixed
#endif
/* hexcoder: Realize a counter that skips zero during overflow.
* Once this counter reaches its maximum value, it next increments to 1
*
* Instead of
* Counter + 1 -> Counter
* we inject now this
* Counter + 1 -> {Counter, OverflowFlag}
* Counter + OverflowFlag -> Counter
*/
/* // we keep the old solutions just in case
// Solution #1
if (neverZero_counters_str[0] == '1') {
CallInst *AddOv = IRB.CreateBinaryIntrinsic(Intrinsic::uadd_with_overflow, Counter, ConstantInt::get(Int8Ty, 1));
AddOv->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));
Value *SumWithOverflowBit = AddOv;
Incr = IRB.CreateAdd(IRB.CreateExtractValue(SumWithOverflowBit, 0), // sum
IRB.CreateZExt( // convert from one bit type to 8 bits type
IRB.CreateExtractValue(SumWithOverflowBit, 1), // overflow
Int8Ty));
// Solution #2
} else if (neverZero_counters_str[0] == '2') {
auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
Incr = IRB.CreateAdd(Incr, cf);
// Solution #3 - creates
//add cl,0x1
//cmp cl,0x1
//adc cl,0x0
} else if (neverZero_counters_str[0] == '3') {
auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0));
Incr = IRB.CreateAdd(Incr, cf);
// Solution #4 - creates
// cmp dl, $0xff
// sete cl
// add dl,cl
// add dl,0x01
} else if (neverZero_counters_str[0] == '4') {
auto cf = IRB.CreateICmpEQ(Counter, ConstantInt::get(Int8Ty, 255));
Value *HowMuch = IRB.CreateAdd(ConstantInt::get(Int8Ty, 1), cf);
Incr = IRB.CreateAdd(Counter, HowMuch);
} else if (neverZero_counters_str[0] == '5') {
// Solution #3
} else if (neverZero_counters_str[0] == '3') {
*/
// this is the solution we choose because llvm9 should do the right thing here
auto cf = IRB.CreateICmpEQ(Incr, ConstantInt::get(Int8Ty, 0));
auto carry = IRB.CreateZExt(cf, Int8Ty);
Incr = IRB.CreateAdd(Incr, carry);
/*
} else if (neverZero_counters_str[0] == '6') {
// Solution #4
} else if (neverZero_counters_str[0] == '4') {
auto cf = IRB.CreateICmpULT(Incr, ConstantInt::get(Int8Ty, 1));
auto carry = IRB.CreateZExt(cf, Int8Ty);
Incr = IRB.CreateAdd(Incr, carry);
// no other implementations yet
} else {
} else {
fprintf(stderr, "Error: unknown value for AFL_NZERO_COUNTS: %s (valid is 1-4)\n", neverZero_counters_str);
exit(-1);
}
}
*/
#if LLVM_VERSION_MAJOR < 9
}
#endif
IRB.CreateStore(Incr, MapPtrIdx)->setMetadata(M.getMDKindID("nosanitize"), MDNode::get(C, None));