Enhace drr, also arr. add dbg.slow and better debugmap names in xnu

This commit is contained in:
pancake 2015-09-28 02:04:08 +02:00
parent 50340be871
commit c94dd22f4d
7 changed files with 147 additions and 95 deletions

View File

@ -1046,6 +1046,7 @@ static void ar_show_help(RCore *core) {
"ar", " 32", "Show 32 bit registers",
"ar", " all", "Show all bit registers",
"ar", " <type>", "Show all registers of given type",
"arr", "", "Show register references (telescoping)",
"ar=", "", "Show register values in columns",
"ar?"," <reg>", "Show register value",
"arb"," <type>", "Display hexdump of the given arena",
@ -1100,6 +1101,9 @@ void cmd_anal_reg(RCore *core, const char *str) {
r_cons_printf ("0x%08"PFMT64x"\n", off);
} else ar_show_help (core);
break;
case 'r':
r_core_debug_rr (core, core->anal->reg);
break;
case 'S':
{
int sz;

View File

@ -891,6 +891,103 @@ static int cmd_debug_map(RCore *core, const char *input) {
return true;
}
R_API void r_core_debug_rr (RCore *core, RReg *reg) {
// also get section and map names
RIOSection *sect;
char *mapname = NULL;
ut64 type, value;
int i, bits = core->assembler->bits;
RList *list = r_reg_get_list (reg, R_REG_TYPE_GPR);
RAnalFunction *fcn;
RListIter *iter;
RFlagItem *fi;
RRegItem *r;
r_debug_map_sync (core->dbg);
r_list_foreach (list, iter, r) {
if (r->size != bits)
continue;
value = r_reg_get_value (core->dbg->reg, r);
fi = r_flag_get_i2 (core->flags, value);
type = r_core_anal_address (core, value);
fcn = r_anal_get_fcn_in (core->anal, value, 0);
{
RDebugMap *map;
map = r_debug_map_get (core->dbg, value);
if (map && map->name && map->name[0])
mapname = strdup (map->name);
else mapname = NULL;
}
sect = r_io_section_vget (core->io, value);
if (bits == 64) {
r_cons_printf ("%6s 0x%016"PFMT64x, r->name, value);
} else {
r_cons_printf ("%6s 0x%08"PFMT64x, r->name, value);
}
if (value && fi) {
if (strcmp (fi->name, r->name))
r_cons_printf (" %s", fi->name);
}
if (fcn) {
if (strcmp (fcn->name, r->name))
r_cons_printf (" %s", fcn->name);
}
if (type) {
const char *c = r_core_anal_optype_colorfor (core, value);
const char *cend = (c&&*c)? Color_RESET: "";
if (!c) c = "";
if (type & R_ANAL_ADDR_TYPE_HEAP) {
r_cons_printf (" %sheap%s", c, cend);
} else if (type & R_ANAL_ADDR_TYPE_STACK) {
r_cons_printf (" %sstack%s", c, cend);
}
if (type & R_ANAL_ADDR_TYPE_PROGRAM)
r_cons_printf (" %sprogram%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_LIBRARY)
r_cons_printf (" %slibrary%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_ASCII)
r_cons_printf (" %sascii%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_SEQUENCE)
r_cons_printf (" %ssequence%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_READ)
r_cons_printf (" %sR%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_WRITE)
r_cons_printf (" %sW%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_EXEC)
r_cons_printf (" %sX%s", c, cend);
{
int ret, len = 0;
int is_text = 0;
ut8 buf[128];
buf[0]=0;
ret = r_io_read_at (core->io, value, buf, sizeof (buf));
if (ret && buf[0] && buf[0] != 0xff)
for (i=0; i<sizeof(buf)-1; i++) {
if (buf[i]==0) {
is_text = len;
break;
}
if (!IS_PRINTABLE(buf[i])) {
is_text = 0;
break;
}
len++;
}
if (is_text) {
r_cons_printf (" \"%s\"", buf);
}
}
}
if (sect && sect->name[0]) {
r_cons_printf (" (%s)", sect->name);
}
if (mapname) {
r_cons_printf (" (%s)", mapname);
free (mapname);
}
r_cons_newline ();
}
}
static void cmd_debug_reg(RCore *core, const char *str) {
int size, i, type = R_REG_TYPE_GPR;
int bits = (core->dbg->bits & R_SYS_BITS_64)? 64: 32;
@ -937,6 +1034,7 @@ static void cmd_debug_reg(RCore *core, const char *str) {
"dro", "", "Show previous (old) values of registers",
"drp", " <file>", "Load register metadata file",
"drp", "", "Display current register profile",
"drr", "", "Show registers references (telescoping)",
"drs", " [?]", "Stack register states",
"drt", "", "Show all register types",
"drt", " flg", "Show flag registers",
@ -1315,83 +1413,7 @@ free (rf);
}
break;
case 'r': // "drr"
{
ut64 type, value;
int bits = core->assembler->bits;
RList *list = r_reg_get_list (core->dbg->reg, R_REG_TYPE_GPR);
RAnalFunction *fcn;
RListIter *iter;
RFlagItem *fi;
RRegItem *r;
r_list_foreach (list, iter, r) {
if (r->size != bits)
continue;
value = r_reg_get_value (core->dbg->reg, r);
fi = r_flag_get_i2 (core->flags, value);
type = r_core_anal_address (core, value);
fcn = r_anal_get_fcn_in (core->anal, value, 0);
if (bits==64) {
r_cons_printf ("%6s 0x%016"PFMT64x, r->name, value);
} else {
r_cons_printf ("%6s 0x%08"PFMT64x, r->name, value);
}
if (value && fi) {
if (strcmp (fi->name, r->name))
r_cons_printf (" %s", fi->name);
}
if (fcn) {
if (strcmp (fcn->name, r->name))
r_cons_printf (" %s", fcn->name);
}
if (type) {
const char *c = r_core_anal_optype_colorfor (core, value);
const char *cend = (c&&*c)? Color_RESET: "";
if (!c) c = "";
if (type & R_ANAL_ADDR_TYPE_HEAP) {
r_cons_printf (" %sheap%s", c, cend);
} else if (type & R_ANAL_ADDR_TYPE_STACK) {
r_cons_printf (" %sstack%s", c, cend);
}
if (type & R_ANAL_ADDR_TYPE_PROGRAM)
r_cons_printf (" %sprogram%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_LIBRARY)
r_cons_printf (" %slibrary%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_ASCII)
r_cons_printf (" %sascii%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_SEQUENCE)
r_cons_printf (" %ssequence%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_READ)
r_cons_printf (" %sR%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_WRITE)
r_cons_printf (" %sW%s", c, cend);
if (type & R_ANAL_ADDR_TYPE_EXEC)
r_cons_printf (" %sX%s", c, cend);
{
int ret, len = 0;
int is_text = 0;
ut8 buf[128];
buf[0]=0;
ret = r_io_read_at (core->io, value, buf, sizeof(buf));
if (ret && buf[0] && buf[0] != 0xff)
for (i=0; i<sizeof(buf)-1; i++) {
if (buf[i]==0) {
is_text = len;
break;
}
if (!IS_PRINTABLE(buf[i])) {
is_text = 0;
break;
}
len++;
}
if (is_text) {
r_cons_printf (" \"%s\"", buf);
}
}
}
r_cons_newline ();
}
}
r_core_debug_rr (core, core->dbg->reg);
break;
case 'j':
case '\0':

View File

@ -1048,9 +1048,9 @@ static int cb_searchin(void *user, void *data) {
RConfigNode *node = (RConfigNode*) data;
if (*node->value == '?') {
r_cons_printf ("raw\nblock\nfile\nio.maps\nio.maprange\nio.section\n" \
"io.sections\nio.sections.write\nio.sections.exec\n" \
"dbg.stack\ndbg.heap\ndbg.map\ndbg.maps\n"\
"dbg.maps.exec\ndbg.maps.write\nanal.fcn\nanal.bb\n");
"io.sections\nio.sections.write\nio.sections.exec\n" \
"dbg.stack\ndbg.heap\ndbg.map\ndbg.maps\n"\
"dbg.maps.exec\ndbg.maps.write\nanal.fcn\nanal.bb\n");
return false;
}
return true;
@ -1270,6 +1270,8 @@ R_API int r_core_config_init(RCore *core) {
SETI("stack.size", 64, "Size of anotated hexdump in visual debug");
SETI("stack.delta", 0, "Delta for the stack dump");
SETPREF("dbg.slow", "false", "Show stack and regs in visual mode in a slow but verbose mode");
SETPREF("dbg.bpinmaps", "true", "Force breakpoints to be inside a valid map");
SETCB("dbg.forks", "false", &cb_dbg_forks, "Stop execution if fork() is done (see dbg.threads)");
SETCB("dbg.btalgo", "fuzzy", &cb_dbg_btalgo, "Select backtrace algorithm");

View File

@ -3,16 +3,21 @@
#include <r_core.h>
#define NPF 7
static int obs = 0;
static int blocksize = 0;
static int autoblocksize = 1;
static ut64 last_printed_address = 0LL;
static void r_core_visual_refresh (RCore *core);
#define debugfmt_default "f tmp;sr sp;pxw 64;dr=;s-;s tmp;f-tmp;pd $r"
const char *debugfmt_extra = "f tmp;sr sp;pxr 64;drr;s-;s tmp;f-tmp;pd $r";
const char *debugfmt = NULL;
static const char *printfmt[] = {
"x", "pd $r",
"f tmp;sr sp;pxw 64;dr=;s-;s tmp;f-tmp;pd $r",
debugfmt_default,
"pxw", "pc", "pxA", "pxa"
};
static int autoblocksize = 1;
static int obs = 0;
#undef USE_THREADS
#define USE_THREADS 1
@ -1650,6 +1655,11 @@ static void r_core_visual_refresh (RCore *core) {
r_config_set_i (core->config, "asm.bytes", 1);
}
}
if (r_config_get_i (core->config, "dbg.slow")) {
printfmt[2] = debugfmt_extra;
} else {
printfmt[2] = debugfmt_default;
}
/* hack to blank last line. move prompt here? */
//r_cons_fill_line ();

View File

@ -854,15 +854,27 @@ RList *xnu_dbg_maps(RDebug *dbg, int only_modules) {
#endif
if (1) {
#define xwr2rwx(x) ((x&1)<<2) | (x&2) | ((x&4)>>2)
char maxperm[32];
char depthstr[32];
if (depth>0) {
snprintf (depthstr, sizeof (depthstr), "_%d", depth);
} else depthstr[0] = 0;
if (info.max_protection != info.protection) {
strcpy (maxperm, r_str_rwx_i (xwr2rwx (
info.max_protection)));
} else {
maxperm[0] = 0;
}
// XXX: if its shared, it cannot be read?
snprintf (buf, sizeof (buf), "%s %02x %s%s%s%s%s %s depth=%d",
r_str_rwx_i (xwr2rwx (info.max_protection)), i,
unparse_inheritance (info.inheritance),
info.user_tag? " user": "",
info.is_submap? " sub": "",
info.inheritance? " inherit": "",
info.is_submap ? " submap": "",
module_name, depth);
snprintf (buf, sizeof (buf), "%02x_%s%s%s%s%s%s%s%s",
//r_str_rwx_i (xwr2rwx (info.max_protection)), i,
i, unparse_inheritance (info.inheritance),
info.user_tag? "_user": "",
info.is_submap? "_sub": "",
"", // info.inheritance? " inherit": "",
info.is_submap ? "_submap": "",
module_name, maxperm, depthstr);
//info.shared ? "shar" : "priv",
//info.reserved ? "reserved" : "not-reserved",
//""); //module_name);

View File

@ -253,6 +253,8 @@ R_API int r_core_set_file_by_name (RBin * bin, const char * name);
R_API RBinFile * r_core_bin_cur (RCore *core);
R_API ut32 r_core_file_cur_fd (RCore *core);
R_API void r_core_debug_rr (RCore *core, RReg *reg);
#define R_CORE_FOREIGN_ADDR -1
R_API int r_core_yank(RCore *core, ut64 addr, int len);
R_API int r_core_yank_string(RCore *core, ut64 addr, int maxlen);

View File

@ -177,18 +177,18 @@ static int filter(RParse *p, RFlag *f, char *data, char *str, int len) {
strcat (num, "b");
break;
case 2: // hack for ascii
snprintf (num, sizeof(num), "'%c'", off);
snprintf (num, sizeof(num), "'%c'", (char)off);
break;
case 8:
snprintf (num, sizeof(num), "0%o", off);
snprintf (num, sizeof(num), "0%o", (int)off);
break;
case 10:
snprintf (num, sizeof(num), "%d", off);
snprintf (num, sizeof(num), "%d", (int)off);
break;
case 16:
/* do nothing */
default:
snprintf (num, sizeof(num), "0x%x", off);
snprintf (num, sizeof(num), "0x%x", (ut32) off);
break;
}
*ptr = 0;