2020-03-24 11:05:22 +01:00
|
|
|
|
/* radare - LGPL - Copyright 2009-2020 - pancake */
|
2016-05-02 22:52:41 -04:00
|
|
|
|
|
2016-11-23 12:52:36 +01:00
|
|
|
|
#include <stddef.h>
|
2018-09-12 18:59:08 +02:00
|
|
|
|
#include <math.h> // required for signbit
|
2016-05-02 22:52:41 -04:00
|
|
|
|
#include "r_cons.h"
|
|
|
|
|
#include "r_core.h"
|
|
|
|
|
#include "r_util.h"
|
2015-01-18 02:17:55 +01:00
|
|
|
|
|
2017-11-30 10:42:23 +01:00
|
|
|
|
static ut32 vernum(const char *s) {
|
|
|
|
|
// XXX this is known to be buggy, only works for strings like "x.x.x"
|
|
|
|
|
// XXX anything like "x.xx.x" will break the parsing
|
|
|
|
|
// XXX -git is ignored, maybe we should shift for it
|
|
|
|
|
char *a = strdup (s);
|
|
|
|
|
a = r_str_replace (a, ".", "0", 1);
|
|
|
|
|
char *dash = strchr (a, '-');
|
|
|
|
|
if (dash) {
|
|
|
|
|
*dash = 0;
|
|
|
|
|
}
|
|
|
|
|
ut32 res = atoi (a);
|
|
|
|
|
free (a);
|
|
|
|
|
return res;
|
|
|
|
|
}
|
|
|
|
|
|
2018-08-02 13:18:48 +02:00
|
|
|
|
static const char *help_msg_percent[] = {
|
|
|
|
|
"Usage:", "%[name[=value]]", "Set each NAME to VALUE in the environment",
|
|
|
|
|
"%", "", "list all environment variables",
|
|
|
|
|
"%", "SHELL", "prints SHELL value",
|
|
|
|
|
"%", "TMPDIR=/tmp", "sets TMPDIR value to \"/tmp\"",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
// NOTE: probably not all environment vars takes sesnse
|
|
|
|
|
// because they can be replaced by commands in the given
|
|
|
|
|
// command.. we should only expose the most essential and
|
|
|
|
|
// unidirectional ones.
|
|
|
|
|
static const char *help_msg_env[] = {
|
2019-01-09 02:47:35 +01:00
|
|
|
|
"\nEnvironment:", "", "",
|
|
|
|
|
"R2_FILE", "", "file name",
|
|
|
|
|
"R2_OFFSET", "", "10base offset 64bit value",
|
|
|
|
|
"R2_BYTES", "", "TODO: variable with bytes in curblock",
|
|
|
|
|
"R2_XOFFSET", "", "same as above, but in 16 base",
|
|
|
|
|
"R2_BSIZE", "", "block size",
|
|
|
|
|
"R2_ENDIAN", "", "'big' or 'little'",
|
|
|
|
|
"R2_IOVA", "", "is io.va true? virtual addressing (1,0)",
|
|
|
|
|
"R2_DEBUG", "", "debug mode enabled? (1,0)",
|
|
|
|
|
"R2_BLOCK", "", "TODO: dump current block to tmp file",
|
|
|
|
|
"R2_SIZE", "","file size",
|
|
|
|
|
"R2_ARCH", "", "value of asm.arch",
|
|
|
|
|
"R2_BITS", "", "arch reg size (8, 16, 32, 64)",
|
|
|
|
|
"RABIN2_LANG", "", "assume this lang to demangle",
|
|
|
|
|
"RABIN2_DEMANGLE", "", "demangle or not",
|
|
|
|
|
"RABIN2_PDBSERVER", "", "e pdb.server",
|
|
|
|
|
NULL
|
2018-08-02 13:18:48 +02:00
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const char *help_msg_exclamation[] = {
|
2019-01-09 02:47:35 +01:00
|
|
|
|
"Usage:", "!<cmd>", " Run given command as in system(3)",
|
|
|
|
|
"!", "", "list all historic commands",
|
|
|
|
|
"!", "ls", "execute 'ls' in shell",
|
2019-06-17 10:34:04 +02:00
|
|
|
|
"!*", "r2p x", "run r2 command via r2pipe in current session",
|
2019-01-09 02:47:35 +01:00
|
|
|
|
"!!", "", "save command history to hist file",
|
|
|
|
|
"!!", "ls~txt", "print output of 'ls' and grep for 'txt'",
|
|
|
|
|
"!!!", "cmd [args|$type]", "adds the autocomplete value",
|
|
|
|
|
"!!!-", "cmd [args]", "removes the autocomplete value",
|
|
|
|
|
".!", "rabin2 -rpsei ${FILE}", "run each output line as a r2 cmd",
|
2019-03-16 19:43:05 +01:00
|
|
|
|
"!", "echo $R2_SIZE", "display file size",
|
2019-01-09 02:47:35 +01:00
|
|
|
|
"!-", "", "clear history in current session",
|
|
|
|
|
"!-*", "", "clear and save empty history log",
|
|
|
|
|
"!=!", "", "enable remotecmd mode",
|
|
|
|
|
"=!=", "", "disable remotecmd mode",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
2018-08-02 13:18:48 +02:00
|
|
|
|
|
2017-08-10 02:52:13 -07:00
|
|
|
|
static const char *help_msg_root[] = {
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"%var", "=value", "alias for 'env' command",
|
|
|
|
|
"*", "[?] off[=[0x]value]", "pointer read/write data/values (see ?v, wx, wv)",
|
|
|
|
|
"(macro arg0 arg1)", "", "manage scripting macros",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
".", "[?] [-|(m)|f|!sh|cmd]", "Define macro or load r2, cparse or rlang file",
|
2020-12-09 03:39:49 +01:00
|
|
|
|
",", "[?] [/jhr]", "create a dummy table import from file and query it to filter/sort",
|
2018-09-16 22:50:56 +02:00
|
|
|
|
"_", "[?]", "Print last output",
|
2019-01-09 02:47:35 +01:00
|
|
|
|
"=","[?] [cmd]", "send/listen for remote commands (rap://, raps://, udp://, http://, <fd>)",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"<","[...]", "push escaped string into the RCons.readChar buffer",
|
|
|
|
|
"/","[?]", "search for bytes, regexps, patterns, ..",
|
|
|
|
|
"!","[?] [cmd]", "run given command as in system(3)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"#","[?] !lang [..]", "Hashbang to run an rlang script",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"a","[?]", "analysis commands",
|
|
|
|
|
"b","[?]", "display or change the block size",
|
|
|
|
|
"c","[?] [arg]", "compare block with given data",
|
|
|
|
|
"C","[?]", "code metadata (comments, format, hints, ..)",
|
|
|
|
|
"d","[?]", "debugger commands",
|
|
|
|
|
"e","[?] [a[=b]]", "list/get/set config evaluable vars",
|
|
|
|
|
"f","[?] [name][sz][at]", "add flag at current address",
|
|
|
|
|
"g","[?] [arg]", "generate shellcodes with r_egg",
|
|
|
|
|
"i","[?] [file]", "get info about opened file from r_bin",
|
|
|
|
|
"k","[?] [sdb-query]", "run sdb-query. see k? for help, 'k *', 'k **' ...",
|
2018-09-08 12:29:12 +02:00
|
|
|
|
"l"," [filepattern]", "list files and directories",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"L","[?] [-] [plugin]", "list, unload load r2 plugins",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"m","[?]", "mountpoints commands",
|
|
|
|
|
"o","[?] [file] ([offset])", "open file at optional address",
|
|
|
|
|
"p","[?] [len]", "print current block with format and length",
|
|
|
|
|
"P","[?]", "project management utilities",
|
|
|
|
|
"q","[?] [ret]", "quit program with a return value",
|
|
|
|
|
"r","[?] [len]", "resize file",
|
|
|
|
|
"s","[?] [addr]", "seek to address (also for '0x', '0x1' == 's 0x1')",
|
|
|
|
|
"t","[?]", "types, noreturn, signatures, C parser and more",
|
2019-01-03 11:33:23 +01:00
|
|
|
|
"T","[?] [-] [num|msg]", "Text log utility (used to chat, sync, log, ...)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"u","[?]", "uname/undo seek/write",
|
Fix wording and whitespacing ##doc (#18065)
* Fix wording, whitespacing and other minor stuff
* cmd.c: ellaborated yy syntax, improved descriptions
- replace "srcoff" with "origin"
* cmd.c(cmd_autocomplete):
- refactor help into function: render autocomplete types with generic
help subsystem;
- "Types" heading now follow the "Usage" style by not being prefixed
by a pipe character;
* cmd_anal.c: fix whitespaces & help text
* cmd_info.c: fix help text capitalization.
* cmd_print.c:
- fix `pf` cmd help;
- TODO: what pz? is doing here?
* cons.c:
- refactor & better document r_cons_cmd_help();
- fix whitespaces;
* visual & panels modes:
- as of commit 46187fe4e14dc465dc6ac03fcc56a362f0b8e335, '!' no longer
launches the r2048 game. The game itself it broken anyway, even when
running from the Help menu in panels mode;
- transitioning from panels to visual is not 'entering' but actually
swapping/replacing visual panels with just panels, thus...
- reword 'enter into the' to 'swap into' or even just 'enter', e.g.:
"enter into the visual panels mode" -> "enter visual panels mode".
- remove the "(dwm style)" words from a fortune tip, because I have no
idea what it is, and it does not appear to be a valid command in any
of the r2 modes.
- update global help text.
* [WIP 2] Fix wording, whitespacing and other minor stuff
* visual.c:
- r_core_visual_append_help(): first steps merging with
r_cons_cmd_help from cons.c; use consistent colors for headers.
* [WIP 3] Fix wording, whitespacing and other minor stuff
* panels.c(__update_help):
- shorten code and titles;
- add comment to clarify that it is not a copy-paste error;
* [WIP 4] Fix wording, whitespacing and other minor stuff
panels.c, visual.c: tweak help text;
* [WIP 5] Fix wording, whitespacing and other minor stuff
* cmd_help.c: update global help text about visual mode -- it was
outdated and overloaded.
* vmenus.c:
- rename stuff, shuffle around static consts to reflect an actual
ordering when viewing as a help text;
- slightly improve help text rendering;
- fix whitespaces;
* [WIP 6] Fix wording, whitespacing and other minor stuff
* lots of help text changed. still working on proper commit message.
2020-12-21 03:12:08 +03:00
|
|
|
|
"v","", "panels mode",
|
|
|
|
|
"V", "", "visual mode (Vv = func/var anal, VV = graph mode, ...)",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"w","[?] [str]", "multiple write operations",
|
|
|
|
|
"x","[?] [len]", "alias for 'px' (print hexadecimal)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"y","[?] [len] [[[@]addr", "Yank/paste bytes from/to memory",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"z", "[?]", "zignatures management",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?[??]","[expr]", "Help or evaluate math expression",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"?$?", "", "show available '$' variables and aliases",
|
|
|
|
|
"?@?", "", "misc help for '@' (seek), '~' (grep) (see ~?""?)",
|
|
|
|
|
"?>?", "", "output redirection",
|
2019-05-09 21:07:35 +08:00
|
|
|
|
"?|?", "", "help for '|' (pipe)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
2020-10-13 15:44:39 +02:00
|
|
|
|
static const char *help_msg_question_e[] = {
|
|
|
|
|
"Usage: ?e[=bdgnpst] arg", "print/echo things", "",
|
|
|
|
|
"?e", "", "echo message with newline",
|
|
|
|
|
"?e=", " 32", "progress bar at 32 percentage",
|
|
|
|
|
"?eb", " 10 20 30", "proportional segments bar",
|
|
|
|
|
"?ed", " 1", "draw a 3D ascii donut at the given animation frame",
|
|
|
|
|
"?eg", " 10 20", "move cursor to column 10, row 20",
|
|
|
|
|
"?en", " nonl", "echo message without ending newline",
|
|
|
|
|
"?ep", " 10 20 30", "draw a pie char with given portion sizes",
|
|
|
|
|
"?es", " msg", "speak message using the text-to-speech program (e cfg.tts)",
|
|
|
|
|
"?et", " msg", "change terminal title",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
2017-08-10 02:52:13 -07:00
|
|
|
|
static const char *help_msg_question[] = {
|
|
|
|
|
"Usage: ?[?[?]] expression", "", "",
|
|
|
|
|
"?!", " [cmd]", "run cmd if $? == 0",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?", " eip-0x804800", "show all representation result for this math expr",
|
2017-09-19 02:42:47 -07:00
|
|
|
|
"?$", "", "show value all the variables ($)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?+", " [cmd]", "run cmd if $? > 0",
|
|
|
|
|
"?-", " [cmd]", "run cmd if $? < 0",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?:", "", "list core cmd plugins",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?=", " eip-0x804800", "hex and dec result for this math expr",
|
2020-09-09 15:51:11 +02:00
|
|
|
|
"?==", " x86 `e asm.arch`", "strcmp two strings",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"??", " [cmd]", "run cmd if $? != 0",
|
2017-09-19 02:42:47 -07:00
|
|
|
|
"??", "", "show value of operation",
|
2018-04-01 03:06:34 -07:00
|
|
|
|
"?a", "", "show ascii table",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?B", " [elem]", "show range boundaries like 'e?search.in",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?b", " [num]", "show binary value of number",
|
|
|
|
|
"?b64[-]", " [str]", "encode/decode in base64",
|
2017-12-03 01:25:00 +01:00
|
|
|
|
"?btw", " num|expr num|expr num|expr", "returns boolean value of a <= b <= c",
|
2020-10-13 15:44:39 +02:00
|
|
|
|
"?e", "[=bdgnpst] arg", "echo messages, bars, pie charts and more (see ?e? for details)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?f", " [num] [str]", "map each bit of the number as flag string index",
|
2017-09-19 02:42:47 -07:00
|
|
|
|
"?F", "", "flush cons output",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?h", " [str]", "calculate hash for given string",
|
|
|
|
|
"?i", "[ynmkp] arg", "prompt for number or Yes,No,Msg,Key,Path and store in $$?",
|
|
|
|
|
"?ik", "", "press any key input dialog",
|
|
|
|
|
"?im", " message", "show message centered in screen",
|
|
|
|
|
"?in", " prompt", "noyes input prompt",
|
2020-10-13 06:48:49 +02:00
|
|
|
|
"?ip", " prompt", "path input prompt",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?iy", " prompt", "yesno input prompt",
|
2019-01-07 11:31:50 +01:00
|
|
|
|
"?j", " arg", "same as '? num' but in JSON",
|
2018-02-13 13:15:11 -06:00
|
|
|
|
"?l", "[q] str", "returns the length of string ('q' for quiet, just set $?)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?o", " num", "get octal value",
|
2017-09-03 01:42:45 +02:00
|
|
|
|
"?P", " paddr", "get virtual address for given physical one",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?p", " vaddr", "get physical address for given virtual address",
|
2018-03-15 01:07:24 +01:00
|
|
|
|
"?q", " eip-0x804800", "compute expression like ? or ?v but in quiet mode",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?r", " [from] [to]", "generate random number between from-to",
|
|
|
|
|
"?s", " from to step", "sequence of numbers from to by steps",
|
|
|
|
|
"?t", " cmd", "returns the time to run a command",
|
2017-09-19 02:42:47 -07:00
|
|
|
|
"?T", "", "show loading times",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?u", " num", "get value in human units (KB, MB, GB, TB)",
|
|
|
|
|
"?v", " eip-0x804800", "show hex value of math expr",
|
2017-09-19 02:42:47 -07:00
|
|
|
|
"?V", "", "show library version of r_core",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?vi", " rsp-rbp", "show decimal value of math expr",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?w", " addr", "show what's in this address (like pxr/pxq does)",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?X", " num|expr", "returns the hexadecimal value numeric expr",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?x", " str", "returns the hexpair of number or string",
|
2017-09-19 02:42:47 -07:00
|
|
|
|
"?x", "+num", "like ?v, but in hexpairs honoring cfg.bigendian",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?x", "-hexst", "convert hexpair into raw string with newline",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"?_", " hudfile", "load hud menu with given file",
|
|
|
|
|
"[cmd]?*", "", "recursive help for the given cmd",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const char *help_msg_question_v[] = {
|
|
|
|
|
"Usage: ?v [$.]","","",
|
2018-09-13 11:16:27 +02:00
|
|
|
|
"flag", "", "offset of flag",
|
2020-12-28 00:27:27 +01:00
|
|
|
|
"$", "{ev}", "get value of eval config variable",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$$", "", "here (current virtual seek)",
|
2018-04-28 00:41:29 +08:00
|
|
|
|
"$$$", "", "current non-temporary virtual seek",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$?", "", "last comparison value",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"$alias", "=value", "alias commands (simple macros)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$B", "", "base address (aligned lowest map address)",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$b", "", "block size",
|
2020-12-28 00:27:27 +01:00
|
|
|
|
"$c", "", "get terminal width in character columns",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$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",
|
2020-12-28 00:27:27 +01:00
|
|
|
|
"$e", "{flag}", "end of flag (flag->offset + flag->size)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$f", "", "jump fail address (e.g. jz 0x10 => next instruction)",
|
2018-10-15 16:18:21 +02:00
|
|
|
|
"$F", "", "Same as $FB",
|
|
|
|
|
"$Fb", "", "begin of basic block",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$FB", "", "begin of function",
|
2018-10-15 16:18:21 +02:00
|
|
|
|
"$Fe", "", "end of basic block",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$FE", "", "end of function",
|
|
|
|
|
"$Ff", "", "function false destination",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$Fi", "", "basic block instructions",
|
|
|
|
|
"$FI", "", "function instructions",
|
2018-10-15 16:18:21 +02:00
|
|
|
|
"$Fj", "", "function jump destination",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$fl", "", "flag length (size) at current address (fla; pD $l @ entry0)",
|
2018-10-15 16:18:21 +02:00
|
|
|
|
"$FS", "", "function size (linear length)",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$Fs", "", "size of the current basic block",
|
2018-10-15 16:18:21 +02:00
|
|
|
|
"$FSS", "", "function size (sum bb sizes)",
|
2020-12-28 00:27:32 +01:00
|
|
|
|
"$i", "{n}", "address of nth instruction forward",
|
|
|
|
|
"$I", "{n}", "address of nth instruction backward (s $I1@$Fe) #last instr in bb",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$j", "", "jump address (e.g. jmp 0x10, jz 0x10 => 0x10)",
|
|
|
|
|
"$Ja", "", "get nth jump of function",
|
2020-12-28 00:27:32 +01:00
|
|
|
|
"$k", "{kv}", "get value of an sdb query value",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$l", "", "opcode length",
|
|
|
|
|
"$M", "", "map address (lowest map address)",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$m", "", "opcode memory reference (e.g. mov eax,[0x10] => 0x10)",
|
2018-08-24 15:55:04 +02:00
|
|
|
|
"$MM", "", "map size (lowest map address)",
|
2019-05-21 13:16:54 +02:00
|
|
|
|
"$O", "", "cursor here (current offset pointed by the cursor)",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$o", "", "here (current disk io offset)",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$p", "", "getpid()",
|
|
|
|
|
"$P", "", "pid of children (only in debug)",
|
2020-12-28 00:27:27 +01:00
|
|
|
|
"$r", "", "get console height (in rows, see $c for columns)",
|
|
|
|
|
"$r", "{reg}", "get value of named register",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$s", "", "file size",
|
|
|
|
|
"$S", "", "section offset",
|
|
|
|
|
"$SS", "", "section size",
|
2020-12-28 00:27:27 +01:00
|
|
|
|
"$s", "{flag}", "get size of flag",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"$v", "", "opcode immediate value (e.g. lui a0,0x8010 => 0x8010)",
|
|
|
|
|
"$w", "", "get word size, 4 if asm.bits=32, 8 if 64, ...",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$Xn", "", "get nth xref of function",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"RNum", "", "$variables usable in math expressions",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const char *help_msg_question_V[] = {
|
|
|
|
|
"Usage: ?V[jq]","","",
|
|
|
|
|
"?V", "", "show version information",
|
2020-01-17 17:42:58 +01:00
|
|
|
|
"?V0", "", "show major version",
|
|
|
|
|
"?V1", "", "show minor version",
|
|
|
|
|
"?V2", "", "show patch version",
|
|
|
|
|
"?Vn", "", "show numeric version (2)",
|
2017-11-30 10:42:23 +01:00
|
|
|
|
"?Vc", "", "show numeric version",
|
2017-08-10 02:52:13 -07:00
|
|
|
|
"?Vj", "", "same as above but in JSON",
|
|
|
|
|
"?Vq", "", "quiet mode, just show the version number",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
2018-03-13 11:52:38 +01:00
|
|
|
|
static const char *help_msg_greater_sign[] = {
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"Usage:", "[cmd]>[file]", "redirects console from 'cmd' output to 'file'",
|
|
|
|
|
"[cmd] > [file]", "", "redirect STDOUT of 'cmd' to 'file'",
|
2019-03-25 01:06:53 +01:00
|
|
|
|
"[cmd] > $alias", "", "save the output of the command as an alias (see $?)",
|
2018-05-07 12:26:01 +02:00
|
|
|
|
"[cmd] H> [file]", "", "redirect html output of 'cmd' to 'file'",
|
|
|
|
|
"[cmd] 2> [file]", "", "redirect STDERR of 'cmd' to 'file'",
|
|
|
|
|
"[cmd] 2> /dev/null", "", "omit the STDERR output of 'cmd'",
|
2018-03-13 11:52:38 +01:00
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
2018-09-07 15:03:01 +02:00
|
|
|
|
static const char *help_msg_intro[] = {
|
|
|
|
|
"Usage: [.][times][cmd][~grep][@[@iter]addr!size][|>pipe] ; ...", "", "",
|
|
|
|
|
"Append '?' to any char command to get detailed help", "", "",
|
|
|
|
|
"Prefix with number to repeat command N times (f.ex: 3x)", "", "",
|
|
|
|
|
NULL
|
|
|
|
|
};
|
|
|
|
|
|
2018-08-02 13:18:48 +02:00
|
|
|
|
static void cmd_help_exclamation(RCore *core) {
|
|
|
|
|
r_core_cmd_help (core, help_msg_exclamation);
|
|
|
|
|
r_core_cmd_help (core, help_msg_env);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void cmd_help_percent(RCore *core) {
|
|
|
|
|
r_core_cmd_help (core, help_msg_percent);
|
|
|
|
|
r_core_cmd_help (core, help_msg_env);
|
|
|
|
|
}
|
|
|
|
|
|
2020-06-17 21:29:23 +02:00
|
|
|
|
static void cmd_help_init(RCore *core, RCmdDesc *parent) {
|
2017-08-10 02:52:13 -07:00
|
|
|
|
DEFINE_CMD_DESCRIPTOR_SPECIAL (core, ?, question);
|
|
|
|
|
DEFINE_CMD_DESCRIPTOR_SPECIAL (core, ?v, question_v);
|
|
|
|
|
DEFINE_CMD_DESCRIPTOR_SPECIAL (core, ?V, question_V);
|
|
|
|
|
}
|
|
|
|
|
|
2015-01-18 02:17:55 +01:00
|
|
|
|
static const char* findBreakChar(const char *s) {
|
|
|
|
|
while (*s) {
|
2016-11-03 11:51:10 +01:00
|
|
|
|
if (!r_name_validate_char (*s)) {
|
2015-01-18 02:17:55 +01:00
|
|
|
|
break;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
}
|
2015-01-18 02:17:55 +01:00
|
|
|
|
s++;
|
|
|
|
|
}
|
|
|
|
|
return s;
|
|
|
|
|
}
|
2016-02-25 10:28:54 +01:00
|
|
|
|
|
2016-11-23 12:52:36 +01:00
|
|
|
|
static char *filterFlags(RCore *core, const char *msg) {
|
2015-01-18 02:53:37 +01:00
|
|
|
|
const char *dollar, *end;
|
|
|
|
|
char *word, *buf = NULL;
|
2015-01-18 02:17:55 +01:00
|
|
|
|
for (;;) {
|
|
|
|
|
dollar = strchr (msg, '$');
|
2016-11-02 03:49:55 +01:00
|
|
|
|
if (!dollar) {
|
2015-01-18 02:17:55 +01:00
|
|
|
|
break;
|
2016-11-02 03:49:55 +01:00
|
|
|
|
}
|
2017-03-16 18:29:49 -03:00
|
|
|
|
buf = r_str_appendlen (buf, msg, dollar-msg);
|
2015-01-18 02:17:55 +01:00
|
|
|
|
if (dollar[1]=='{') {
|
|
|
|
|
// find }
|
|
|
|
|
end = strchr (dollar+2, '}');
|
|
|
|
|
if (end) {
|
|
|
|
|
word = r_str_newlen (dollar+2, end-dollar-2);
|
|
|
|
|
end++;
|
|
|
|
|
} else {
|
|
|
|
|
msg = dollar+1;
|
2017-03-16 18:29:49 -03:00
|
|
|
|
buf = r_str_append (buf, "$");
|
2015-01-18 02:17:55 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
end = findBreakChar (dollar+1);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
if (!end) {
|
|
|
|
|
end = dollar + strlen (dollar);
|
|
|
|
|
}
|
2015-01-18 02:17:55 +01:00
|
|
|
|
word = r_str_newlen (dollar+1, end-dollar-1);
|
|
|
|
|
}
|
|
|
|
|
if (end && word) {
|
2015-01-18 02:53:37 +01:00
|
|
|
|
ut64 val = r_num_math (core->num, word);
|
|
|
|
|
char num[32];
|
2016-11-03 11:51:10 +01:00
|
|
|
|
snprintf (num, sizeof (num), "0x%"PFMT64x, val);
|
2017-03-16 18:29:49 -03:00
|
|
|
|
buf = r_str_append (buf, num);
|
2015-01-18 02:17:55 +01:00
|
|
|
|
msg = end;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
|
|
|
|
break;
|
|
|
|
|
}
|
2015-01-18 02:17:55 +01:00
|
|
|
|
free (word);
|
|
|
|
|
}
|
2017-03-16 18:29:49 -03:00
|
|
|
|
buf = r_str_append (buf, msg);
|
2015-01-18 02:17:55 +01:00
|
|
|
|
return buf;
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
|
2019-09-30 23:33:27 +02:00
|
|
|
|
static const char *avatar_orangg[] = {
|
|
|
|
|
" _______\n"
|
|
|
|
|
" / \\ .-%s-.\n"
|
|
|
|
|
" _| ( o) (o)\\_ | %s |\n"
|
|
|
|
|
" / _ .\\. | \\ <| %s |\n"
|
|
|
|
|
" \\| \\ ____ / 7` | %s |\n"
|
|
|
|
|
" '|\\| `---'/ `-%s-'\n"
|
|
|
|
|
" | /----. \\\n"
|
|
|
|
|
" | \\___/ |___\n"
|
|
|
|
|
" `-----'`-----'\n"
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const char *avatar_clippy[] = {
|
|
|
|
|
" .--. .-%s-.\n"
|
|
|
|
|
" | _| | %s |\n"
|
|
|
|
|
" | O O < %s |\n"
|
|
|
|
|
" | | | | %s |\n"
|
|
|
|
|
" || | / `-%s-'\n"
|
|
|
|
|
" |`-'|\n"
|
|
|
|
|
" `---'\n",
|
|
|
|
|
" .--. .-%s-.\n"
|
|
|
|
|
" | \\ | %s |\n"
|
|
|
|
|
" | O o < %s |\n"
|
|
|
|
|
" | | / | %s |\n"
|
|
|
|
|
" | ( / `-%s-'\n"
|
|
|
|
|
" | / \n"
|
|
|
|
|
" `--'\n",
|
|
|
|
|
" .--. .-%s-.\n"
|
|
|
|
|
" | _|_ | %s |\n"
|
|
|
|
|
" | O O < %s |\n"
|
|
|
|
|
" | || | %s |\n"
|
|
|
|
|
" | _:| `-%s-'\n"
|
|
|
|
|
" | |\n"
|
|
|
|
|
" `---'\n",
|
|
|
|
|
};
|
|
|
|
|
|
|
|
|
|
static const char *avatar_clippy_utf8[] = {
|
|
|
|
|
" ╭──╮ ╭─%s─╮\n"
|
|
|
|
|
" │ _│ │ %s │\n"
|
|
|
|
|
" │ O O < %s │\n"
|
|
|
|
|
" │ │╭ │ %s │\n"
|
|
|
|
|
" ││ ││ ╰─%s─╯\n"
|
|
|
|
|
" │└─┘│\n"
|
|
|
|
|
" ╰───╯\n",
|
|
|
|
|
" ╭──╮ ╭─%s─╮\n"
|
|
|
|
|
" │ ╶│╶ │ %s │\n"
|
|
|
|
|
" │ O o < %s │\n"
|
|
|
|
|
" │ │ ╱ │ %s │\n"
|
|
|
|
|
" │ ╭┘ ╱ ╰─%s─╯\n"
|
|
|
|
|
" │ ╰ ╱\n"
|
|
|
|
|
" ╰──'\n",
|
|
|
|
|
" ╭──╮ ╭─%s─╮\n"
|
|
|
|
|
" │ _│_ │ %s │\n"
|
|
|
|
|
" │ O O < %s │\n"
|
|
|
|
|
" │ │╷ │ %s │\n"
|
|
|
|
|
" │ ││ ╰─%s─╯\n"
|
|
|
|
|
" │ ─╯│\n"
|
|
|
|
|
" ╰───╯\n",
|
|
|
|
|
};
|
|
|
|
|
|
2019-10-08 17:47:49 +02:00
|
|
|
|
static const char *avatar_cybcat[] = {
|
|
|
|
|
" /\\.---./\\ .-%s-.\n"
|
|
|
|
|
" '-- --' | %s |\n"
|
|
|
|
|
"---- ^ ^ ---- < %s |\n"
|
|
|
|
|
" _.- Y -._ | %s |\n"
|
|
|
|
|
" `-%s-'\n",
|
|
|
|
|
" /\\.---./\\ .-%s-.\n"
|
|
|
|
|
" '-- @ @ --' | %s |\n"
|
|
|
|
|
"---- Y ---- < %s |\n"
|
|
|
|
|
" _.- O -._ | %s |\n"
|
|
|
|
|
" `-%s-'\n",
|
|
|
|
|
" /\\.---./\\ .-%s-.\n"
|
|
|
|
|
" '-- = = --' | %s |\n"
|
|
|
|
|
"---- Y ---- < %s |\n"
|
|
|
|
|
" _.- U -._ | %s |\n"
|
|
|
|
|
" `-%s-'\n",
|
|
|
|
|
};
|
|
|
|
|
|
2019-01-11 00:32:23 +01:00
|
|
|
|
enum {
|
|
|
|
|
R_AVATAR_ORANGG,
|
2019-10-08 17:47:49 +02:00
|
|
|
|
R_AVATAR_CYBCAT,
|
2019-01-11 00:32:23 +01:00
|
|
|
|
R_AVATAR_CLIPPY,
|
|
|
|
|
};
|
|
|
|
|
|
2019-09-30 23:33:27 +02:00
|
|
|
|
R_API void r_core_clippy(RCore *core, const char *msg) {
|
2019-01-11 00:32:23 +01:00
|
|
|
|
int type = R_AVATAR_CLIPPY;
|
2019-10-08 17:47:49 +02:00
|
|
|
|
if (*msg == '+' || *msg == '3') {
|
2019-01-11 00:32:23 +01:00
|
|
|
|
char *space = strchr (msg, ' ');
|
2019-01-13 03:07:51 +01:00
|
|
|
|
if (!space) {
|
|
|
|
|
return;
|
|
|
|
|
}
|
2019-10-09 00:21:09 +08:00
|
|
|
|
type = (*msg == '+')? R_AVATAR_ORANGG: R_AVATAR_CYBCAT;
|
2019-01-11 00:32:23 +01:00
|
|
|
|
msg = space + 1;
|
|
|
|
|
}
|
2019-09-30 23:33:27 +02:00
|
|
|
|
const char *f;
|
|
|
|
|
int msglen = r_str_len_utf8 (msg);
|
2018-03-01 10:53:53 +01:00
|
|
|
|
char *s = strdup (r_str_pad (' ', msglen));
|
2019-09-30 23:33:27 +02:00
|
|
|
|
char *l;
|
|
|
|
|
|
|
|
|
|
if (type == R_AVATAR_ORANGG) {
|
|
|
|
|
l = strdup (r_str_pad ('-', msglen));
|
|
|
|
|
f = avatar_orangg[0];
|
2019-10-08 17:47:49 +02:00
|
|
|
|
} else if (type == R_AVATAR_CYBCAT) {
|
|
|
|
|
l = strdup (r_str_pad ('-', msglen));
|
|
|
|
|
f = avatar_cybcat[r_num_rand (R_ARRAY_SIZE (avatar_cybcat))];
|
2019-09-30 23:33:27 +02:00
|
|
|
|
} else if (r_config_get_i (core->config, "scr.utf8")) {
|
|
|
|
|
l = (char *)r_str_repeat ("─", msglen);
|
|
|
|
|
f = avatar_clippy_utf8[r_num_rand (R_ARRAY_SIZE (avatar_clippy_utf8))];
|
|
|
|
|
} else {
|
|
|
|
|
l = strdup (r_str_pad ('-', msglen));
|
|
|
|
|
f = avatar_clippy[r_num_rand (R_ARRAY_SIZE (avatar_clippy))];
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
r_cons_printf (f, l, s, msg, s, l);
|
2016-03-30 12:44:56 +02:00
|
|
|
|
free (l);
|
|
|
|
|
free (s);
|
|
|
|
|
}
|
|
|
|
|
|
2012-02-27 02:40:27 +01:00
|
|
|
|
static int cmd_help(void *data, const char *input) {
|
|
|
|
|
RCore *core = (RCore *)data;
|
2017-09-12 00:25:01 +02:00
|
|
|
|
RIOMap *map;
|
2013-02-07 03:09:53 +01:00
|
|
|
|
const char *k;
|
2017-09-12 00:25:01 +02:00
|
|
|
|
RListIter *iter;
|
2017-03-25 02:30:00 +01:00
|
|
|
|
char *p, out[128] = R_EMPTY;
|
2017-09-12 00:25:01 +02:00
|
|
|
|
ut64 n;
|
2012-11-16 01:34:26 +01:00
|
|
|
|
int i;
|
2014-10-09 09:19:48 +02:00
|
|
|
|
RList *tmp;
|
2012-11-16 01:34:26 +01:00
|
|
|
|
|
2012-02-27 02:40:27 +01:00
|
|
|
|
switch (input[0]) {
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '0': // "?0"
|
2016-02-25 10:28:54 +01:00
|
|
|
|
core->curtab = 0;
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '1': // "?1"
|
2016-11-03 11:51:10 +01:00
|
|
|
|
if (core->curtab < 0) {
|
2016-02-25 10:28:54 +01:00
|
|
|
|
core->curtab = 0;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
}
|
2016-02-25 10:28:54 +01:00
|
|
|
|
core->curtab ++;
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'r': // "?r"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
{ // TODO : Add support for 64bit random numbers
|
|
|
|
|
ut64 b = 0;
|
|
|
|
|
ut32 r = UT32_MAX;
|
|
|
|
|
if (input[1]) {
|
|
|
|
|
strncpy (out, input+(input[1]==' '? 2: 1), sizeof (out)-1);
|
2019-01-07 11:31:50 +01:00
|
|
|
|
p = strchr (out + 1, ' ');
|
2012-02-27 02:40:27 +01:00
|
|
|
|
if (p) {
|
|
|
|
|
*p = 0;
|
|
|
|
|
b = (ut32)r_num_math (core->num, out);
|
|
|
|
|
r = (ut32)r_num_math (core->num, p+1)-b;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
|
|
|
|
r = (ut32)r_num_math (core->num, out);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
r = 0LL;
|
|
|
|
|
}
|
|
|
|
|
if (!r) {
|
|
|
|
|
r = UT32_MAX >> 1;
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
core->num->value = (ut64) (b + r_num_rand (r));
|
|
|
|
|
r_cons_printf ("0x%"PFMT64x"\n", core->num->value);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2018-03-21 23:06:42 +05:30
|
|
|
|
case 'a': // "?a"
|
2018-03-21 23:10:17 +01:00
|
|
|
|
r_cons_printf ("%s", ret_ascii_table());
|
2018-03-21 23:06:42 +05:30
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'b': // "?b"
|
2014-05-01 17:29:09 +02:00
|
|
|
|
if (input[1] == '6' && input[2] == '4') {
|
|
|
|
|
//b64 decoding takes at most strlen(str) * 4
|
|
|
|
|
const int buflen = (strlen (input+3) * 4) + 1;
|
2015-02-09 11:48:06 +01:00
|
|
|
|
char* buf = calloc (buflen, sizeof(char));
|
2016-11-03 11:51:10 +01:00
|
|
|
|
if (!buf) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
|
|
|
|
if (input[3] == '-') {
|
2019-07-23 02:50:35 +02:00
|
|
|
|
r_base64_decode ((ut8*)buf, input + 4, -1);
|
|
|
|
|
} else if (input[3] == ' ') {
|
|
|
|
|
r_base64_encode (buf, (const ut8*)input + 4, -1);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
}
|
2016-06-26 00:51:17 -04:00
|
|
|
|
r_cons_println (buf);
|
2014-05-01 17:29:09 +02:00
|
|
|
|
free (buf);
|
2017-11-08 15:29:58 +01:00
|
|
|
|
} else if (input[1] == 't' && input[2] == 'w') { // "?btw"
|
|
|
|
|
if (r_num_between (core->num, input + 3) == -1) {
|
|
|
|
|
eprintf ("Usage: ?btw num|(expr) num|(expr) num|(expr)\n");
|
|
|
|
|
}
|
2014-05-01 17:29:09 +02:00
|
|
|
|
} else {
|
|
|
|
|
n = r_num_get (core->num, input+1);
|
|
|
|
|
r_num_to_bits (out, n);
|
|
|
|
|
r_cons_printf ("%sb\n", out);
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'B': // "?B"
|
2020-03-02 21:39:37 +01:00
|
|
|
|
k = r_str_trim_head_ro (input + 1);
|
2018-01-28 03:40:02 +05:30
|
|
|
|
tmp = r_core_get_boundaries_prot (core, -1, k, "search");
|
2018-11-15 19:35:47 +01:00
|
|
|
|
if (!tmp) {
|
|
|
|
|
return false;
|
|
|
|
|
}
|
2017-09-12 00:25:01 +02:00
|
|
|
|
r_list_foreach (tmp, iter, map) {
|
2020-12-08 08:57:08 -06:00
|
|
|
|
r_cons_printf ("0x%"PFMT64x" 0x%"PFMT64x"\n", r_io_map_begin (map), r_io_map_end (map));
|
2017-09-12 00:25:01 +02:00
|
|
|
|
}
|
2014-10-09 09:19:48 +02:00
|
|
|
|
r_list_free (tmp);
|
2013-02-07 03:09:53 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'h': // "?h"
|
2017-09-12 00:25:01 +02:00
|
|
|
|
if (input[1] == ' ') {
|
2018-06-01 01:10:55 +02:00
|
|
|
|
r_cons_printf ("0x%08x\n", (ut32)r_str_hash (input + 2));
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
|
|
|
|
eprintf ("Usage: ?h [string-to-hash]\n");
|
|
|
|
|
}
|
2013-06-07 10:26:37 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'F': // "?F"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
r_cons_flush ();
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'f': // "?f"
|
2016-11-03 11:51:10 +01:00
|
|
|
|
if (input[1] == ' ') {
|
|
|
|
|
char *q, *p = strdup (input + 2);
|
2012-02-27 02:40:27 +01:00
|
|
|
|
if (!p) {
|
|
|
|
|
eprintf ("Cannot strdup\n");
|
|
|
|
|
return 0;
|
|
|
|
|
}
|
|
|
|
|
q = strchr (p, ' ');
|
|
|
|
|
if (q) {
|
|
|
|
|
*q = 0;
|
|
|
|
|
n = r_num_get (core->num, p);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
r_str_bits (out, (const ut8*)&n, sizeof (n) * 8, q + 1);
|
2016-06-26 00:51:17 -04:00
|
|
|
|
r_cons_println (out);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
|
|
|
|
eprintf ("Usage: \"?b value bitstring\"\n");
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
free (p);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
|
|
|
|
eprintf ("Whitespace expected after '?f'\n");
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'o': // "?o"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
n = r_num_math (core->num, input+1);
|
2013-04-08 09:38:23 +02:00
|
|
|
|
r_cons_printf ("0%"PFMT64o"\n", n);
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'T': // "?T"
|
2016-03-18 13:39:45 +01:00
|
|
|
|
r_cons_printf("plug.init = %"PFMT64d"\n"
|
|
|
|
|
"plug.load = %"PFMT64d"\n"
|
|
|
|
|
"file.load = %"PFMT64d"\n",
|
|
|
|
|
core->times->loadlibs_init_time,
|
|
|
|
|
core->times->loadlibs_time,
|
|
|
|
|
core->times->file_open_time);
|
2016-03-14 22:12:54 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'u': // "?u"
|
2013-04-08 09:38:23 +02:00
|
|
|
|
{
|
2018-11-15 05:35:44 +07:00
|
|
|
|
char unit[8];
|
2013-04-08 09:38:23 +02:00
|
|
|
|
n = r_num_math (core->num, input+1);
|
2018-11-15 05:35:44 +07:00
|
|
|
|
r_num_units (unit, sizeof (unit), n);
|
2016-06-26 00:51:17 -04:00
|
|
|
|
r_cons_println (unit);
|
2012-12-03 04:01:55 +01:00
|
|
|
|
}
|
2013-04-08 09:38:23 +02:00
|
|
|
|
break;
|
2019-01-07 11:31:50 +01:00
|
|
|
|
case 'j': // "?j"
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case ' ': // "? "
|
2013-04-08 09:38:23 +02:00
|
|
|
|
{
|
2018-11-15 05:35:44 +07:00
|
|
|
|
char *asnum, unit[8];
|
2016-06-10 04:20:28 +02:00
|
|
|
|
ut32 s, a;
|
2015-04-03 19:02:52 +02:00
|
|
|
|
double d;
|
2013-04-08 09:38:23 +02:00
|
|
|
|
float f;
|
2017-12-02 16:15:06 +01:00
|
|
|
|
char * const inputs = strdup (input + 1);
|
2017-12-03 01:25:00 +01:00
|
|
|
|
RList *list = r_num_str_split_list (inputs);
|
|
|
|
|
const int list_len = r_list_length (list);
|
2019-01-07 11:31:50 +01:00
|
|
|
|
PJ *pj = NULL;
|
|
|
|
|
if (*input == 'j') {
|
|
|
|
|
pj = pj_new ();
|
|
|
|
|
pj_o (pj);
|
|
|
|
|
}
|
2017-12-03 01:25:00 +01:00
|
|
|
|
for (i = 0; i < list_len; i++) {
|
|
|
|
|
const char *str = r_list_pop_head (list);
|
2018-04-14 17:34:27 +02:00
|
|
|
|
if (!*str) {
|
2017-12-02 16:15:06 +01:00
|
|
|
|
continue;
|
|
|
|
|
}
|
2017-12-03 01:25:00 +01:00
|
|
|
|
n = r_num_math (core->num, str);
|
2017-12-02 16:15:06 +01:00
|
|
|
|
if (core->num->dbz) {
|
|
|
|
|
eprintf ("RNum ERROR: Division by Zero\n");
|
|
|
|
|
}
|
|
|
|
|
asnum = r_num_as_string (NULL, n, false);
|
|
|
|
|
/* decimal, hexa, octal */
|
|
|
|
|
s = n >> 16 << 12;
|
|
|
|
|
a = n & 0x0fff;
|
2018-11-15 05:35:44 +07:00
|
|
|
|
r_num_units (unit, sizeof (unit), n);
|
2019-01-07 11:31:50 +01:00
|
|
|
|
if (*input == 'j') {
|
2019-03-19 22:41:53 +05:30
|
|
|
|
pj_ks (pj, "int32", sdb_fmt ("%d", (st32)(n & UT32_MAX)));
|
2019-05-05 01:30:31 -06:00
|
|
|
|
pj_ks (pj, "uint32", sdb_fmt ("%u", (ut32)n));
|
2019-03-19 22:41:53 +05:30
|
|
|
|
pj_ks (pj, "int64", sdb_fmt ("%"PFMT64d, (st64)n));
|
2019-05-05 01:30:31 -06:00
|
|
|
|
pj_ks (pj, "uint64", sdb_fmt ("%"PFMT64u, (ut64)n));
|
2019-01-07 11:31:50 +01:00
|
|
|
|
pj_ks (pj, "hex", sdb_fmt ("0x%08"PFMT64x, n));
|
|
|
|
|
pj_ks (pj, "octal", sdb_fmt ("0%"PFMT64o, n));
|
|
|
|
|
pj_ks (pj, "unit", unit);
|
2019-01-07 11:36:24 +01:00
|
|
|
|
pj_ks (pj, "segment", sdb_fmt ("%04x:%04x", s, a));
|
2020-02-29 22:47:10 +03:00
|
|
|
|
|
2017-12-02 16:15:06 +01:00
|
|
|
|
} else {
|
2019-01-07 11:31:50 +01:00
|
|
|
|
if (n >> 32) {
|
|
|
|
|
r_cons_printf ("int64 %"PFMT64d"\n", (st64)n);
|
2019-05-05 00:54:21 -06:00
|
|
|
|
r_cons_printf ("uint64 %"PFMT64u"\n", (ut64)n);
|
2019-01-07 11:31:50 +01:00
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("int32 %d\n", (st32)n);
|
2019-05-05 00:54:21 -06:00
|
|
|
|
r_cons_printf ("uint32 %u\n", (ut32)n);
|
2019-01-07 11:31:50 +01:00
|
|
|
|
}
|
2019-03-19 22:41:53 +05:30
|
|
|
|
r_cons_printf ("hex 0x%"PFMT64x"\n", n);
|
|
|
|
|
r_cons_printf ("octal 0%"PFMT64o"\n", n);
|
|
|
|
|
r_cons_printf ("unit %s\n", unit);
|
|
|
|
|
r_cons_printf ("segment %04x:%04x\n", s, a);
|
2020-02-29 22:47:10 +03:00
|
|
|
|
|
2019-01-07 11:31:50 +01:00
|
|
|
|
if (asnum) {
|
|
|
|
|
r_cons_printf ("string \"%s\"\n", asnum);
|
|
|
|
|
free (asnum);
|
|
|
|
|
}
|
2017-12-02 16:15:06 +01:00
|
|
|
|
}
|
|
|
|
|
/* binary and floating point */
|
|
|
|
|
r_str_bits64 (out, n);
|
|
|
|
|
f = d = core->num->fvalue;
|
2018-07-14 10:58:19 +02:00
|
|
|
|
memcpy (&f, &n, sizeof (f));
|
|
|
|
|
memcpy (&d, &n, sizeof (d));
|
2018-04-15 17:45:47 +02:00
|
|
|
|
/* adjust sign for nan floats, different libcs are confused */
|
2018-04-15 18:13:02 +02:00
|
|
|
|
if (isnan (f) && signbit (f)) {
|
2018-04-15 17:45:47 +02:00
|
|
|
|
f = -f;
|
|
|
|
|
}
|
2018-04-15 18:13:02 +02:00
|
|
|
|
if (isnan (d) && signbit (d)) {
|
2018-04-15 17:45:47 +02:00
|
|
|
|
d = -d;
|
|
|
|
|
}
|
2019-01-07 11:31:50 +01:00
|
|
|
|
if (*input == 'j') {
|
|
|
|
|
pj_ks (pj, "fvalue", sdb_fmt ("%.1lf", core->num->fvalue));
|
|
|
|
|
pj_ks (pj, "float", sdb_fmt ("%ff", f));
|
|
|
|
|
pj_ks (pj, "double", sdb_fmt ("%lf", d));
|
2019-03-19 22:41:53 +05:30
|
|
|
|
pj_ks (pj, "binary", sdb_fmt ("0b%s", out));
|
2020-12-17 15:24:27 -06:00
|
|
|
|
r_num_to_ternary (out, n);
|
|
|
|
|
pj_ks (pj, "ternary", sdb_fmt ("0t%s", out));
|
2019-01-07 11:31:50 +01:00
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("fvalue: %.1lf\n", core->num->fvalue);
|
|
|
|
|
r_cons_printf ("float: %ff\n", f);
|
|
|
|
|
r_cons_printf ("double: %lf\n", d);
|
2019-03-19 22:41:53 +05:30
|
|
|
|
r_cons_printf ("binary 0b%s\n", out);
|
2020-12-17 15:24:27 -06:00
|
|
|
|
r_num_to_ternary (out, n);
|
|
|
|
|
r_cons_printf ("ternary 0t%s\n", out);
|
2019-01-07 11:31:50 +01:00
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
if (*input == 'j') {
|
|
|
|
|
pj_end (pj);
|
2014-05-07 02:51:04 +02:00
|
|
|
|
}
|
2017-12-02 16:15:06 +01:00
|
|
|
|
free (inputs);
|
2017-12-03 01:25:00 +01:00
|
|
|
|
r_list_free (list);
|
2019-01-07 11:31:50 +01:00
|
|
|
|
if (pj) {
|
|
|
|
|
r_cons_printf ("%s\n", pj_string (pj));
|
|
|
|
|
pj_free (pj);
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
}
|
|
|
|
|
break;
|
2018-03-15 01:07:24 +01:00
|
|
|
|
case 'q': // "?q"
|
|
|
|
|
if (core->num->dbz) {
|
|
|
|
|
eprintf ("RNum ERROR: Division by Zero\n");
|
|
|
|
|
}
|
|
|
|
|
if (input[1] == '?') {
|
|
|
|
|
r_cons_printf ("|Usage: ?q [num] # Update $? without printing anything\n"
|
|
|
|
|
"|?q 123; ?? x # hexdump if 123 != 0");
|
|
|
|
|
} else {
|
|
|
|
|
const char *space = strchr (input, ' ');
|
|
|
|
|
if (space) {
|
|
|
|
|
n = r_num_math (core->num, space + 1);
|
|
|
|
|
} else {
|
|
|
|
|
n = r_num_math (core->num, "$?");
|
|
|
|
|
}
|
|
|
|
|
core->num->value = n; // redundant
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'v': // "?v"
|
2016-02-27 17:58:32 +01:00
|
|
|
|
{
|
|
|
|
|
const char *space = strchr (input, ' ');
|
|
|
|
|
if (space) {
|
2016-11-02 22:59:32 +01:00
|
|
|
|
n = r_num_math (core->num, space + 1);
|
2016-02-27 17:58:32 +01:00
|
|
|
|
} else {
|
|
|
|
|
n = r_num_math (core->num, "$?");
|
|
|
|
|
}
|
|
|
|
|
}
|
2014-11-07 12:16:29 +01:00
|
|
|
|
if (core->num->dbz) {
|
|
|
|
|
eprintf ("RNum ERROR: Division by Zero\n");
|
|
|
|
|
}
|
2012-12-03 04:01:55 +01:00
|
|
|
|
switch (input[1]) {
|
2013-11-29 17:27:46 +01:00
|
|
|
|
case '?':
|
2014-02-15 14:12:50 -05:00
|
|
|
|
r_cons_printf ("|Usage: ?v[id][ num] # Show value\n"
|
2018-07-18 17:15:59 +02:00
|
|
|
|
"|?vx number -> show 8 digit padding in hex\n"
|
2016-02-27 18:35:50 +01:00
|
|
|
|
"|?vi1 200 -> 1 byte size value (char)\n"
|
|
|
|
|
"|?vi2 0xffff -> 2 byte size value (short)\n"
|
|
|
|
|
"|?vi4 0xffff -> 4 byte size value (int)\n"
|
|
|
|
|
"|?vi8 0xffff -> 8 byte size value (st64)\n"
|
2013-12-23 01:57:43 +01:00
|
|
|
|
"| No argument shows $? value\n"
|
|
|
|
|
"|?vi will show in decimal instead of hex\n");
|
2013-11-29 17:27:46 +01:00
|
|
|
|
break;
|
|
|
|
|
case '\0':
|
2016-11-02 22:59:32 +01:00
|
|
|
|
r_cons_printf ("%d\n", (st32)n);
|
2013-11-29 17:27:46 +01:00
|
|
|
|
break;
|
2018-07-18 17:15:59 +02:00
|
|
|
|
case 'x': // "?vx"
|
2018-07-18 18:29:49 +02:00
|
|
|
|
r_cons_printf ("0x%08"PFMT64x"\n", n);
|
2018-07-18 17:15:59 +02:00
|
|
|
|
break;
|
2016-02-27 17:58:32 +01:00
|
|
|
|
case 'i': // "?vi"
|
|
|
|
|
switch (input[2]) {
|
|
|
|
|
case '1': // byte
|
|
|
|
|
r_cons_printf ("%d\n", (st8)(n & UT8_MAX));
|
|
|
|
|
break;
|
|
|
|
|
case '2': // word
|
|
|
|
|
r_cons_printf ("%d\n", (st16)(n & UT16_MAX));
|
|
|
|
|
break;
|
|
|
|
|
case '4': // dword
|
|
|
|
|
r_cons_printf ("%d\n", (st32)(n & UT32_MAX));
|
|
|
|
|
break;
|
|
|
|
|
case '8': // qword
|
|
|
|
|
r_cons_printf ("%"PFMT64d"\n", (st64)(n & UT64_MAX));
|
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
r_cons_printf ("%"PFMT64d"\n", n);
|
|
|
|
|
break;
|
|
|
|
|
}
|
2012-12-03 04:01:55 +01:00
|
|
|
|
break;
|
|
|
|
|
case 'd':
|
2012-06-12 02:51:34 +02:00
|
|
|
|
r_cons_printf ("%"PFMT64d"\n", n);
|
2012-12-03 04:01:55 +01:00
|
|
|
|
break;
|
|
|
|
|
default:
|
|
|
|
|
r_cons_printf ("0x%"PFMT64x"\n", n);
|
|
|
|
|
}
|
2012-12-01 00:15:19 +01:00
|
|
|
|
core->num->value = n; // redundant
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '=': // "?=" set num->value
|
2020-09-09 15:51:11 +02:00
|
|
|
|
if (input[1] == '=') { // ?==
|
|
|
|
|
if (input[2] == ' ') {
|
|
|
|
|
char *s = strdup (input + 3);
|
|
|
|
|
char *e = strchr (s, ' ');
|
|
|
|
|
if (e) {
|
|
|
|
|
*e++ = 0;
|
|
|
|
|
core->num->value = strcmp (s, e);
|
|
|
|
|
} else {
|
|
|
|
|
eprintf ("Missing secondary word in expression to compare\n");
|
|
|
|
|
}
|
|
|
|
|
free (s);
|
|
|
|
|
} else {
|
|
|
|
|
eprintf ("Usage: ?== str1 str2\n");
|
|
|
|
|
}
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
2020-09-09 15:51:11 +02:00
|
|
|
|
if (input[1]) { // ?=
|
|
|
|
|
r_num_math (core->num, input+1);
|
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("0x%"PFMT64x"\n", core->num->value);
|
|
|
|
|
}
|
2016-11-03 11:51:10 +01:00
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '+': // "?+"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
if (input[1]) {
|
2012-12-01 00:15:19 +01:00
|
|
|
|
st64 n = (st64)core->num->value;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
if (n > 0) {
|
|
|
|
|
r_core_cmd (core, input + 1, 0);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("0x%"PFMT64x"\n", core->num->value);
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '-': // "?-"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
if (input[1]) {
|
2012-12-01 00:15:19 +01:00
|
|
|
|
st64 n = (st64)core->num->value;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
if (n < 0) {
|
|
|
|
|
r_core_cmd (core, input + 1, 0);
|
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("0x%"PFMT64x"\n", core->num->value);
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2016-03-31 04:48:36 +02:00
|
|
|
|
case '!': // "?!"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
if (input[1]) {
|
2016-08-28 13:41:06 +02:00
|
|
|
|
if (!core->num->value) {
|
|
|
|
|
if (input[1] == '?') {
|
2018-08-02 13:18:48 +02:00
|
|
|
|
cmd_help_exclamation (core);
|
2016-08-28 13:41:06 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2020-09-09 15:51:11 +02:00
|
|
|
|
return core->num->value = r_core_cmd (core, input+1, 0);
|
2016-08-28 13:41:06 +02:00
|
|
|
|
}
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("0x%"PFMT64x"\n", core->num->value);
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '@': // "?@"
|
2017-08-11 02:45:32 -07:00
|
|
|
|
if (input[1] == '@') {
|
2018-03-02 18:58:14 +01:00
|
|
|
|
if (input[2] == '@') {
|
|
|
|
|
r_core_cmd_help (core, help_msg_at_at_at);
|
|
|
|
|
} else {
|
|
|
|
|
r_core_cmd_help (core, help_msg_at_at);
|
|
|
|
|
}
|
2017-03-02 10:39:11 +01:00
|
|
|
|
} else {
|
2017-08-11 02:45:32 -07:00
|
|
|
|
r_core_cmd_help (core, help_msg_at);
|
2014-08-07 02:39:34 +02:00
|
|
|
|
}
|
2017-03-02 10:39:11 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '&': // "?&"
|
2017-03-02 10:39:11 +01:00
|
|
|
|
helpCmdTasks (core);
|
|
|
|
|
break;
|
2018-08-02 13:18:48 +02:00
|
|
|
|
case '%': // "?%"
|
|
|
|
|
if (input[1] == '?') {
|
|
|
|
|
cmd_help_percent (core);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '$': // "?$"
|
2016-09-09 14:29:42 +02:00
|
|
|
|
if (input[1] == '?') {
|
2017-08-10 02:52:13 -07:00
|
|
|
|
r_core_cmd_help (core, help_msg_question_v);
|
2016-09-09 14:29:42 +02:00
|
|
|
|
} else {
|
|
|
|
|
int i = 0;
|
|
|
|
|
const char *vars[] = {
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$$", "$$$", "$?", "$B", "$b", "$c", "$Cn", "$D", "$DB", "$DD", "$Dn",
|
|
|
|
|
"$e", "$f", "$F", "$Fb", "$FB", "$Fe", "$FE", "$Ff", "$Fi", "$FI", "$Fj",
|
2020-12-28 00:27:32 +01:00
|
|
|
|
"$fl", "$FS", "$Fs", "$FSS", "$i", "$j", "$Ja", "$l", "$M", "$m", "$MM", "$O",
|
2020-12-27 22:48:24 +01:00
|
|
|
|
"$o", "$p", "$P", "$r", "$s", "$S", "$SS", "$v", "$w", "$Xn", NULL
|
2016-09-09 14:29:42 +02:00
|
|
|
|
};
|
2019-06-19 19:15:15 +02:00
|
|
|
|
const bool wideOffsets = r_config_get_i (core->config, "scr.wideoff");
|
2016-09-09 14:29:42 +02:00
|
|
|
|
while (vars[i]) {
|
|
|
|
|
const char *pad = r_str_pad (' ', 6 - strlen (vars[i]));
|
2019-06-19 19:15:15 +02:00
|
|
|
|
if (wideOffsets) {
|
|
|
|
|
eprintf ("%s %s 0x%016"PFMT64x"\n", vars[i], pad, r_num_math (core->num, vars[i]));
|
|
|
|
|
} else {
|
|
|
|
|
eprintf ("%s %s 0x%08"PFMT64x"\n", vars[i], pad, r_num_math (core->num, vars[i]));
|
|
|
|
|
}
|
2016-09-09 14:29:42 +02:00
|
|
|
|
i++;
|
|
|
|
|
}
|
2014-06-21 14:37:40 +02:00
|
|
|
|
}
|
2015-09-14 12:35:38 +02:00
|
|
|
|
return true;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'V': // "?V"
|
2016-05-19 03:42:23 +02:00
|
|
|
|
switch (input[1]) {
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '?': // "?V?"
|
2017-08-10 02:52:13 -07:00
|
|
|
|
r_core_cmd_help (core, help_msg_question_V);
|
2016-05-19 03:42:23 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 0: // "?V"
|
2017-01-29 15:25:14 +01:00
|
|
|
|
#if R2_VERSION_COMMIT == 0
|
|
|
|
|
r_cons_printf ("%s release\n", R2_VERSION);
|
|
|
|
|
#else
|
2016-05-19 03:42:23 +02:00
|
|
|
|
if (!strcmp (R2_VERSION, R2_GITTAP)) {
|
2015-07-20 21:37:42 +02:00
|
|
|
|
r_cons_printf ("%s %d\n", R2_VERSION, R2_VERSION_COMMIT);
|
2016-05-19 03:42:23 +02:00
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("%s aka %s commit %d\n", R2_VERSION, R2_GITTAP, R2_VERSION_COMMIT);
|
|
|
|
|
}
|
2017-01-29 15:25:14 +01:00
|
|
|
|
#endif
|
2016-05-19 03:42:23 +02:00
|
|
|
|
break;
|
2017-11-30 10:42:23 +01:00
|
|
|
|
case 'c': // "?Vc"
|
|
|
|
|
r_cons_printf ("%d\n", vernum (R2_VERSION));
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'j': // "?Vj"
|
2020-01-17 17:42:58 +01:00
|
|
|
|
{
|
|
|
|
|
PJ *pj = pj_new ();
|
|
|
|
|
pj_o (pj);
|
|
|
|
|
pj_ks (pj, "arch", R_SYS_ARCH);
|
|
|
|
|
pj_ks (pj, "os", R_SYS_OS);
|
|
|
|
|
pj_ki (pj, "bits", R_SYS_BITS);
|
|
|
|
|
pj_ki (pj, "commit", R2_VERSION_COMMIT);
|
|
|
|
|
pj_ks (pj, "tap", R2_GITTAP);
|
|
|
|
|
pj_ki (pj, "major", R2_VERSION_MAJOR);
|
|
|
|
|
pj_ki (pj, "minor", R2_VERSION_MINOR);
|
|
|
|
|
pj_ki (pj, "patch", R2_VERSION_PATCH);
|
|
|
|
|
pj_ki (pj, "number", R2_VERSION_NUMBER);
|
|
|
|
|
pj_ki (pj, "nversion", vernum (R2_VERSION));
|
|
|
|
|
pj_ks (pj, "version", R2_VERSION);
|
|
|
|
|
pj_end (pj);
|
|
|
|
|
r_cons_printf ("%s\n", pj_string (pj));
|
|
|
|
|
pj_free (pj);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case 'n': // "?Vn"
|
|
|
|
|
r_cons_printf ("%d\n", R2_VERSION_NUMBER);
|
2016-05-19 03:42:23 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'q': // "?Vq"
|
2016-06-26 00:51:17 -04:00
|
|
|
|
r_cons_println (R2_VERSION);
|
2016-05-19 03:42:23 +02:00
|
|
|
|
break;
|
2020-01-17 17:42:58 +01:00
|
|
|
|
case '0':
|
|
|
|
|
r_cons_printf ("%d\n", R2_VERSION_MAJOR);
|
|
|
|
|
break;
|
|
|
|
|
case '1':
|
|
|
|
|
r_cons_printf ("%d\n", R2_VERSION_MINOR);
|
|
|
|
|
break;
|
|
|
|
|
case '2':
|
|
|
|
|
r_cons_printf ("%d\n", R2_VERSION_PATCH);
|
|
|
|
|
break;
|
2015-07-20 21:37:42 +02:00
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'l': // "?l"
|
2018-02-13 13:15:11 -06:00
|
|
|
|
if (input[1] == 'q') {
|
2020-12-28 00:27:27 +01:00
|
|
|
|
for (input += 2; input[0] == ' '; input++);
|
2018-02-13 13:15:11 -06:00
|
|
|
|
core->num->value = strlen (input);
|
|
|
|
|
} else {
|
|
|
|
|
for (input++; input[0] == ' '; input++);
|
|
|
|
|
core->num->value = strlen (input);
|
2020-10-13 16:26:15 +02:00
|
|
|
|
r_cons_printf ("%" PFMT64d "\n", core->num->value);
|
2018-02-13 13:15:11 -06:00
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'X': // "?X"
|
2016-11-03 11:51:10 +01:00
|
|
|
|
for (input++; input[0] == ' '; input++);
|
2012-12-22 04:28:19 +01:00
|
|
|
|
n = r_num_math (core->num, input);
|
|
|
|
|
r_cons_printf ("%"PFMT64x"\n", n);
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'x': // "?x"
|
2016-11-03 11:51:10 +01:00
|
|
|
|
for (input++; input[0] == ' '; input++);
|
|
|
|
|
if (*input == '-') {
|
2018-09-02 15:58:13 +02:00
|
|
|
|
ut8 *out = malloc (strlen (input) + 1);
|
|
|
|
|
if (out) {
|
|
|
|
|
int len = r_hex_str2bin (input + 1, out);
|
|
|
|
|
if (len >= 0) {
|
|
|
|
|
out[len] = 0;
|
|
|
|
|
r_cons_println ((const char*)out);
|
|
|
|
|
} else {
|
|
|
|
|
eprintf ("Error parsing the hexpair string\n");
|
|
|
|
|
}
|
|
|
|
|
free (out);
|
|
|
|
|
}
|
2017-01-21 03:47:44 +01:00
|
|
|
|
} else if (*input == '+') {
|
2012-02-27 02:40:27 +01:00
|
|
|
|
ut64 n = r_num_math (core->num, input);
|
|
|
|
|
int bits = r_num_to_bits (NULL, n) / 8;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
for (i = 0; i < bits; i++) {
|
|
|
|
|
r_cons_printf ("%02x", (ut8)((n >> (i * 8)) &0xff));
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
r_cons_newline ();
|
|
|
|
|
} else {
|
2017-01-21 03:47:44 +01:00
|
|
|
|
if (*input == ' ') {
|
|
|
|
|
input++;
|
|
|
|
|
}
|
2016-11-03 11:51:10 +01:00
|
|
|
|
for (i = 0; input[i]; i++) {
|
2012-02-27 02:40:27 +01:00
|
|
|
|
r_cons_printf ("%02x", input[i]);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
r_cons_newline ();
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'E': // "?E" clippy echo
|
2020-03-02 21:39:37 +01:00
|
|
|
|
r_core_clippy (core, r_str_trim_head_ro (input + 1));
|
2016-03-30 12:44:56 +02:00
|
|
|
|
break;
|
2017-09-03 01:42:45 +02:00
|
|
|
|
case 'e': // "?e" echo
|
2017-06-10 18:37:56 +02:00
|
|
|
|
switch (input[1]) {
|
2020-09-12 04:28:09 +02:00
|
|
|
|
case 't': // "?e=t newtitle"
|
|
|
|
|
r_cons_set_title (r_str_trim_head_ro (input + 2));
|
|
|
|
|
break;
|
2019-07-11 05:14:41 +02:00
|
|
|
|
case '=': { // "?e="
|
|
|
|
|
ut64 pc = r_num_math (core->num, input + 2);
|
|
|
|
|
r_print_progressbar (core->print, pc, 80);
|
|
|
|
|
r_cons_newline ();
|
|
|
|
|
break;
|
|
|
|
|
}
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'b': { // "?eb"
|
2020-03-02 21:39:37 +01:00
|
|
|
|
char *arg = strdup (r_str_trim_head_ro (input + 2));
|
2017-09-19 02:42:47 -07:00
|
|
|
|
int n = r_str_split (arg, ' ');
|
|
|
|
|
ut64 *portions = calloc (n, sizeof (ut64));
|
|
|
|
|
for (i = 0; i < n; i++) {
|
|
|
|
|
portions[i] = r_num_math (core->num, r_str_word_get0 (arg, i));
|
|
|
|
|
}
|
|
|
|
|
r_print_portionbar (core->print, portions, n);
|
|
|
|
|
free (arg);
|
2017-09-03 01:42:45 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
}
|
|
|
|
|
case 's': { // "?es"
|
2017-01-11 00:21:58 +01:00
|
|
|
|
char *msg = strdup (input + 2);
|
2019-06-16 20:58:40 +02:00
|
|
|
|
r_str_trim (msg);
|
2017-01-11 00:21:58 +01:00
|
|
|
|
char *p = strchr (msg, '&');
|
|
|
|
|
if (p) *p = 0;
|
|
|
|
|
r_sys_tts (msg, p != NULL);
|
|
|
|
|
free (msg);
|
2017-06-10 18:37:56 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
}
|
|
|
|
|
case 'c': // "?ec" column
|
2017-06-10 18:37:56 +02:00
|
|
|
|
r_cons_column (r_num_math (core->num, input + 2));
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'g': { // "?eg" gotoxy
|
2017-06-10 18:37:56 +02:00
|
|
|
|
int x = atoi (input + 2);
|
|
|
|
|
char *arg = strchr (input + 2, ' ');
|
|
|
|
|
int y = arg? atoi (arg + 1): 0;
|
|
|
|
|
r_cons_gotoxy (x, y);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'n': { // "?en" echo -n
|
2020-03-02 21:39:37 +01:00
|
|
|
|
const char *msg = r_str_trim_head_ro (input + 2);
|
2016-09-15 09:25:32 -05:00
|
|
|
|
// TODO: replace all ${flagname} by its value in hexa
|
2016-11-23 12:52:36 +01:00
|
|
|
|
char *newmsg = filterFlags (core, msg);
|
2016-09-15 09:25:32 -05:00
|
|
|
|
r_str_unescape (newmsg);
|
|
|
|
|
r_cons_print (newmsg);
|
|
|
|
|
free (newmsg);
|
2017-06-10 18:37:56 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
}
|
2019-07-11 05:14:41 +02:00
|
|
|
|
case 'd': // "?ed"
|
|
|
|
|
if (input[2] == 'd') {
|
|
|
|
|
int i,j;
|
|
|
|
|
r_cons_show_cursor (0);
|
|
|
|
|
r_cons_clear00 ();
|
|
|
|
|
for (i = 1; i < 100; i++) {
|
|
|
|
|
if (r_cons_is_breaked ()) {
|
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
for (j = 0; j < 20; j++) {
|
|
|
|
|
char *d = r_str_donut (i);
|
|
|
|
|
r_cons_gotoxy (0,0);
|
|
|
|
|
r_str_trim_tail (d);
|
|
|
|
|
r_cons_clear_line (0);
|
|
|
|
|
r_cons_printf ("Downloading the Gibson...\n\n");
|
|
|
|
|
r_core_cmdf (core, "?e=%d", i);
|
|
|
|
|
r_cons_strcat (d);
|
|
|
|
|
r_cons_clear_line (0);
|
|
|
|
|
r_cons_newline ();
|
|
|
|
|
free (d);
|
|
|
|
|
r_cons_flush ();
|
|
|
|
|
r_sys_usleep (2000);
|
|
|
|
|
}
|
|
|
|
|
}
|
|
|
|
|
r_cons_clear00();
|
|
|
|
|
r_cons_printf ("\nPayload installed. Thanks for your patience.\n\n");
|
|
|
|
|
} else {
|
|
|
|
|
char *d = r_str_donut (r_num_math (core->num, input + 2));
|
|
|
|
|
r_str_trim_tail (d);
|
|
|
|
|
const char *color = (core->cons && core->cons->context->pal.flag)? core->cons->context->pal.flag: "";
|
|
|
|
|
r_cons_printf ("%s%s", color, d);
|
|
|
|
|
r_cons_newline ();
|
|
|
|
|
free (d);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2018-05-10 13:13:08 +02:00
|
|
|
|
case 'p':
|
|
|
|
|
{
|
|
|
|
|
char *word, *str = strdup (input + 2);
|
2019-08-28 22:34:16 +02:00
|
|
|
|
RList *list = r_str_split_list (str, " ", 0);
|
2018-05-10 13:13:08 +02:00
|
|
|
|
ut64 *nums = calloc (sizeof (ut64), r_list_length (list));
|
|
|
|
|
int i = 0;
|
|
|
|
|
r_list_foreach (list, iter, word) {
|
|
|
|
|
nums[i] = r_num_math (core->num, word);;
|
|
|
|
|
i++;
|
|
|
|
|
}
|
|
|
|
|
int size = r_config_get_i (core->config, "hex.cols");
|
|
|
|
|
r_print_pie (core->print, nums, r_list_length (list), size);
|
|
|
|
|
r_list_free (list);
|
|
|
|
|
}
|
|
|
|
|
break;
|
|
|
|
|
case ' ': {
|
2020-03-02 21:39:37 +01:00
|
|
|
|
const char *msg = r_str_trim_head_ro (input+1);
|
2016-09-15 09:25:32 -05:00
|
|
|
|
// TODO: replace all ${flagname} by its value in hexa
|
2016-11-23 12:52:36 +01:00
|
|
|
|
char *newmsg = filterFlags (core, msg);
|
2016-09-15 09:25:32 -05:00
|
|
|
|
r_str_unescape (newmsg);
|
|
|
|
|
r_cons_println (newmsg);
|
|
|
|
|
free (newmsg);
|
2017-06-10 18:37:56 +02:00
|
|
|
|
}
|
|
|
|
|
break;
|
2018-05-10 15:51:29 +02:00
|
|
|
|
case 0:
|
|
|
|
|
r_cons_newline ();
|
|
|
|
|
break;
|
2018-05-10 13:13:08 +02:00
|
|
|
|
default:
|
2020-10-13 15:44:39 +02:00
|
|
|
|
r_core_cmd_help (core, help_msg_question_e);
|
2018-05-10 13:13:08 +02:00
|
|
|
|
break;
|
2015-01-18 02:17:55 +01:00
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 's': { // "?s" sequence from to step
|
2012-02-27 02:40:27 +01:00
|
|
|
|
ut64 from, to, step;
|
|
|
|
|
char *p, *p2;
|
|
|
|
|
for (input++; *input==' '; input++);
|
|
|
|
|
p = strchr (input, ' ');
|
|
|
|
|
if (p) {
|
2015-01-18 02:17:55 +01:00
|
|
|
|
*p = '\0';
|
2012-02-27 02:40:27 +01:00
|
|
|
|
from = r_num_math (core->num, input);
|
|
|
|
|
p2 = strchr (p+1, ' ');
|
|
|
|
|
if (p2) {
|
2015-01-18 02:17:55 +01:00
|
|
|
|
*p2 = '\0';
|
2016-11-03 11:51:10 +01:00
|
|
|
|
step = r_num_math (core->num, p2 + 1);
|
|
|
|
|
} else {
|
|
|
|
|
step = 1;
|
|
|
|
|
}
|
|
|
|
|
to = r_num_math (core->num, p + 1);
|
|
|
|
|
for (;from <= to; from += step)
|
2012-02-27 02:40:27 +01:00
|
|
|
|
r_cons_printf ("%"PFMT64d" ", from);
|
|
|
|
|
r_cons_newline ();
|
|
|
|
|
}
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
}
|
|
|
|
|
case 'P': // "?P"
|
2012-12-08 02:17:21 +01:00
|
|
|
|
if (core->io->va) {
|
|
|
|
|
ut64 o, n = (input[0] && input[1])?
|
|
|
|
|
r_num_math (core->num, input+2): core->offset;
|
2017-09-02 23:17:39 +02:00
|
|
|
|
RIOMap *map = r_io_map_get_paddr (core->io, n);
|
|
|
|
|
if (map) {
|
2020-12-08 08:57:08 -06:00
|
|
|
|
o = n + r_io_map_begin (map) - map->delta;
|
2017-08-22 07:42:16 +00:00
|
|
|
|
r_cons_printf ("0x%08"PFMT64x"\n", o);
|
2017-08-23 01:41:46 +02:00
|
|
|
|
} else {
|
2017-09-02 23:17:39 +02:00
|
|
|
|
r_cons_printf ("no map at 0x%08"PFMT64x"\n", n);
|
2017-08-23 01:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("0x%08"PFMT64x"\n", core->offset);
|
|
|
|
|
}
|
2012-12-08 02:17:21 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'p': // "?p"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
if (core->io->va) {
|
2013-02-07 03:09:53 +01:00
|
|
|
|
// physical address
|
|
|
|
|
ut64 o, n = (input[0] && input[1])?
|
2016-11-03 11:51:10 +01:00
|
|
|
|
r_num_math (core->num, input + 2): core->offset;
|
2017-09-02 23:17:39 +02:00
|
|
|
|
RIOMap *map = r_io_map_get (core->io, n);
|
|
|
|
|
if (map) {
|
2020-12-08 08:57:08 -06:00
|
|
|
|
o = n - r_io_map_begin (map) + map->delta;
|
2017-08-22 07:42:16 +00:00
|
|
|
|
r_cons_printf ("0x%08"PFMT64x"\n", o);
|
2017-08-23 01:41:46 +02:00
|
|
|
|
} else {
|
2017-09-02 23:17:39 +02:00
|
|
|
|
r_cons_printf ("no map at 0x%08"PFMT64x"\n", n);
|
2017-08-23 01:41:46 +02:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
r_cons_printf ("0x%08"PFMT64x"\n", core->offset);
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '_': // "?_" hud input
|
2014-03-20 11:59:08 -05:00
|
|
|
|
r_core_yank_hud_file (core, input+1);
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2016-03-31 05:15:20 +02:00
|
|
|
|
case 'i': // "?i" input num
|
2015-04-11 20:51:08 +02:00
|
|
|
|
r_cons_set_raw(0);
|
2019-02-18 06:20:01 +01:00
|
|
|
|
if (!r_cons_is_interactive ()) {
|
2012-11-27 14:09:53 +01:00
|
|
|
|
eprintf ("Not running in interactive mode\n");
|
2016-11-03 11:51:10 +01:00
|
|
|
|
} else {
|
|
|
|
|
switch (input[1]) {
|
|
|
|
|
case 'f': // "?if"
|
|
|
|
|
core->num->value = !r_num_conditional (core->num, input + 2);
|
|
|
|
|
eprintf ("%s\n", r_str_bool (!core->num->value));
|
|
|
|
|
break;
|
2017-08-10 02:52:13 -07:00
|
|
|
|
case 'm': // "?im"
|
2019-05-17 12:07:39 +02:00
|
|
|
|
r_cons_message (input + 2);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
break;
|
2017-08-10 02:52:13 -07:00
|
|
|
|
case 'p': // "?ip"
|
2016-11-03 11:51:10 +01:00
|
|
|
|
core->num->value = r_core_yank_hud_path (core, input + 2, 0) == true;
|
|
|
|
|
break;
|
|
|
|
|
case 'k': // "?ik"
|
|
|
|
|
r_cons_any_key (NULL);
|
|
|
|
|
break;
|
|
|
|
|
case 'y': // "?iy"
|
|
|
|
|
for (input += 2; *input==' '; input++);
|
|
|
|
|
core->num->value = r_cons_yesno (1, "%s? (Y/n)", input);
|
|
|
|
|
break;
|
|
|
|
|
case 'n': // "?in"
|
|
|
|
|
for (input += 2; *input==' '; input++);
|
|
|
|
|
core->num->value = r_cons_yesno (0, "%s? (y/N)", input);
|
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
default: {
|
2016-11-03 11:51:10 +01:00
|
|
|
|
char foo[1024];
|
|
|
|
|
r_cons_flush ();
|
|
|
|
|
for (input++; *input == ' '; input++);
|
|
|
|
|
// TODO: r_cons_input()
|
|
|
|
|
snprintf (foo, sizeof (foo) - 1, "%s: ", input);
|
|
|
|
|
r_line_set_prompt (foo);
|
2020-02-29 22:47:10 +03:00
|
|
|
|
r_cons_fgets (foo, sizeof (foo), 0, NULL);
|
2017-03-12 11:22:16 +01:00
|
|
|
|
foo[sizeof (foo) - 1] = 0;
|
2016-11-03 11:51:10 +01:00
|
|
|
|
r_core_yank_set_str (core, R_CORE_FOREIGN_ADDR, foo, strlen (foo) + 1);
|
|
|
|
|
core->num->value = r_num_math (core->num, foo);
|
|
|
|
|
}
|
|
|
|
|
break;
|
2013-03-03 05:03:48 +01:00
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
}
|
2015-05-06 11:37:06 +02:00
|
|
|
|
r_cons_set_raw (0);
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case 'w': { // "?w"
|
2016-11-03 11:51:10 +01:00
|
|
|
|
ut64 addr = r_num_math (core->num, input + 1);
|
2018-10-01 15:33:30 +02:00
|
|
|
|
char *rstr = core->print->hasrefs (core->print->user, addr, true);
|
|
|
|
|
if (!rstr) {
|
|
|
|
|
eprintf ("Cannot get refs\n");
|
|
|
|
|
break;
|
|
|
|
|
}
|
2016-11-03 11:51:10 +01:00
|
|
|
|
r_cons_println (rstr);
|
2018-10-01 15:33:30 +02:00
|
|
|
|
free (rstr);
|
2016-09-03 14:22:31 +02:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
}
|
|
|
|
|
case 't': { // "?t"
|
2012-02-27 02:40:27 +01:00
|
|
|
|
struct r_prof_t prof;
|
|
|
|
|
r_prof_start (&prof);
|
2016-11-03 11:51:10 +01:00
|
|
|
|
r_core_cmd (core, input + 1, 0);
|
2012-02-27 02:40:27 +01:00
|
|
|
|
r_prof_end (&prof);
|
|
|
|
|
core->num->value = (ut64)(int)prof.result;
|
|
|
|
|
eprintf ("%lf\n", prof.result);
|
2017-09-19 02:42:47 -07:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
case '?': // "??"
|
|
|
|
|
if (input[1] == '?') {
|
|
|
|
|
if (input[2] == '?') { // "???"
|
2019-09-30 23:33:27 +02:00
|
|
|
|
r_core_clippy (core, "What are you doing?");
|
2013-10-06 15:04:19 +02:00
|
|
|
|
return 0;
|
|
|
|
|
}
|
2012-12-01 00:15:19 +01:00
|
|
|
|
if (input[2]) {
|
2016-11-02 22:59:32 +01:00
|
|
|
|
if (core->num->value) {
|
|
|
|
|
r_core_cmd (core, input + 1, 0);
|
|
|
|
|
}
|
2016-03-14 22:12:54 +02:00
|
|
|
|
break;
|
2012-12-01 00:15:19 +01:00
|
|
|
|
}
|
2017-08-10 02:52:13 -07:00
|
|
|
|
r_core_cmd_help (core, help_msg_question);
|
2012-02-27 02:40:27 +01:00
|
|
|
|
return 0;
|
2014-11-07 12:16:29 +01:00
|
|
|
|
} else if (input[1]) {
|
|
|
|
|
if (core->num->value) {
|
2016-03-31 04:48:36 +02:00
|
|
|
|
core->num->value = r_core_cmd (core, input+1, 0);
|
2014-11-07 12:16:29 +01:00
|
|
|
|
}
|
|
|
|
|
} else {
|
|
|
|
|
if (core->num->dbz) {
|
|
|
|
|
eprintf ("RNum ERROR: Division by Zero\n");
|
|
|
|
|
}
|
|
|
|
|
r_cons_printf ("%"PFMT64d"\n", core->num->value);
|
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
2017-09-19 02:42:47 -07:00
|
|
|
|
case '\0': // "?"
|
2017-08-10 02:52:13 -07:00
|
|
|
|
default:
|
|
|
|
|
// TODO #7967 help refactor
|
2018-09-07 15:03:01 +02:00
|
|
|
|
r_core_cmd_help (core, help_msg_intro);
|
2017-08-10 02:52:13 -07:00
|
|
|
|
r_core_cmd_help (core, help_msg_root);
|
2012-02-27 02:40:27 +01:00
|
|
|
|
break;
|
|
|
|
|
}
|
|
|
|
|
return 0;
|
|
|
|
|
}
|