Skip to content

Instantly share code, notes, and snippets.

@NeatMonster
Created June 28, 2017 15:40
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 1 You must be signed in to fork a gist
  • Save NeatMonster/0c111029613948f7562d2df916d3f5ac to your computer and use it in GitHub Desktop.
Save NeatMonster/0c111029613948f7562d2df916d3f5ac to your computer and use it in GitHub Desktop.
This small patch adds support for value profiling into AFL 2.42b.
diff -Naur a/llvm_mode/afl-clang-fast.c b/llvm_mode/afl-clang-fast.c
--- a/llvm_mode/afl-clang-fast.c 2017-01-25 03:51:26.000000000 +0100
+++ b/llvm_mode/afl-clang-fast.c 2017-06-21 16:35:01.203146919 +0200
@@ -120,7 +120,28 @@
http://clang.llvm.org/docs/SanitizerCoverage.html#tracing-pcs-with-guards */
#ifdef USE_TRACE_PC
- cc_params[cc_par_cnt++] = "-fsanitize-coverage=trace-pc-guard";
+ u8 *trace_ind = "";
+ #ifdef USE_TRACE_IND
+ trace_ind = ",indirect-calls";
+ #endif
+
+ u8 *trace_cmp = "";
+ #ifdef USE_TRACE_CMP
+ trace_cmp = ",trace-cmp";
+ #endif
+
+ u8 *trace_div = "";
+ #ifdef USE_TRACE_DIV
+ trace_div = ",trace-div";
+ #endif
+
+ u8 *trace_gep = "";
+ #ifdef USE_TRACE_GEP
+ trace_gep = ",trace-gep";
+ #endif
+
+ cc_params[cc_par_cnt++] = alloc_printf("-fsanitize-coverage=trace-pc-guard%s%s%s%s",
+ trace_ind, trace_cmp, trace_div, trace_gep);
cc_params[cc_par_cnt++] = "-mllvm";
cc_params[cc_par_cnt++] = "-sanitizer-coverage-block-threshold=0";
#else
diff -Naur a/llvm_mode/afl-llvm-rt.o.c b/llvm_mode/afl-llvm-rt.o.c
--- a/llvm_mode/afl-llvm-rt.o.c 2017-02-01 02:59:41.000000000 +0100
+++ b/llvm_mode/afl-llvm-rt.o.c 2017-06-21 16:38:43.640190279 +0200
@@ -304,3 +304,126 @@
}
}
+
+void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) {
+ uintptr_t Caller = (uintptr_t)__builtin_return_address(0);
+ const uintptr_t kBits = MAP_SIZE_POW2 / 2;
+ const uintptr_t kMask = (1 << kBits) - 1;
+ uintptr_t Idx = (Caller & kMask) | ((Callee & kMask) << kBits);
+ __afl_area_ptr[Idx % MAP_SIZE]++;
+}
+
+void handle_cmp(uintptr_t PC, uint64_t Arg1, uint64_t Arg2) {
+ uint64_t ArgXor = Arg1 ^ Arg2;
+ uint64_t ArgDistance = __builtin_popcountll(ArgXor) + 1;
+ uint64_t Idx = ((PC & 4095) + 1) * ArgDistance;
+ __afl_area_ptr[Idx % MAP_SIZE]++;
+}
+
+void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ handle_cmp(PC, Arg1, Arg2);
+}
+
+void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ handle_cmp(PC, Arg1, Arg2);
+}
+
+void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ handle_cmp(PC, Arg1, Arg2);
+}
+
+void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ handle_cmp(PC, Arg1, Arg2);
+}
+
+void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) {
+ uint64_t N = Cases[0];
+ uint64_t *Vals = Cases + 2;
+ if (Vals[N - 1] < 256 && Val < 256) return;
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ size_t i;
+ uint64_t Token = 0;
+ for (i = 0; i < N; i++) {
+ Token = Val ^ Vals[i];
+ if (Val < Vals[i])
+ break;
+ }
+ handle_cmp(PC + i, Token, 0);
+}
+
+void __sanitizer_cov_trace_div4(uint32_t Val) {
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ handle_cmp(PC, Val, 0);
+}
+
+void __sanitizer_cov_trace_div8(uint64_t Val) {
+ uintptr_t PC = (uintptr_t)__builtin_return_address(0);
+ handle_cmp(PC, Val, 0);
+}
+
+void __sanitizer_cov_trace_gep(uintptr_t Idx) {
+ uintptr_t PC =(uintptr_t)__builtin_return_address(0);
+ handle_cmp(PC, Idx, 0);
+}
+
+#ifdef USE_TRACE_MEM
+void handle_memcmp(void *caller_pc, const void *s1, const void *s2,
+ size_t n, int StopAtZero) {
+ if (!n) return;
+ size_t Len = MIN(n, 256);
+ const uint8_t *B1 = (const uint8_t*)s1;
+ const uint8_t *B2 = (const uint8_t*)s2;
+ size_t I = 0;
+ while (I < Len) {
+ if (B1[I] != B2[I] || (StopAtZero && B1[I] == 0))
+ break;
+ I++;
+ }
+ size_t PC = (size_t)caller_pc;
+ size_t Idx = (PC & 4095) | (I << 12);
+ __afl_area_ptr[Idx % MAP_SIZE]++;
+}
+
+void __sanitizer_weak_hook_memcmp(void *caller_pc, const void *s1,
+ const void *s2, size_t n, int result) {
+ if (result == 0) return;
+ if (n <= 1) return;
+ handle_memcmp(caller_pc, s1, s2, n, 0);
+}
+
+void __sanitizer_weak_hook_strcmp(void *caller_pc, const char *s1,
+ const char *s2, int result) {
+ if (result == 0) return;
+ size_t N = 0;
+ while (s1[N] && s2[N]) N++;
+ if (N <= 1) return;
+ handle_memcmp(caller_pc, s1, s2, N, 1);
+}
+
+void __sanitizer_weak_hook_strncmp(void *caller_pc, const char *s1,
+ const char *s2, size_t n, int result) {
+ if (result == 0) return;
+ size_t Len1 = 0;
+ while (Len1 < n && s1[Len1]) Len1++;
+ size_t Len2 = 0;
+ while (Len2 < n && s2[Len2]) Len2++;
+ n = MIN(n, Len1);
+ n = MIN(n, Len2);
+ if (n <= 1) return;
+ handle_memcmp(caller_pc, s1, s2, n, 1);
+}
+
+void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1,
+ const char *s2, int result) {
+ return __sanitizer_weak_hook_strcmp(called_pc, s1, s2, result);
+}
+
+void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1,
+ const char *s2, size_t n, int result) {
+ return __sanitizer_weak_hook_strncmp(called_pc, s1, s2, n, result);
+}
+#endif
diff -Naur a/llvm_mode/Makefile b/llvm_mode/Makefile
--- a/llvm_mode/Makefile 2016-06-24 04:38:49.000000000 +0200
+++ b/llvm_mode/Makefile 2017-06-21 16:33:56.294838821 +0200
@@ -30,6 +30,21 @@
-DVERSION=\"$(VERSION)\"
ifdef AFL_TRACE_PC
CFLAGS += -DUSE_TRACE_PC=1
+ ifdef AFL_TRACE_IND
+ CFLAGS += -DUSE_TRACE_IND=1
+ endif
+ ifdef AFL_TRACE_CMP
+ CFLAGS += -DUSE_TRACE_CMP=1
+ endif
+ ifdef AFL_TRACE_DIV
+ CFLAGS += -DUSE_TRACE_DIV=1
+ endif
+ ifdef AFL_TRACE_GEP
+ CFLAGS += -DUSE_TRACE_GEP=1
+ endif
+ ifdef AFL_TRACE_MEM
+ CFLAGS += -DUSE_TRACE_MEM=1
+ endif
endif
CXXFLAGS ?= -O3 -funroll-loops
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment