about summary refs log tree commit diff
diff options
context:
space:
mode:
authorAndrea Fioraldi <andreafioraldi@gmail.com>2019-10-31 16:19:26 +0100
committerAndrea Fioraldi <andreafioraldi@gmail.com>2019-10-31 16:19:26 +0100
commit58fe2f2c767b4dfe973b75feaf7df78c798b62d5 (patch)
tree9c00033f34783b1f184641a2ae47734c2b542913
parent664f603a31ff7b118d14fa6409dd662ee604b36c (diff)
parentb17afc10a23cf87b3a0b8290491de4edd80c9c71 (diff)
downloadafl++-58fe2f2c767b4dfe973b75feaf7df78c798b62d5.tar.gz
Merge branch 'master' of github.com:vanhauser-thc/AFLplusplus
-rw-r--r--.travis.yml21
-rw-r--r--docs/ChangeLog13
-rw-r--r--gcc_plugin/afl-gcc-fast.c15
-rw-r--r--libdislocator/libdislocator.so.c49
-rw-r--r--libtokencap/Makefile3
-rw-r--r--libtokencap/libtokencap.so.c61
-rw-r--r--llvm_mode/LLVMInsTrim.so.cc15
-rw-r--r--llvm_mode/Makefile2
-rw-r--r--llvm_mode/afl-clang-fast.c16
-rw-r--r--llvm_mode/afl-llvm-pass.so.cc2
-rw-r--r--llvm_mode/compare-transform-pass.so.cc4
-rw-r--r--llvm_mode/split-compares-pass.so.cc2
-rw-r--r--src/afl-analyze.c2
-rw-r--r--src/afl-gcc.c1
-rwxr-xr-xtest/test.sh15
15 files changed, 184 insertions, 37 deletions
diff --git a/.travis.yml b/.travis.yml
index 9ef95bcf..87b3ef04 100644
--- a/.travis.yml
+++ b/.travis.yml
@@ -1,11 +1,20 @@
+dist: bionic
 language: c
 
 env:
-  - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1
+  - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_STOP_MANUALLY=1
+  - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_EXIT_WHEN_DONE=1
+ # TODO: test AFL_BENCH_UNTIL_CRASH once we have a target that crashes
+  - AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1 AFL_NO_UI=1 AFL_BENCH_JUST_ONE=1
+
+before_install:
+  - sudo apt update
+  - sudo apt install -y libtool libtool-bin automake bison libglib2.0 build-essential clang gcc-8 gcc-8-plugin-dev libc++-8-dev
+# libc++-7-dev
 
 script:
-  - make
-  - ./afl-gcc ./test-instr.c -o test-instr
-  - mkdir seeds; mkdir out
-  - echo "" > seeds/nil_seed
-  - timeout --preserve-status 5s ./afl-fuzz -i seeds -o out/ -- ./test-instr
+  - gcc -v
+  - clang -v
+  - make distrib
+  - make tests
+  - make clean
diff --git a/docs/ChangeLog b/docs/ChangeLog
index c2d46e4d..4c51502b 100644
--- a/docs/ChangeLog
+++ b/docs/ChangeLog
@@ -13,6 +13,19 @@ Want to stay in the loop on major new features? Join our mailing list by
 sending a mail to <afl-users+subscribe@googlegroups.com>.
 
 
+----------------------
+Version ++2.58d (dev):
+----------------------
+
+  - afl-analyze: added AFL_SKIP_BIN_CHECK support
+  - better random numbers for gcc_plugin and llvm_mode (thanks to devnexen)
+  - afl-fuzz: CPU affinity support for DragonFly
+  - llvm_mode: float splitting is now configured via AFL_LLVM_LAF_SPLIT_FLOATS
+  - libtokencap: support for *BSD/OSX added
+  - libcompcov floating point splitting support for qemu and unicorn
+  - removed unnecessary warnings
+
+
 --------------------------
 Version ++2.58c (release):
 --------------------------
diff --git a/gcc_plugin/afl-gcc-fast.c b/gcc_plugin/afl-gcc-fast.c
index 093249a0..057b44cc 100644
--- a/gcc_plugin/afl-gcc-fast.c
+++ b/gcc_plugin/afl-gcc-fast.c
@@ -108,7 +108,7 @@ static void edit_params(u32 argc, char** argv) {
   u8  fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1;
   u8* name;
 
-  cc_params = ck_alloc((argc + 64) * sizeof(u8*));
+  cc_params = ck_alloc((argc + 128) * sizeof(u8*));
 
   name = strrchr(argv[0], '/');
   if (!name)
@@ -202,6 +202,19 @@ static void edit_params(u32 argc, char** argv) {
 
   }
 
+  if (getenv("AFL_NO_BUILTIN")) {
+
+    cc_params[cc_par_cnt++] = "-fno-builtin-strcmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strncmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-bcmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";
+
+  }
+
 #ifdef USEMMAP
   cc_params[cc_par_cnt++] = "-lrt";
 #endif
diff --git a/libdislocator/libdislocator.so.c b/libdislocator/libdislocator.so.c
index d172f7a2..7fe40afa 100644
--- a/libdislocator/libdislocator.so.c
+++ b/libdislocator/libdislocator.so.c
@@ -23,6 +23,7 @@
 #include <stdlib.h>
 #include <string.h>
 #include <limits.h>
+#include <errno.h>
 #include <sys/mman.h>
 
 #include "config.h"
@@ -264,6 +265,54 @@ void* realloc(void* ptr, size_t len) {
 
 }
 
+/* posix_memalign we mainly check the proper alignment argument
+   if the requested size fits within the alignment we do
+   a normal request */
+
+int posix_memalign(void** ptr, size_t align, size_t len) {
+   if (*ptr == NULL) 
+     return EINVAL;
+   if ((align % 2) || (align % sizeof(void *)))
+     return EINVAL;
+   if (len == 0) {
+     *ptr = NULL;
+     return 0;
+   }
+   if (align >= 4 * sizeof(size_t)) len += align -1;
+
+   *ptr = malloc(len);
+
+   DEBUGF("posix_memalign(%p %zu, %zu)", ptr, align, len);
+
+   return 0;
+}
+
+/* just the non-posix fashion */
+
+void *memalign(size_t align, size_t len) {
+   void* ret = NULL;
+
+   if (posix_memalign(&ret, align, len)) {
+     DEBUGF("memalign(%zu, %zu) failed", align, len);
+   }
+
+   return ret;
+}
+
+/* sort of C11 alias of memalign only more severe, alignment-wise */
+
+void *aligned_alloc(size_t align, size_t len) {
+   void *ret = NULL;
+
+   if ((len % align)) return NULL;
+
+   if (posix_memalign(&ret, align, len)) {
+     DEBUGF("aligned_alloc(%zu, %zu) failed", align, len);
+   }
+
+   return ret;
+}
+
 __attribute__((constructor)) void __dislocator_init(void) {
 
   u8* tmp = getenv("AFL_LD_LIMIT_MB");
diff --git a/libtokencap/Makefile b/libtokencap/Makefile
index 441412c7..df2426ed 100644
--- a/libtokencap/Makefile
+++ b/libtokencap/Makefile
@@ -33,6 +33,9 @@ endif
 ifeq "$(shell uname)" "OpenBSD"
   TARGETS = libtokencap.so
 endif
+ifeq "$(shell uname)" "NetBSD"
+  TARGETS = libtokencap.so
+endif
 all: $(TARGETS)
 
 libtokencap.so: libtokencap.so.c ../config.h
diff --git a/libtokencap/libtokencap.so.c b/libtokencap/libtokencap.so.c
index 7ed231fe..2fe9ae63 100644
--- a/libtokencap/libtokencap.so.c
+++ b/libtokencap/libtokencap.so.c
@@ -23,6 +23,7 @@
 #include <string.h>
 #include <ctype.h>
 #include <unistd.h>
+#include <fcntl.h>
 
 #include "../types.h"
 #include "../config.h"
@@ -49,7 +50,7 @@ static struct mapping { void *st, *en; } __tokencap_ro[MAX_MAPPINGS];
 
 static u32   __tokencap_ro_cnt;
 static u8    __tokencap_ro_loaded;
-static FILE* __tokencap_out_file;
+static int __tokencap_out_file = -1;
 
 /* Identify read-only regions in memory. Only parameters that fall into these
    ranges are worth dumping when passed to strcmp() and so on. Read-write
@@ -114,7 +115,7 @@ static void __tokencap_load_mappings(void) {
 #elif defined __FreeBSD__ || defined __OpenBSD__ || defined __NetBSD__
 
 #if defined __FreeBSD__
-  int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, getpid()};
+  int mib[] = {CTL_KERN, KERN_PROC, KERN_PROC_VMMAP, -1};
 #elif defined __OpenBSD__
   int mib[] = {CTL_KERN, KERN_PROC_VMMAP, getpid()};
 #elif defined __NetBSD__
@@ -133,9 +134,7 @@ static void __tokencap_load_mappings(void) {
 #endif
 
   buf = mmap(NULL, len, PROT_READ | PROT_WRITE, MAP_SHARED | MAP_ANON, -1, 0);
-  if (!buf) {
-     return;
-  }
+  if (buf == MAP_FAILED) return;
 
   if (sysctl(mib, miblen, buf, &len, NULL, 0) == -1) {
 
@@ -211,7 +210,7 @@ static void __tokencap_dump(const u8* ptr, size_t len, u8 is_text) {
   u32 i;
   u32 pos = 0;
 
-  if (len < MIN_AUTO_EXTRA || len > MAX_AUTO_EXTRA || !__tokencap_out_file)
+  if (len < MIN_AUTO_EXTRA || len > MAX_AUTO_EXTRA || __tokencap_out_file == -1)
     return;
 
   for (i = 0; i < len; i++) {
@@ -237,7 +236,9 @@ static void __tokencap_dump(const u8* ptr, size_t len, u8 is_text) {
 
   buf[pos] = 0;
 
-  fprintf(__tokencap_out_file, "\"%s\"\n", buf);
+  int wrt_ok = (  1 == write(__tokencap_out_file, "\"", 1));
+  wrt_ok    &= (pos == write(__tokencap_out_file, buf, pos));
+  wrt_ok    &= (2   == write(__tokencap_out_file, "\"\n", 2));
 
 }
 
@@ -253,7 +254,7 @@ int strcmp(const char* str1, const char* str2) {
 
   while (1) {
 
-    unsigned char c1 = *str1, c2 = *str2;
+    const unsigned char c1 = *str1, c2 = *str2;
 
     if (c1 != c2) return (c1 > c2) ? 1 : -1;
     if (!c1) return 0;
@@ -295,7 +296,7 @@ int strcasecmp(const char* str1, const char* str2) {
 
   while (1) {
 
-    unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
+    const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
 
     if (c1 != c2) return (c1 > c2) ? 1 : -1;
     if (!c1) return 0;
@@ -315,7 +316,7 @@ int strncasecmp(const char* str1, const char* str2, size_t len) {
 
   while (len--) {
 
-    unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
+    const unsigned char c1 = tolower(*str1), c2 = tolower(*str2);
 
     if (!c1) return 0;
     if (c1 != c2) return (c1 > c2) ? 1 : -1;
@@ -335,12 +336,15 @@ int memcmp(const void* mem1, const void* mem2, size_t len) {
   if (__tokencap_is_ro(mem1)) __tokencap_dump(mem1, len, 0);
   if (__tokencap_is_ro(mem2)) __tokencap_dump(mem2, len, 0);
 
+  const char *strmem1 = (const char *)mem1;
+  const char *strmem2 = (const char *)mem2;
+
   while (len--) {
 
-    unsigned char c1 = *(const char*)mem1, c2 = *(const char*)mem2;
+    const unsigned char c1 = *strmem1, c2 = *strmem2;
     if (c1 != c2) return (c1 > c2) ? 1 : -1;
-    mem1++;
-    mem2++;
+    strmem1++;
+    strmem2++;
 
   }
 
@@ -348,6 +352,28 @@ int memcmp(const void* mem1, const void* mem2, size_t len) {
 
 }
 
+#undef bcmp
+
+int bcmp(const void* mem1, const void* mem2, size_t len) {
+
+  if (__tokencap_is_ro(mem1)) __tokencap_dump(mem1, len, 0);
+  if (__tokencap_is_ro(mem2)) __tokencap_dump(mem2, len, 0);
+
+  const char *strmem1 = (const char *)mem1;
+  const char *strmem2 = (const char *)mem2;
+
+  while (len--) {
+
+    int diff = *strmem1 ^ *strmem2;
+    if (diff != 0) return 1;
+    strmem1++;
+    strmem2++;
+
+  }
+
+  return 0;
+}
+
 #undef strstr
 
 char* strstr(const char* haystack, const char* needle) {
@@ -403,8 +429,13 @@ char* strcasestr(const char* haystack, const char* needle) {
 __attribute__((constructor)) void __tokencap_init(void) {
 
   u8* fn = getenv("AFL_TOKEN_FILE");
-  if (fn) __tokencap_out_file = fopen(fn, "a");
-  if (!__tokencap_out_file) __tokencap_out_file = stderr;
+  if (fn) __tokencap_out_file = open(fn, O_RDWR | O_CREAT | O_APPEND, 0655);
+  if (__tokencap_out_file == -1) __tokencap_out_file = STDERR_FILENO;
+
+}
 
+/* closing as best as we can the tokens file */
+__attribute__((destructor)) void __tokencap_shutdown(void) {
+  if (__tokencap_out_file != STDERR_FILENO) close(__tokencap_out_file);
 }
 
diff --git a/llvm_mode/LLVMInsTrim.so.cc b/llvm_mode/LLVMInsTrim.so.cc
index 4b5597e2..89738812 100644
--- a/llvm_mode/LLVMInsTrim.so.cc
+++ b/llvm_mode/LLVMInsTrim.so.cc
@@ -158,6 +158,7 @@ struct InsTrim : public ModulePass {
         bool      instrumentBlock = false;
         DebugLoc  Loc;
         StringRef instFilename;
+        unsigned int instLine = 0;
 
         for (auto &BB : F) {
 
@@ -171,7 +172,7 @@ struct InsTrim : public ModulePass {
 
           DILocation *cDILoc = dyn_cast<DILocation>(Loc.getAsMDNode());
 
-          unsigned int instLine = cDILoc->getLine();
+          instLine = cDILoc->getLine();
           instFilename = cDILoc->getFilename();
 
           if (instFilename.str().empty()) {
@@ -217,11 +218,13 @@ struct InsTrim : public ModulePass {
          * not whitelisted, so we skip instrumentation. */
         if (!instrumentBlock) {
 
-          if (!instFilename.str().empty())
-            SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s ...\n",
-                 instFilename.str().c_str());
-          else
-            SAYF(cYEL "[!] " cBRI "No filename information found, skipping it");
+          if (!be_quiet) {
+             if (!instFilename.str().empty())
+               SAYF(cYEL "[!] " cBRI "Not in whitelist, skipping %s line %u...\n",
+                    instFilename.str().c_str(), instLine);
+             else
+               SAYF(cYEL "[!] " cBRI "No filename information found, skipping it");
+          }
           continue;
 
         }
diff --git a/llvm_mode/Makefile b/llvm_mode/Makefile
index 7cfbe92d..033babac 100644
--- a/llvm_mode/Makefile
+++ b/llvm_mode/Makefile
@@ -52,7 +52,7 @@ endif
 CFLAGS      ?= -O3 -funroll-loops
 CFLAGS      += -Wall -D_FORTIFY_SOURCE=2 -g -Wno-pointer-sign -I ../include/ \
                -DAFL_PATH=\"$(HELPER_PATH)\" -DBIN_PATH=\"$(BIN_PATH)\" \
-               -DVERSION=\"$(VERSION)\"
+               -DLLVM_BINDIR=\"$(LLVM_BINDIR)\" -DVERSION=\"$(VERSION)\"
 ifdef AFL_TRACE_PC
   CFLAGS    += -DUSE_TRACE_PC=1
 endif
diff --git a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
index a7f6acdc..b2243492 100644
--- a/llvm_mode/afl-clang-fast.c
+++ b/llvm_mode/afl-clang-fast.c
@@ -32,11 +32,13 @@
 #include <unistd.h>
 #include <stdlib.h>
 #include <string.h>
+#include <limits.h>
 #include <assert.h>
 
 static u8*  obj_path;                  /* Path to runtime libraries         */
 static u8** cc_params;                 /* Parameters passed to the real CC  */
 static u32  cc_par_cnt = 1;            /* Param count, including argv0      */
+static u8   llvm_fullpath[PATH_MAX];
 
 /* Try to find the runtime libraries. If that fails, abort. */
 
@@ -104,6 +106,7 @@ static void find_obj(u8* argv0) {
 static void edit_params(u32 argc, char** argv) {
 
   u8  fortify_set = 0, asan_set = 0, x_set = 0, maybe_linking = 1, bit_mode = 0;
+  u8  has_llvm_config = 0;
   u8* name;
 
   cc_params = ck_alloc((argc + 128) * sizeof(u8*));
@@ -114,15 +117,21 @@ static void edit_params(u32 argc, char** argv) {
   else
     ++name;
 
+  has_llvm_config = (strlen(LLVM_BINDIR) > 0);
+
   if (!strcmp(name, "afl-clang-fast++")) {
 
     u8* alt_cxx = getenv("AFL_CXX");
-    cc_params[0] = alt_cxx ? alt_cxx : (u8*)"clang++";
+    if (has_llvm_config)  snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang++", LLVM_BINDIR);
+    else sprintf(llvm_fullpath, "clang++");
+    cc_params[0] = alt_cxx ? alt_cxx : (u8*)llvm_fullpath;
 
   } else {
 
     u8* alt_cc = getenv("AFL_CC");
-    cc_params[0] = alt_cc ? alt_cc : (u8*)"clang";
+    if (has_llvm_config)  snprintf(llvm_fullpath, sizeof(llvm_fullpath), "%s/clang", LLVM_BINDIR);
+    else sprintf(llvm_fullpath, "clang");
+    cc_params[0] = alt_cc ? alt_cc : (u8*)llvm_fullpath;
 
   }
 
@@ -273,6 +282,9 @@ static void edit_params(u32 argc, char** argv) {
     cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-bcmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
+    cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";
 
   }
 
diff --git a/llvm_mode/afl-llvm-pass.so.cc b/llvm_mode/afl-llvm-pass.so.cc
index e094a0b2..0c68136b 100644
--- a/llvm_mode/afl-llvm-pass.so.cc
+++ b/llvm_mode/afl-llvm-pass.so.cc
@@ -190,6 +190,8 @@ bool AFLCoverage::runOnModule(Module &M) {
 
           }
 
+          (void)instLine;
+
           /* Continue only if we know where we actually are */
           if (!instFilename.str().empty()) {
 
diff --git a/llvm_mode/compare-transform-pass.so.cc b/llvm_mode/compare-transform-pass.so.cc
index e1b6e671..0ccce875 100644
--- a/llvm_mode/compare-transform-pass.so.cc
+++ b/llvm_mode/compare-transform-pass.so.cc
@@ -234,6 +234,10 @@ bool CompareTransform::transformCmps(Module &M, const bool processStrcmp,
       ConstantInt *ilen = dyn_cast<ConstantInt>(op2);
       sizedLen = ilen->getZExtValue();
 
+    } else {
+
+      sizedLen = 0;
+
     }
 
     if (HasStr1) {
diff --git a/llvm_mode/split-compares-pass.so.cc b/llvm_mode/split-compares-pass.so.cc
index 06bdeb60..60420f77 100644
--- a/llvm_mode/split-compares-pass.so.cc
+++ b/llvm_mode/split-compares-pass.so.cc
@@ -118,6 +118,8 @@ bool SplitComparesTransform::simplifyCompares(Module &M) {
             /* this is probably not needed but we do it anyway */
             if (TyOp0 != TyOp1) { continue; }
 
+            if (TyOp0->isArrayTy() || TyOp0->isVectorTy()) { continue; }
+
             fcomps.push_back(selectcmpInst);
 
           }
diff --git a/src/afl-analyze.c b/src/afl-analyze.c
index 5555a262..ee281af8 100644
--- a/src/afl-analyze.c
+++ b/src/afl-analyze.c
@@ -987,7 +987,7 @@ int main(int argc, char** argv) {
   if (child_timed_out)
     FATAL("Target binary times out (adjusting -t may help).");
 
-  if (!anything_set()) FATAL("No instrumentation detected.");
+  if (getenv("AFL_SKIP_BIN_CHECK") == NULL && !anything_set()) FATAL("No instrumentation detected.");
 
   analyze(use_argv);
 
diff --git a/src/afl-gcc.c b/src/afl-gcc.c
index 740442dc..e0706a5f 100644
--- a/src/afl-gcc.c
+++ b/src/afl-gcc.c
@@ -320,6 +320,7 @@ static void edit_params(u32 argc, char** argv) {
     cc_params[cc_par_cnt++] = "-fno-builtin-strcasecmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-strncasecmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-memcmp";
+    cc_params[cc_par_cnt++] = "-fno-builtin-bcmp";
     cc_params[cc_par_cnt++] = "-fno-builtin-strstr";
     cc_params[cc_par_cnt++] = "-fno-builtin-strcasestr";
 
diff --git a/test/test.sh b/test/test.sh
index 42ddf70b..2d5c5e39 100755
--- a/test/test.sh
+++ b/test/test.sh
@@ -26,6 +26,7 @@ test -z "$ECHO" && { printf Error: printf command does not support octal charact
 
 export AFL_EXIT_WHEN_DONE=1
 export AFL_SKIP_CPUFREQ=1
+export AFL_I_DONT_CARE_ABOUT_MISSING_CRASHES=1
 unset AFL_QUIET
 unset AFL_DEBUG
 unset AFL_HARDEN
@@ -87,7 +88,7 @@ test -e ../${AFL_GCC} -a -e ../afl-showmap -a -e ../afl-fuzz && {
   # now we want to be sure that afl-fuzz is working  
   # make sure core_pattern is set to core on linux
   (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && {
-    $ECHO "$RED[!] we cannot run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
+    $ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
     true
   }) ||
   # make sure crash reporter is disabled on Mac OS X
@@ -143,7 +144,7 @@ test -e ../afl-clang-fast && {
   } || $ECHO "$RED[!] llvm_mode hardened mode compilation failed"
   # now we want to be sure that afl-fuzz is working  
   (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && {
-    $ECHO "$RED[!] we cannot run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
+    $ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
     true
   }) ||
   # make sure crash reporter is disabled on Mac OS X
@@ -226,7 +227,7 @@ test -e ../afl-gcc-fast && {
   } || $ECHO "$RED[!] gcc_plugin hardened mode compilation failed"
   # now we want to be sure that afl-fuzz is working  
   (test "$(uname -s)" = "Linux" && test "$(sysctl kernel.core_pattern)" != "kernel.core_pattern = core" && {
-    $ECHO "$RED[!] we cannot run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
+    $ECHO "$YELLOW[!] we should not run afl-fuzz with enabled core dumps. Run 'sudo sh afl-system-config'.$RESET"
     true
   }) ||
   # make sure crash reporter is disabled on Mac OS X
@@ -372,11 +373,15 @@ $ECHO "$BLUE[*] Testing: unicorn_mode"
 test -d ../unicorn_mode/unicorn && {
   test -e ../unicorn_mode/samples/simple/simple_target.bin -a -e ../unicorn_mode/samples/compcov_x64/compcov_target.bin && {
     {
+      # travis workaround
+      PY=`which python2.7`
+      test "$PY" = "/opt/pyenv/shims/python2.7" -a -x /usr/bin/python2.7 && PY=/usr/bin/python2.7
       mkdir -p in
       echo 0 > in/in
+      $ECHO "$GREY[*] Using python binary $PY"
       $ECHO "$GREY[*] running afl-fuzz for unicorn_mode, this will take approx 20 seconds"
       {
-        ../afl-fuzz -V20 -U -i in -o out -d -- python ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1
+        ../afl-fuzz -V20 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/simple/simple_test_harness.py @@ >>errors 2>&1
       } >>errors 2>&1
       test -n "$( ls out/queue/id:000002* 2> /dev/null )" && {
         $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode"
@@ -391,7 +396,7 @@ test -d ../unicorn_mode/unicorn && {
       $ECHO "$GREY[*] running afl-fuzz for unicorn_mode compcov, this will take approx 25 seconds"
       {
         export AFL_COMPCOV_LEVEL=2
-        ../afl-fuzz -V25 -U -i in -o out -d -- python ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1
+        ../afl-fuzz -V25 -U -i in -o out -d -- "$PY" ../unicorn_mode/samples/compcov_x64/compcov_test_harness.py @@ >>errors 2>&1
       } >>errors 2>&1
       test -n "$( ls out/queue/id:000001* 2> /dev/null )" && {
         $ECHO "$GREEN[+] afl-fuzz is working correctly with unicorn_mode compcov"