2022-03-08 12:44:29 +01:00
|
|
|
/* radare2 - LGPL - Copyright 2009-2022 - pancake */
|
2016-05-18 02:29:41 +02:00
|
|
|
|
2016-05-02 22:52:41 -04:00
|
|
|
#include "r_anal.h"
|
|
|
|
#include "r_bin.h"
|
|
|
|
#include "r_cons.h"
|
|
|
|
#include "r_core.h"
|
2018-11-14 14:54:22 +05:00
|
|
|
#include "r_util.h"
|
2016-05-02 22:52:41 -04:00
|
|
|
#include "r_types.h"
|
2022-11-19 01:05:18 +01:00
|
|
|
#include <sdb/sdb.h>
|
2014-05-05 01:00:23 +02:00
|
|
|
|
2020-04-13 19:34:15 -04:00
|
|
|
char *getcommapath(RCore *core);
|
|
|
|
|
2022-03-08 12:44:29 +01:00
|
|
|
static R_TH_LOCAL ut64 filter_offset = UT64_MAX;
|
|
|
|
static R_TH_LOCAL int filter_format = 0;
|
|
|
|
static R_TH_LOCAL size_t filter_count = 0;
|
|
|
|
static R_TH_LOCAL Sdb *fscache = NULL;
|
|
|
|
|
2017-07-26 06:09:39 -07:00
|
|
|
static const char *help_msg_C[] = {
|
|
|
|
"Usage:", "C[-LCvsdfm*?][*?] [...]", " # Metadata management",
|
2017-09-12 18:14:09 +08:00
|
|
|
"C", "", "list meta info in human friendly form",
|
2017-07-26 06:09:39 -07:00
|
|
|
"C*", "", "list meta info in r2 commands",
|
2018-12-13 14:49:59 +00:00
|
|
|
"C*.", "", "list meta info of current offset in r2 commands",
|
2017-07-26 06:09:39 -07:00
|
|
|
"C-", " [len] [[@]addr]", "delete metadata at given address range",
|
2019-07-25 13:21:56 +02:00
|
|
|
"C.", "", "list meta info of current offset in human friendly form",
|
|
|
|
"CC!", " [@addr]", "edit comment with $EDITOR",
|
2017-07-26 06:09:39 -07:00
|
|
|
"CC", "[?] [-] [comment-text] [@addr]", "add/remove comment",
|
|
|
|
"CC.", "[addr]", "show comment in current address",
|
2020-07-30 22:16:41 -06:00
|
|
|
"CCa", "[+-] [addr] [text]", "add/remove comment at given address",
|
2017-07-26 06:09:39 -07:00
|
|
|
"CCu", " [comment-text] [@addr]", "add unique comment",
|
2019-07-25 13:21:56 +02:00
|
|
|
"CF", "[sz] [fcn-sign..] [@addr]", "function signature",
|
|
|
|
"CL", "[-][*] [file:line] [addr]", "show or add 'code line' information (bininfo)",
|
|
|
|
"CS", "[-][space]", "manage meta-spaces to filter comments, etc..",
|
|
|
|
"C[Cthsdmf]", "", "list comments/types/hidden/strings/data/magic/formatted in human friendly form",
|
|
|
|
"C[Cthsdmf]*", "", "list comments/types/hidden/strings/data/magic/formatted in r2 commands",
|
2017-07-26 06:09:39 -07:00
|
|
|
"Cd", "[-] [size] [repeat] [@addr]", "hexdump data array (Cd 4 10 == dword [10])",
|
2018-08-04 11:37:42 +08:00
|
|
|
"Cd.", " [@addr]", "show size of data at current address",
|
2017-07-26 06:09:39 -07:00
|
|
|
"Cf", "[?][-] [sz] [0|cnt][fmt] [a0 a1...] [@addr]", "format memory (see pf?)",
|
2019-07-25 13:21:56 +02:00
|
|
|
"Ch", "[-] [size] [@addr]", "hide data",
|
2017-07-26 06:09:39 -07:00
|
|
|
"Cm", "[-] [sz] [fmt..] [@addr]", "magic parse (see pm?)",
|
2019-07-25 13:21:56 +02:00
|
|
|
"Cs", "[?] [-] [size] [@addr]", "add string",
|
|
|
|
"Ct", "[?] [-] [comment-text] [@addr]", "add/remove type analysis comment",
|
|
|
|
"Ct.", "[@addr]", "show comment at current or specified address",
|
2021-08-14 18:28:20 +02:00
|
|
|
"Cv", "[?][bsr]", "add comments to args",
|
2019-07-25 13:21:56 +02:00
|
|
|
"Cz", "[@addr]", "add string (see Cs?)",
|
2017-07-26 06:09:39 -07:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *help_msg_CC[] = {
|
|
|
|
"Usage:", "CC[-+!*au] [base64:..|str] @ addr", "",
|
2019-07-25 13:21:56 +02:00
|
|
|
"CC!", "", "edit comment using cfg.editor (vim, ..)",
|
|
|
|
"CC", " [text]", "append comment at current address",
|
2017-07-26 06:09:39 -07:00
|
|
|
"CC", "", "list all comments in human friendly form",
|
|
|
|
"CC*", "", "list all comments in r2 commands",
|
2019-07-25 13:21:56 +02:00
|
|
|
"CC+", " [text]", "append comment at current address",
|
2021-01-15 01:20:32 +01:00
|
|
|
"CC,", " [table-query]", "list comments in table format",
|
|
|
|
"CCF", " [file]", "show or set comment file",
|
2019-07-25 13:21:56 +02:00
|
|
|
"CC-", " @ cmt_addr", "remove comment at given address",
|
|
|
|
"CC.", "", "show comment at current offset",
|
2017-07-26 06:09:39 -07:00
|
|
|
"CCf", "", "list comments in function",
|
2019-06-23 01:15:43 +02:00
|
|
|
"CCf-", "", "delete all comments in current function",
|
2017-07-26 06:09:39 -07:00
|
|
|
"CCu", " base64:AA== @ addr", "add comment in base64",
|
2019-07-25 13:21:56 +02:00
|
|
|
"CCu", " good boy @ addr", "add good boy comment at given address",
|
2017-07-26 06:09:39 -07:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2022-03-08 13:55:55 +01:00
|
|
|
// IMHO 'code-line' should be universal concept, instead of dbginfo/dwarf/...
|
|
|
|
static const char *help_msg_CL[] = {
|
|
|
|
"Usage: CL", ".j-", "@addr - manage code-line references (loaded via bin.dbginfo and shown when asm.dwarf)",
|
|
|
|
"CL", "", "list all code line information (virtual address <-> source file:line)",
|
2022-04-11 14:39:41 +05:30
|
|
|
"CLj", "", "same as above but in JSON format (See dir.source to change the path to find the referenced lines)",
|
|
|
|
"CL*", "", "same as above but in r2 commands format",
|
|
|
|
"CL.", "", "show list all code line information (virtual address <-> source file:line)",
|
|
|
|
"CL-", "*", "remove all the cached codeline information",
|
|
|
|
"CL", " addr file:line", "register new file:line source details, r2 will slurp the line",
|
|
|
|
"CL", " addr base64:text", "register new source details for given address using base64",
|
2022-03-08 13:55:55 +01:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2018-09-10 01:27:47 -07:00
|
|
|
static const char *help_msg_Ct[] = {
|
|
|
|
"Usage: Ct", "[.|-] [@ addr]", " # Manage comments for variable types",
|
|
|
|
"Ct", "", "list all variable type comments",
|
|
|
|
"Ct", " comment-text [@ addr]", "place comment at current or specified address",
|
|
|
|
"Ct.", " [@ addr]", "show comment at current or specified address",
|
|
|
|
"Ct-", " [@ addr]", "remove comment at current or specified address",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2017-07-26 06:09:39 -07:00
|
|
|
static const char *help_msg_CS[] = {
|
|
|
|
"Usage: CS","[*] [+-][metaspace|addr]", " # Manage metaspaces",
|
|
|
|
"CS","","display metaspaces",
|
|
|
|
"CS"," *","select all metaspaces",
|
|
|
|
"CS"," metaspace","select metaspace or create if it doesn't exist",
|
|
|
|
"CS","-metaspace","remove metaspace",
|
|
|
|
"CS","-*","remove all metaspaces",
|
|
|
|
"CS","+foo","push previous metaspace and set",
|
|
|
|
"CS","-","pop to the previous metaspace",
|
|
|
|
// "CSm"," [addr]","move metas at given address to the current metaspace",
|
|
|
|
"CSr"," newname","rename selected metaspace",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2017-10-04 18:49:37 +08:00
|
|
|
static const char *help_msg_Cs[] = {
|
2017-10-12 06:17:51 +08:00
|
|
|
"Usage:", "Cs[ga-*.] [size] [@addr]", "",
|
2017-10-18 07:27:31 +08:00
|
|
|
"NOTE:", " size", "1 unit in bytes == width in bytes of smallest possible char in encoding,",
|
2017-11-17 22:44:08 +08:00
|
|
|
"", "", " so ascii/latin1/utf8 = 1, utf16le = 2",
|
2019-07-25 13:21:56 +02:00
|
|
|
" Cz", " [size] [@addr]", "ditto",
|
|
|
|
"Cs", " [size] @addr", "add string (guess latin1/utf16le)",
|
2017-10-04 18:49:37 +08:00
|
|
|
"Cs", "", "list all strings in human friendly form",
|
|
|
|
"Cs*", "", "list all strings in r2 commands",
|
|
|
|
"Cs-", " [@addr]", "remove string",
|
2017-10-12 06:17:51 +08:00
|
|
|
"Cs.", "", "show string at current address",
|
2017-10-16 05:29:43 +08:00
|
|
|
"Cs..", "", "show string + info about it at current address",
|
2019-07-25 13:21:56 +02:00
|
|
|
"Cs.j", "", "show string at current address in JSON",
|
|
|
|
"Cs8", " [size] [@addr]", "add utf8 string",
|
|
|
|
"Csa", " [size] [@addr]", "add ascii/latin1 string",
|
|
|
|
"Csg", " [size] [@addr]", "as above but addr not needed",
|
2017-10-04 18:49:37 +08:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2017-07-26 06:09:39 -07:00
|
|
|
static const char *help_msg_Cvb[] = {
|
|
|
|
"Usage:", "Cvb", "[name] [comment]",
|
|
|
|
"Cvb?", "", "show this help",
|
|
|
|
"Cvb", "", "list all base pointer args/vars comments in human friendly format",
|
|
|
|
"Cvb*", "", "list all base pointer args/vars comments in r2 format",
|
|
|
|
"Cvb-", "[name]", "delete comments for var/arg at current offset for base pointer",
|
2022-04-11 14:39:41 +05:30
|
|
|
"Cvb", " [name]", "show comments for var/arg at current offset for base pointer",
|
2017-07-26 06:09:39 -07:00
|
|
|
"Cvb", " [name] [comment]", "add/append comment for the variable with the current name",
|
|
|
|
"Cvb!", "[name]", "edit comment using cfg editor",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *help_msg_Cvr[] = {
|
|
|
|
"Usage:", "Cvr", "[name] [comment]",
|
|
|
|
"Cvr?", "", "show this help",
|
|
|
|
"Cvr", "", "list all register based args comments in human friendly format",
|
|
|
|
"Cvr*", "", "list all register based args comments in r2 format",
|
|
|
|
"Cvr-", "[name]", "delete comments for register based arg for that name",
|
2022-04-11 14:39:41 +05:30
|
|
|
"Cvr", "[name]", "show comments for register based arg for that name",
|
2017-07-26 06:09:39 -07:00
|
|
|
"Cvr", "[name] [comment]", "add/append comment for the variable",
|
|
|
|
"Cvr!", "[name]", "edit comment using cfg editor",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
|
|
|
static const char *help_msg_Cvs[] = {
|
|
|
|
"Usage:", "Cvs", "[name] [comment]",
|
2019-07-25 13:21:56 +02:00
|
|
|
"Cvs!", "[name]", "edit comment using cfg editor",
|
2017-07-26 06:09:39 -07:00
|
|
|
"Cvs", "", "list all stack based args/vars comments in human friendly format",
|
2019-07-25 13:21:56 +02:00
|
|
|
"Cvs", "[name] [comment]", "add/append comment for the variable",
|
2022-04-11 14:39:41 +05:30
|
|
|
"Cvs", "[name]", "show comments for stack pointer var/arg with that name",
|
2017-07-26 06:09:39 -07:00
|
|
|
"Cvs*", "", "list all stack based args/vars comments in r2 format",
|
|
|
|
"Cvs-", "[name]", "delete comments for stack pointer var/arg with that name",
|
2019-07-25 13:21:56 +02:00
|
|
|
"Cvs?", "", "show this help",
|
2017-07-26 06:09:39 -07:00
|
|
|
NULL
|
|
|
|
};
|
|
|
|
|
2014-05-05 01:00:23 +02:00
|
|
|
static int remove_meta_offset(RCore *core, ut64 offset) {
|
2022-09-18 19:22:37 +02:00
|
|
|
char aoffset[SDB_NUM_BUFSZ];
|
|
|
|
char *aoffsetptr = sdb_itoa (offset, 16, aoffset, sizeof (aoffset));
|
2014-05-05 01:00:23 +02:00
|
|
|
if (!aoffsetptr) {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("Failed to convert %"PFMT64x" to a key", offset);
|
2014-05-05 01:00:23 +02:00
|
|
|
return -1;
|
|
|
|
}
|
2015-11-18 17:02:42 +01:00
|
|
|
return sdb_unset (core->bin->cur->sdb_addrinfo, aoffsetptr, 0);
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
|
2021-04-04 18:54:24 +02:00
|
|
|
static bool print_meta_offset(RCore *core, ut64 addr, PJ *pj) {
|
2019-06-10 02:27:11 +02:00
|
|
|
int line, line_old, i;
|
2014-05-05 01:00:23 +02:00
|
|
|
char file[1024];
|
|
|
|
|
2019-06-10 02:27:11 +02:00
|
|
|
int ret = r_bin_addr2line (core->bin, addr, file, sizeof (file) - 1, &line);
|
2014-05-05 01:00:23 +02:00
|
|
|
if (ret) {
|
2021-04-04 18:54:24 +02:00
|
|
|
if (pj) {
|
|
|
|
pj_o (pj);
|
|
|
|
pj_ks (pj, "file", file);
|
|
|
|
pj_kn (pj, "line", line);
|
|
|
|
pj_kn (pj, "addr", addr);
|
|
|
|
if (r_file_exists (file)) {
|
|
|
|
char *row = r_file_slurp_line (file, line, 0);
|
|
|
|
pj_ks (pj, "text", file);
|
|
|
|
free (row);
|
|
|
|
} else {
|
|
|
|
// eprintf ("Cannot open '%s'\n", file);
|
|
|
|
}
|
|
|
|
pj_end (pj);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
r_cons_printf ("file: %s\nline: %d\naddr: 0x%08"PFMT64x"\n", file, line, addr);
|
2014-05-05 01:00:23 +02:00
|
|
|
line_old = line;
|
2017-01-11 12:23:48 +01:00
|
|
|
if (line >= 2) {
|
2014-05-05 01:00:23 +02:00
|
|
|
line -= 2;
|
2017-01-11 12:23:48 +01:00
|
|
|
}
|
2014-12-10 23:21:55 +01:00
|
|
|
if (r_file_exists (file)) {
|
2016-12-14 16:09:45 +01:00
|
|
|
for (i = 0; i < 5; i++) {
|
|
|
|
char *row = r_file_slurp_line (file, line + i, 0);
|
2014-12-10 23:21:55 +01:00
|
|
|
if (row) {
|
|
|
|
r_cons_printf ("%c %.3x %s\n", line+i == line_old ? '>' : ' ', line+i, row);
|
|
|
|
free (row);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
} else {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("Cannot open '%s'", file);
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
}
|
2019-06-10 02:27:11 +02:00
|
|
|
return ret;
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
|
2019-06-21 11:39:59 +02:00
|
|
|
#if 0
|
2014-05-05 01:00:23 +02:00
|
|
|
static int remove_meta_fileline(RCore *core, const char *file_line) {
|
2015-11-18 17:02:42 +01:00
|
|
|
return sdb_unset (core->bin->cur->sdb_addrinfo, file_line, 0);
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
static int print_meta_fileline(RCore *core, const char *file_line) {
|
2016-02-16 02:42:44 +01:00
|
|
|
char *meta_info = sdb_get (core->bin->cur->sdb_addrinfo, file_line, 0);
|
2014-05-05 01:00:23 +02:00
|
|
|
if (meta_info) {
|
2016-02-16 02:42:44 +01:00
|
|
|
r_cons_printf ("Meta info %s\n", meta_info);
|
2014-05-05 01:00:23 +02:00
|
|
|
} else {
|
2016-02-16 02:42:44 +01:00
|
|
|
r_cons_printf ("No meta info for %s found\n", file_line);
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
2019-06-21 11:39:59 +02:00
|
|
|
#endif
|
2014-05-05 01:00:23 +02:00
|
|
|
|
2021-04-04 18:54:24 +02:00
|
|
|
static bool print_addrinfo_json(void *user, const char *k, const char *v) {
|
|
|
|
ut64 offset = sdb_atoi (k);
|
|
|
|
if (!offset || offset == UT64_MAX) {
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
char *subst = strdup (v);
|
|
|
|
char *colonpos = strchr (subst, '|'); // XXX keep only : for simplicity?
|
|
|
|
if (!colonpos) {
|
|
|
|
colonpos = strchr (subst, ':');
|
|
|
|
}
|
|
|
|
if (!colonpos) {
|
|
|
|
r_cons_printf ("%s\n", subst);
|
|
|
|
}
|
|
|
|
if (colonpos && (filter_offset == UT64_MAX || filter_offset == offset)) {
|
|
|
|
if (filter_format) {
|
|
|
|
*colonpos = ':';
|
|
|
|
// r_cons_printf ("CL %s %s\n", k, subst);
|
|
|
|
} else {
|
|
|
|
*colonpos = 0;
|
|
|
|
// r_cons_printf ("file: %s\nline: %s\naddr: 0x%08"PFMT64x"\n", subst, colonpos + 1, offset);
|
|
|
|
}
|
|
|
|
filter_count++;
|
|
|
|
}
|
|
|
|
const char *file = subst;
|
|
|
|
int line = atoi (colonpos + 1);
|
|
|
|
ut64 addr = offset;
|
|
|
|
PJ *pj = (PJ*)user;
|
2022-03-08 12:44:29 +01:00
|
|
|
if (pj) {
|
|
|
|
pj_o (pj);
|
|
|
|
pj_ks (pj, "file", file);
|
|
|
|
pj_kn (pj, "line", line);
|
|
|
|
pj_kn (pj, "addr", addr);
|
|
|
|
const char *cached_existance = sdb_const_get (fscache, file, NULL);
|
|
|
|
bool file_exists = false;
|
|
|
|
if (cached_existance) {
|
2022-08-22 23:25:40 +02:00
|
|
|
file_exists = !strcmp (cached_existance, "1");
|
2022-03-08 12:44:29 +01:00
|
|
|
} else {
|
|
|
|
if (r_file_exists (file)) {
|
|
|
|
sdb_set (fscache, file, "1", 0);
|
|
|
|
} else {
|
|
|
|
sdb_set (fscache, file, "0", 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if (file_exists) {
|
|
|
|
char *row = r_file_slurp_line (file, line, 0);
|
|
|
|
pj_ks (pj, "text", file);
|
|
|
|
free (row);
|
|
|
|
}
|
|
|
|
pj_end (pj);
|
2021-04-04 18:54:24 +02:00
|
|
|
}
|
|
|
|
free (subst);
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
|
|
|
static bool print_addrinfo(void *user, const char *k, const char *v) {
|
2016-12-22 12:49:33 +01:00
|
|
|
ut64 offset = sdb_atoi (k);
|
2019-06-10 02:27:11 +02:00
|
|
|
if (!offset || offset == UT64_MAX) {
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2016-11-06 01:16:02 +01:00
|
|
|
}
|
2019-06-10 02:27:11 +02:00
|
|
|
char *subst = strdup (v);
|
|
|
|
char *colonpos = strchr (subst, '|'); // XXX keep only : for simplicity?
|
|
|
|
if (!colonpos) {
|
|
|
|
colonpos = strchr (subst, ':');
|
|
|
|
}
|
|
|
|
if (!colonpos) {
|
|
|
|
r_cons_printf ("%s\n", subst);
|
|
|
|
}
|
2019-06-14 10:57:21 +02:00
|
|
|
if (colonpos && (filter_offset == UT64_MAX || filter_offset == offset)) {
|
2019-06-10 02:27:11 +02:00
|
|
|
if (filter_format) {
|
|
|
|
*colonpos = ':';
|
|
|
|
r_cons_printf ("CL %s %s\n", k, subst);
|
|
|
|
} else {
|
|
|
|
*colonpos = 0;
|
2021-04-04 18:54:24 +02:00
|
|
|
r_cons_printf ("file: %s\nline: %s\naddr: 0x%08"PFMT64x"\n", subst, colonpos + 1, offset);
|
2019-06-10 02:27:11 +02:00
|
|
|
}
|
|
|
|
filter_count++;
|
2016-11-06 01:16:02 +01:00
|
|
|
}
|
2014-05-05 01:00:23 +02:00
|
|
|
free (subst);
|
|
|
|
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
|
2014-05-05 19:27:25 +04:00
|
|
|
static int cmd_meta_add_fileline(Sdb *s, char *fileline, ut64 offset) {
|
2022-09-18 19:22:37 +02:00
|
|
|
char aoffset[SDB_NUM_BUFSZ];
|
|
|
|
char *aoffsetptr = sdb_itoa (offset, 16, aoffset, sizeof (aoffset));
|
2016-11-06 01:16:02 +01:00
|
|
|
if (!aoffsetptr) {
|
2014-05-05 19:27:25 +04:00
|
|
|
return -1;
|
2016-11-06 01:16:02 +01:00
|
|
|
}
|
2014-05-05 19:27:25 +04:00
|
|
|
if (!sdb_add (s, aoffsetptr, fileline, 0)) {
|
|
|
|
sdb_set (s, aoffsetptr, fileline, 0);
|
|
|
|
}
|
|
|
|
if (!sdb_add (s, fileline, aoffsetptr, 0)) {
|
|
|
|
sdb_set (s, fileline, aoffsetptr, 0);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int cmd_meta_lineinfo(RCore *core, const char *input) {
|
2014-05-05 01:00:23 +02:00
|
|
|
int ret;
|
2014-06-25 04:19:23 +02:00
|
|
|
ut64 offset = UT64_MAX; // use this as error value
|
2019-06-10 02:27:11 +02:00
|
|
|
bool remove = false;
|
2021-04-04 18:54:24 +02:00
|
|
|
bool use_json = false;
|
2015-09-14 12:35:38 +02:00
|
|
|
int all = false;
|
2014-05-05 01:00:23 +02:00
|
|
|
const char *p = input;
|
2019-06-10 02:27:11 +02:00
|
|
|
char *file_line = NULL;
|
2014-05-05 01:00:23 +02:00
|
|
|
|
|
|
|
if (*p == '?') {
|
2022-03-08 13:55:55 +01:00
|
|
|
r_core_cmd_help (core, help_msg_CL);
|
2014-05-05 01:00:23 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
if (*p == '-') {
|
|
|
|
p++;
|
2015-09-14 12:35:38 +02:00
|
|
|
remove = true;
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
2021-04-04 18:54:24 +02:00
|
|
|
if (*p == 'j') {
|
|
|
|
p++;
|
|
|
|
use_json = true;
|
|
|
|
}
|
2019-06-10 02:27:11 +02:00
|
|
|
if (*p == '.') {
|
|
|
|
p++;
|
|
|
|
offset = core->offset;
|
|
|
|
}
|
|
|
|
if (*p == ' ') {
|
2020-03-02 21:39:37 +01:00
|
|
|
p = r_str_trim_head_ro (p + 1);
|
2019-06-16 20:49:45 +02:00
|
|
|
char *arg = strchr (p, ' ');
|
|
|
|
if (!arg) {
|
2019-06-10 02:27:11 +02:00
|
|
|
offset = r_num_math (core->num, p);
|
|
|
|
p = "";
|
|
|
|
}
|
2019-06-16 20:49:45 +02:00
|
|
|
} else if (*p == '*') {
|
2014-05-05 01:00:23 +02:00
|
|
|
p++;
|
2015-09-14 12:35:38 +02:00
|
|
|
all = true;
|
2019-06-10 02:27:11 +02:00
|
|
|
filter_format = '*';
|
|
|
|
} else {
|
|
|
|
filter_format = 0;
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
if (all) {
|
|
|
|
if (remove) {
|
|
|
|
sdb_reset (core->bin->cur->sdb_addrinfo);
|
|
|
|
} else {
|
|
|
|
sdb_foreach (core->bin->cur->sdb_addrinfo, print_addrinfo, NULL);
|
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2020-03-02 21:39:37 +01:00
|
|
|
p = r_str_trim_head_ro (p);
|
2019-06-10 02:27:11 +02:00
|
|
|
char *myp = strdup (p);
|
|
|
|
char *sp = strchr (myp, ' ');
|
|
|
|
if (sp) {
|
|
|
|
*sp = 0;
|
|
|
|
sp++;
|
2019-06-16 20:49:45 +02:00
|
|
|
if (offset == UT64_MAX) {
|
|
|
|
offset = r_num_math (core->num, myp);
|
|
|
|
}
|
|
|
|
|
2022-03-08 13:55:55 +01:00
|
|
|
char *pheap = NULL;
|
2019-06-16 20:49:45 +02:00
|
|
|
if (!strncmp (sp, "base64:", 7)) {
|
|
|
|
int len = 0;
|
|
|
|
ut8 *o = sdb_decode (sp + 7, &len);
|
|
|
|
if (!o) {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("Invalid base64");
|
2019-06-16 20:49:45 +02:00
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
sp = pheap = (char *)o;
|
|
|
|
}
|
2019-06-10 02:27:11 +02:00
|
|
|
RBinFile *bf = r_bin_cur (core->bin);
|
|
|
|
ret = 0;
|
|
|
|
if (bf && bf->sdb_addrinfo) {
|
2019-06-16 20:49:45 +02:00
|
|
|
ret = cmd_meta_add_fileline (bf->sdb_addrinfo, sp, offset);
|
2014-12-11 19:27:51 +01:00
|
|
|
} else {
|
2022-09-16 17:08:13 +03:00
|
|
|
R_LOG_TODO ("Support global SdbAddrinfo or dummy rbinfile to handlee this case");
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
2014-12-11 19:27:51 +01:00
|
|
|
free (file_line);
|
2019-06-10 02:27:11 +02:00
|
|
|
free (myp);
|
2019-06-16 20:49:45 +02:00
|
|
|
free (pheap);
|
2019-06-10 02:27:11 +02:00
|
|
|
return ret;
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
2019-06-10 02:27:11 +02:00
|
|
|
free (myp);
|
|
|
|
if (remove) {
|
|
|
|
remove_meta_offset (core, offset);
|
|
|
|
} else {
|
|
|
|
// taken from r2 // TODO: we should move this addrinfo sdb logic into RBin.. use HT
|
|
|
|
filter_offset = offset;
|
|
|
|
filter_count = 0;
|
2022-03-08 12:44:29 +01:00
|
|
|
fscache = sdb_new0 ();
|
|
|
|
PJ *pj = NULL;
|
2021-04-04 18:54:24 +02:00
|
|
|
if (use_json) {
|
2022-03-08 12:44:29 +01:00
|
|
|
pj = r_core_pj_new (core);
|
2021-04-04 18:54:24 +02:00
|
|
|
pj_a (pj);
|
2022-04-18 22:07:29 +02:00
|
|
|
if (core->bin->cur && core->bin->cur->sdb_addrinfo) {
|
|
|
|
sdb_foreach (core->bin->cur->sdb_addrinfo, print_addrinfo_json, pj);
|
|
|
|
}
|
2022-03-08 12:44:29 +01:00
|
|
|
} else {
|
2022-04-18 22:07:29 +02:00
|
|
|
if (core->bin->cur && core->bin->cur->sdb_addrinfo) {
|
|
|
|
sdb_foreach (core->bin->cur->sdb_addrinfo, print_addrinfo, NULL);
|
|
|
|
}
|
2022-03-08 12:44:29 +01:00
|
|
|
}
|
|
|
|
if (filter_count == 0) {
|
|
|
|
print_meta_offset (core, offset, pj);
|
|
|
|
}
|
|
|
|
if (use_json) {
|
2021-04-04 18:54:24 +02:00
|
|
|
pj_end (pj);
|
|
|
|
char *s = pj_drain (pj);
|
2022-03-08 13:55:55 +01:00
|
|
|
if (s) {
|
|
|
|
r_cons_printf ("%s\n", s);
|
|
|
|
free (s);
|
|
|
|
}
|
2014-05-14 06:34:54 +04:00
|
|
|
}
|
2022-03-08 12:44:29 +01:00
|
|
|
sdb_free (fscache);
|
2014-05-05 01:00:23 +02:00
|
|
|
}
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2018-07-23 18:14:03 +02:00
|
|
|
static int cmd_meta_comment(RCore *core, const char *input) {
|
2014-05-06 14:56:49 +04:00
|
|
|
ut64 addr = core->offset;
|
2014-08-06 19:11:51 +02:00
|
|
|
switch (input[1]) {
|
2017-07-26 06:09:39 -07:00
|
|
|
case '?':
|
2018-07-23 18:14:03 +02:00
|
|
|
r_core_cmd_help (core, help_msg_CC);
|
2017-07-26 06:09:39 -07:00
|
|
|
break;
|
2015-11-18 17:02:42 +01:00
|
|
|
case ',': // "CC,"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_COMMENT, ',', input + 2);
|
|
|
|
break;
|
|
|
|
case 'F': // "CC,"
|
2015-11-18 17:02:42 +01:00
|
|
|
if (input[2]=='?') {
|
2021-01-15 01:20:32 +01:00
|
|
|
eprintf ("Usage: CCF [file]\n");
|
2017-01-11 22:47:45 +01:00
|
|
|
} else if (input[2] == ' ') {
|
2021-10-19 12:06:46 +02:00
|
|
|
const char *fn = input + 2;
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
|
2022-07-31 04:20:31 +02:00
|
|
|
fn = r_str_trim_head_ro (fn);
|
2015-11-18 17:02:42 +01:00
|
|
|
if (comment && *comment) {
|
|
|
|
// append filename in current comment
|
|
|
|
char *nc = r_str_newf ("%s ,(%s)", comment, fn);
|
2018-07-23 18:14:03 +02:00
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
|
2015-11-18 17:02:42 +01:00
|
|
|
free (nc);
|
|
|
|
} else {
|
2020-05-09 20:49:28 +02:00
|
|
|
char *newcomment = r_str_newf (",(%s)", fn);
|
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment);
|
|
|
|
free (newcomment);
|
2015-11-18 17:02:42 +01:00
|
|
|
}
|
|
|
|
} else {
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
|
2015-11-18 17:02:42 +01:00
|
|
|
if (comment && *comment) {
|
|
|
|
char *cmtfile = r_str_between (comment, ",(", ")");
|
|
|
|
if (cmtfile && *cmtfile) {
|
|
|
|
char *cwd = getcommapath (core);
|
|
|
|
r_cons_printf ("%s"R_SYS_DIR"%s\n", cwd, cmtfile);
|
|
|
|
free (cwd);
|
|
|
|
}
|
|
|
|
free (cmtfile);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2015-06-01 00:48:57 +02:00
|
|
|
case '.':
|
2015-06-01 00:55:18 +02:00
|
|
|
{
|
2017-03-28 13:07:52 +02:00
|
|
|
ut64 at = input[2]? r_num_math (core->num, input + 2): addr;
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, at);
|
2015-06-01 00:55:18 +02:00
|
|
|
if (comment) {
|
2016-06-26 00:51:17 -04:00
|
|
|
r_cons_println (comment);
|
2015-06-01 00:55:18 +02:00
|
|
|
}
|
|
|
|
}
|
2015-06-01 00:48:57 +02:00
|
|
|
break;
|
2016-11-20 11:20:20 +01:00
|
|
|
case 0: // "CC"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_COMMENT, 0, NULL);
|
2015-06-01 00:48:57 +02:00
|
|
|
break;
|
2016-11-20 11:20:20 +01:00
|
|
|
case 'f': // "CCf"
|
2017-09-07 13:24:13 +02:00
|
|
|
switch (input[2]) {
|
2019-06-23 01:15:43 +02:00
|
|
|
case '-': // "CCf-"
|
|
|
|
{
|
|
|
|
ut64 arg = r_num_math (core->num, input + 2);
|
|
|
|
if (!arg) {
|
|
|
|
arg = core->offset;
|
|
|
|
}
|
|
|
|
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, arg, 0);
|
|
|
|
if (fcn) {
|
|
|
|
RAnalBlock *bb;
|
|
|
|
RListIter *iter;
|
|
|
|
r_list_foreach (fcn->bbs, iter, bb) {
|
|
|
|
int i;
|
|
|
|
for (i = 0; i < bb->size; i++) {
|
|
|
|
ut64 addr = bb->addr + i;
|
|
|
|
r_meta_del (core->anal, R_META_TYPE_COMMENT, addr, 1);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2021-01-15 01:20:32 +01:00
|
|
|
case ',': // "CCf,"
|
|
|
|
r_meta_print_list_in_function (core->anal, R_META_TYPE_COMMENT, ',', core->offset, input + 3);
|
|
|
|
break;
|
2017-09-07 13:24:13 +02:00
|
|
|
case 'j': // "CCfj"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_in_function (core->anal, R_META_TYPE_COMMENT, 'j', core->offset, NULL);
|
2017-09-07 13:24:13 +02:00
|
|
|
break;
|
2018-11-08 15:06:30 +01:00
|
|
|
case '*': // "CCf*"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_in_function (core->anal, R_META_TYPE_COMMENT, 1, core->offset, NULL);
|
2018-11-08 15:06:30 +01:00
|
|
|
break;
|
2017-09-07 13:24:13 +02:00
|
|
|
default:
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_in_function (core->anal, R_META_TYPE_COMMENT, 0, core->offset, NULL);
|
2017-09-07 13:24:13 +02:00
|
|
|
break;
|
|
|
|
}
|
2016-11-06 01:40:51 +01:00
|
|
|
break;
|
2016-11-20 11:20:20 +01:00
|
|
|
case 'j': // "CCj"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_COMMENT, 'j', input + 2);
|
2015-10-08 23:13:24 +02:00
|
|
|
break;
|
2014-09-15 10:18:00 +02:00
|
|
|
case '!':
|
|
|
|
{
|
2020-05-09 20:49:28 +02:00
|
|
|
char *out;
|
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
|
2014-12-19 03:17:28 +01:00
|
|
|
out = r_core_editor (core, NULL, comment);
|
2014-09-15 10:18:00 +02:00
|
|
|
if (out) {
|
2020-05-09 20:49:28 +02:00
|
|
|
//r_meta_set (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
|
2018-07-23 18:14:03 +02:00
|
|
|
r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
|
2017-10-30 23:01:46 +08:00
|
|
|
//r_meta_del (core->anal->meta, input[0], addr, addr+1);
|
2014-09-15 10:18:00 +02:00
|
|
|
r_meta_set_string (core->anal,
|
2018-07-23 18:14:03 +02:00
|
|
|
R_META_TYPE_COMMENT, addr, out);
|
2014-09-15 10:18:00 +02:00
|
|
|
free (out);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2014-08-06 19:11:51 +02:00
|
|
|
case '+':
|
|
|
|
case ' ':
|
|
|
|
{
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *newcomment = r_str_trim_head_ro (input + 2);
|
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
|
|
|
|
char *text;
|
2016-05-17 10:36:33 +02:00
|
|
|
char *nc = strdup (newcomment);
|
2015-06-02 00:27:26 +02:00
|
|
|
r_str_unescape (nc);
|
2014-05-06 14:56:49 +04:00
|
|
|
if (comment) {
|
2020-05-09 20:49:28 +02:00
|
|
|
text = malloc (strlen (comment) + strlen (newcomment) + 2);
|
2015-12-24 15:30:25 +01:00
|
|
|
if (text) {
|
|
|
|
strcpy (text, comment);
|
2016-12-27 15:40:02 +01:00
|
|
|
strcat (text, " ");
|
2015-12-24 15:30:25 +01:00
|
|
|
strcat (text, nc);
|
2018-07-23 18:14:03 +02:00
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, text);
|
2015-12-24 15:30:25 +01:00
|
|
|
free (text);
|
2016-05-17 10:36:33 +02:00
|
|
|
} else {
|
|
|
|
r_sys_perror ("malloc");
|
|
|
|
}
|
2014-05-06 14:56:49 +04:00
|
|
|
} else {
|
2018-07-23 18:14:03 +02:00
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, nc);
|
2022-07-31 04:20:31 +02:00
|
|
|
if (r_config_get_b (core->config, "cmd.undo")) {
|
|
|
|
char *a = r_str_newf ("CC-0x%08"PFMT64x, addr);
|
|
|
|
char *b = r_str_newf ("CC %s@0x%08"PFMT64x, nc, addr);
|
|
|
|
RCoreUndo *uc = r_core_undo_new (core->offset, b, a);
|
|
|
|
r_core_undo_push (core, uc);
|
|
|
|
free (a);
|
|
|
|
free (b);
|
|
|
|
}
|
2014-05-06 14:56:49 +04:00
|
|
|
}
|
2015-06-02 00:27:26 +02:00
|
|
|
free (nc);
|
2014-08-06 19:11:51 +02:00
|
|
|
}
|
|
|
|
break;
|
2019-06-23 01:15:43 +02:00
|
|
|
case '*': // "CC*"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_COMMENT, 1, NULL);
|
2014-08-06 19:11:51 +02:00
|
|
|
break;
|
2015-12-24 15:30:25 +01:00
|
|
|
case '-': // "CC-"
|
2019-06-23 01:15:43 +02:00
|
|
|
if (input[2] == '*') { // "CC-*"
|
|
|
|
r_meta_del (core->anal, R_META_TYPE_COMMENT, UT64_MAX, UT64_MAX);
|
|
|
|
} else if (input[2]) { // "CC-$$+32"
|
|
|
|
ut64 arg = r_num_math (core->num, input + 2);
|
|
|
|
r_meta_del (core->anal, R_META_TYPE_COMMENT, arg, 1);
|
|
|
|
} else { // "CC-"
|
|
|
|
r_meta_del (core->anal, R_META_TYPE_COMMENT, core->offset, 1);
|
|
|
|
}
|
2014-08-06 19:11:51 +02:00
|
|
|
break;
|
2019-06-23 01:15:43 +02:00
|
|
|
case 'u': // "CCu"
|
2014-08-06 19:11:51 +02:00
|
|
|
//
|
|
|
|
{
|
2015-06-01 00:48:57 +02:00
|
|
|
char *newcomment;
|
2015-12-24 15:30:25 +01:00
|
|
|
const char *arg = input + 2;
|
2015-06-01 00:48:57 +02:00
|
|
|
while (*arg && *arg == ' ') arg++;
|
|
|
|
if (!strncmp (arg, "base64:", 7)) {
|
2017-12-30 05:18:35 +01:00
|
|
|
char *s = (char *)sdb_decode (arg + 7, NULL);
|
2015-06-01 00:48:57 +02:00
|
|
|
if (s) {
|
|
|
|
newcomment = s;
|
|
|
|
} else {
|
|
|
|
newcomment = NULL;
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
newcomment = strdup (arg);
|
|
|
|
}
|
|
|
|
if (newcomment) {
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
|
2015-06-01 00:48:57 +02:00
|
|
|
if (!comment || (comment && !strstr (comment, newcomment))) {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, newcomment);
|
2015-06-01 00:48:57 +02:00
|
|
|
}
|
|
|
|
free (newcomment);
|
2014-08-06 19:11:51 +02:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2019-06-23 01:15:43 +02:00
|
|
|
case 'a': // "CCa"
|
2014-08-06 19:11:51 +02:00
|
|
|
{
|
2014-05-06 14:56:49 +04:00
|
|
|
char *s, *p;
|
|
|
|
s = strchr (input, ' ');
|
|
|
|
if (s) {
|
2016-10-27 23:51:22 +02:00
|
|
|
s = strdup (s + 1);
|
2014-05-06 14:56:49 +04:00
|
|
|
} else {
|
2022-09-10 02:03:36 +02:00
|
|
|
eprintf ("Usage: CCa [address] [comment]\n");
|
|
|
|
eprintf ("Usage: CCa-[address]\n");
|
2015-09-14 12:35:38 +02:00
|
|
|
return false;
|
2014-05-06 14:56:49 +04:00
|
|
|
}
|
|
|
|
p = strchr (s, ' ');
|
2016-10-27 23:51:22 +02:00
|
|
|
if (p) {
|
|
|
|
*p++ = 0;
|
|
|
|
}
|
2014-05-06 14:56:49 +04:00
|
|
|
ut64 addr;
|
2022-09-10 02:03:36 +02:00
|
|
|
if (input[2] == '-') {
|
2014-05-06 14:56:49 +04:00
|
|
|
if (input[3]) {
|
|
|
|
addr = r_num_math (core->num, input+3);
|
|
|
|
r_meta_del (core->anal,
|
2018-07-23 18:14:03 +02:00
|
|
|
R_META_TYPE_COMMENT,
|
2017-10-30 23:01:46 +08:00
|
|
|
addr, 1);
|
2022-09-10 02:03:36 +02:00
|
|
|
} else {
|
|
|
|
eprintf ("Usage: CCa-[address]\n");
|
|
|
|
}
|
2014-05-06 14:56:49 +04:00
|
|
|
free (s);
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2014-05-06 14:56:49 +04:00
|
|
|
}
|
|
|
|
addr = r_num_math (core->num, s);
|
|
|
|
// Comment at
|
|
|
|
if (p) {
|
|
|
|
if (input[2]=='+') {
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
|
2014-05-06 14:56:49 +04:00
|
|
|
if (comment) {
|
2020-05-09 20:49:28 +02:00
|
|
|
char *text = r_str_newf ("%s\n%s", comment, p);
|
|
|
|
r_meta_set (core->anal, R_META_TYPE_COMMENT, addr, 1, text);
|
2014-05-06 14:56:49 +04:00
|
|
|
free (text);
|
|
|
|
} else {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_set (core->anal, R_META_TYPE_COMMENT, addr, 1, p);
|
2014-05-06 14:56:49 +04:00
|
|
|
}
|
|
|
|
} else {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_set (core->anal, R_META_TYPE_COMMENT, addr, 1, p);
|
2014-05-06 14:56:49 +04:00
|
|
|
}
|
2016-10-27 23:51:22 +02:00
|
|
|
} else {
|
2018-07-23 18:14:03 +02:00
|
|
|
eprintf ("Usage: CCa [address] [comment]\n");
|
2016-10-27 23:51:22 +02:00
|
|
|
}
|
2014-05-06 14:56:49 +04:00
|
|
|
free (s);
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2014-08-06 19:11:51 +02:00
|
|
|
}
|
2014-05-06 14:56:49 +04:00
|
|
|
}
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2014-05-06 14:56:49 +04:00
|
|
|
}
|
|
|
|
|
2018-09-10 01:27:47 -07:00
|
|
|
static int cmd_meta_vartype_comment(RCore *core, const char *input) {
|
|
|
|
ut64 addr = core->offset;
|
|
|
|
switch (input[1]) {
|
|
|
|
case '?': // "Ct?"
|
|
|
|
r_core_cmd_help (core, help_msg_Ct);
|
|
|
|
break;
|
|
|
|
case 0: // "Ct"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_VARTYPE, 0, NULL);
|
2018-09-10 01:27:47 -07:00
|
|
|
break;
|
|
|
|
case ' ': // "Ct <vartype comment> @ addr"
|
|
|
|
{
|
2020-03-02 21:39:37 +01:00
|
|
|
const char* newcomment = r_str_trim_head_ro (input + 2);
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, addr);
|
2018-09-10 01:27:47 -07:00
|
|
|
char *nc = strdup (newcomment);
|
|
|
|
r_str_unescape (nc);
|
|
|
|
if (comment) {
|
2020-05-09 20:49:28 +02:00
|
|
|
char *text = r_str_newf ("%s %s", comment, nc);
|
2018-09-10 01:27:47 -07:00
|
|
|
if (text) {
|
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_VARTYPE, addr, text);
|
|
|
|
free (text);
|
|
|
|
} else {
|
|
|
|
r_sys_perror ("malloc");
|
|
|
|
}
|
|
|
|
} else {
|
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_VARTYPE, addr, nc);
|
|
|
|
}
|
|
|
|
free (nc);
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '.': // "Ct. @ addr"
|
|
|
|
{
|
|
|
|
ut64 at = input[2]? r_num_math (core->num, input + 2): addr;
|
2020-05-09 20:49:28 +02:00
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_VARTYPE, at);
|
2018-09-10 01:27:47 -07:00
|
|
|
if (comment) {
|
|
|
|
r_cons_println (comment);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
case '-': // "Ct-"
|
|
|
|
r_meta_del (core->anal, R_META_TYPE_VARTYPE, core->offset, 1);
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
r_core_cmd_help (core, help_msg_Ct);
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
|
|
|
return true;
|
|
|
|
}
|
|
|
|
|
2018-07-24 15:42:24 +02:00
|
|
|
static int cmd_meta_others(RCore *core, const char *input) {
|
2017-10-21 15:28:42 +08:00
|
|
|
int n, type = input[0], subtype;
|
2022-09-24 23:14:29 +02:00
|
|
|
char *t = 0, *p, *p2, name[256] = {0};
|
2016-02-16 02:42:44 +01:00
|
|
|
int repeat = 1;
|
2020-05-09 20:49:28 +02:00
|
|
|
ut64 addr = core->offset;
|
2013-02-11 04:08:21 +01:00
|
|
|
|
2020-07-20 12:18:38 +02:00
|
|
|
if (!type) {
|
|
|
|
return 0;
|
|
|
|
}
|
|
|
|
|
2014-05-06 15:24:03 +04:00
|
|
|
switch (input[1]) {
|
|
|
|
case '?':
|
2017-02-09 13:28:43 +00:00
|
|
|
switch (input[0]) {
|
2020-03-07 20:07:12 +01:00
|
|
|
case 'f': // "Cf?"
|
2022-09-24 23:14:29 +02:00
|
|
|
r_cons_println (
|
2017-02-09 13:28:43 +00:00
|
|
|
"Usage: Cf[-] [sz] [fmt..] [@addr]\n\n"
|
|
|
|
"'sz' indicates the byte size taken up by struct.\n"
|
|
|
|
"'fmt' is a 'pf?' style format string. It controls only the display format.\n\n"
|
2022-08-18 14:37:29 +02:00
|
|
|
"You may wish to have 'sz' != sizeof (fmt) when you have a large struct\n"
|
2017-02-09 13:28:43 +00:00
|
|
|
"but have only identified specific fields in it. In that case, use 'fmt'\n"
|
|
|
|
"to show the fields you know about (perhaps using 'skip' fields), and 'sz'\n"
|
|
|
|
"to match the total struct size in mem.\n");
|
|
|
|
break;
|
2020-03-07 20:07:12 +01:00
|
|
|
case 's': // "Cs?"
|
2017-10-04 18:49:37 +08:00
|
|
|
r_core_cmd_help (core, help_msg_Cs);
|
|
|
|
break;
|
2017-02-09 13:28:43 +00:00
|
|
|
default:
|
2017-05-22 02:54:26 +02:00
|
|
|
r_cons_println ("See C?");
|
2017-02-09 13:28:43 +00:00
|
|
|
break;
|
|
|
|
}
|
2017-08-24 13:31:27 +02:00
|
|
|
break;
|
2020-03-07 20:07:12 +01:00
|
|
|
case '-': // "Cf-", "Cd-", ...
|
2014-05-06 15:24:03 +04:00
|
|
|
switch (input[2]) {
|
2020-03-07 20:07:12 +01:00
|
|
|
case '*': // "Cf-*", "Cd-*", ...
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_del (core->anal, input[0], 0, UT64_MAX);
|
2016-02-10 11:45:25 -06:00
|
|
|
break;
|
|
|
|
case ' ':
|
2017-11-06 18:13:37 +08:00
|
|
|
p2 = strchr (input + 3, ' ');
|
|
|
|
if (p2) {
|
|
|
|
ut64 i;
|
|
|
|
ut64 size = r_num_math (core->num, input + 3);
|
|
|
|
ut64 rep = r_num_math (core->num, p2 + 1);
|
|
|
|
ut64 cur_addr = addr;
|
|
|
|
if (!size) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
for (i = 0; i < rep && UT64_MAX - cur_addr > size; i++, cur_addr += size) {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_del (core->anal, input[0], cur_addr, size);
|
2017-11-06 18:13:37 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
} else {
|
|
|
|
addr = r_num_math (core->num, input + 3);
|
|
|
|
/* fallthrough */
|
|
|
|
}
|
2016-02-10 11:45:25 -06:00
|
|
|
default:
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_del (core->anal, input[0], addr, 1);
|
2016-02-10 11:45:25 -06:00
|
|
|
break;
|
2014-05-06 15:24:03 +04:00
|
|
|
}
|
|
|
|
break;
|
2020-03-07 20:07:12 +01:00
|
|
|
case '*': // "Cf*", "Cd*", ...
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, input[0], 1, NULL);
|
2014-05-06 15:24:03 +04:00
|
|
|
break;
|
2020-03-07 20:07:12 +01:00
|
|
|
case 'j': // "Cfj", "Cdj", ...
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, input[0], 'j', NULL);
|
2017-09-16 10:14:11 +08:00
|
|
|
break;
|
2020-03-07 20:07:12 +01:00
|
|
|
case '!': // "Cf!", "Cd!", ...
|
2014-05-06 15:24:03 +04:00
|
|
|
{
|
2020-05-09 20:49:28 +02:00
|
|
|
char *out;
|
|
|
|
const char *comment = r_meta_get_string (core->anal, R_META_TYPE_COMMENT, addr);
|
2014-12-19 03:17:28 +01:00
|
|
|
out = r_core_editor (core, NULL, comment);
|
2014-05-06 15:24:03 +04:00
|
|
|
if (out) {
|
2020-05-09 20:49:28 +02:00
|
|
|
//r_meta_set (core->anal->meta, R_META_TYPE_COMMENT, addr, 0, out);
|
2014-05-06 15:24:03 +04:00
|
|
|
r_core_cmdf (core, "CC-@0x%08"PFMT64x, addr);
|
2017-10-30 23:01:46 +08:00
|
|
|
//r_meta_del (core->anal->meta, input[0], addr, addr+1);
|
2016-05-17 10:36:33 +02:00
|
|
|
r_meta_set_string (core->anal, R_META_TYPE_COMMENT, addr, out);
|
2014-05-06 15:24:03 +04:00
|
|
|
free (out);
|
2013-02-11 04:08:21 +01:00
|
|
|
}
|
2014-05-06 15:24:03 +04:00
|
|
|
}
|
|
|
|
break;
|
2020-03-07 20:07:12 +01:00
|
|
|
case '.': // "Cf.", "Cd.", ...
|
2019-05-20 14:57:17 +02:00
|
|
|
if (input[2] == '.') { // "Cs.."
|
2020-05-09 20:49:28 +02:00
|
|
|
ut64 size;
|
|
|
|
RAnalMetaItem *mi = r_meta_get_at (core->anal, addr, type, &size);
|
2017-10-16 05:29:43 +08:00
|
|
|
if (mi) {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_print (core->anal, mi, addr, size, input[3], NULL, false);
|
2019-05-20 14:57:17 +02:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
} else if (input[2] == 'j') { // "Cs.j"
|
2020-05-09 20:49:28 +02:00
|
|
|
ut64 size;
|
|
|
|
RAnalMetaItem *mi = r_meta_get_at (core->anal, addr, type, &size);
|
2019-05-20 14:57:17 +02:00
|
|
|
if (mi) {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_print (core->anal, mi, addr, size, input[2], NULL, false);
|
2019-05-20 14:57:17 +02:00
|
|
|
r_cons_newline ();
|
2017-10-16 05:29:43 +08:00
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2020-05-09 20:49:28 +02:00
|
|
|
ut64 size;
|
|
|
|
RAnalMetaItem *mi = r_meta_get_at (core->anal, addr, type, &size);
|
2020-05-14 11:02:41 +02:00
|
|
|
if (!mi) {
|
|
|
|
break;
|
|
|
|
}
|
2017-11-30 21:41:13 +08:00
|
|
|
if (type == 's') {
|
|
|
|
char *esc_str;
|
2020-05-09 20:49:28 +02:00
|
|
|
bool esc_bslash = core->print->esc_bslash;
|
|
|
|
switch (mi->subtype) {
|
2017-11-30 21:41:13 +08:00
|
|
|
case R_STRING_ENC_UTF8:
|
2020-05-09 20:49:28 +02:00
|
|
|
esc_str = r_str_escape_utf8 (mi->str, false, esc_bslash);
|
2017-11-30 21:41:13 +08:00
|
|
|
break;
|
|
|
|
case 0: /* temporary legacy workaround */
|
|
|
|
esc_bslash = false;
|
|
|
|
default:
|
2020-05-09 20:49:28 +02:00
|
|
|
esc_str = r_str_escape_latin1 (mi->str, false, esc_bslash, false);
|
2017-11-30 21:41:13 +08:00
|
|
|
}
|
|
|
|
if (esc_str) {
|
|
|
|
r_cons_printf ("\"%s\"\n", esc_str);
|
|
|
|
free (esc_str);
|
2017-10-12 06:17:51 +08:00
|
|
|
} else {
|
2017-11-30 21:41:13 +08:00
|
|
|
r_cons_println ("<oom>");
|
2017-10-12 06:17:51 +08:00
|
|
|
}
|
2018-08-04 11:37:42 +08:00
|
|
|
} else if (type == 'd') {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_cons_printf ("%"PFMT64u"\n", size);
|
2017-11-30 21:41:13 +08:00
|
|
|
} else {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_cons_println (mi->str);
|
2017-10-12 06:17:51 +08:00
|
|
|
}
|
|
|
|
break;
|
2020-03-07 20:07:12 +01:00
|
|
|
case ' ': // "Cf", "Cd", ...
|
2014-05-06 15:24:03 +04:00
|
|
|
case '\0':
|
2017-10-05 22:00:57 +08:00
|
|
|
case 'g':
|
2017-10-04 20:39:39 +08:00
|
|
|
case 'a':
|
2021-03-04 18:32:14 +01:00
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '4':
|
2017-11-17 22:44:08 +08:00
|
|
|
case '8':
|
2021-03-04 18:32:14 +01:00
|
|
|
if (type == 'd') { // "Cd4"
|
|
|
|
switch (input[1]) {
|
|
|
|
case '1':
|
|
|
|
case '2':
|
|
|
|
case '4':
|
|
|
|
case '8':
|
|
|
|
input--;
|
|
|
|
break;
|
|
|
|
}
|
2014-05-06 15:24:03 +04:00
|
|
|
}
|
2016-05-18 02:29:41 +02:00
|
|
|
if (type == 'z') {
|
2016-04-08 03:30:00 +02:00
|
|
|
type = 's';
|
2021-03-04 18:32:14 +01:00
|
|
|
} else {
|
|
|
|
if (!input[1] && !core->tmpseek) {
|
|
|
|
r_meta_print_list_all (core->anal, type, 0, NULL);
|
|
|
|
break;
|
|
|
|
}
|
2016-05-18 02:29:41 +02:00
|
|
|
}
|
2017-10-18 17:18:44 +08:00
|
|
|
int len = (!input[1] || input[1] == ' ') ? 2 : 3;
|
|
|
|
if (strlen (input) > len) {
|
|
|
|
char *rep = strchr (input + len, '[');
|
2017-10-04 13:07:40 +02:00
|
|
|
if (!rep) {
|
2017-10-18 17:18:44 +08:00
|
|
|
rep = strchr (input + len, ' ');
|
2017-10-04 13:07:40 +02:00
|
|
|
}
|
2019-03-29 13:00:49 +01:00
|
|
|
if (*input == 'd') {
|
|
|
|
if (rep) {
|
|
|
|
repeat = r_num_math (core->num, rep + 1);
|
|
|
|
}
|
2014-09-23 11:55:11 +02:00
|
|
|
}
|
2016-02-16 02:42:44 +01:00
|
|
|
}
|
|
|
|
int repcnt = 0;
|
2016-10-27 23:51:22 +02:00
|
|
|
if (repeat < 1) {
|
|
|
|
repeat = 1;
|
|
|
|
}
|
2016-02-16 02:42:44 +01:00
|
|
|
while (repcnt < repeat) {
|
2017-10-18 07:27:31 +08:00
|
|
|
int off = (!input[1] || input[1] == ' ') ? 1 : 2;
|
2020-03-02 21:39:37 +01:00
|
|
|
t = strdup (r_str_trim_head_ro (input + off));
|
2016-02-16 02:42:44 +01:00
|
|
|
p = NULL;
|
|
|
|
n = 0;
|
|
|
|
strncpy (name, t, sizeof (name) - 1);
|
2016-04-08 03:30:00 +02:00
|
|
|
if (type != 'C') {
|
2016-02-16 02:42:44 +01:00
|
|
|
n = r_num_math (core->num, t);
|
2016-10-30 23:24:20 +01:00
|
|
|
if (type == 'f') { // "Cf"
|
2016-02-16 02:42:44 +01:00
|
|
|
p = strchr (t, ' ');
|
2016-11-06 01:40:51 +01:00
|
|
|
if (p) {
|
2020-03-02 21:39:37 +01:00
|
|
|
p = (char *)r_str_trim_head_ro (p);
|
2019-09-01 19:12:31 +02:00
|
|
|
if (*p == '.') {
|
|
|
|
const char *realformat = r_print_format_byname (core->print, p + 1);
|
|
|
|
if (realformat) {
|
|
|
|
p = (char *)realformat;
|
|
|
|
} else {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_WARN ("Cannot resolve format '%s'", p + 1);
|
2019-09-01 19:21:00 +02:00
|
|
|
break;
|
2019-09-01 19:12:31 +02:00
|
|
|
}
|
|
|
|
}
|
2016-10-30 23:24:20 +01:00
|
|
|
if (n < 1) {
|
2019-09-01 19:12:31 +02:00
|
|
|
n = r_print_format_struct_size (core->print, p, 0, 0);
|
2016-11-06 01:40:51 +01:00
|
|
|
if (n < 1) {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_WARN ("Cannot resolve struct size for '%s'", p);
|
2016-11-06 01:40:51 +01:00
|
|
|
n = 32; //
|
|
|
|
}
|
2016-10-30 23:24:20 +01:00
|
|
|
}
|
2017-02-24 23:57:39 +01:00
|
|
|
//make sure we do not overflow on r_print_format
|
|
|
|
if (n > core->blocksize) {
|
|
|
|
n = core->blocksize;
|
|
|
|
}
|
2016-12-14 13:21:28 +01:00
|
|
|
int r = r_print_format (core->print, addr, core->block,
|
2017-12-30 05:18:35 +01:00
|
|
|
n, p, 0, NULL, NULL);
|
2016-12-14 13:21:28 +01:00
|
|
|
if (r < 0) {
|
|
|
|
n = -1;
|
|
|
|
}
|
2016-12-14 16:09:45 +01:00
|
|
|
} else {
|
|
|
|
eprintf ("Usage: Cf [size] [pf-format-string]\n");
|
|
|
|
break;
|
2014-05-06 15:24:03 +04:00
|
|
|
}
|
2020-03-07 20:07:12 +01:00
|
|
|
} else if (type == 's') { // "Cs"
|
2022-03-11 19:48:37 -06:00
|
|
|
char tmp[256] = {0};
|
2016-11-07 21:06:11 +01:00
|
|
|
int i, j, name_len = 0;
|
2017-11-17 22:44:08 +08:00
|
|
|
if (input[1] == 'a' || input[1] == '8') {
|
2018-05-21 23:06:00 +02:00
|
|
|
(void)r_io_read_at (core->io, addr, (ut8*)name, sizeof (name) - 1);
|
2017-10-04 20:39:39 +08:00
|
|
|
name[sizeof (name) - 1] = '\0';
|
|
|
|
name_len = strlen (name);
|
|
|
|
} else {
|
2018-05-21 23:06:00 +02:00
|
|
|
(void)r_io_read_at (core->io, addr, (ut8*)tmp, sizeof (tmp) - 3);
|
2017-10-04 20:39:39 +08:00
|
|
|
name_len = r_str_nlen_w (tmp, sizeof (tmp) - 3);
|
|
|
|
//handle wide strings
|
|
|
|
for (i = 0, j = 0; i < sizeof (name); i++, j++) {
|
|
|
|
name[i] = tmp[j];
|
|
|
|
if (!tmp[j]) {
|
|
|
|
break;
|
|
|
|
}
|
|
|
|
if (!tmp[j + 1]) {
|
|
|
|
if (j + 3 < sizeof (tmp)) {
|
|
|
|
if (tmp[j + 3]) {
|
|
|
|
break;
|
|
|
|
}
|
2016-11-07 22:53:06 +01:00
|
|
|
}
|
2017-10-04 20:39:39 +08:00
|
|
|
j++;
|
2016-11-07 22:53:06 +01:00
|
|
|
}
|
2016-11-07 21:06:11 +01:00
|
|
|
}
|
2017-10-04 20:39:39 +08:00
|
|
|
name[sizeof (name) - 1] = '\0';
|
2016-11-07 21:06:11 +01:00
|
|
|
}
|
2016-05-18 02:29:41 +02:00
|
|
|
if (n == 0) {
|
|
|
|
n = name_len + 1;
|
|
|
|
} else {
|
|
|
|
if (n > 0 && n < name_len) {
|
|
|
|
name[n] = 0;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2016-12-14 13:21:28 +01:00
|
|
|
if (n < 1) {
|
|
|
|
/* invalid length, do not insert into db */
|
|
|
|
return false;
|
|
|
|
}
|
2016-02-16 02:42:44 +01:00
|
|
|
if (!*t || n > 0) {
|
|
|
|
RFlagItem *fi;
|
|
|
|
p = strchr (t, ' ');
|
|
|
|
if (p) {
|
2019-04-01 03:07:09 +02:00
|
|
|
*p++ = '\0';
|
2020-03-02 21:39:37 +01:00
|
|
|
p = (char *)r_str_trim_head_ro (p);
|
2019-04-01 03:07:09 +02:00
|
|
|
strncpy (name, p, sizeof (name)-1);
|
2016-04-08 03:30:00 +02:00
|
|
|
} else {
|
2016-05-18 02:29:41 +02:00
|
|
|
if (type != 's') {
|
2016-04-08 03:30:00 +02:00
|
|
|
fi = r_flag_get_i (core->flags, addr);
|
2019-04-01 03:07:09 +02:00
|
|
|
if (fi) {
|
2022-09-24 23:14:29 +02:00
|
|
|
strncpy (name, fi->name, sizeof (name) - 1);
|
2019-04-01 03:07:09 +02:00
|
|
|
}
|
2016-02-16 02:42:44 +01:00
|
|
|
}
|
2016-04-08 03:30:00 +02:00
|
|
|
}
|
2016-02-16 02:42:44 +01:00
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
}
|
2016-10-27 23:51:22 +02:00
|
|
|
if (!n) {
|
|
|
|
n++;
|
|
|
|
}
|
2017-10-21 15:28:42 +08:00
|
|
|
if (type == 's') {
|
2017-11-17 22:44:08 +08:00
|
|
|
switch (input[1]) {
|
|
|
|
case 'a':
|
|
|
|
case '8':
|
|
|
|
subtype = input[1];
|
|
|
|
break;
|
|
|
|
default:
|
|
|
|
subtype = R_STRING_ENC_GUESS;
|
|
|
|
}
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_set_with_subtype (core->anal, type, subtype, addr, n, name);
|
2017-10-21 15:28:42 +08:00
|
|
|
} else {
|
2020-05-09 20:49:28 +02:00
|
|
|
r_meta_set (core->anal, type, addr, n, name);
|
2017-10-21 15:28:42 +08:00
|
|
|
}
|
2016-02-16 02:42:44 +01:00
|
|
|
free (t);
|
|
|
|
repcnt ++;
|
2020-05-09 20:49:28 +02:00
|
|
|
addr += n;
|
2012-02-27 02:40:27 +01:00
|
|
|
}
|
2014-05-06 15:24:03 +04:00
|
|
|
//r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX);
|
|
|
|
break;
|
|
|
|
default:
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("Missing space after CC");
|
2014-05-06 15:24:03 +04:00
|
|
|
break;
|
|
|
|
}
|
|
|
|
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2014-05-06 15:24:03 +04:00
|
|
|
}
|
2016-11-13 01:40:44 +01:00
|
|
|
|
2016-09-04 15:49:24 +02:00
|
|
|
void r_comment_var_help(RCore *core, char type) {
|
2016-06-10 19:08:12 +03:00
|
|
|
switch (type) {
|
2016-07-01 17:15:29 +03:00
|
|
|
case 'b':
|
2017-07-26 06:09:39 -07:00
|
|
|
r_core_cmd_help (core, help_msg_Cvb);
|
2016-06-10 19:08:12 +03:00
|
|
|
break;
|
2016-07-01 17:15:29 +03:00
|
|
|
case 's':
|
2017-07-26 06:09:39 -07:00
|
|
|
r_core_cmd_help (core, help_msg_Cvs);
|
2016-06-10 19:08:12 +03:00
|
|
|
break;
|
2016-07-01 17:15:29 +03:00
|
|
|
case 'r':
|
2017-07-26 06:09:39 -07:00
|
|
|
r_core_cmd_help (core, help_msg_Cvr);
|
2016-06-10 19:08:12 +03:00
|
|
|
break;
|
2017-02-05 23:06:30 +00:00
|
|
|
case '?':
|
|
|
|
r_cons_printf("See Cvb?, Cvs? and Cvr?\n");
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
|
|
|
}
|
2016-11-13 01:40:44 +01:00
|
|
|
|
2016-09-04 15:49:24 +02:00
|
|
|
void r_comment_vars(RCore *core, const char *input) {
|
2016-06-13 00:39:40 +03:00
|
|
|
//TODO enable base64 and make it the default for C*
|
2016-06-10 19:08:12 +03:00
|
|
|
RAnalFunction *fcn = r_anal_get_fcn_in (core->anal, core->offset, 0);
|
2016-06-14 23:42:40 +02:00
|
|
|
char *oname = NULL, *name = NULL;
|
|
|
|
|
2020-06-15 02:04:56 -03:00
|
|
|
if (!input[0] || input[1] == '?' || (input[0] != 'b' && input[0] != 'r' && input[0] != 's')) {
|
2016-06-10 19:08:12 +03:00
|
|
|
r_comment_var_help (core, input[0]);
|
|
|
|
return;
|
|
|
|
}
|
|
|
|
if (!fcn) {
|
2022-08-20 02:39:01 +02:00
|
|
|
R_LOG_ERROR ("Can't find function here");
|
2016-06-10 19:08:12 +03:00
|
|
|
return;
|
|
|
|
}
|
2020-06-15 02:04:56 -03:00
|
|
|
oname = name = r_str_trim_dup (input + 1);
|
2016-06-10 19:08:12 +03:00
|
|
|
switch (input[1]) {
|
2018-08-22 02:17:08 -07:00
|
|
|
case '*': // "Cv*"
|
|
|
|
case '\0': { // "Cv"
|
2020-04-25 17:23:36 +02:00
|
|
|
void **it;
|
|
|
|
char kind = input[0];
|
|
|
|
r_pvector_foreach (&fcn->vars, it) {
|
|
|
|
RAnalVar *var = *it;
|
|
|
|
if (var->kind != kind || !var->comment) {
|
2016-06-10 19:08:12 +03:00
|
|
|
continue;
|
|
|
|
}
|
|
|
|
if (!input[1]) {
|
2020-04-25 17:23:36 +02:00
|
|
|
r_cons_printf ("%s : %s\n", var->name, var->comment);
|
2016-06-10 19:08:12 +03:00
|
|
|
} else {
|
2020-04-25 17:23:36 +02:00
|
|
|
char *b64 = sdb_encode ((const ut8 *)var->comment, strlen (var->comment));
|
|
|
|
if (!b64) {
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
r_cons_printf ("\"Cv%c %s base64:%s @ 0x%08"PFMT64x"\"\n", kind, var->name, b64, fcn->addr);
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case ' ': { // "Cv "
|
2019-12-15 21:05:42 +03:00
|
|
|
char *comment = strchr (name, ' ');
|
2020-04-25 17:23:36 +02:00
|
|
|
char *heap_comment = NULL;
|
2016-09-04 15:49:24 +02:00
|
|
|
if (comment) { // new comment given
|
|
|
|
if (*comment) {
|
|
|
|
*comment++ = 0;
|
|
|
|
}
|
|
|
|
if (!strncmp (comment, "base64:", 7)) {
|
|
|
|
heap_comment = (char *)sdb_decode (comment + 7, NULL);
|
|
|
|
comment = heap_comment;
|
|
|
|
}
|
2016-06-13 00:39:40 +03:00
|
|
|
}
|
2020-04-25 17:23:36 +02:00
|
|
|
RAnalVar *var = r_anal_function_get_var_byname (fcn, name);
|
|
|
|
if (!var) {
|
|
|
|
int idx = (int)strtol (name, NULL, 0);
|
|
|
|
var = r_anal_function_get_var (fcn, input[0], idx);
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
2020-04-25 17:23:36 +02:00
|
|
|
if (!var) {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("can't find variable at given offset");
|
2016-06-10 19:08:12 +03:00
|
|
|
} else {
|
2020-04-25 17:23:36 +02:00
|
|
|
if (var->comment) {
|
2016-06-14 23:42:40 +02:00
|
|
|
if (comment && *comment) {
|
2020-04-25 17:23:36 +02:00
|
|
|
char *text = r_str_newf ("%s\n%s", var->comment, comment);
|
|
|
|
free (var->comment);
|
|
|
|
var->comment = text;
|
2016-06-14 23:42:40 +02:00
|
|
|
} else {
|
2020-04-25 17:23:36 +02:00
|
|
|
r_cons_println (var->comment);
|
2016-06-14 23:42:40 +02:00
|
|
|
}
|
|
|
|
} else {
|
2020-04-25 17:23:36 +02:00
|
|
|
var->comment = strdup (comment);
|
2016-06-14 23:42:40 +02:00
|
|
|
}
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
2016-06-14 23:42:40 +02:00
|
|
|
free (heap_comment);
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
|
|
|
break;
|
2020-04-25 17:23:36 +02:00
|
|
|
case '-': { // "Cv-"
|
2020-06-15 02:04:56 -03:00
|
|
|
name++;
|
|
|
|
r_str_trim (name);
|
2020-04-25 17:23:36 +02:00
|
|
|
RAnalVar *var = r_anal_function_get_var_byname (fcn, name);
|
|
|
|
if (!var) {
|
|
|
|
int idx = (int)strtol (name, NULL, 0);
|
|
|
|
var = r_anal_function_get_var (fcn, input[0], idx);
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
2020-04-25 17:23:36 +02:00
|
|
|
if (!var) {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("can't find variable at given offset");
|
2016-06-13 00:39:40 +03:00
|
|
|
break;
|
|
|
|
}
|
2020-04-25 17:23:36 +02:00
|
|
|
free (var->comment);
|
|
|
|
var->comment = NULL;
|
2016-06-10 19:08:12 +03:00
|
|
|
break;
|
2020-04-25 17:23:36 +02:00
|
|
|
}
|
2018-08-22 02:17:08 -07:00
|
|
|
case '!': { // "Cv!"
|
2016-06-10 19:08:12 +03:00
|
|
|
char *comment;
|
2020-06-15 02:04:56 -03:00
|
|
|
name++;
|
|
|
|
r_str_trim (name);
|
2020-04-25 17:23:36 +02:00
|
|
|
RAnalVar *var = r_anal_function_get_var_byname (fcn, name);
|
2016-06-10 19:08:12 +03:00
|
|
|
if (!var) {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("can't find variable named `%s`", name);
|
2016-06-10 19:08:12 +03:00
|
|
|
break;
|
|
|
|
}
|
2020-04-25 17:23:36 +02:00
|
|
|
comment = r_core_editor (core, NULL, var->comment);
|
2016-06-10 19:08:12 +03:00
|
|
|
if (comment) {
|
2020-04-25 17:23:36 +02:00
|
|
|
free (var->comment);
|
|
|
|
var->comment = comment;
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
|
|
|
}
|
|
|
|
break;
|
|
|
|
}
|
2016-06-14 23:42:40 +02:00
|
|
|
free (oname);
|
2016-06-10 19:08:12 +03:00
|
|
|
}
|
2014-05-06 15:24:03 +04:00
|
|
|
|
|
|
|
static int cmd_meta(void *data, const char *input) {
|
|
|
|
RCore *core = (RCore*)data;
|
|
|
|
RAnalFunction *f;
|
2016-02-16 02:42:44 +01:00
|
|
|
RSpaces *ms;
|
|
|
|
int i;
|
2014-05-06 15:24:03 +04:00
|
|
|
|
|
|
|
switch (*input) {
|
2018-08-22 02:17:08 -07:00
|
|
|
case 'v': // "Cv"
|
2016-07-01 17:15:29 +03:00
|
|
|
r_comment_vars (core, input + 1);
|
2016-06-10 19:08:12 +03:00
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case '\0': // "C"
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_ANY, 0, NULL);
|
2019-01-10 16:57:22 +01:00
|
|
|
break;
|
2021-01-15 01:20:32 +01:00
|
|
|
case ',': // "C,"
|
2022-08-20 02:39:01 +02:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_ANY, *input, input + 1);
|
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case 'j': // "Cj"
|
2018-12-13 14:49:59 +00:00
|
|
|
case '*': { // "C*"
|
2022-08-20 12:35:11 +02:00
|
|
|
if (input[1] == '.') {
|
|
|
|
r_meta_print_list_at (core->anal, core->offset, *input, input + 2);
|
|
|
|
} else if (input[1]) {
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_at (core->anal, core->offset, *input, input + 2);
|
2018-12-13 14:49:59 +00:00
|
|
|
} else {
|
2022-08-20 12:35:11 +02:00
|
|
|
r_meta_print_list_all (core->anal, R_META_TYPE_ANY, *input, input + 1);
|
2018-12-13 14:49:59 +00:00
|
|
|
}
|
2014-05-06 15:24:03 +04:00
|
|
|
break;
|
2018-12-13 14:49:59 +00:00
|
|
|
}
|
|
|
|
case '.': { // "C."
|
2021-01-15 01:20:32 +01:00
|
|
|
r_meta_print_list_at (core->anal, core->offset, 0, NULL);
|
2018-12-13 14:49:59 +00:00
|
|
|
break;
|
|
|
|
}
|
2016-11-22 23:59:04 +01:00
|
|
|
case 'L': // "CL"
|
2014-05-06 15:24:03 +04:00
|
|
|
cmd_meta_lineinfo (core, input + 1);
|
|
|
|
break;
|
2015-11-18 17:02:42 +01:00
|
|
|
case 'C': // "CC"
|
2018-07-23 18:14:03 +02:00
|
|
|
cmd_meta_comment (core, input);
|
2014-05-06 15:24:03 +04:00
|
|
|
break;
|
2018-09-10 01:27:47 -07:00
|
|
|
case 't': // "Ct" type analysis commnets
|
|
|
|
cmd_meta_vartype_comment (core, input);
|
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case 'r': // "Cr" run command
|
|
|
|
case 'h': // "Ch" comment
|
|
|
|
case 's': // "Cs" string
|
|
|
|
case 'z': // "Cz" zero-terminated string
|
|
|
|
case 'd': // "Cd" data
|
|
|
|
case 'm': // "Cm" magic
|
|
|
|
case 'f': // "Cf" formatted
|
2018-07-24 15:42:24 +02:00
|
|
|
cmd_meta_others (core, input);
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case '-': // "C-"
|
2017-11-08 23:37:40 +08:00
|
|
|
if (input[1] != '*') {
|
|
|
|
i = input[1] ? r_num_math (core->num, input + (input[1] == ' ' ? 2 : 1)) : 1;
|
2017-10-30 23:01:46 +08:00
|
|
|
r_meta_del (core->anal, R_META_TYPE_ANY, core->offset, i);
|
2020-05-09 20:49:28 +02:00
|
|
|
} else {
|
|
|
|
r_meta_del (core->anal, R_META_TYPE_ANY, 0, UT64_MAX);
|
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case '?': // "C?"
|
2017-07-26 06:09:39 -07:00
|
|
|
r_core_cmd_help (core, help_msg_C);
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-01-13 12:59:28 +01:00
|
|
|
case 'F': // "CF"
|
2014-09-26 15:40:17 +02:00
|
|
|
f = r_anal_get_fcn_in (core->anal, core->offset,
|
2014-05-05 01:00:23 +02:00
|
|
|
R_ANAL_FCN_TYPE_FCN|R_ANAL_FCN_TYPE_SYM);
|
2017-01-13 12:59:28 +01:00
|
|
|
if (f) {
|
|
|
|
r_anal_str_to_fcn (core->anal, f, input + 2);
|
|
|
|
} else {
|
2022-09-10 02:03:36 +02:00
|
|
|
R_LOG_ERROR ("Cannot find function here");
|
2017-01-13 12:59:28 +01:00
|
|
|
}
|
2012-02-27 02:40:27 +01:00
|
|
|
break;
|
2017-01-13 12:59:28 +01:00
|
|
|
case 'S': // "CS"
|
2016-02-16 02:42:44 +01:00
|
|
|
ms = &core->anal->meta_spaces;
|
2015-06-15 04:19:29 +02:00
|
|
|
/** copypasta from `fs`.. this must be refactorized to be shared */
|
|
|
|
switch (input[1]) {
|
2018-08-22 02:17:08 -07:00
|
|
|
case '?': // "CS?"
|
2017-07-26 06:09:39 -07:00
|
|
|
r_core_cmd_help (core, help_msg_CS);
|
2015-06-15 04:19:29 +02:00
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case '+': // "CS+"
|
2019-01-28 16:41:42 +01:00
|
|
|
r_spaces_push (ms, input + 2);
|
2015-06-15 04:19:29 +02:00
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case 'r': // "CSr"
|
2017-01-11 12:23:48 +01:00
|
|
|
if (input[2] == ' ') {
|
2021-10-19 12:06:46 +02:00
|
|
|
r_spaces_rename (ms, NULL, input + 2);
|
2017-01-11 12:23:48 +01:00
|
|
|
} else {
|
|
|
|
eprintf ("Usage: CSr [newname]\n");
|
|
|
|
}
|
2015-06-15 04:19:29 +02:00
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case '-': // "CS-"
|
2015-06-15 04:19:29 +02:00
|
|
|
if (input[2]) {
|
2021-10-19 12:06:46 +02:00
|
|
|
if (input[2] == '*') {
|
2019-01-28 16:41:42 +01:00
|
|
|
r_spaces_unset (ms, NULL);
|
2015-06-15 04:19:29 +02:00
|
|
|
} else {
|
2021-10-19 12:06:46 +02:00
|
|
|
r_spaces_unset (ms, input + 2);
|
2015-06-15 04:19:29 +02:00
|
|
|
}
|
|
|
|
} else {
|
2019-01-28 16:41:42 +01:00
|
|
|
r_spaces_pop (ms);
|
2015-06-15 04:19:29 +02:00
|
|
|
}
|
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case 'j': // "CSj"
|
|
|
|
case '\0': // "CS"
|
|
|
|
case '*': // "CS*"
|
2019-01-28 16:41:42 +01:00
|
|
|
spaces_list (ms, input[1]);
|
2015-06-15 04:19:29 +02:00
|
|
|
break;
|
2018-08-22 02:17:08 -07:00
|
|
|
case ' ': // "CS "
|
2019-01-28 16:41:42 +01:00
|
|
|
r_spaces_set (ms, input + 2);
|
2015-06-15 04:19:29 +02:00
|
|
|
break;
|
2019-02-03 16:06:45 +01:00
|
|
|
default:
|
|
|
|
spaces_list (ms, 0);
|
2015-06-15 04:19:29 +02:00
|
|
|
break;
|
2019-01-28 16:41:42 +01:00
|
|
|
}
|
2015-06-15 04:19:29 +02:00
|
|
|
break;
|
2012-02-27 02:40:27 +01:00
|
|
|
}
|
2015-09-14 12:35:38 +02:00
|
|
|
return true;
|
2012-02-27 02:40:27 +01:00
|
|
|
}
|