From 9d5a6eb81457d6572229aff24246c3bbd36dc90a Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 22 Nov 2024 23:23:41 +0100 Subject: [PATCH 1/3] Indent fixes --- src/core_r2yara.c | 71 +++++++++++++++++++++++------------------------ 1 file changed, 35 insertions(+), 36 deletions(-) diff --git a/src/core_r2yara.c b/src/core_r2yara.c index 093f8e3..d876bd7 100644 --- a/src/core_r2yara.c +++ b/src/core_r2yara.c @@ -266,7 +266,6 @@ static int cmd_yara_show(R2Yara *r2yara, const char * name) { } #endif } - return true; } @@ -567,37 +566,39 @@ static int cmd_yara_gen(R2Yara *r2yara, const char* input) { break; case 's': { - char *s; - if (input[1]) { - int len = r_num_math(r2yara->core->num, input + 1); - s = r_core_cmd_strf(r2yara->core, "psz %d", len); - } else { - s = r_core_cmd_str(r2yara->core, "psz"); - } - r_list_append(r2yara->genstrings, yarastring(s)); - } break; - case '-': - if (input && input[1] == '*') { - r_list_free(r2yara->genstrings); - r2yara->genstrings = r_list_newf(free); - } else { - char *s = r_list_pop(r2yara->genstrings); - free(s); - } - break; - case 'x': { - char *s; - if (input[1]) { - int len = r_num_math(r2yara->core->num, input + 1); - s = r_core_cmd_strf(r2yara->core, "pcy %d", len); - } else { - s = r_core_cmd_str(r2yara->core, "pcy"); - } - r_str_trim(s); - r_list_append(r2yara->genstrings, s); - } break; - } - return 0; + char *s; + if (input[1]) { + int len = (int)r_num_math (r2yara->core->num, input + 1); + s = r_core_cmd_strf (r2yara->core, "psz %d", len); + } else { + s = r_core_cmd_str (r2yara->core, "psz"); + } + r_list_append (r2yara->genstrings, yarastring (s)); + } + break; + case '-': + if (input && input[1] == '*') { + r_list_free (r2yara->genstrings); + r2yara->genstrings = r_list_newf (free); + } else { + free (r_list_pop (r2yara->genstrings)); + } + break; + case 'x': + { + char *s; + if (input[1]) { + int len = r_num_math (r2yara->core->num, input + 1); + s = r_core_cmd_strf (r2yara->core, "pcy %d", len); + } else { + s = r_core_cmd_str (r2yara->core, "pcy"); + } + r_str_trim (s); + r_list_append (r2yara->genstrings, s); + } + break; + } + return 0; } static bool cmd_yara_add(R2Yara *r2yara, const char* input) { @@ -801,14 +802,12 @@ static int cmd_yara_load_default_rules(R2Yara *r2yara) { return false; } +// Move to r_sys_time_ymd? static char *yyyymmdd(void) { time_t current_time; - struct tm *time_info; char *ds = calloc (16, 1); - time (¤t_time); - time_info = localtime (¤t_time); - + struct tm *time_info = localtime (¤t_time); strftime (ds, 16, "%Y-%m-%d", time_info); return ds; } From 0981477b42233d45858e9738295ef631d515d81f Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 22 Nov 2024 23:24:04 +0100 Subject: [PATCH 2/3] Add yara.in and yara.va options and use the proper scan ranges --- src/core_r2yara.c | 133 +++++++++++++++++++++++++++++++++------------- 1 file changed, 97 insertions(+), 36 deletions(-) diff --git a/src/core_r2yara.c b/src/core_r2yara.c index d876bd7..b0ebacc 100644 --- a/src/core_r2yara.c +++ b/src/core_r2yara.c @@ -81,6 +81,7 @@ typedef struct { bool iova; // true RList* rules_list; RList *genstrings; + ut64 map_addr; RCore *core; } R2Yara; @@ -151,7 +152,7 @@ static int callback(YR_SCAN_CONTEXT* context, int message, void *msg_data, void RPrint *print = core->print; st64 offset = 0; ut64 n = 0; - + ut64 map_addr = r2yara->map_addr; R2YR_RULE* rule = msg_data; #if USE_YARAX @@ -163,20 +164,28 @@ static int callback(YR_SCAN_CONTEXT* context, int message, void *msg_data, void yr_rule_strings_foreach (rule, string) { YR_MATCH* match; yr_string_matches_foreach (context, string, match) { - n = match->base + match->offset; + n = map_addr + match->base + match->offset; // Find virtual address if needed - if (r2yara->iova) { + if (!r2yara->iova) { + RIOMap *map = r_io_map_get_at (core->io, n); + if (map) { + n -= r_io_map_begin (map) - map->delta; + } +#if 0 RIOMap *map = r_io_map_get_paddr (core->io, n); if (map) { - offset = r_io_map_begin (map) - map->delta; + // offset = r_io_map_begin (map) - map->delta; + n -= r_io_map_begin (map) + map->delta; + // n = r_io_map_begin (map) - map->delta; } +#endif } r_strf_var (flag, 256, "yara%d.%s_%d", r2yara->flagidx, rule->identifier, ruleidx); if (r2yara->print_strings) { - r_cons_printf ("0x%08" PFMT64x ": %s : ", n + offset, flag); + r_cons_printf ("0x%08" PFMT64x ": %s : ", n, flag); r_print_bytes (print, match->data, match->data_length, "%02x"); } - r_flag_set (core->flags, flag, n + offset, match->data_length); + r_flag_set (core->flags, flag, n, match->data_length); ruleidx++; } } @@ -194,59 +203,107 @@ static void compiler_callback(int error_level, const char* file_name, } #endif -static int cmd_yara_scan(R2Yara *r2yara, R_NULLABLE const char* option) { - RCore *core = r2yara->core; +static bool yr_scan(R2Yara *r2yara, void *to_scan, size_t to_scan_size) { RListIter* rules_it; R2YR_RULES* rules; +#if USE_YARAX + YRX_SCANNER *scanner = NULL; + r_list_foreach (r2yara->rules_list, rules_it, rules) { + YRX_RESULT res = yrx_scanner_create (rules, &scanner); + if (res == SUCCESS) { + YRX_RESULT res = yrx_scanner_on_matching_rule (scanner, callback, r2yara); + yrx_scanner_scan (scanner, to_scan, to_scan_size); + } + } +#else + r_list_foreach (r2yara->rules_list, rules_it, rules) { + yr_rules_scan_mem (rules, to_scan, to_scan_size, 0, callback, (void*)r2yara, 0); + } +#endif + return true; +} - r_flag_space_push (core->flags, "yara"); - const size_t to_scan_size = r_io_size (core->io); - r2yara->iova = r_config_get_b (core->config, "io.va"); - +static bool yr_vscan(R2Yara *r2yara, ut64 from, int to_scan_size) { + eprintf ("-> 0x%"PFMT64x" + %d\n", from, to_scan_size); + RCore *core = r2yara->core; if (to_scan_size < 1) { R_LOG_ERROR ("Invalid file size"); return false; } - - r2yara->print_strings = true; - if (option != NULL) { - if (*option == 'q') { - r2yara->print_strings = false; - } else { - R_LOG_ERROR ("Invalid option"); - return false; - } + void* to_scan = malloc (to_scan_size); + if (!to_scan) { + R_LOG_ERROR ("Something went wrong during memory allocation"); + return false; } + int result = r_io_read_at (core->io, from, to_scan, to_scan_size); + if (!result) { + R_LOG_ERROR ("Something went wrong during r_io_read_at"); + free (to_scan); + return false; + } + bool res = yr_scan (r2yara, to_scan, to_scan_size); + free (to_scan); + return res; +} +static bool yr_pscan(R2Yara *r2yara) { + RCore *core = r2yara->core; + const size_t to_scan_size = r_io_size (core->io); + if (to_scan_size < 1) { + R_LOG_ERROR ("Invalid file size"); + return false; + } void* to_scan = malloc (to_scan_size); if (!to_scan) { R_LOG_ERROR ("Something went wrong during memory allocation"); return false; } - int result = r_io_pread_at (core->io, 0L, to_scan, to_scan_size); if (!result) { R_LOG_ERROR ("Something went wrong during r_io_read_at"); free (to_scan); return false; } -#if USE_YARAX - YRX_SCANNER *scanner = NULL; - r_list_foreach (r2yara->rules_list, rules_it, rules) { - YRX_RESULT res = yrx_scanner_create (rules, &scanner); - if (res == SUCCESS) { - YRX_RESULT res = yrx_scanner_on_matching_rule (scanner, callback, r2yara); - yrx_scanner_scan (scanner, to_scan, to_scan_size); + bool res = yr_scan (r2yara, to_scan, to_scan_size); + free (to_scan); + return res; +} + +static int cmd_yara_scan(R2Yara *r2yara, R_NULLABLE const char* option) { + RCore *core = r2yara->core; + + const char *yara_in = r_config_get (core->config, "yara.in"); + RList *ranges = r_core_get_boundaries_prot (core, 0, yara_in, NULL); + RListIter *iter; + RIOMap *range; + r_flag_space_push (core->flags, "yara"); + r2yara->iova = r_config_get_b (core->config, "yara.va"); +#if 0 + if (r2yara->iova) { + r2yara->iova = r_config_get_b (core->config, "io.va"); + } +#endif + r2yara->print_strings = true; + if (option != NULL) { + if (*option == 'q') { + r2yara->print_strings = false; + } else { + R_LOG_ERROR ("Invalid option"); + return false; } } -#else - r_list_foreach (r2yara->rules_list, rules_it, rules) { - yr_rules_scan_mem (rules, to_scan, to_scan_size, 0, callback, (void*)r2yara, 0); + r2yara->map_addr = 0; + if (!r_list_empty (ranges)) { + r_list_foreach (ranges, iter, range) { + ut64 begin = r_io_map_begin (range); + ut64 end = r_io_map_end (range); + ut64 size = end - begin; + r2yara->map_addr = begin; + yr_vscan (r2yara, begin, (int)size); + } + return true; } -#endif - free (to_scan); - - return true; + return yr_pscan (r2yara); } static int cmd_yara_show(R2Yara *r2yara, const char * name) { @@ -834,6 +891,10 @@ static void setup_config(R2Yara *r2yara) { r_config_node_desc (node, "YARA rule tags"); node = r_config_set_i (cfg, "yara.amount", 0); r_config_node_desc (node, "Amount of strings to match (0 means all of them)"); + node = r_config_set_b (cfg, "yara.va", true); + r_config_node_desc (node, "Show results in virtual or physical addresses, overrides io.va"); + node = r_config_set (cfg, "yara.in", "io.map"); + r_config_node_desc (node, "Where to scan for matches (see yara.in=? for help)"); r_config_lock (cfg, true); } From 61528abae02ae41c6478eecc6ad61485776d6b86 Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 22 Nov 2024 23:28:15 +0100 Subject: [PATCH 3/3] =?UTF-8?q?Add=20help=20for=20yara.in=3D=3F?= --- src/core_r2yara.c | 32 +++++++++++++++++++++++++++++++- 1 file changed, 31 insertions(+), 1 deletion(-) diff --git a/src/core_r2yara.c b/src/core_r2yara.c index b0ebacc..3b48399 100644 --- a/src/core_r2yara.c +++ b/src/core_r2yara.c @@ -869,6 +869,36 @@ static char *yyyymmdd(void) { return ds; } +static bool yara_in_callback(void *user, void *data) { + RCore *core = (RCore*)user; + RConfigNode *node = (RConfigNode*) data; + if (*node->value == '?') { + r_cons_printf ( + "range search between .from/.to boundaries\n" + "flag find boundaries in ranges defined by flags larger than 1 byte\n" + "flag:[glob] find boundaries in flags matching given glob and larger than 1 byte\n" + "block search in the current block\n" + "io.map search in current map\n" + "io.maps search in all maps\n" + "io.maps.[rwx] search in all r-w-x io maps\n" + "bin.segment search in current mapped segment\n" + "bin.segments search in all mapped segments\n" + "bin.segments.[rwx] search in all r-w-x segments\n" + "bin.section search in current mapped section\n" + "bin.sections search in all mapped sections\n" + "bin.sections.[rwx] search in all r-w-x sections\n" + "dbg.stack search in the stack\n" + "dbg.heap search in the heap\n" + "dbg.map search in current memory map\n" + "dbg.maps search in all memory maps\n" + "dbg.maps.[rwx] search in all executable marked memory maps\n" + "anal.fcn search in the current function\n" + "anal.bb search in the current basic-block\n"); + return false; + } + return true; +} + static void setup_config(R2Yara *r2yara) { RConfig *cfg = r2yara->core->config; RConfigNode *node = NULL; @@ -893,7 +923,7 @@ static void setup_config(R2Yara *r2yara) { r_config_node_desc (node, "Amount of strings to match (0 means all of them)"); node = r_config_set_b (cfg, "yara.va", true); r_config_node_desc (node, "Show results in virtual or physical addresses, overrides io.va"); - node = r_config_set (cfg, "yara.in", "io.map"); + node = r_config_set_cb (cfg, "yara.in", "io.map", yara_in_callback); r_config_node_desc (node, "Where to scan for matches (see yara.in=? for help)"); r_config_lock (cfg, true); }