diff --git a/librz/core/cmd/cmd_math.c b/librz/core/cmd/cmd_math.c index 57dadffc22..f809679dbc 100644 --- a/librz/core/cmd/cmd_math.c +++ b/librz/core/cmd/cmd_math.c @@ -18,10 +18,71 @@ static const char *help_msg_greater_sign[] = { NULL }; +struct rz_core_var { + const char *name; + const char *description; +}; + +struct rz_core_var core_vars[] = { + { "$$", "here (current virtual seek)" }, + { "$$$", "current non-temporary virtual seek" }, + { "$?", "last comparison value" }, + { "$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" }, + { "$DB", "same as dbg.baddr, progam base address" }, + { "$DD", "current debug map size" }, + { "$Dn", "get nth data reference in function" }, + { "$e", "1 if end of block, else 0" }, + { "$f", "jump fail address (e.g. jz 0x10 => next instruction)" }, + { "$F", "Same as $FB" }, + { "$Fb", "begin of basic block" }, + { "$FB", "begin of function" }, + { "$Fe", "end of basic block" }, + { "$FE", "end of function" }, + { "$Ff", "function false destination" }, + { "$Fi", "basic block instructions" }, + { "$FI", "function instructions" }, + { "$Fj", "function jump destination" }, + { "$fl", "flag length (size) at current address (fla; pD $l @ entry0)" }, + { "$FS", "function size (linear length)" }, + { "$Fs", "size of the current basic block" }, + { "$FSS", "function size (sum bb sizes)" }, + { "$j", "jump address (e.g. jmp 0x10, jz 0x10 => 0x10)" }, + { "$Ja", "get nth jump of function" }, + { "$l", "opcode length" }, + { "$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)" }, + { "$r", "get console height (in rows, see $c for columns)" }, + { "$s", "file size" }, + { "$S", "section offset" }, + { "$SS", "section size" }, + { "$v", "opcode immediate value (e.g. lui a0,0x8010 => 0x8010)" }, + { "$w", "get word size, 4 if asm.bits=32, 8 if 64, ..." }, + { "$Xn", "get nth xref of function" }, +}; + +struct rz_core_var help_core_vars[] = { + { "flag", "offset of flag" }, + { "${ev}", "get value of eval " }, + { "$alias", "alias commands (simple macros)" }, + { "$e{flag}", "end of (flag->offset + flag->size)" }, + { "$k{kv}", "get value of an sdb query value" }, + { "$r{reg}", "get value of named register " }, + { "$s{flag}", "get size of " }, +}; + /** * \brief Returns all the $ variable names in a NULL-terminated arr */ -RZ_API const char **rz_core_help_vars_get(RzCore *core) { +RZ_DEPRECATE RZ_API const char **rz_core_help_vars_get(RzCore *core) { static const char *vars[] = { "$$", "$$$", "$?", "$B", "$b", "$c", "$Cn", "$D", "$DB", "$DD", "$Dn", "$e", "$f", "$F", "$Fb", "$FB", "$Fe", "$FE", "$Ff", "$Fi", "$FI", "$Fj", @@ -31,19 +92,25 @@ RZ_API const char **rz_core_help_vars_get(RzCore *core) { return vars; } -RZ_API void rz_core_help_vars_print(RzCore *core) { - int i = 0; - const char **vars = rz_core_help_vars_get(core); +RZ_DEPRECATE RZ_API void rz_core_help_vars_print(RzCore *core) { + rz_list_rizin_vars_handler(core, 0, NULL); +} + +RZ_IPI RzCmdStatus rz_list_rizin_vars_handler(RzCore *core, int argc, const char **argv) { const bool wideOffsets = rz_config_get_i(core->config, "scr.wideoff"); - while (vars[i]) { - const char *pad = rz_str_pad(' ', 6 - strlen(vars[i])); - if (wideOffsets) { - rz_cons_printf("%s %s 0x%016" PFMT64x "\n", vars[i], pad, rz_num_math(core->num, vars[i])); - } else { - rz_cons_printf("%s %s 0x%08" PFMT64x "\n", vars[i], pad, rz_num_math(core->num, vars[i])); + for (int i = 0; i < RZ_ARRAY_SIZE(core_vars); i++) { + struct rz_core_var *var = &core_vars[i]; + if (argc > 1 && strcmp(argv[1], var->name)) { + continue; + } + const char *pad = rz_str_pad(' ', 6 - strlen(var->name)); + if (wideOffsets) { + rz_cons_printf("%s %s 0x%016" PFMT64x "\n", var->name, pad, rz_num_math(core->num, var->name)); + } else { + rz_cons_printf("%s %s 0x%08" PFMT64x "\n", var->name, pad, rz_num_math(core->num, var->name)); } - i++; } + return RZ_CMD_STATUS_OK; } /** @@ -394,9 +461,44 @@ RZ_IPI RzCmdStatus rz_exec_cmd_if_core_num_value_nonzero_handler(RzCore *core, i return RZ_CMD_STATUS_OK; } -RZ_IPI RzCmdStatus rz_show_help_vars_handler(RzCore *core, int argc, const char **argv) { - rz_core_help_vars_print(core); - return RZ_CMD_STATUS_OK; +RZ_IPI RzCmdDescDetail *rz_cmd_math_help_vars_details_cb(RzCore *core, int argc, const char **argv) { + RzCmdDescDetail *details = RZ_NEWS0(RzCmdDescDetail, 2); + if (!details) { + return NULL; + } + details[0].name = (const char *)strdup("Rizin variables"); + if (!details->name) { + goto err; + } + RzCmdDescDetailEntry *entries = RZ_NEWS0(RzCmdDescDetailEntry, RZ_ARRAY_SIZE(core_vars) + RZ_ARRAY_SIZE(help_core_vars) + 1); + details[0].entries = (const RzCmdDescDetailEntry *)entries; + if (!entries) { + goto err; + } + int i; + for (i = 0; i < RZ_ARRAY_SIZE(core_vars); i++) { + struct rz_core_var *var = &core_vars[i]; + entries[i].text = (char *)strdup(var->name); + entries[i].arg_str = strdup(""); + entries[i].comment = strdup(var->description); + if (!entries[i].text || !entries[i].arg_str || !entries[i].comment) { + goto err; + } + } + for (int j = 0; j < RZ_ARRAY_SIZE(help_core_vars); j++, i++) { + struct rz_core_var *var = &help_core_vars[j]; + entries[i].text = (char *)strdup(var->name); + entries[i].arg_str = strdup(""); + entries[i].comment = strdup(var->description); + if (!entries[i].text || !entries[i].arg_str || !entries[i].comment) { + goto err; + } + } + details->entries = (const RzCmdDescDetailEntry *)entries; + return details; +err: + rz_cmd_desc_details_free(details); + return NULL; } RZ_IPI RzCmdStatus rz_calculate_string_length_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state) { diff --git a/librz/core/cmd_descs/cmd_descs.c b/librz/core/cmd_descs/cmd_descs.c index 804f314b38..8dc7b40c12 100644 --- a/librz/core/cmd_descs/cmd_descs.c +++ b/librz/core/cmd_descs/cmd_descs.c @@ -108,6 +108,7 @@ static const RzCmdDescArg remote_tcp_args[3]; static const RzCmdDescArg remote_rap_bg_args[2]; static const RzCmdDescArg cmd_help_search_args[2]; static const RzCmdDescArg calculate_expr_args[2]; +static const RzCmdDescArg list_rizin_vars_args[2]; static const RzCmdDescArg generate_random_number_args[3]; static const RzCmdDescArg print_binary_args[2]; static const RzCmdDescArg base64_encode_args[2]; @@ -1483,6 +1484,22 @@ static const RzCmdDescHelp calculate_expr_help = { .args = calculate_expr_args, }; +static const RzCmdDescArg list_rizin_vars_args[] = { + { + .name = "var", + .type = RZ_CMD_ARG_TYPE_STRING, + .flags = RZ_CMD_ARG_FLAG_LAST, + .optional = true, + + }, + { 0 }, +}; +static const RzCmdDescHelp list_rizin_vars_help = { + .summary = "Print Rizin variables and their values", + .details_cb = rz_cmd_math_help_vars_details_cb, + .args = list_rizin_vars_args, +}; + static const RzCmdDescArg set_active_tab_zero_args[] = { { 0 }, }; @@ -18732,6 +18749,9 @@ RZ_IPI void rzshell_cmddescs_init(RzCore *core) { RzCmdDesc *cmd_math_cd = rz_cmd_desc_group_state_new(core->rcmd, root_cd, "%", RZ_OUTPUT_MODE_STANDARD | RZ_OUTPUT_MODE_JSON, rz_calculate_expr_handler, &calculate_expr_help, &cmd_math_help); rz_warn_if_fail(cmd_math_cd); + RzCmdDesc *list_rizin_vars_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_math_cd, "%$", rz_list_rizin_vars_handler, &list_rizin_vars_help); + rz_warn_if_fail(list_rizin_vars_cd); + RzCmdDesc *set_active_tab_zero_cd = rz_cmd_desc_argv_new(core->rcmd, cmd_math_cd, "%0", rz_set_active_tab_zero_handler, &set_active_tab_zero_help); rz_warn_if_fail(set_active_tab_zero_cd); diff --git a/librz/core/cmd_descs/cmd_descs.h b/librz/core/cmd_descs/cmd_descs.h index f721604b33..682617810b 100644 --- a/librz/core/cmd_descs/cmd_descs.h +++ b/librz/core/cmd_descs/cmd_descs.h @@ -91,6 +91,9 @@ RZ_IPI RzCmdStatus rz_remote_rap_bg_handler(RzCore *core, int argc, const char * RZ_IPI RzCmdStatus rz_cmd_help_search_handler(RzCore *core, int argc, const char **argv, RzOutputMode mode); // "%" RZ_IPI RzCmdStatus rz_calculate_expr_handler(RzCore *core, int argc, const char **argv, RzCmdStateOutput *state); +// "%$" +RZ_IPI RzCmdStatus rz_list_rizin_vars_handler(RzCore *core, int argc, const char **argv); +RZ_IPI RzCmdDescDetail *rz_cmd_math_help_vars_details_cb(RzCore *core, int argc, const char **argv); // "%0" RZ_IPI RzCmdStatus rz_set_active_tab_zero_handler(RzCore *core, int argc, const char **argv); // "%1" diff --git a/librz/core/cmd_descs/cmd_math.yaml b/librz/core/cmd_descs/cmd_math.yaml index e5c58b42ca..b043aa80fb 100644 --- a/librz/core/cmd_descs/cmd_math.yaml +++ b/librz/core/cmd_descs/cmd_math.yaml @@ -13,6 +13,14 @@ commands: args: - name: expr type: RZ_CMD_ARG_TYPE_STRING + - name: "%$" + summary: Print Rizin variables and their values + cname: list_rizin_vars + args: + - name: var + type: RZ_CMD_ARG_TYPE_STRING + optional: true + details_cb: rz_cmd_math_help_vars_details_cb - name: "%0" summary: Set first tab as the current active tab cname: set_active_tab_zero diff --git a/librz/core/tui/config.c b/librz/core/tui/config.c index a5bbf1bc3a..e1ccd308f3 100644 --- a/librz/core/tui/config.c +++ b/librz/core/tui/config.c @@ -10,6 +10,7 @@ #include #include #include +#include static void config_visual_hit_i(RzCore *core, const char *name, int delta) { struct rz_config_node_t *node; @@ -189,7 +190,7 @@ RZ_IPI void rz_core_visual_config(RzCore *core) { option = _option; break; case '$': - rz_core_help_vars_print(core); + rz_list_rizin_vars_handler(core, 0, NULL); rz_cons_any_key(NULL); break; case '*': diff --git a/librz/include/rz_core.h b/librz/include/rz_core.h index f8abe4b1b9..418109f406 100644 --- a/librz/include/rz_core.h +++ b/librz/include/rz_core.h @@ -481,7 +481,7 @@ RZ_API bool rz_core_write_seq_at(RzCore *core, ut64 addr, ut64 from, ut64 to, ut RZ_API bool rz_core_shift_block(RzCore *core, ut64 addr, ut64 b_size, st64 dist); RZ_API void rz_core_autocomplete(RZ_NULLABLE RzCore *core, RzLineCompletion *completion, RzLineBuffer *buf, RzLinePromptType prompt_type); RZ_API RzLineNSCompletionResult *rz_core_autocomplete_rzshell(RzCore *core, RzLineBuffer *buf, RzLinePromptType prompt_type); -RZ_API void rz_core_help_vars_print(RzCore *core); +RZ_DEPRECATE RZ_API void rz_core_help_vars_print(RzCore *core); RZ_API bool rz_core_prevop_addr(RzCore *core, ut64 start_addr, int numinstrs, RZ_OUT RZ_BORROW RZ_NONNULL ut64 *prev_addr); RZ_API ut64 rz_core_prevop_addr_force(RzCore *core, ut64 start_addr, int numinstrs); RZ_API RzBinReloc *rz_core_getreloc(RzCore *core, ut64 addr, int size); @@ -1081,7 +1081,7 @@ typedef char *(*PrintItemCallback)(void *user, void *p, bool selected); RZ_API char *rz_str_widget_list(void *user, RzList /**/ *list, int rows, int cur, PrintItemCallback cb); /* help */ RZ_API void rz_core_cmd_help(const RzCore *core, const char *help[]); -RZ_API const char **rz_core_help_vars_get(RzCore *core); +RZ_DEPRECATE RZ_API const char **rz_core_help_vars_get(RzCore *core); /* analysis stats */