cmp dict for LTO
MODIFY
docs/Changelog.md
docs/Changelog.md
@@ -18,9 +18,10 @@ sending a mail to <afl-users+subscribe@googlegroups.com>.
- allow up to 4 -x command line options
- loaded extras now have a duplicate protection
- instrumentation
+ - not overriding -Ox or -fno-unroll-loops anymore
- new llvm pass: dict2file via AFL_LLVM_DICT2FILE, create afl-fuzz
-x dictionary of string comparisons found during compilation
- - not overriding -Ox or -fno-unroll-loops anymore
+ - LTO autodict now also collects interesting cmp comparisons
### Version ++2.68c (release)

MODIFY
include/xxhash.h
include/xxhash.h
@@ -1189,7 +1189,7 @@ static int XXH_isLittleEndian(void) {
return one.c[0];
}
-\
+
#define XXH_CPU_LITTLE_ENDIAN XXH_isLittleEndian()
#endif
#endif
@@ -1397,7 +1397,9 @@ static xxh_u32 XXH32_avalanche(xxh_u32 h32) {
static xxh_u32 XXH32_finalize(xxh_u32 h32, const xxh_u8 *ptr, size_t len,
XXH_alignment align) {
-\
+
+ /* dummy comment */
+
#define XXH_PROCESS1 \
do { \
\
@@ -1950,15 +1952,20 @@ XXH_FORCE_INLINE xxh_u64 XXH_readLE64_align(const void * ptr,
/******* xxh64 *******/
-static const xxh_u64 XXH_PRIME64_1 = 0x9E3779B185EBCA87ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111
+static const xxh_u64 XXH_PRIME64_1 =
+ 0x9E3779B185EBCA87ULL; /* 0b1001111000110111011110011011000110000101111010111100101010000111
*/
-static const xxh_u64 XXH_PRIME64_2 = 0xC2B2AE3D27D4EB4FULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111
+static const xxh_u64 XXH_PRIME64_2 =
+ 0xC2B2AE3D27D4EB4FULL; /* 0b1100001010110010101011100011110100100111110101001110101101001111
*/
-static const xxh_u64 XXH_PRIME64_3 = 0x165667B19E3779F9ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001
+static const xxh_u64 XXH_PRIME64_3 =
+ 0x165667B19E3779F9ULL; /* 0b0001011001010110011001111011000110011110001101110111100111111001
*/
-static const xxh_u64 XXH_PRIME64_4 = 0x85EBCA77C2B2AE63ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011
+static const xxh_u64 XXH_PRIME64_4 =
+ 0x85EBCA77C2B2AE63ULL; /* 0b1000010111101011110010100111011111000010101100101010111001100011
*/
-static const xxh_u64 XXH_PRIME64_5 = 0x27D4EB2F165667C5ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101
+static const xxh_u64 XXH_PRIME64_5 =
+ 0x27D4EB2F165667C5ULL; /* 0b0010011111010100111010110010111100010110010101100110011111000101
*/
#ifdef XXH_OLD_NAMES
@@ -2002,7 +2009,9 @@ static xxh_u64 XXH64_avalanche(xxh_u64 h64) {
static xxh_u64 XXH64_finalize(xxh_u64 h64, const xxh_u8 *ptr, size_t len,
XXH_alignment align) {
-\
+
+ /* dummy comment */
+
#define XXH_PROCESS1_64 \
do { \
\
@@ -2752,6 +2761,7 @@ XXH64_hashFromCanonical(const XXH64_canonical_t *src) {
(outHi) = vget_high_u32(vreinterpretq_u32_u64(in)); \
\
} while (0)
+
#else
#define XXH_SPLIT_IN_PLACE(in, outLo, outHi) \
do { \
@@ -2760,6 +2770,7 @@ XXH64_hashFromCanonical(const XXH64_canonical_t *src) {
(outHi) = vshrn_n_u64((in), 32); \
\
} while (0)
+
#endif
#endif /* XXH_VECTOR == XXH_NEON */

MODIFY
instrumentation/SanitizerCoverageLTO.so.cc
instrumentation/SanitizerCoverageLTO.so.cc
#include <string>
#include <fstream>
#include <set>
+#include <iostream>
#include "llvm/Transforms/Instrumentation/SanitizerCoverage.h"
#include "llvm/ADT/ArrayRef.h"
@@ -249,6 +250,7 @@ class ModuleSanitizerCoverage {
GlobalVariable * AFLMapPtr = NULL;
Value * MapPtrFixed = NULL;
FILE * documentFile = NULL;
+ size_t found = 0;
// afl++ END
};
@@ -513,6 +515,92 @@ bool ModuleSanitizerCoverage::instrumentModule(
for (auto &IN : BB) {
CallInst *callInst = nullptr;
+ CmpInst * cmpInst = nullptr;
+
+ if ((cmpInst = dyn_cast<CmpInst>(&IN))) {
+
+ Value * op = cmpInst->getOperand(1);
+ ConstantInt *ilen = dyn_cast<ConstantInt>(op);
+
+ if (ilen) {
+
+ u64 val2 = 0, val = ilen->getZExtValue();
+ u32 len = 0;
+ if (val > 0x10000 && val < 0xffffffff) len = 4;
+ if (val > 0x100000001 && val < 0xffffffffffffffff) len = 8;
+
+ if (len) {
+
+ auto c = cmpInst->getPredicate();
+
+ switch (c) {
+
+ case CmpInst::FCMP_OGT: // fall through
+ case CmpInst::FCMP_OLE: // fall through
+ case CmpInst::ICMP_SLE: // fall through
+ case CmpInst::ICMP_SGT:
+
+ // signed comparison and it is a negative constant
+ if ((len == 4 && (val & 80000000)) ||
+ (len == 8 && (val & 8000000000000000))) {
+
+ if ((val & 0xffff) != 1) val2 = val - 1;
+ break;
+
+ }
+
+ // fall through
+
+ case CmpInst::FCMP_UGT: // fall through
+ case CmpInst::FCMP_ULE: // fall through
+ case CmpInst::ICMP_UGT: // fall through
+ case CmpInst::ICMP_ULE:
+ if ((val & 0xffff) != 0xfffe) val2 = val + 1;
+ break;
+
+ case CmpInst::FCMP_OLT: // fall through
+ case CmpInst::FCMP_OGE: // fall through
+ case CmpInst::ICMP_SLT: // fall through
+ case CmpInst::ICMP_SGE:
+
+ // signed comparison and it is a negative constant
+ if ((len == 4 && (val & 80000000)) ||
+ (len == 8 && (val & 8000000000000000))) {
+
+ if ((val & 0xffff) != 1) val2 = val - 1;
+ break;
+
+ }
+
+ // fall through
+
+ case CmpInst::FCMP_ULT: // fall through
+ case CmpInst::FCMP_UGE: // fall through
+ case CmpInst::ICMP_ULT: // fall through
+ case CmpInst::ICMP_UGE:
+ if ((val & 0xffff) != 1) val2 = val - 1;
+ break;
+
+ default:
+ val2 = 0;
+
+ }
+
+ dictionary.push_back(std::string((char *)&val, len));
+ found++;
+
+ if (val2) {
+
+ dictionary.push_back(std::string((char *)&val2, len));
+ found++;
+
+ }
+
+ }
+
+ }
+
+ }
if ((callInst = dyn_cast<CallInst>(&IN))) {
@@ -917,6 +1005,11 @@ bool ModuleSanitizerCoverage::instrumentModule(
size_t memlen = 0, count = 0, offset = 0;
char * ptr;
+ // sort and unique the dictionary
+ std::sort(dictionary.begin(), dictionary.end());
+ auto last = std::unique(dictionary.begin(), dictionary.end());
+ dictionary.erase(last, dictionary.end());
+
for (auto token : dictionary) {
memlen += token.length();

MODIFY
instrumentation/afl-llvm-lto-instrumentation.so.cc
instrumentation/afl-llvm-lto-instrumentation.so.cc
#include <string>
#include <fstream>
#include <set>
+#include <iostream>
#include "llvm/Config/llvm-config.h"
#include "llvm/ADT/Statistic.h"
@@ -106,6 +107,7 @@ bool AFLLTOPass::runOnModule(Module &M) {
std::vector<BasicBlock *> BlockList;
char * ptr;
FILE * documentFile = NULL;
+ size_t found = 0;
srand((unsigned int)time(NULL));
@@ -284,6 +286,92 @@ bool AFLLTOPass::runOnModule(Module &M) {
for (auto &IN : BB) {
CallInst *callInst = nullptr;
+ CmpInst * cmpInst = nullptr;
+
+ if ((cmpInst = dyn_cast<CmpInst>(&IN))) {
+
+ Value * op = cmpInst->getOperand(1);
+ ConstantInt *ilen = dyn_cast<ConstantInt>(op);
+
+ if (ilen) {
+
+ u64 val2 = 0, val = ilen->getZExtValue();
+ u32 len = 0;
+ if (val > 0x10000 && val < 0xffffffff) len = 4;
+ if (val > 0x100000001 && val < 0xffffffffffffffff) len = 8;
+
+ if (len) {
+
+ auto c = cmpInst->getPredicate();
+
+ switch (c) {
+
+ case CmpInst::FCMP_OGT: // fall through
+ case CmpInst::FCMP_OLE: // fall through
+ case CmpInst::ICMP_SLE: // fall through
+ case CmpInst::ICMP_SGT:
+
+ // signed comparison and it is a negative constant
+ if ((len == 4 && (val & 80000000)) ||
+ (len == 8 && (val & 8000000000000000))) {
+
+ if ((val & 0xffff) != 1) val2 = val - 1;
+ break;
+
+ }
+
+ // fall through
+
+ case CmpInst::FCMP_UGT: // fall through
+ case CmpInst::FCMP_ULE: // fall through
+ case CmpInst::ICMP_UGT: // fall through
+ case CmpInst::ICMP_ULE:
+ if ((val & 0xffff) != 0xfffe) val2 = val + 1;
+ break;
+
+ case CmpInst::FCMP_OLT: // fall through
+ case CmpInst::FCMP_OGE: // fall through
+ case CmpInst::ICMP_SLT: // fall through
+ case CmpInst::ICMP_SGE:
+
+ // signed comparison and it is a negative constant
+ if ((len == 4 && (val & 80000000)) ||
+ (len == 8 && (val & 8000000000000000))) {
+
+ if ((val & 0xffff) != 1) val2 = val - 1;
+ break;
+
+ }
+
+ // fall through
+
+ case CmpInst::FCMP_ULT: // fall through
+ case CmpInst::FCMP_UGE: // fall through
+ case CmpInst::ICMP_ULT: // fall through
+ case CmpInst::ICMP_UGE:
+ if ((val & 0xffff) != 1) val2 = val - 1;
+ break;
+
+ default:
+ val2 = 0;
+
+ }
+
+ dictionary.push_back(std::string((char *)&val, len));
+ found++;
+
+ if (val2) {
+
+ dictionary.push_back(std::string((char *)&val2, len));
+ found++;
+
+ }
+
+ }
+
+ }
+
+ }
if ((callInst = dyn_cast<CallInst>(&IN))) {
@@ -842,6 +930,11 @@ bool AFLLTOPass::runOnModule(Module &M) {
size_t memlen = 0, count = 0, offset = 0;
char * ptr;
+ // sort and unique the dictionary
+ std::sort(dictionary.begin(), dictionary.end());
+ auto last = std::unique(dictionary.begin(), dictionary.end());
+ dictionary.erase(last, dictionary.end());
+
for (auto token : dictionary) {
memlen += token.length();

cmp dict for LTO