about summary refs log tree commit diff
path: root/instrumentation/afl-compiler-rt.o.c
diff options
context:
space:
mode:
Diffstat (limited to 'instrumentation/afl-compiler-rt.o.c')
-rw-r--r--instrumentation/afl-compiler-rt.o.c156
1 files changed, 84 insertions, 72 deletions
diff --git a/instrumentation/afl-compiler-rt.o.c b/instrumentation/afl-compiler-rt.o.c
index 759c813a..5d198ada 100644
--- a/instrumentation/afl-compiler-rt.o.c
+++ b/instrumentation/afl-compiler-rt.o.c
@@ -670,7 +670,7 @@ static void __afl_start_snapshots(void) {
 
   u8 child_stopped = 0;
 
-  void (*old_sigchld_handler)(int) = 0;  // = signal(SIGCHLD, SIG_DFL);
+  void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
 
   /* Phone home and tell the parent that we're OK. If parent isn't there,
      assume we're not running in forkserver mode and just execute program. */
@@ -926,7 +926,7 @@ static void __afl_start_forkserver(void) {
 
   u8 child_stopped = 0;
 
-  void (*old_sigchld_handler)(int) = 0;  // = signal(SIGCHLD, SIG_DFL);
+  void (*old_sigchld_handler)(int) = signal(SIGCHLD, SIG_DFL);
 
   if (__afl_map_size <= FS_OPT_MAX_MAPSIZE) {
 
@@ -1885,30 +1885,21 @@ static int area_is_valid(void *ptr, size_t len) {
 
 }
 
-void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
-
-  /*
-    u32 i;
-    if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return;
-    fprintf(stderr, "rtn_n len=%u arg0=", len);
-    for (i = 0; i < len; i++)
-      fprintf(stderr, "%02x", ptr1[i]);
-    fprintf(stderr, " arg1=");
-    for (i = 0; i < len; i++)
-      fprintf(stderr, "%02x", ptr2[i]);
-    fprintf(stderr, "\n");
-  */
+/* hook for string with length functions, eg. strncmp, strncasecmp etc.
+   Note that we ignore the len parameter and take longer strings if present. */
+void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
 
-  if (likely(!__afl_cmp_map)) return;
   // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
+  if (likely(!__afl_cmp_map)) return;
   if (unlikely(!len)) return;
-  int l = MIN(31, len);
-
-  if ((l = area_is_valid(ptr1, l)) <= 0 ||
-      (l = area_is_valid(ptr2, l)) <= 0)
-    return;
+  int len0 = MIN(len, 31);
+  int len1 = strnlen(ptr1, len0);
+  if (len1 < 31) len1 = area_is_valid(ptr1, len1 + 1);
+  int len2 = strnlen(ptr2, len0);
+  if (len2 < 31) len2 = area_is_valid(ptr1, len2 + 1);
+  int l = MAX(len1, len2);
+  if (l < 2) return;
 
-  // fprintf(stderr, "RTN2 %u\n", l);
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
 
@@ -1936,27 +1927,25 @@ void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
   struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
   hits &= CMP_MAP_RTN_H - 1;
 
-  cmpfn[hits].v0_len = l;
-  cmpfn[hits].v1_len = l;
-  __builtin_memcpy(cmpfn[hits].v0, ptr1, l);
-  __builtin_memcpy(cmpfn[hits].v1, ptr2, l);
+  cmpfn[hits].v0_len = 0x80 + l;
+  cmpfn[hits].v1_len = 0x80 + l;
+  __builtin_memcpy(cmpfn[hits].v0, ptr1, len1);
+  __builtin_memcpy(cmpfn[hits].v1, ptr2, len2);
   // fprintf(stderr, "RTN3\n");
 
 }
 
-void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
-
-  /*
-    if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return;
-    fprintf(stderr, "rtn_strn len=%u arg0=%s arg1=%s\n", len, ptr1, ptr2);
-  */
+/* hook for string functions, eg. strcmp, strcasecmp etc. */
+void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
 
+  // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
   if (likely(!__afl_cmp_map)) return;
-  // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
-  if (unlikely(!len)) return;
-  int l = MIN(31, len + 1);
+  if (unlikely(!ptr1 || !ptr2)) return;
+  int len1 = strnlen(ptr1, 30) + 1;
+  int len2 = strnlen(ptr2, 30) + 1;
+  int l = MAX(len1, len2);
+  if (l < 3) return;
 
-  // fprintf(stderr, "RTN2 %u\n", l);
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
 
@@ -1984,29 +1973,38 @@ void __cmplog_rtn_hook_strn(u8 *ptr1, u8 *ptr2, u64 len) {
   struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
   hits &= CMP_MAP_RTN_H - 1;
 
-  cmpfn[hits].v0_len = 0x80 + l;
-  cmpfn[hits].v1_len = 0x80 + l;
-  __builtin_memcpy(cmpfn[hits].v0, ptr1, l);
-  __builtin_memcpy(cmpfn[hits].v1, ptr2, l);
+  cmpfn[hits].v0_len = 0x80 + len1;
+  cmpfn[hits].v1_len = 0x80 + len2;
+  __builtin_memcpy(cmpfn[hits].v0, ptr1, len1);
+  __builtin_memcpy(cmpfn[hits].v1, ptr2, len2);
   // fprintf(stderr, "RTN3\n");
 
 }
 
-void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
+/* hook function for all other func(ptr, ptr, ...) variants */
+void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
 
   /*
+    u32 i;
     if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return;
-    fprintf(stderr, "rtn_str arg0=%s arg1=%s\n", ptr1, ptr2);
+    fprintf(stderr, "rtn arg0=");
+    for (i = 0; i < 32; i++)
+      fprintf(stderr, "%02x", ptr1[i]);
+    fprintf(stderr, " arg1=");
+    for (i = 0; i < 32; i++)
+      fprintf(stderr, "%02x", ptr2[i]);
+    fprintf(stderr, "\n");
   */
 
-  if (likely(!__afl_cmp_map)) return;
   // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
-  if (unlikely(!ptr1 || !ptr2)) return;
-  int len1 = MIN(31, strlen(ptr1) + 1);
-  int len2 = MIN(31, strlen(ptr2) + 1);
-  int l = MIN(MAX(len1, len2), 31);
+  if (likely(!__afl_cmp_map)) return;
+  int l1, l2;
+  if ((l1 = area_is_valid(ptr1, 31)) <= 0 ||
+      (l2 = area_is_valid(ptr2, 31)) <= 0)
+    return;
+  int len = MIN(31, MIN(l1, l2));
 
-  // fprintf(stderr, "RTN2 %u\n", l);
+  // fprintf(stderr, "RTN2 %u\n", len);
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
 
@@ -2016,16 +2014,16 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
 
     __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
     __afl_cmp_map->headers[k].hits = 1;
-    __afl_cmp_map->headers[k].shape = l - 1;
+    __afl_cmp_map->headers[k].shape = len - 1;
     hits = 0;
 
   } else {
 
     hits = __afl_cmp_map->headers[k].hits++;
 
-    if (__afl_cmp_map->headers[k].shape < l) {
+    if (__afl_cmp_map->headers[k].shape < len) {
 
-      __afl_cmp_map->headers[k].shape = l - 1;
+      __afl_cmp_map->headers[k].shape = len - 1;
 
     }
 
@@ -2034,37 +2032,44 @@ void __cmplog_rtn_hook_str(u8 *ptr1, u8 *ptr2) {
   struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
   hits &= CMP_MAP_RTN_H - 1;
 
-  cmpfn[hits].v0_len = 0x80 + len1;
-  cmpfn[hits].v1_len = 0x80 + len2;
-  __builtin_memcpy(cmpfn[hits].v0, ptr1, len1);
-  __builtin_memcpy(cmpfn[hits].v1, ptr2, len2);
+  cmpfn[hits].v0_len = len;
+  cmpfn[hits].v1_len = len;
+  __builtin_memcpy(cmpfn[hits].v0, ptr1, len);
+  __builtin_memcpy(cmpfn[hits].v1, ptr2, len);
   // fprintf(stderr, "RTN3\n");
 
 }
 
-void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
+/* hook for func(ptr, ptr, len, ...) looking functions.
+   Note that for the time being we ignore len as this could be wrong
+   information and pass it on to the standard binary rtn hook */
+void __cmplog_rtn_hook_n(u8 *ptr1, u8 *ptr2, u64 len) {
 
+  (void)(len);
+  __cmplog_rtn_hook(ptr1, ptr2);
+
+#if 0
   /*
     u32 i;
     if (area_is_valid(ptr1, 31) <= 0 || area_is_valid(ptr2, 31) <= 0) return;
-    fprintf(stderr, "rtn arg0=");
-    for (i = 0; i < 32; i++)
+    fprintf(stderr, "rtn_n len=%u arg0=", len);
+    for (i = 0; i < len; i++)
       fprintf(stderr, "%02x", ptr1[i]);
     fprintf(stderr, " arg1=");
-    for (i = 0; i < 32; i++)
+    for (i = 0; i < len; i++)
       fprintf(stderr, "%02x", ptr2[i]);
     fprintf(stderr, "\n");
   */
 
+  // fprintf(stderr, "RTN1 %p %p %u\n", ptr1, ptr2, len);
   if (likely(!__afl_cmp_map)) return;
-  // fprintf(stderr, "RTN1 %p %p\n", ptr1, ptr2);
-  int l1, l2;
-  if ((l1 = area_is_valid(ptr1, 31)) <= 0 ||
-      (l2 = area_is_valid(ptr2, 31)) <= 0)
+  if (unlikely(!len)) return;
+  int l = MIN(31, len);
+
+  if ((l = area_is_valid(ptr1, l)) <= 0 || (l = area_is_valid(ptr2, l)) <= 0)
     return;
-  int len = MIN(31, MIN(l1, l2));
 
-  // fprintf(stderr, "RTN2 %u\n", len);
+  // fprintf(stderr, "RTN2 %u\n", l);
   uintptr_t k = (uintptr_t)__builtin_return_address(0);
   k = (uintptr_t)(default_hash((u8 *)&k, sizeof(uintptr_t)) & (CMP_MAP_W - 1));
 
@@ -2074,16 +2079,16 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
 
     __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
     __afl_cmp_map->headers[k].hits = 1;
-    __afl_cmp_map->headers[k].shape = len - 1;
+    __afl_cmp_map->headers[k].shape = l - 1;
     hits = 0;
 
   } else {
 
     hits = __afl_cmp_map->headers[k].hits++;
 
-    if (__afl_cmp_map->headers[k].shape < len) {
+    if (__afl_cmp_map->headers[k].shape < l) {
 
-      __afl_cmp_map->headers[k].shape = len - 1;
+      __afl_cmp_map->headers[k].shape = l - 1;
 
     }
 
@@ -2092,11 +2097,12 @@ void __cmplog_rtn_hook(u8 *ptr1, u8 *ptr2) {
   struct cmpfn_operands *cmpfn = (struct cmpfn_operands *)__afl_cmp_map->log[k];
   hits &= CMP_MAP_RTN_H - 1;
 
-  cmpfn[hits].v0_len = len;
-  cmpfn[hits].v1_len = len;
-  __builtin_memcpy(cmpfn[hits].v0, ptr1, len);
-  __builtin_memcpy(cmpfn[hits].v1, ptr2, len);
+  cmpfn[hits].v0_len = l;
+  cmpfn[hits].v1_len = l;
+  __builtin_memcpy(cmpfn[hits].v0, ptr1, l);
+  __builtin_memcpy(cmpfn[hits].v1, ptr2, l);
   // fprintf(stderr, "RTN3\n");
+#endif
 
 }
 
@@ -2247,5 +2253,11 @@ void __afl_coverage_interesting(u8 val, u32 id) {
 
 }
 
+void __afl_set_persistent_mode(u8 mode) {
+
+  is_persistent = mode;
+
+}
+
 #undef write_error