about summary refs log tree commit diff
path: root/frida_mode/src/ranges.c
diff options
context:
space:
mode:
authorvan Hauser <vh@thc.org>2021-05-10 13:57:47 +0200
committerGitHub <noreply@github.com>2021-05-10 13:57:47 +0200
commit8b7a7b29c60f11cdf6226b3e418e87a5c3f5caac (patch)
tree6ce9d90644f161d21d802e9cbe48eb38467684e9 /frida_mode/src/ranges.c
parentd0225c2c4d465968660a08c93857fed354e539b1 (diff)
downloadafl++-8b7a7b29c60f11cdf6226b3e418e87a5c3f5caac.tar.gz
Push to stable (#895)
* sync (#886)

* Create FUNDING.yml

* Update FUNDING.yml

* moved custom_mutator examples

* unicorn speedtest makefile cleanup

* fixed example location

* fix qdbi

* update util readme

* Frida persistent (#880)

* Added x64 support for persistent mode (function call only), in-memory teest cases and complog

* Review changes, fix NeverZero and code to parse the .text section of the main executable. Excluded ranges TBC

* Various minor fixes and finished support for AFL_INST_LIBS

* Review changes

Co-authored-by: Your Name <you@example.com>

* nits

* fix frida mode

* Integer overflow/underflow fixes in libdislocator (#889)

* libdislocator: fixing integer overflow in 'max_mem' variable and setting 'max_mem' type to 'size_t'

* libdislocator: fixing potential integer underflow in 'total_mem' variable due to its different values in different threads

* Bumped warnings up to the max and fixed remaining issues (#890)

Co-authored-by: Your Name <you@example.com>

* nits

* frida mode - support non-pie

* nits

* nit

* update grammar mutator

* Fixes for aarch64, OSX and other minor issues (#891)

Co-authored-by: Your Name <you@example.com>

* nits

* nits

* fix PCGUARD, build aflpp_driver with fPIC

* Added representative fuzzbench test and test for libxml (#893)

* Added representative fuzzbench test and test for libxml

* Added support for building FRIDA from source with FRIDA_SOURCE=1

Co-authored-by: Your Name <you@example.com>

* nits

* update changelog

* typos

* fixed potential double free in custom trim (#881)

* error handling, freeing mem

* frida: complog -> cmplog

* fix statsd writing

* let aflpp_qemu_driver_hook.so build fail gracefully

* fix stdin trimming

* Support for AFL_ENTRYPOINT (#898)

Co-authored-by: Your Name <you@example.com>

* remove the input file .cur_input at the end of the fuzzing, if AFL_TMPDIR is used

* reverse push (#901)

* Create FUNDING.yml

* Update FUNDING.yml

* disable QEMU static pie

Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>

* clarify that no modifications are required.

* add new test for frida_mode (please review)

* typos

* fix persistent mode (64-bit)

* set ARCH for linux intel 32-bit for frida-gum-devkit

* prepare for 32-bit support (later)

* not on qemu 3 anymore

* unicorn mips fixes

* instrumentation further move to C++11 (#900)

* unicorn fixes

* more unicorn fixes

* Fix memory errors when trim causes testcase growth (#881) (#903)

* Revert "fixed potential double free in custom trim (#881)"

This reverts commit e9d2f72382cab75832721d859c3e731da071435d.

* Revert "fix custom trim for increasing data"

This reverts commit 86a8ef168dda766d2f25f15c15c4d3ecf21d0667.

* Fix memory errors when trim causes testcase growth

Modify trim_case_custom to avoid writing into in_buf because
some custom mutators can cause the testcase to grow rather than
shrink.

Instead of modifying in_buf directly, we write the update out
to the disk when trimming is complete, and then the caller is
responsible for refreshing the in-memory buffer from the file.

This is still a bit sketchy because it does need to modify q->len in
order to notify the upper layers that something changed, and it could
end up telling upper layer code that the q->len is *bigger* than
the buffer (q->testcase_buf) that contains it, which is asking
for trouble down the line somewhere...

* Fix an unlikely situation

Put back some `unlikely()` calls that were in
the e9d2f72382cab75832721d859c3e731da071435d commit that was
reverted.

* typo

* Exit on time (#904)

* Variable AFL_EXIT_ON_TIME description has been added.
Variables AFL_EXIT_ON_TIME and afl_exit_on_time has been added.
afl->exit_on_time variable initialization has been added.
The asignment of a value to the afl->afl_env.afl_exit_on_time variable from
environment variables has been added.
Code to exit on timeout if new path not found has been added.

* Type of afl_exit_on_time variable has been changed.
Variable exit_on_time has been added to the afl_state_t structure.

* Command `export AFL_EXIT_WHEN_DONE=1` has been added.

* Millisecond to second conversion has been added.
Call get_cur_time() has been added.

* Revert to using the saved current time value.

* Useless check has been removed.

* fix new path to custom-mutators

* ensure crashes/README.txt exists

* fix

* Changes to bump FRIDA version and to clone FRIDA repo in to build directory rather than use a submodule as the FRIDA build scripts don't like it (#906)

Co-authored-by: Your Name <you@example.com>

* Fix numeric overflow in cmplog implementation (#907)

Co-authored-by: Your Name <you@example.com>

* testcase fixes for unicorn

* remove merge conflict artifacts

* fix afl-plot

* Changes to remove binaries from frida_mode (#913)

Co-authored-by: Your Name <you@example.com>

* Frida cmplog fail fast (#914)

* Changes to remove binaries from frida_mode

* Changes to make cmplog fail fast

Co-authored-by: Your Name <you@example.com>

* afl-plot: relative time

* arch linux and mac os support for afl-system-config

* typo

* code-format

* update documentation

Co-authored-by: Dominik Maier <domenukk@gmail.com>
Co-authored-by: WorksButNotTested <62701594+WorksButNotTested@users.noreply.github.com>
Co-authored-by: Your Name <you@example.com>
Co-authored-by: Dmitry Zheregelya <zheregelya.d@gmail.com>
Co-authored-by: hexcoder <hexcoder-@users.noreply.github.com>
Co-authored-by: hexcoder- <heiko@hexco.de>
Co-authored-by: Andrea Fioraldi <andreafioraldi@gmail.com>
Co-authored-by: David CARLIER <devnexen@gmail.com>
Co-authored-by: realmadsci <71108352+realmadsci@users.noreply.github.com>
Co-authored-by: Roman M. Iudichev <SecNotice@ya.ru>
Diffstat (limited to 'frida_mode/src/ranges.c')
-rw-r--r--frida_mode/src/ranges.c462
1 files changed, 321 insertions, 141 deletions
diff --git a/frida_mode/src/ranges.c b/frida_mode/src/ranges.c
index 49ef5a62..e3f09f9e 100644
--- a/frida_mode/src/ranges.c
+++ b/frida_mode/src/ranges.c
@@ -1,9 +1,12 @@
-// 0x123-0x321
-// module.so
+#include "frida-gum.h"
 
-#include "ranges.h"
 #include "debug.h"
 
+#include "lib.h"
+#include "ranges.h"
+#include "stalker.h"
+#include "util.h"
+
 #define MAX_RANGES 20
 
 typedef struct {
@@ -14,15 +17,11 @@ typedef struct {
 
 } convert_name_ctx_t;
 
-typedef struct {
-
-  GumStalker *stalker;
-  GArray *    array;
-
-} include_range_ctx_t;
-
-GArray * ranges = NULL;
-gboolean exclude_ranges = false;
+GArray *module_ranges = NULL;
+GArray *libs_ranges = NULL;
+GArray *include_ranges = NULL;
+GArray *exclude_ranges = NULL;
+GArray *ranges = NULL;
 
 static void convert_address_token(gchar *token, GumMemoryRange *range) {
 
@@ -159,236 +158,417 @@ static void convert_token(gchar *token, GumMemoryRange *range) {
 
 }
 
-static gboolean include_ranges(const GumRangeDetails *details,
-                               gpointer               user_data) {
+gint range_sort(gconstpointer a, gconstpointer b) {
 
-  include_range_ctx_t *ctx = (include_range_ctx_t *)user_data;
-  GArray *             array = (GArray *)ctx->array;
-  GumAddress           base = details->range->base_address;
-  GumAddress limit = details->range->base_address + details->range->size;
+  return ((GumMemoryRange *)a)->base_address -
+         ((GumMemoryRange *)b)->base_address;
 
-  OKF("Range for inclusion 0x%016" G_GINT64_MODIFIER
-      "x-0x%016" G_GINT64_MODIFIER "x",
-      base, limit);
+}
 
-  for (int i = 0; i < array->len; i++) {
+static gboolean print_ranges_callback(const GumRangeDetails *details,
+                                      gpointer               user_data) {
 
-    GumMemoryRange *range = &g_array_index(array, GumMemoryRange, i);
-    GumAddress      range_base = range->base_address;
-    GumAddress      range_limit = range->base_address + range->size;
+  UNUSED_PARAMETER(user_data);
+  if (details->file == NULL) {
 
-    /* Before the region */
-    if (range_limit < base) { continue; }
+    OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER "X",
+        details->range->base_address,
+        details->range->base_address + details->range->size);
 
-    /* After the region */
-    if (range_base > limit) {
+  } else {
 
-      GumMemoryRange exclude = {.base_address = base, .size = limit - base};
-      OKF("\t Excluding 0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
-          "x",
-          base, limit);
-      gum_stalker_exclude(ctx->stalker, &exclude);
-      return true;
+    OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER
+        "X %s(0x%016" G_GINT64_MODIFIER "x)",
+        details->range->base_address,
+        details->range->base_address + details->range->size,
+        details->file->path, details->file->offset);
 
-    }
+  }
 
-    /* Overlap the start of the region */
-    if (range_base < base) {
+  return true;
 
-      /* Range contains the region */
-      if (range_limit > limit) {
+}
 
-        return true;
+static void print_ranges(char *key, GArray *ranges) {
 
-      } else {
+  OKF("Range: %s Length: %d", key, ranges->len);
+  for (guint i = 0; i < ranges->len; i++) {
 
-        base = range_limit;
-        continue;
+    GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i);
+    GumAddress      curr_limit = curr->base_address + curr->size;
+    OKF("Range: %s Idx: %3d - 0x%016" G_GINT64_MODIFIER
+        "x-0x%016" G_GINT64_MODIFIER "x",
+        key, i, curr->base_address, curr_limit);
 
-      }
+  }
 
-      /* Overlap the end of the region */
+}
 
-    } else {
+static gboolean collect_module_ranges_callback(const GumRangeDetails *details,
+                                               gpointer user_data) {
 
-      GumMemoryRange exclude = {.base_address = base,
-                                .size = range_base - base};
-      OKF("\t Excluding 0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER
-          "x",
-          base, range_base);
-      gum_stalker_exclude(ctx->stalker, &exclude);
-      /* Extend past the end of the region */
-      if (range_limit >= limit) {
+  GArray *       ranges = (GArray *)user_data;
+  GumMemoryRange range = *details->range;
+  g_array_append_val(ranges, range);
+  return TRUE;
 
-        return true;
+}
 
-        /* Contained within the region */
+static GArray *collect_module_ranges(void) {
 
-      } else {
+  GArray *result;
+  result = g_array_new(false, false, sizeof(GumMemoryRange));
+  gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS,
+                               collect_module_ranges_callback, result);
+  print_ranges("Modules", result);
+  return result;
 
-        base = range_limit;
-        continue;
+}
 
-      }
+static GArray *collect_ranges(char *env_key) {
 
-    }
+  char *         env_val;
+  gchar **       tokens;
+  int            token_count;
+  GumMemoryRange range;
+  int            i;
+  GArray *       result;
+
+  result = g_array_new(false, false, sizeof(GumMemoryRange));
+
+  env_val = getenv(env_key);
+  if (env_val == NULL) return result;
+
+  tokens = g_strsplit(env_val, ",", MAX_RANGES);
+
+  for (token_count = 0; tokens[token_count] != NULL; token_count++)
+    ;
+
+  for (i = 0; i < token_count; i++) {
+
+    convert_token(tokens[i], &range);
+    g_array_append_val(result, range);
 
   }
 
-  GumMemoryRange exclude = {.base_address = base, .size = limit - base};
-  OKF("\t Excluding 0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER "x",
-      base, limit);
-  gum_stalker_exclude(ctx->stalker, &exclude);
-  return true;
+  g_array_sort(result, range_sort);
 
-}
+  /* Check for overlaps */
+  for (i = 1; i < token_count; i++) {
 
-gint range_sort(gconstpointer a, gconstpointer b) {
+    GumMemoryRange *prev = &g_array_index(result, GumMemoryRange, i - 1);
+    GumMemoryRange *curr = &g_array_index(result, GumMemoryRange, i);
+    GumAddress      prev_limit = prev->base_address + prev->size;
+    GumAddress      curr_limit = curr->base_address + curr->size;
+    if (prev_limit > curr->base_address) {
 
-  return ((GumMemoryRange *)a)->base_address -
-         ((GumMemoryRange *)b)->base_address;
+      FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER
+            "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER
+            "x-0x%016" G_GINT64_MODIFIER "x",
+            prev->base_address, prev_limit, curr->base_address, curr_limit);
+
+    }
+
+  }
+
+  print_ranges(env_key, result);
+
+  g_strfreev(tokens);
+
+  return result;
 
 }
 
-static gboolean print_ranges(const GumRangeDetails *details,
-                             gpointer               user_data) {
+static GArray *collect_libs_ranges(void) {
 
-  if (details->file == NULL) {
+  GArray *       result;
+  GumMemoryRange range;
+  result = g_array_new(false, false, sizeof(GumMemoryRange));
 
-    OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER "X",
-        details->range->base_address,
-        details->range->base_address + details->range->size);
+  if (getenv("AFL_INST_LIBS") == NULL) {
+
+    range.base_address = lib_get_text_base();
+    range.size = lib_get_text_limit() - lib_get_text_base();
 
   } else {
 
-    OKF("MAP - 0x%016" G_GINT64_MODIFIER "x - 0x%016" G_GINT64_MODIFIER
-        "X %s(0x%016" G_GINT64_MODIFIER "x)",
-        details->range->base_address,
-        details->range->base_address + details->range->size,
-        details->file->path, details->file->offset);
+    range.base_address = 0;
+    range.size = G_MAXULONG;
 
   }
 
+  g_array_append_val(result, range);
+
+  print_ranges("AFL_INST_LIBS", result);
+
+  return result;
+
+}
+
+static gboolean intersect_range(GumMemoryRange *rr, GumMemoryRange *ra,
+                                GumMemoryRange *rb) {
+
+  GumAddress rab = ra->base_address;
+  GumAddress ral = rab + ra->size;
+
+  GumAddress rbb = rb->base_address;
+  GumAddress rbl = rbb + rb->size;
+
+  GumAddress rrb = 0;
+  GumAddress rrl = 0;
+
+  rr->base_address = 0;
+  rr->size = 0;
+
+  /* ra is before rb */
+  if (ral < rbb) { return false; }
+
+  /* ra is after rb */
+  if (rab > rbl) { return true; }
+
+  /* The largest of the two base addresses */
+  rrb = rab > rbb ? rab : rbb;
+
+  /* The smallest of the two limits */
+  rrl = ral < rbl ? ral : rbl;
+
+  rr->base_address = rrb;
+  rr->size = rrl - rrb;
   return true;
 
 }
 
-void ranges_init(GumStalker *stalker) {
+static GArray *intersect_ranges(GArray *a, GArray *b) {
 
-  char *         showmaps;
-  char *         include;
-  char *         exclude;
-  char *         list;
-  gchar **       tokens;
-  int            token_count;
-  GumMemoryRange range;
+  GArray *        result;
+  GumMemoryRange *ra;
+  GumMemoryRange *rb;
+  GumMemoryRange  ri;
 
-  int i;
+  result = g_array_new(false, false, sizeof(GumMemoryRange));
 
-  showmaps = getenv("AFL_FRIDA_DEBUG_MAPS");
-  include = getenv("AFL_FRIDA_INST_RANGES");
-  exclude = getenv("AFL_FRIDA_EXCLUDE_RANGES");
+  for (guint i = 0; i < a->len; i++) {
 
-  if (showmaps) {
+    ra = &g_array_index(a, GumMemoryRange, i);
+    for (guint j = 0; j < b->len; j++) {
 
-    gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges, NULL);
+      rb = &g_array_index(b, GumMemoryRange, j);
 
-  }
+      if (!intersect_range(&ri, ra, rb)) { break; }
+
+      if (ri.size == 0) { continue; }
 
-  if (include != NULL && exclude != NULL) {
+      g_array_append_val(result, ri);
 
-    FATAL(
-        "Cannot specifify both AFL_FRIDA_INST_RANGES and "
-        "AFL_FRIDA_EXCLUDE_RANGES");
+    }
 
   }
 
-  if (include == NULL && exclude == NULL) { return; }
+  return result;
 
-  list = include == NULL ? exclude : include;
-  exclude_ranges = include == NULL ? true : false;
+}
 
-  tokens = g_strsplit(list, ",", MAX_RANGES);
+static GArray *subtract_ranges(GArray *a, GArray *b) {
 
-  for (token_count = 0; tokens[token_count] != NULL; token_count++)
-    ;
+  GArray *        result;
+  GumMemoryRange *ra;
+  GumAddress      ral;
+  GumMemoryRange *rb;
+  GumMemoryRange  ri;
+  GumMemoryRange  rs;
 
-  ranges = g_array_sized_new(false, false, sizeof(GumMemoryRange), token_count);
+  result = g_array_new(false, false, sizeof(GumMemoryRange));
 
-  for (i = 0; i < token_count; i++) {
+  for (guint i = 0; i < a->len; i++) {
 
-    convert_token(tokens[i], &range);
-    g_array_append_val(ranges, range);
+    ra = &g_array_index(a, GumMemoryRange, i);
+    ral = ra->base_address + ra->size;
+    for (guint j = 0; j < b->len; j++) {
+
+      rb = &g_array_index(b, GumMemoryRange, j);
+
+      /*
+       * If rb is after ra, we have no more possible intersections and we can
+       * simply keep the remaining range
+       */
+      if (!intersect_range(&ri, ra, rb)) { break; }
+
+      /*
+       * If there is no intersection, then rb must be before ra, so we must
+       * continue
+       */
+      if (ri.size == 0) { continue; }
+
+      /*
+       * If the intersection is part way through the range, then we keep the
+       * start of the range
+       */
+      if (ra->base_address < ri.base_address) {
+
+        rs.base_address = ra->base_address;
+        rs.size = ri.base_address - ra->base_address;
+        g_array_append_val(result, rs);
+
+      }
+
+      /*
+       * If the intersection extends past the limit of the range, then we should
+       * continue with the next range
+       */
+      if ((ri.base_address + ri.size) > ral) {
+
+        ra->base_address = ral;
+        ra->size = 0;
+        break;
+
+      }
+
+      /*
+       * Otherwise we advance the base of the range to the end of the
+       * intersection and continue with the remainder of the range
+       */
+      ra->base_address = ri.base_address + ri.size;
+      ra->size = ral - ra->base_address;
+
+    }
+
+    /*
+     * When we have processed all the possible intersections, we add what is
+     * left
+     */
+    if (ra->size != 0) g_array_append_val(result, *ra);
 
   }
 
-  g_array_sort(ranges, range_sort);
+  return result;
 
-  /* Check for overlaps */
-  for (i = 1; i < token_count; i++) {
+}
 
-    GumMemoryRange *prev = &g_array_index(ranges, GumMemoryRange, i - 1);
-    GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i);
-    GumAddress      prev_limit = prev->base_address + prev->size;
-    GumAddress      curr_limit = curr->base_address + curr->size;
-    if (prev_limit > curr->base_address) {
+static GArray *merge_ranges(GArray *a) {
 
-      FATAL("OVerlapping ranges 0x%016" G_GINT64_MODIFIER
-            "x-0x%016" G_GINT64_MODIFIER "x 0x%016" G_GINT64_MODIFIER
-            "x-0x%016" G_GINT64_MODIFIER "x",
-            prev->base_address, prev_limit, curr->base_address, curr_limit);
+  GArray *        result;
+  GumMemoryRange  rp;
+  GumMemoryRange *r;
+
+  result = g_array_new(false, false, sizeof(GumMemoryRange));
+  if (a->len == 0) return result;
+
+  rp = g_array_index(a, GumMemoryRange, 0);
+
+  for (guint i = 1; i < a->len; i++) {
+
+    r = &g_array_index(a, GumMemoryRange, i);
+
+    if (rp.base_address + rp.size == r->base_address) {
+
+      rp.size += r->size;
+
+    } else {
+
+      g_array_append_val(result, rp);
+      rp.base_address = r->base_address;
+      rp.size = r->size;
+      continue;
 
     }
 
   }
 
-  for (i = 0; i < token_count; i++) {
+  g_array_append_val(result, rp);
 
-    GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i);
-    GumAddress      curr_limit = curr->base_address + curr->size;
-    OKF("Range %3d - 0x%016" G_GINT64_MODIFIER "x-0x%016" G_GINT64_MODIFIER "x",
-        i, curr->base_address, curr_limit);
+  return result;
+
+}
+
+void ranges_init(void) {
+
+  GumMemoryRange  ri;
+  GArray *        step1;
+  GArray *        step2;
+  GArray *        step3;
+  GArray *        step4;
+  GumMemoryRange *r;
+  GumStalker *    stalker;
+
+  if (getenv("AFL_FRIDA_DEBUG_MAPS") != NULL) {
+
+    gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, print_ranges_callback,
+                                 NULL);
 
   }
 
-  if (include == NULL) {
+  module_ranges = collect_module_ranges();
+  libs_ranges = collect_libs_ranges();
+  include_ranges = collect_ranges("AFL_FRIDA_INST_RANGES");
 
-    for (i = 0; i < token_count; i++) {
+  /* If include ranges is empty, then assume everything is included */
+  if (include_ranges->len == 0) {
 
-      gum_stalker_exclude(stalker, &g_array_index(ranges, GumMemoryRange, i));
+    ri.base_address = 0;
+    ri.size = G_MAXULONG;
+    g_array_append_val(include_ranges, ri);
 
-    }
+  }
 
-  } else {
+  exclude_ranges = collect_ranges("AFL_FRIDA_EXCLUDE_RANGES");
 
-    include_range_ctx_t ctx = {.stalker = stalker, .array = ranges};
-    gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, include_ranges, &ctx);
+  /* Intersect with .text section of main executable unless AFL_INST_LIBS */
+  step1 = intersect_ranges(module_ranges, libs_ranges);
+  print_ranges("step1", step1);
+
+  /* Intersect with AFL_FRIDA_INST_RANGES */
+  step2 = intersect_ranges(step1, include_ranges);
+  print_ranges("step2", step2);
+
+  /* Subtract AFL_FRIDA_EXCLUDE_RANGES */
+  step3 = subtract_ranges(step2, exclude_ranges);
+  print_ranges("step3", step3);
+
+  /*
+   * After step3, we have the total ranges to be instrumented, we now subtract
+   * that from the original ranges of the modules to configure stalker.
+   */
+
+  step4 = subtract_ranges(module_ranges, step3);
+  print_ranges("step4", step4);
+
+  ranges = merge_ranges(step4);
+  print_ranges("final", ranges);
+
+  stalker = stalker_get();
+
+  for (guint i = 0; i < ranges->len; i++) {
+
+    r = &g_array_index(ranges, GumMemoryRange, i);
+    gum_stalker_exclude(stalker, r);
 
   }
 
-  g_strfreev(tokens);
+  g_array_free(step4, TRUE);
+  g_array_free(step3, TRUE);
+  g_array_free(step2, TRUE);
+  g_array_free(step1, TRUE);
 
 }
 
 gboolean range_is_excluded(gpointer address) {
 
-  int        i;
   GumAddress test = GUM_ADDRESS(address);
 
   if (ranges == NULL) { return false; }
 
-  for (i = 0; i < ranges->len; i++) {
+  for (guint i = 0; i < ranges->len; i++) {
 
     GumMemoryRange *curr = &g_array_index(ranges, GumMemoryRange, i);
     GumAddress      curr_limit = curr->base_address + curr->size;
 
-    if (test < curr->base_address) { return !exclude_ranges; }
+    if (test < curr->base_address) { return false; }
 
-    if (test < curr_limit) { return exclude_ranges; }
+    if (test < curr_limit) { return true; }
 
   }
 
-  return !exclude_ranges;
+  return false;
 
 }