Skip to content
New issue

Have a question about this project? # for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “#”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? # to your account

Add yara.va, to override io.va if set to false #42

Merged
merged 3 commits into from
Nov 22, 2024
Merged
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
234 changes: 162 additions & 72 deletions src/core_r2yara.c
Original file line number Diff line number Diff line change
Expand Up @@ -81,6 +81,7 @@ typedef struct {
bool iova; // true
RList* rules_list;
RList *genstrings;
ut64 map_addr;
RCore *core;
} R2Yara;

Expand Down Expand Up @@ -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
Expand All @@ -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++;
}
}
Expand All @@ -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) {
Expand All @@ -266,7 +323,6 @@ static int cmd_yara_show(R2Yara *r2yara, const char * name) {
}
#endif
}

return true;
}

Expand Down Expand Up @@ -567,37 +623,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) {
Expand Down Expand Up @@ -801,18 +859,46 @@ 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 (&current_time);
time_info = localtime (&current_time);

struct tm *time_info = localtime (&current_time);
strftime (ds, 16, "%Y-%m-%d", time_info);
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;
Expand All @@ -835,6 +921,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_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);
}

Expand Down
Loading