From edda239131164945068d967acae813156a352898 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 25 Aug 2021 18:34:39 +0100 Subject: Fix issues with cmplog caused by coverage writing to STDIN --- frida_mode/src/instrument/instrument_coverage.c | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/frida_mode/src/instrument/instrument_coverage.c b/frida_mode/src/instrument/instrument_coverage.c index 4c0d1a14..b3323e1d 100644 --- a/frida_mode/src/instrument/instrument_coverage.c +++ b/frida_mode/src/instrument/instrument_coverage.c @@ -13,7 +13,7 @@ char *instrument_coverage_filename = NULL; static int coverage_fd = -1; -static int coverage_pipes[2] = {0}; +static int coverage_pipes[2] = {-1, -1}; static uint64_t coverage_last_start = 0; static GHashTable *coverage_hash = NULL; static GArray * coverage_modules = NULL; @@ -353,12 +353,16 @@ void instrument_coverage_init(void) { void instrument_coverage_start(uint64_t address) { + if (instrument_coverage_filename == NULL) { return; } + coverage_last_start = address; } void instrument_coverage_end(uint64_t address) { + if (instrument_coverage_filename == NULL) { return; } + coverage_data_t data = { .start = coverage_last_start, .end = address, .module = NULL}; -- cgit 1.4.1 From 4cdf4d2eaf9f81c37e99fd589858abf98d8be173 Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 25 Aug 2021 18:34:39 +0100 Subject: Changes to fix coverage output --- frida_mode/frida.map | 1 + frida_mode/src/instrument/instrument_coverage.c | 69 +++++++++++++++++-------- 2 files changed, 49 insertions(+), 21 deletions(-) diff --git a/frida_mode/frida.map b/frida_mode/frida.map index 7ad5e682..288633ab 100644 --- a/frida_mode/frida.map +++ b/frida_mode/frida.map @@ -26,6 +26,7 @@ js_api_set_prefetch_backpatch_disable; js_api_set_prefetch_disable; js_api_set_stalker_callback; + js_api_set_stalker_ic_entries; js_api_set_stats_file; js_api_set_stats_interval; js_api_set_stderr; diff --git a/frida_mode/src/instrument/instrument_coverage.c b/frida_mode/src/instrument/instrument_coverage.c index b3323e1d..b4ba523c 100644 --- a/frida_mode/src/instrument/instrument_coverage.c +++ b/frida_mode/src/instrument/instrument_coverage.c @@ -27,7 +27,7 @@ typedef struct { gsize size; char name[PATH_MAX + 1]; char path[PATH_MAX + 1]; - bool referenced; + guint count; guint16 id; } coverage_module_t; @@ -62,7 +62,7 @@ static gboolean coverage_module(const GumModuleDetails *details, if (details->path != NULL) strncpy(coverage.path, details->path, PATH_MAX); - coverage.referenced = false; + coverage.count = 0; coverage.id = 0; g_array_append_val(coverage_modules, coverage); @@ -83,9 +83,25 @@ static gint coverage_sort(gconstpointer a, gconstpointer b) { } +void instrument_coverage_print(char *format, ...) { + + char buffer[4096] = {0}; + int len; + + va_list ap; + va_start(ap, format); + + if (vsnprintf(buffer, sizeof(buffer) - 1, format, ap) < 0) { return; } + + len = strnlen(buffer, sizeof(buffer)); + IGNORED_RETURN(write(STDOUT_FILENO, buffer, len)); + va_end(ap); + +} + static void coverage_get_ranges(void) { - OKF("Coverage - Collecting ranges"); + instrument_coverage_print("Coverage - Collecting ranges\n"); coverage_modules = g_array_sized_new(false, false, sizeof(coverage_module_t), 100); @@ -96,9 +112,10 @@ static void coverage_get_ranges(void) { coverage_module_t *module = &g_array_index(coverage_modules, coverage_module_t, i); - OKF("Coverage Module - %3u: 0x%016" G_GINT64_MODIFIER - "X - 0x%016" G_GINT64_MODIFIER "X", - i, module->base_address, module->limit); + instrument_coverage_print("Coverage Module - %3u: 0x%016" G_GINT64_MODIFIER + "X - 0x%016" G_GINT64_MODIFIER "X (%s)\n", + i, module->base_address, module->limit, + module->path); } @@ -121,13 +138,14 @@ static void instrument_coverage_mark(void *key, void *value, void *user_data) { val->module = module; coverage_marked_entries++; - module->referenced = true; + module->count++; return; } - OKF("Coverage cannot find module for: 0x%016" G_GINT64_MODIFIER - "X - 0x%016" G_GINT64_MODIFIER "X %u %u", + instrument_coverage_print( + "Coverage cannot find module for: 0x%016" G_GINT64_MODIFIER + "X - 0x%016" G_GINT64_MODIFIER "X %u %u\n", val->start, val->end, i, coverage_modules->len); } @@ -178,7 +196,7 @@ static void coverage_write_modules() { coverage_module_t *module = &g_array_index(coverage_modules, coverage_module_t, i); - if (!module->referenced) continue; + if (module->count == 0) continue; coverage_format("%3u, ", emitted); coverage_format("%016" G_GINT64_MODIFIER "X, ", module->base_address); @@ -201,6 +219,9 @@ static void coverage_write_events(void *key, void *value, void *user_data) { UNUSED_PARAMETER(key); UNUSED_PARAMETER(user_data); coverage_data_t *val = (coverage_data_t *)value; + + if (val->module == NULL) { return; } + coverage_event_t evt = { .offset = val->start - val->module->base_address, @@ -237,12 +258,13 @@ static void coverage_mark_modules() { coverage_module_t *module = &g_array_index(coverage_modules, coverage_module_t, i); - OKF("Coverage Module - %3u: [%c] 0x%016" G_GINT64_MODIFIER - "X - 0x%016" G_GINT64_MODIFIER "X (%u:%s)", - i, module->referenced ? 'X' : ' ', module->base_address, module->limit, - module->id, module->path); + instrument_coverage_print( + "Coverage Module - %3u: [%c] 0x%016" G_GINT64_MODIFIER + "X - 0x%016" G_GINT64_MODIFIER "X [%u] (%u:%s)\n", + i, module->count == 0 ? ' ' : 'X', module->base_address, module->limit, + module->count, module->id, module->path); - if (!module->referenced) { continue; } + if (module->count == 0) { continue; } module->id = coverage_marked_modules; coverage_marked_modules++; @@ -256,7 +278,7 @@ static void instrument_coverage_run() { int bytes; coverage_data_t data; coverage_data_t *value; - OKF("Coverage - Running"); + instrument_coverage_print("Coverage - Running\n"); if (close(coverage_pipes[STDOUT_FILENO]) != 0) { @@ -278,22 +300,24 @@ static void instrument_coverage_run() { if (bytes != 0) { FATAL("Coverage data truncated"); } - OKF("Coverage - Preparing"); + instrument_coverage_print("Coverage - Preparing\n"); coverage_get_ranges(); guint size = g_hash_table_size(coverage_hash); - OKF("Coverage - Total Entries: %u", size); + instrument_coverage_print("Coverage - Total Entries: %u\n", size); g_hash_table_foreach(coverage_hash, instrument_coverage_mark, NULL); - OKF("Coverage - Marked Entries: %u", coverage_marked_entries); + instrument_coverage_print("Coverage - Marked Entries: %u\n", + coverage_marked_entries); coverage_mark_modules(); - OKF("Coverage - Marked Modules: %u", coverage_marked_modules); + instrument_coverage_print("Coverage - Marked Modules: %u\n", + coverage_marked_modules); coverage_write_header(); - OKF("Coverage - Completed"); + instrument_coverage_print("Coverage - Completed\n"); } @@ -339,10 +363,13 @@ void instrument_coverage_init(void) { if (pid == 0) { instrument_coverage_run(); + kill(getpid(), SIGKILL); _exit(0); } + if (close(coverage_fd) < 0) { FATAL("Failed to close coverage output file"); } + if (close(coverage_pipes[STDIN_FILENO]) != 0) { FATAL("Failed to close parent read pipe"); -- cgit 1.4.1 From 1a8819c9ad1b37b633a9fb9d558e3cf34cd0ecca Mon Sep 17 00:00:00 2001 From: Your Name Date: Wed, 25 Aug 2021 18:34:39 +0100 Subject: Changes to how modules are identified for coverage --- frida_mode/src/instrument/instrument_coverage.c | 122 ++++++++++++++++++------ 1 file changed, 94 insertions(+), 28 deletions(-) diff --git a/frida_mode/src/instrument/instrument_coverage.c b/frida_mode/src/instrument/instrument_coverage.c index b4ba523c..495791c7 100644 --- a/frida_mode/src/instrument/instrument_coverage.c +++ b/frida_mode/src/instrument/instrument_coverage.c @@ -17,6 +17,7 @@ static int coverage_pipes[2] = {-1, -1}; static uint64_t coverage_last_start = 0; static GHashTable *coverage_hash = NULL; static GArray * coverage_modules = NULL; +static GArray * coverage_ranges = NULL; static guint coverage_marked_modules = 0; static guint coverage_marked_entries = 0; @@ -25,18 +26,19 @@ typedef struct { GumAddress base_address; GumAddress limit; gsize size; - char name[PATH_MAX + 1]; char path[PATH_MAX + 1]; + guint64 offset; + gboolean is_executable; guint count; guint16 id; -} coverage_module_t; +} coverage_range_t; typedef struct { - uint64_t start; - uint64_t end; - coverage_module_t *module; + uint64_t start; + uint64_t end; + coverage_range_t *module; } coverage_data_t; @@ -48,32 +50,44 @@ typedef struct { } coverage_event_t; -static gboolean coverage_module(const GumModuleDetails *details, - gpointer user_data) { +static gboolean coverage_range(const GumRangeDetails *details, + gpointer user_data) { UNUSED_PARAMETER(user_data); - coverage_module_t coverage = {0}; + coverage_range_t coverage = {0}; + + if (details->file == NULL) { return TRUE; } + if (details->protection == GUM_PAGE_NO_ACCESS) { return TRUE; } coverage.base_address = details->range->base_address; coverage.size = details->range->size; coverage.limit = coverage.base_address + coverage.size; - if (details->name != NULL) strncpy(coverage.name, details->name, PATH_MAX); + strncpy(coverage.path, details->file->path, PATH_MAX); + coverage.offset = details->file->offset; + + if ((details->protection & GUM_PAGE_EXECUTE) == 0) { + + coverage.is_executable = false; - if (details->path != NULL) strncpy(coverage.path, details->path, PATH_MAX); + } else { + + coverage.is_executable = true; + + } coverage.count = 0; coverage.id = 0; - g_array_append_val(coverage_modules, coverage); + g_array_append_val(coverage_ranges, coverage); return TRUE; } static gint coverage_sort(gconstpointer a, gconstpointer b) { - coverage_module_t *ma = (coverage_module_t *)a; - coverage_module_t *mb = (coverage_module_t *)b; + coverage_range_t *ma = (coverage_range_t *)a; + coverage_range_t *mb = (coverage_range_t *)b; if (ma->base_address < mb->base_address) return -1; @@ -99,19 +113,48 @@ void instrument_coverage_print(char *format, ...) { } -static void coverage_get_ranges(void) { +static void coverage_get_modules(void) { - instrument_coverage_print("Coverage - Collecting ranges\n"); + instrument_coverage_print("Coverage - Collecting modules\n"); coverage_modules = - g_array_sized_new(false, false, sizeof(coverage_module_t), 100); - gum_process_enumerate_modules(coverage_module, NULL); - g_array_sort(coverage_modules, coverage_sort); + g_array_sized_new(false, false, sizeof(coverage_range_t), 100); + + coverage_range_t current = {0}; + + for (guint i = 0; i < coverage_ranges->len; i++) { + + coverage_range_t *range = + &g_array_index(coverage_ranges, coverage_range_t, i); + + if (range->offset == 0 || + (strncmp(range->path, current.path, PATH_MAX) != 0)) { + + if (current.is_executable) { + + g_array_append_val(coverage_modules, current); + memset(¤t, '\0', sizeof(coverage_range_t)); + + } + + memcpy(¤t, range, sizeof(coverage_range_t)); + + } else { + + current.limit = range->limit; + current.size = current.limit - current.base_address; + if (range->is_executable) { current.is_executable = true; } + + } + + } + + if (current.is_executable) { g_array_append_val(coverage_modules, current); } for (guint i = 0; i < coverage_modules->len; i++) { - coverage_module_t *module = - &g_array_index(coverage_modules, coverage_module_t, i); + coverage_range_t *module = + &g_array_index(coverage_modules, coverage_range_t, i); instrument_coverage_print("Coverage Module - %3u: 0x%016" G_GINT64_MODIFIER "X - 0x%016" G_GINT64_MODIFIER "X (%s)\n", i, module->base_address, module->limit, @@ -121,6 +164,28 @@ static void coverage_get_ranges(void) { } +static void coverage_get_ranges(void) { + + instrument_coverage_print("Coverage - Collecting ranges\n"); + + coverage_ranges = + g_array_sized_new(false, false, sizeof(coverage_range_t), 100); + gum_process_enumerate_ranges(GUM_PAGE_NO_ACCESS, coverage_range, NULL); + g_array_sort(coverage_ranges, coverage_sort); + + for (guint i = 0; i < coverage_ranges->len; i++) { + + coverage_range_t *range = + &g_array_index(coverage_ranges, coverage_range_t, i); + instrument_coverage_print("Coverage Range - %3u: 0x%016" G_GINT64_MODIFIER + "X - 0x%016" G_GINT64_MODIFIER "X (%s)\n", + i, range->base_address, range->limit, + range->path); + + } + +} + static void instrument_coverage_mark(void *key, void *value, void *user_data) { UNUSED_PARAMETER(key); @@ -130,8 +195,8 @@ static void instrument_coverage_mark(void *key, void *value, void *user_data) { for (i = 0; i < coverage_modules->len; i++) { - coverage_module_t *module = - &g_array_index(coverage_modules, coverage_module_t, i); + coverage_range_t *module = + &g_array_index(coverage_modules, coverage_range_t, i); if (val->start > module->limit) continue; if (val->end >= module->limit) break; @@ -145,8 +210,8 @@ static void instrument_coverage_mark(void *key, void *value, void *user_data) { instrument_coverage_print( "Coverage cannot find module for: 0x%016" G_GINT64_MODIFIER - "X - 0x%016" G_GINT64_MODIFIER "X %u %u\n", - val->start, val->end, i, coverage_modules->len); + "X - 0x%016" G_GINT64_MODIFIER "X\n", + val->start, val->end); } @@ -194,8 +259,8 @@ static void coverage_write_modules() { guint emitted = 0; for (guint i = 0; i < coverage_modules->len; i++) { - coverage_module_t *module = - &g_array_index(coverage_modules, coverage_module_t, i); + coverage_range_t *module = + &g_array_index(coverage_modules, coverage_range_t, i); if (module->count == 0) continue; coverage_format("%3u, ", emitted); @@ -255,8 +320,8 @@ static void coverage_mark_modules() { guint i; for (i = 0; i < coverage_modules->len; i++) { - coverage_module_t *module = - &g_array_index(coverage_modules, coverage_module_t, i); + coverage_range_t *module = + &g_array_index(coverage_modules, coverage_range_t, i); instrument_coverage_print( "Coverage Module - %3u: [%c] 0x%016" G_GINT64_MODIFIER @@ -303,6 +368,7 @@ static void instrument_coverage_run() { instrument_coverage_print("Coverage - Preparing\n"); coverage_get_ranges(); + coverage_get_modules(); guint size = g_hash_table_size(coverage_hash); instrument_coverage_print("Coverage - Total Entries: %u\n", size); -- cgit 1.4.1