From bf52a651699fd8d020ca4fd950d947690a120b79 Mon Sep 17 00:00:00 2001 From: pancake Date: Wed, 30 Oct 2024 12:19:13 +0100 Subject: [PATCH] Refactor and extend few RNum $O->$$c|$$$c + error handling ##shell --- libr/core/cmd_anal.inc.c | 3 ++- libr/core/cmd_help.inc.c | 16 ++++++++---- libr/core/core.c | 56 ++++++++++++++++++++++++++-------------- test/db/anal/emu | 19 +++++++++----- test/db/cmd/numvars | 49 +++++++++++++++++++++++++++++++++++ 5 files changed, 112 insertions(+), 31 deletions(-) create mode 100644 test/db/cmd/numvars diff --git a/libr/core/cmd_anal.inc.c b/libr/core/cmd_anal.inc.c index ce47a7e9424b8..7c037ec1dbcd8 100644 --- a/libr/core/cmd_anal.inc.c +++ b/libr/core/cmd_anal.inc.c @@ -262,7 +262,7 @@ static RCoreHelpMessage help_msg_ab = { "abj", " [addr]", "display basic block information in JSON", "abl", "[?] [.-cqj]", "list all basic blocks", "abo", "", "list opcode offsets of current basic block", - "abp", "[?] [addr] [num]", "follow basic blocks paths from current offset to addr", + "abp", "[?] [addr]", "follow basic blocks paths from $$ to `addr`", "abt", "[tag] ([color])", "no args = show current trace tag, otherwise set the color", "abx", " [hexpair-bytes]", "analyze N bytes", NULL @@ -13125,6 +13125,7 @@ static void cmd_anal_abp(RCore *core, const char *input) { r_core_cmd_help (core, help_msg_abp); return; } + *p = 0; ut64 addr = r_num_math (core->num, p + 1); RList *paths = r_core_anal_graph_to (core, addr, n); if (paths) { diff --git a/libr/core/cmd_help.inc.c b/libr/core/cmd_help.inc.c index efbbd52e5b3be..d1f0ca1db7ae9 100644 --- a/libr/core/cmd_help.inc.c +++ b/libr/core/cmd_help.inc.c @@ -330,12 +330,15 @@ static RCoreHelpMessage help_msg_question_v = { "Usage: ?v [$.]", "", "", "flag", "", "offset of flag", "$", "{ev}", "get value of eval config variable", + "$", "[addr:size]", "get value of eval config variable", "$$", "", "here (current virtual seek)", + "$$c", "", "cursor position relative to current offset (previously $O)", "$$$", "", "current non-temporary virtual seek", + "$$$c", "", "cursor + current non-temporary virtual seek", "$?", "", "last comparison value", "$alias", "=value", "alias commands (simple macros)", + "$b", "", "block size (see b command and the @! operator)", "$B", "", "base address (aligned lowest map address)", - "$b", "", "block size", "$c", "", "get terminal width in character columns", "$Cn", "", "get nth call of function", "$D", "", "current debug map base address ?v $D @ rsp", @@ -367,7 +370,6 @@ static RCoreHelpMessage help_msg_question_v = { "$M", "", "map address (lowest map address)", "$m", "", "opcode memory reference (e.g. mov eax,[0x10] => 0x10)", "$MM", "", "map size (lowest map address)", - "$O", "", "cursor here (current offset pointed by the cursor)", "$o", "", "here (current disk io offset)", "$p", "", "getpid()", "$P", "", "pid of children (only in debug)", @@ -1024,7 +1026,11 @@ static int cmd_help(void *data, const char *input) { n = r_num_math (core->num, "$?"); } if (core->num->nc.errors > 0) { - R_LOG_ERROR (core->num->nc.calc_err); + if (core->num->nc.calc_err) { + R_LOG_ERROR ("%s", core->num->nc.calc_err); + } else { + R_LOG_ERROR ("RNum.error"); + } } if (core->num->dbz) { R_LOG_ERROR ("Division by Zero"); @@ -1153,9 +1159,9 @@ static int cmd_help(void *data, const char *input) { } else { int i = 0; const char *vars[] = { - "$$", "$$$", "$?", "$B", "$b", "$c", "$Cn", "$D", "$DB", "$DD", "$Dn", + "$$", "$$c", "$$$", "$$$c", "$?", "$B", "$b", "$c", "$Cn", "$D", "$DB", "$DD", "$Dn", "$e", "$f", "$F", "$Fb", "$FB", "$Fe", "$FE", "$Ff", "$Fi", "$FI", "$Fj", - "$fl", "$FS", "$Fs", "$FSS", "$i", "$j", "$Ja", "$l", "$M", "$m", "$MM", "$O", + "$fl", "$FS", "$Fs", "$FSS", "$i", "$j", "$Ja", "$l", "$M", "$m", "$MM", "$o", "$p", "$P", "$r", "$s", "$S", "$SS", "$v", "$w", "$Xn", NULL }; const bool wideOffsets = r_config_get_i (core->config, "scr.wideoff"); diff --git a/libr/core/core.c b/libr/core/core.c index 131e8fad1aab6..fc52df466f332 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -513,6 +513,7 @@ static ut64 numvar_instruction_backward(RCore *core, const char *input) { } static ut64 numvar_instruction(RCore *core, const char *input) { + RAnalOp op; ut64 addr = core->offset; // N forward instructions ut8 data[32]; @@ -528,7 +529,7 @@ static ut64 numvar_instruction(RCore *core, const char *input) { } for (i = 0; i < n; i++) { r_io_read_at (core->io, val, data, sizeof (data)); - RAnalOp op = {0}; + r_anal_op_init (&op); int ret = r_anal_op (core->anal, &op, val, data, sizeof (data), R_ARCH_OP_MASK_BASIC); if (ret < 1) { @@ -541,14 +542,23 @@ static ut64 numvar_instruction(RCore *core, const char *input) { } +static ut64 invalid_numvar(RCore *core, const char *str) { + R_LOG_ERROR ("Invalid variable '%s'", str); + core->num->nc.errors ++; + core->num->nc.calc_err = NULL; + // core->num->nc.calc_err = "Invalid $numvar"; + return 0; +} + static ut64 num_callback(RNum *userptr, const char *str, int *ok) { RCore *core = (RCore *)userptr; // XXX ? RAnalFunction *fcn; char *ptr, *bptr, *out = NULL; RFlagItem *flag; RBinSection *s; - RAnalOp op; ut64 ret = 0; + + RAnalOp op; r_anal_op_init (&op); if (ok) { @@ -740,12 +750,10 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) { } free (bptr); return 0; // UT64_MAX; - } else { - int rows; - (void)r_cons_get_size (&rows); - return rows; } - break; + int rows; + (void)r_cons_get_size (&rows); + return rows; case 'e': // $e if (str[2] == '{') { // $e{flag} flag off + size char *flagName = strdup (str + 3); @@ -804,7 +812,7 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) { return op.val; case 'l': // $l opcode length return op.size; - case 'b': // $b + case 'b': // "$b" block size return core->blocksize; case 's': // $s file size if (str[2] == '{') { // $s{flag} flag size @@ -853,16 +861,27 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) { case '?': // $? return core->num->value; // rc; case '$': // $$ offset - return str[2] == '$' ? core->prompt_offset : core->offset; - case 'o': { // $o - RBinSection *s = r_bin_get_section_at (r_bin_cur_object (core->bin), core->offset, true); - return s ? core->offset - s->vaddr + s->paddr : core->offset; - } - case 'O': // $O - if (core->print->cur_enabled) { - return core->offset + core->print->cur; + if (!strcmp (str, "$$")) { + return core->offset; + } else if (!strcmp (str, "$$c")) { + if (core->print->cur_enabled) { + return core->offset + core->print->cur; + } + return core->offset; + } else if (!strcmp (str, "$$$")) { + return core->prompt_offset; + } else if (!strcmp (str, "$$$c")) { + if (core->print->cur_enabled) { + return core->prompt_offset + core->print->cur; + } + return core->prompt_offset; + } + return invalid_numvar (core, str); + case 'o': // $o + { + RBinSection *s = r_bin_get_section_at (r_bin_cur_object (core->bin), core->offset, true); + return s ? core->offset - s->vaddr + s->paddr : core->offset; } - return core->offset; case 'C': // $C nth call return getref (core, atoi (str + 2), 'r', R_ANAL_REF_TYPE_CALL); case 'J': // $J nth jump @@ -890,8 +909,7 @@ static ut64 num_callback(RNum *userptr, const char *str, int *ok) { } return 0; default: - R_LOG_ERROR ("Invalid variable '%s'", str); - return 0; + return invalid_numvar (core, str); } break; default: diff --git a/test/db/anal/emu b/test/db/anal/emu index 9ceee9eef8099..d6cda3e9649cc 100644 --- a/test/db/anal/emu +++ b/test/db/anal/emu @@ -19,9 +19,9 @@ RUN NAME=emu ret0 FILE=bins/mach0/ret0ret1restr -ARGS=-2 +ARGS=-1 CMDS=< /dev/null aeim ?e ret0 s sym._ret0 @@ -39,6 +39,7 @@ aeb psz@R0 EOF EXPECT=<