From 243d2a03d31c15b617af68916a0a020b6f6a2098 Mon Sep 17 00:00:00 2001 From: radare Date: Thu, 21 Feb 2019 14:57:04 +0100 Subject: [PATCH] Initial implementation of the dri command - inverse debug registers ##debug --- libr/core/cmd_anal.c | 20 +++++++++- libr/core/cmd_debug.c | 88 ++++++++++++++++++++++++++++++++++++++++++- libr/core/core.c | 13 ++++--- libr/util/vector.c | 4 -- 4 files changed, 111 insertions(+), 14 deletions(-) diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index 559e2f4c10..4c13bc8b2a 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -3127,6 +3127,10 @@ static int cmd_anal_fcn(RCore *core, const char *input) { // size: 0: bits; -1: any; >0: exact size static void __anal_reg_list(RCore *core, int type, int bits, char mode) { + if (mode == 'i') { + r_core_debug_ri (core, core->anal->reg, 0); + return; + } RReg *hack = core->dbg->reg; const char *use_color; int use_colors = r_config_get_i (core->config, "scr.color"); @@ -3195,6 +3199,17 @@ static void __anal_reg_list(RCore *core, int type, int bits, char mode) { // XXX dup from drp :OOO void cmd_anal_reg(RCore *core, const char *str) { + if (0) { + /* enable this block when dr and ar use the same code but just using + core->dbg->reg or core->anal->reg and removing all the debugger + dependent code */ + RReg *reg = core->dbg->reg; + core->dbg->reg = core->anal->reg; + cmd_debug_reg (core, str); + core->dbg->reg = reg; + return; + } + int size = 0, i, type = R_REG_TYPE_GPR; int bits = (core->anal->bits & R_SYS_BITS_64)? 64: 32; int use_colors = r_config_get_i (core->config, "scr.color"); @@ -3308,10 +3323,10 @@ void cmd_anal_reg(RCore *core, const char *str) { case 'r': // "arr" switch (str[1]) { case 'j': // "arrj" - r_core_debug_rr (core, core->dbg->reg, 'j'); + r_core_debug_rr (core, core->anal->reg, 'j'); break; default: - r_core_debug_rr (core, core->dbg->reg, 0); + r_core_debug_rr (core, core->anal->reg, 0); break; } break; @@ -3486,6 +3501,7 @@ void cmd_anal_reg(RCore *core, const char *str) { case '*': // "ar*" case 'R': // "arR" case 'j': // "arj" + case 'i': // "arj" case '\0': // "ar" __anal_reg_list (core, type, size, str[0]); break; diff --git a/libr/core/cmd_debug.c b/libr/core/cmd_debug.c index de8ba8b6c3..30aca26a62 100644 --- a/libr/core/cmd_debug.c +++ b/libr/core/cmd_debug.c @@ -317,6 +317,7 @@ static const char *help_msg_dr[] = { "drC", "", "Show register profile comments", "drd", "", "Show only different registers", "drf", "", "Show fpu registers (80 bit long double)", + "dri", "", "Show inverse registers dump (sorted by value)", "drl", "[j]", "List all register names", "drm", "", "Show multimedia packed registers", "drm", " mmx0 0 32 = 12", "Set the first 32 bit word of the mmx reg to 12", @@ -1832,6 +1833,86 @@ static int cmd_debug_map(RCore *core, const char *input) { #include "linux_heap_glibc.c" #endif +// move into basic_types.h + +#define HEAPTYPE(x) \ + static x* x##_new(x n) {\ + x *m = malloc(sizeof (x));\ + return m? *m = n, m: m; \ + } + +HEAPTYPE(ut64); + +static int regcmp(void *a, void *b) { + ut64 *A = a; + ut64 *B = b; + if (*A > *B) { + return 1; + } + if (*A == *B) { + return 0; + } + return -1; +} + +static bool regcb(void *u, const ut64 k, const void *v) { + RList *sorted = (RList*) u; + ut64 *n = ut64_new (k); + r_list_add_sorted (sorted, n, regcmp); + return true; +} + +R_API void r_core_debug_ri(RCore *core, RReg *reg, int mode) { + RList *list = r_reg_get_list (reg, R_REG_TYPE_GPR); + RListIter *iter; + RRegItem *r; + HtUP *db = ht_up_new0 (); + + r_list_foreach (list, iter, r) { + if (r->size != core->assembler->bits) { + continue; + } + ut64 value = r_reg_get_value (reg, r); + RList *list = ht_up_find (db, value, NULL); + if (!list) { + list = r_list_newf (NULL); + ht_up_update (db, value, list); + } + r_list_append (list, r->name); + } + + RList *sorted = r_list_newf (free); + ht_up_foreach (db, regcb, sorted); + ut64 *addr; + r_list_foreach (sorted, iter, addr) { + int rwx = 0; + RDebugMap *map = r_debug_map_get (core->dbg, *addr); + if (map) { + rwx = map->perm; + } + r_cons_printf (" %s ", r_str_rwx_i (rwx)); + + r_cons_printf ("0x%08"PFMT64x" ", *addr); + RList *list = ht_up_find (db, *addr, NULL); + if (list) { + RListIter *iter; + const char *r; + r_cons_strcat (Color_YELLOW); + r_list_foreach (list, iter, r) { + r_cons_printf (" %s", r); + } + r_cons_strcat (Color_RESET); + char *rrstr = r_core_anal_hasrefs (core, *addr, true); + if (rrstr && *rrstr && strchr (rrstr, 'R')) { + r_cons_printf (" ;%s"Color_RESET, rrstr); + } + r_cons_newline (); + } + } + r_list_free (sorted); + ht_up_free (db); +} + R_API void r_core_debug_rr(RCore *core, RReg *reg, int mode) { char *use_color, *color = ""; int use_colors = r_config_get_i (core->config, "scr.color"); @@ -1848,9 +1929,9 @@ R_API void r_core_debug_rr(RCore *core, RReg *reg, int mode) { } else { use_color = NULL; } - r_debug_map_sync (core->dbg); +// r_debug_map_sync (core->dbg); if (mode == 'j') { - r_cons_printf("["); + r_cons_printf ("["); } r_list_foreach (list, iter, r) { char *rrstr, *tmp = NULL; @@ -2566,6 +2647,9 @@ static void cmd_debug_reg(RCore *core, const char *str) { r_cons_printf ("fs-\n"); } break; + case 'i': // "dri" + r_core_debug_ri (core, core->dbg->reg, 0); + break; case 'r': // "drr" switch (str[1]) { case 'j': // "drrj" diff --git a/libr/core/core.c b/libr/core/core.c index 905ef8ac8d..a3c6807c66 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -1842,7 +1842,7 @@ static int is_string (const ut8 *buf, int size, int *len) { static char *r_core_anal_hasrefs_to_depth(RCore *core, ut64 value, int depth); R_API char *r_core_anal_hasrefs(RCore *core, ut64 value, bool verbose) { if (verbose) { - return r_core_anal_hasrefs_to_depth(core, value, r_config_get_i (core->config, "hex.depth")); + return r_core_anal_hasrefs_to_depth (core, value, r_config_get_i (core->config, "hex.depth")); } RFlagItem *fi = r_flag_get_i (core->flags, value); if (fi) { @@ -1853,12 +1853,10 @@ R_API char *r_core_anal_hasrefs(RCore *core, ut64 value, bool verbose) { static char *r_core_anal_hasrefs_to_depth(RCore *core, ut64 value, int depth) { RStrBuf *s = r_strbuf_new (NULL); - ut64 type; char *mapname = NULL; - RAnalFunction *fcn; RFlagItem *fi = r_flag_get_i (core->flags, value); - type = r_core_anal_address (core, value); - fcn = r_anal_get_fcn_in (core->anal, value, 0); + ut64 type = r_core_anal_address (core, value); + RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, value, 0); if (value && value != UT64_MAX) { RDebugMap *map = r_debug_map_get (core->dbg, value); if (map && map->name && map->name[0]) { @@ -1877,7 +1875,10 @@ static char *r_core_anal_hasrefs_to_depth(RCore *core, ut64 value, int depth) { } } if (fi) { - r_strbuf_appendf (s, " %s", fi->name); + RRegItem *r = r_reg_get (core->dbg->reg, fi->name, -1); + if (!r) { + r_strbuf_appendf (s, " %s", fi->name); + } } if (fcn) { r_strbuf_appendf (s, " %s", fcn->name); diff --git a/libr/util/vector.c b/libr/util/vector.c index 5a7016f373..d971c59ab6 100644 --- a/libr/util/vector.c +++ b/libr/util/vector.c @@ -96,8 +96,6 @@ R_API RVector *r_vector_clone(RVector *vec) { return ret; } - - R_API void *r_vector_index_ptr(RVector *vec, size_t index) { return (char *)vec->a + vec->elem_size * index; } @@ -125,8 +123,6 @@ R_API void r_vector_remove_at(RVector *vec, size_t index, void *into) { } } - - R_API void *r_vector_insert(RVector *vec, size_t index, void *x) { if (vec->len >= vec->capacity) { RESIZE_OR_RETURN_NULL (NEXT_VECTOR_CAPACITY);