radare2/libr/core/cmd_log.c

428 lines
10 KiB
C
Raw Normal View History

/* radare - LGPL - Copyright 2009-2022 - pancake */
2016-05-03 02:52:41 +00:00
#include <string.h>
2016-05-03 02:52:41 +00:00
#include "r_config.h"
#include "r_cons.h"
#include "r_core.h"
bool rasm2_list(RCore *core, const char *arch, int fmt);
static const char *help_msg_La[] = {
"Usage:", "La[qj]", " # asm/anal plugin list",
"La", "", "List asm/anal pluginsh (See rasm2 -L)",
"Laq", "", "Only list the plugin name",
"Laj", "", "Full list, but in JSON format",
NULL
};
// TODO #7967 help refactor: move to another place
static const char *help_msg_L[] = {
"Usage:", "L[acio]", "[-name][ file]",
"L", "", "show this help",
"L", " blah."R_LIB_EXT, "load plugin file",
"L-", "duk", "unload core plugin by name",
"La", "[qj]", "list asm/anal plugins (see: aL, e asm.arch=" "??" ")",
"Lc", "", "list core plugins (see",
"Ld", "", "list debug plugins (dL)",
"LD", "", "list supported decompilers (e cmd.pdc=?)",
2021-06-04 12:43:18 +00:00
"Le", "", "list esil plugins",
"Lg", "", "list egg plugins",
"Lh", "", "list hash plugins (ph)",
"Li", "", "list bin plugins (iL)",
"Lt", "", "list color themes (eco)",
"Ll", "", "list lang plugins (#!)",
2021-06-04 12:43:18 +00:00
"LL", "", "lock screen",
"Lm", "", "list fs plugins (mL)",
"Lo", "", "list io plugins (oL)",
"Lp", "", "list parser plugins (e asm.parser=?)",
NULL
};
static const char *help_msg_T[] = {
"Usage:", "T", "[-][ num|msg]",
"T", "", "list all Text log messages",
"T", " message", "add new log message",
"T", " 123", "list log from 123",
"T", " 10 3", "list 3 log messages starting from 10",
"T*", "", "list in radare commands",
"T-", "", "delete all logs",
"T-", " 123", "delete logs before 123",
"Tl", "", "get last log message id",
"Tj", "", "list in json format",
"Tm", " [idx]", "display log messages without index",
"Ts", "", "list files in current directory (see pwd, cd)",
"TT", "", "enter into the text log chat console",
"T=", "[.]", "pull logs from remote r2 instance specified by http.sync",
"T=&", "", "start background thread syncing with the remote server",
NULL
};
static void screenlock(RCore *core) {
// char *pass = r_cons_input ("Enter new password: ");
char *pass = r_cons_password (Color_INVERT "Enter new password:"Color_INVERT_RESET);
if (!pass || !*pass) {
return;
}
char *again = r_cons_password (Color_INVERT "Type it again:"Color_INVERT_RESET);
if (!again || !*again) {
2020-01-17 04:58:29 +00:00
free (pass);
return;
}
if (strcmp (pass, again)) {
eprintf ("Password mismatch!\n");
2020-01-17 04:58:29 +00:00
free (pass);
free (again);
return;
}
bool running = true;
r_cons_clear_buffer ();
ut64 begin = r_time_now ();
ut64 last = UT64_MAX;
2020-10-21 09:27:17 +00:00
int tries = 0;
do {
r_cons_clear00 ();
r_cons_printf ("Retries: %d\n", tries);
r_cons_printf ("Locked ts: %s\n", r_time_to_string (begin));
if (last != UT64_MAX) {
r_cons_printf ("Last try: %s\n", r_time_to_string (last));
}
r_cons_newline ();
r_cons_flush ();
char *msg = r_cons_password ("radare2 password: ");
if (msg && !strcmp (msg, pass)) {
running = false;
} else {
eprintf ("\nInvalid password.\n");
last = r_time_now ();
tries++;
}
free (msg);
int n = r_num_rand (10) + 1;
r_sys_usleep (n * 100000);
} while (running);
r_cons_set_cup (true);
free (pass);
eprintf ("Unlocked!\n");
}
static int textlog_chat(RCore *core) {
char prompt[64];
char buf[1024];
int lastmsg = 0;
const char *me = r_config_get (core->config, "cfg.user");
2018-06-26 16:05:31 +00:00
char msg[2048];
eprintf ("Type '/help' for commands:\n");
snprintf (prompt, sizeof (prompt) - 1, "[%s]> ", me);
r_line_set_prompt (prompt);
for (;;) {
r_core_log_list (core, lastmsg, 0, 0);
lastmsg = core->log->last;
2020-02-29 19:47:10 +00:00
if (r_cons_fgets (buf, sizeof (buf), 0, NULL) < 0) {
return 1;
}
if (!*buf) {
continue;
}
if (!strcmp (buf, "/help")) {
eprintf ("/quit quit the chat (same as ^D)\n");
eprintf ("/name <nick> set cfg.user name\n");
eprintf ("/log show full log\n");
eprintf ("/clear clear text log messages\n");
} else if (!strncmp (buf, "/name ", 6)) {
snprintf (msg, sizeof (msg) - 1, "* '%s' is now known as '%s'", me, buf + 6);
r_core_log_add (core, msg);
r_config_set (core->config, "cfg.user", buf + 6);
me = r_config_get (core->config, "cfg.user");
snprintf (prompt, sizeof (prompt) - 1, "[%s]> ", me);
r_line_set_prompt (prompt);
return 0;
} else if (!strcmp (buf, "/log")) {
r_core_log_list (core, 0, 0, 0);
return 0;
} else if (!strcmp (buf, "/clear")) {
// r_core_log_del (core, 0);
r_core_cmd0 (core, "T-");
return 0;
} else if (!strcmp (buf, "/quit")) {
return 0;
} else if (*buf == '/') {
eprintf ("Unknown command: %s\n", buf);
} else {
2018-06-26 16:05:31 +00:00
snprintf (msg, sizeof (msg), "[%s] %s", me, buf);
r_core_log_add (core, msg);
}
}
return 1;
}
static int getIndexFromLogString(const char *s) {
int len = strlen (s);
const char *m = s + len;
int nlctr = 2;
const char *nl = NULL;
while (m > s) {
if (*m == '\n') {
nl = m;
if (--nlctr < 1) {
return atoi (m + 1);
}
}
m--;
}
return atoi (nl?nl + 1: s);
return -1;
}
static char *expr2cmd(RCoreLog *log, const char *line) {
if (!line || !*line) {
return NULL;
}
line++;
if (!strncmp (line, "add-comment", 11)) {
line += 11;
if (*line == ' ') {
char *sp = strchr (line + 1, ' ');
if (sp) {
char *msg = sp + 1;
ut64 addr = r_num_get (NULL, line);
return r_str_newf ("CCu base64:%s @ 0x%"PFMT64x"\n", msg, addr);
}
}
eprintf ("add-comment parsing error\n");
}
if (!strncmp (line, "del-comment", 11)) {
if (line[11] == ' ') {
return r_str_newf ("CC-%s\n", line + 12);
}
eprintf ("add-comment parsing error\n");
}
return NULL;
}
static int log_callback_r2(RCore *core, int count, const char *line) {
if (*line == ':') {
char *cmd = expr2cmd (core->log, line);
if (cmd) {
r_cons_printf ("%s\n", cmd);
r_core_cmd (core, cmd, 0);
free (cmd);
}
}
return 0;
}
static int log_callback_all(RCore *log, int count, const char *line) {
r_cons_printf ("%d %s\n", count, line);
return 0;
}
static int cmd_log(void *data, const char *input) {
RCore *core = (RCore *) data;
const char *arg, *input2;
2015-04-19 02:32:48 +00:00
int n, n2;
if (!input) {
2015-04-19 02:32:48 +00:00
return 1;
}
2015-04-19 02:32:48 +00:00
input2 = (input && *input)? input + 1: "";
2015-04-19 02:32:48 +00:00
arg = strchr (input2, ' ');
n = atoi (input2);
n2 = arg? atoi (arg + 1): 0;
switch (*input) {
case 'e': // "Te" shell: less
{
char *p = strchr (input, ' ');
if (p) {
char *b = r_file_slurp (p + 1, NULL);
if (b) {
r_cons_less_str (b, NULL);
free (b);
} else {
eprintf ("File not found\n");
}
} else {
eprintf ("Usage: less [filename]\n");
}
}
break;
case 'l': // "Tl"
r_cons_printf ("%d\n", core->log->last - 1);
break;
case '-': // "T-"
r_core_log_del (core, n);
break;
case '?': // "T?"
r_core_cmd_help (core, help_msg_T);
break;
case 'T': // "TT" Ts ? as ms?
if (r_cons_is_interactive ()) {
2015-02-12 16:23:30 +00:00
textlog_chat (core);
} else {
eprintf ("Only available when the screen is interactive\n");
}
break;
case '=': // "T="
if (input[1] == '&') { // "T=&"
if (input[2] == '&') { // "T=&&"
r_cons_break_push (NULL, NULL);
while (!r_cons_is_breaked ()) {
r_core_cmd0 (core, "T=");
void *bed = r_cons_sleep_begin();
r_sys_sleep (1);
r_cons_sleep_end (bed);
}
r_cons_break_pop ();
} else {
// TODO: Sucks that we can't enqueue functions, only commands
eprintf ("Background thread syncing with http.sync started.\n");
RCoreTask *task = r_core_task_new (core, true, "T=&&", NULL, core);
2019-11-26 07:52:17 +00:00
r_core_task_enqueue (&core->tasks, task);
}
} else {
if (atoi (input + 1) > 0 || (input[1] == '0')) {
core->sync_index = 0;
} else {
RCoreLogCallback log_callback = (input[1] == '*')
? log_callback_all: log_callback_r2;
char *res = r_core_log_get (core, core->sync_index);
if (res) {
int idx = getIndexFromLogString (res);
if (idx != -1) {
core->sync_index = idx + 1;
}
r_core_log_run (core, res, log_callback);
free (res);
} else {
r_cons_printf ("Please check e http.sync\n");
}
}
}
break;
case ' ': // "T "
if (n > 0 || *input == '0') {
r_core_log_list (core, n, n2, *input);
} else {
r_core_log_add (core, input + 1);
}
break;
case 'm': // "Tm"
if (n > 0) {
r_core_log_list (core, n, 1, 't');
} else {
r_core_log_list (core, n, 0, 't');
}
break;
case 'j': // "Tj"
case '*':
case '\0':
r_core_log_list (core, n, n2, *input);
break;
}
return 0;
}
static int cmd_plugins(void *data, const char *input) {
RCore *core = (RCore *) data;
switch (input[0]) {
case 0:
r_core_cmd_help (core, help_msg_L);
// return r_core_cmd0 (core, "Lc");
break;
case '-':
r_lib_close (core->lib, r_str_trim_head_ro (input + 1));
break;
case ' ':
r_lib_open (core->lib, r_str_trim_head_ro (input + 1));
break;
case '?':
r_core_cmd_help (core, help_msg_L);
break;
case 't': // "Lt"
r_core_cmd0 (core, "eco");
break;
2019-05-05 00:02:06 +00:00
case 'm': // "Lm"
r_core_cmdf (core, "mL%s", input + 1);
2019-05-05 00:02:06 +00:00
break;
case 'e': // "Le"
r_core_cmdf (core, "aeL%s", input + 1);
break;
case 'd': // "Ld"
r_core_cmdf (core, "dL%s", input + 1);
break;
case 'h': // "Lh"
r_core_cmd0 (core, "ph"); // rahash2 -L is more verbose
break;
case 'a': // "La"
if (input[1] == '?') {
r_core_cmd_help (core, help_msg_La);
} else {
// r_core_cmd0 (core, "e asm.arch=??");
rasm2_list (core, NULL, input[1]);
}
break;
case 'p': // "Lp"
r_core_cmd0 (core, "e asm.parser=?");
break;
case 'D': // "LD"
if (input[1] == ' ') {
r_core_cmdf (core, "e cmd.pdc=%s", r_str_trim_head_ro (input + 2));
} else {
r_core_cmd0 (core, "e cmd.pdc=?");
}
break;
2019-01-11 13:07:01 +00:00
case 'l': // "Ll"
r_core_cmd0 (core, "#!");
break;
case 'L': // "LL"
screenlock (core);
break;
2021-06-04 12:43:18 +00:00
case 'g': // "Lg"
r_core_cmd0 (core, "gL");
break;
case 'o': // "Lo"
case 'i': // "Li"
r_core_cmdf (core, "%cL%s", input[0], input + 1);
break;
case 'c': { // "Lc"
2018-03-09 08:01:16 +00:00
RListIter *iter;
RCorePlugin *cp;
switch (input[1]) {
case 'j': {
PJ *pj = r_core_pj_new (core);
if (!pj) {
return 1;
}
pj_a (pj);
2018-03-09 08:01:16 +00:00
r_list_foreach (core->rcmd->plist, iter, cp) {
pj_o (pj);
pj_ks (pj, "Name", cp->name);
pj_ks (pj, "Description", cp->desc);
pj_end (pj);
2018-03-09 08:01:16 +00:00
}
pj_end (pj);
r_cons_println (pj_string (pj));
pj_free (pj);
2018-03-09 08:01:16 +00:00
break;
}
case ' ':
r_lib_open (core->lib, r_str_trim_head_ro (input + 2));
break;
case 0:
r_lib_list (core->lib);
2017-11-22 14:25:34 +00:00
r_list_foreach (core->rcmd->plist, iter, cp) {
r_cons_printf ("%s: %s\n", cp->name, cp->desc);
}
break;
2018-03-09 08:01:16 +00:00
default:
r_core_cmd_help (core, help_msg_L);
break;
2018-03-09 08:01:16 +00:00
}
}
break;
}
return 0;
}