about summary refs log tree commit diff
path: root/frida_mode/src/cmplog/cmplog_x86.c
diff options
context:
space:
mode:
Diffstat (limited to 'frida_mode/src/cmplog/cmplog_x86.c')
-rw-r--r--frida_mode/src/cmplog/cmplog_x86.c63
1 files changed, 44 insertions, 19 deletions
diff --git a/frida_mode/src/cmplog/cmplog_x86.c b/frida_mode/src/cmplog/cmplog_x86.c
index dd666c34..4a747417 100644
--- a/frida_mode/src/cmplog/cmplog_x86.c
+++ b/frida_mode/src/cmplog/cmplog_x86.c
@@ -5,6 +5,7 @@
 
 #include "ctx.h"
 #include "frida_cmplog.h"
+#include "instrument.h"
 #include "util.h"
 
 #if defined(__i386__)
@@ -58,7 +59,7 @@ static gboolean cmplog_read_mem(GumCpuContext *ctx, uint8_t size,
       *val = *((guint32 *)GSIZE_TO_POINTER(address));
       return TRUE;
     default:
-      FATAL("Invalid operand size: %d\n", size);
+      FFATAL("Invalid operand size: %d\n", size);
 
   }
 
@@ -80,7 +81,7 @@ static gboolean cmplog_get_operand_value(GumCpuContext *context,
     case X86_OP_MEM:
       return cmplog_read_mem(context, ctx->size, &ctx->mem, val);
     default:
-      FATAL("Invalid operand type: %d\n", ctx->type);
+      FFATAL("Invalid operand type: %d\n", ctx->type);
 
   }
 
@@ -104,30 +105,43 @@ static void cmplog_call_callout(GumCpuContext *context, gpointer user_data) {
   gsize arg1 = esp[0];
   gsize arg2 = esp[1];
 
-  if (((G_MAXULONG - arg1) < 32) || ((G_MAXULONG - arg2) < 32)) return;
+  if (((G_MAXULONG - arg1) < 31) || ((G_MAXULONG - arg2) < 31)) return;
 
-  if (!cmplog_is_readable(arg1, 32) || !cmplog_is_readable(arg2, 32)) return;
+  if (!cmplog_is_readable(arg1, 31) || !cmplog_is_readable(arg2, 31)) return;
 
   void *ptr1 = GSIZE_TO_POINTER(arg1);
   void *ptr2 = GSIZE_TO_POINTER(arg2);
 
-  uintptr_t k = address;
+  guint64 k = instrument_get_offset_hash(GUM_ADDRESS(address));
 
-  k = (k >> 4) ^ (k << 8);
-  k &= CMP_MAP_W - 1;
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_RTN) {
 
-  __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+    __afl_cmp_map->headers[k].type = CMP_TYPE_RTN;
+    __afl_cmp_map->headers[k].hits = 0;
 
-  u32 hits = __afl_cmp_map->headers[k].hits;
-  __afl_cmp_map->headers[k].hits = hits + 1;
+  }
+
+  u32 hits = 0;
+
+  if (__afl_cmp_map->headers[k].hits == 0) {
+
+    __afl_cmp_map->headers[k].shape = 30;
+
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits;
+
+  }
 
-  __afl_cmp_map->headers[k].shape = 31;
+  __afl_cmp_map->headers[k].hits = hits + 1;
 
   hits &= CMP_MAP_RTN_H - 1;
+  ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0_len = 31;
+  ((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1_len = 31;
   gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v0, ptr1,
-             32);
+             31);
   gum_memcpy(((struct cmpfn_operands *)__afl_cmp_map->log[k])[hits].v1, ptr2,
-             32);
+             31);
 
 }
 
@@ -148,7 +162,7 @@ static void cmplog_instrument_put_operand(cmplog_ctx_t *ctx,
       gum_memcpy(&ctx->mem, &operand->mem, sizeof(x86_op_mem));
       break;
     default:
-      FATAL("Invalid operand type: %d\n", operand->type);
+      FFATAL("Invalid operand type: %d\n", operand->type);
 
   }
 
@@ -184,12 +198,23 @@ static void cmplog_handle_cmp_sub(GumCpuContext *context, gsize operand1,
   k = (k >> 4) ^ (k << 8);
   k &= CMP_MAP_W - 1;
 
-  __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+  if (__afl_cmp_map->headers[k].type != CMP_TYPE_INS)
+    __afl_cmp_map->headers[k].hits = 0;
 
-  u32 hits = __afl_cmp_map->headers[k].hits;
-  __afl_cmp_map->headers[k].hits = hits + 1;
+  u32 hits = 0;
+
+  if (__afl_cmp_map->headers[k].hits == 0) {
+
+    __afl_cmp_map->headers[k].type = CMP_TYPE_INS;
+    __afl_cmp_map->headers[k].shape = (size - 1);
 
-  __afl_cmp_map->headers[k].shape = (size - 1);
+  } else {
+
+    hits = __afl_cmp_map->headers[k].hits;
+
+  }
+
+  __afl_cmp_map->headers[k].hits = hits + 1;
 
   hits &= CMP_MAP_H - 1;
   __afl_cmp_map->log[k][hits].v0 = operand1;
@@ -203,7 +228,7 @@ static void cmplog_cmp_sub_callout(GumCpuContext *context, gpointer user_data) {
   gsize              operand1;
   gsize              operand2;
 
-  if (ctx->operand1.size != ctx->operand2.size) FATAL("Operand size mismatch");
+  if (ctx->operand1.size != ctx->operand2.size) FFATAL("Operand size mismatch");
 
   if (!cmplog_get_operand_value(context, &ctx->operand1, &operand1)) { return; }
   if (!cmplog_get_operand_value(context, &ctx->operand2, &operand2)) { return; }