radare2/libr/core/cmd_info.c

380 lines
11 KiB
C
Raw Normal View History

/* radare - LGPL - Copyright 2009-2015 - pancake */
2014-01-12 01:20:40 +01:00
#define PAIR_WIDTH 9
static void pair(const char *a, const char *b) {
char ws[16];
int al = strlen (a);
2015-04-07 20:03:13 +02:00
if (!b) return; // b = "";
memset (ws, ' ', sizeof (ws));
al = PAIR_WIDTH - al;
if (al<0) al = 0;
ws[al] = 0;
r_cons_printf ("%s%s%s\n", a, ws, b);
}
static int demangle_internal(RCore *core, const char *lang, const char *s) {
char *res = NULL;
int type = r_bin_demangle_type (lang);
switch (type) {
case R_BIN_NM_CXX: res = r_bin_demangle_cxx (s); break;
case R_BIN_NM_JAVA: res = r_bin_demangle_java (s); break;
case R_BIN_NM_OBJC: res = r_bin_demangle_objc (NULL, s); break;
case R_BIN_NM_SWIFT: res = r_bin_demangle_swift (s); break;
case R_BIN_NM_DLANG: res = r_bin_demangle_plugin (core->bin, "dlang", s); break;
default:
r_bin_demangle_list (core->bin);
return 1;
}
2015-01-10 17:55:59 +01:00
if (res) {
if (*res)
printf ("%s\n", res);
free (res);
return 0;
}
2015-01-10 17:55:59 +01:00
return 1;
}
static int demangle(RCore *core, const char *s) {
char *p, *q;
const char *ss = strchr (s, ' ');
if (!*s) return 0;
if (!ss) {
const char *lang = r_config_get (core->config, "bin.lang");
demangle_internal (core, lang, s);
return 1;
}
p = strdup (s);
q = p + (ss-s);
*q = 0;
demangle_internal (core, p, q+1);
free (p);
return 1;
}
2014-07-10 03:16:48 +02:00
#define STR(x) (x)?(x):""
2012-12-23 20:51:23 +01:00
static void r_core_file_info (RCore *core, int mode) {
const char *fn = NULL;
int dbg = r_config_get_i (core->config, "cfg.debug");
RBinInfo *info = r_bin_get_info (core->bin);
RBinFile *binfile = r_core_bin_cur (core);
RCoreFile *cf = core->file;
RBinPlugin *plugin = r_bin_file_cur_plugin (binfile);
2012-12-23 20:51:23 +01:00
if (mode == R_CORE_BIN_JSON)
r_cons_printf ("{");
if (mode == R_CORE_BIN_RADARE)
return;
if (mode == R_CORE_BIN_SIMPLE)
return;
2012-12-23 20:51:23 +01:00
if (info) {
fn = info->file;
switch (mode) {
case R_CORE_BIN_JSON:
r_cons_printf ("\"type\":\"%s\","
2015-04-07 20:03:13 +02:00
/*"\"os\":\"%s\","*/
2015-04-09 11:34:36 +02:00
/*"\"machine\":\"%s\","*/
2012-12-23 20:51:23 +01:00
"\"bits\":%d,"
"\"endian\":\"%s\","
2014-07-10 03:16:48 +02:00
, STR(info->type)
2015-04-07 20:03:13 +02:00
/*, STR(info->os)*/
2015-04-09 11:34:36 +02:00
/*, STR(info->machine)*/
2012-12-23 20:51:23 +01:00
, info->bits
, info->big_endian? "big": "little");
break;
default:
pair ("type", info->type);
2015-04-07 20:03:13 +02:00
/*pair ("os", info->os);*/
2015-04-09 11:34:36 +02:00
/*pair ("machine", info->machine);*/
pair ("bits", sdb_fmt (0, "%d", info->bits));
pair ("endian", info->big_endian? "big": "little");
2012-12-23 20:51:23 +01:00
break;
}
2014-09-09 17:01:04 +02:00
} else fn = (cf && cf->desc) ? cf->desc->name : NULL;
if (cf && mode == R_CORE_BIN_JSON) {
2012-12-23 20:51:23 +01:00
r_cons_printf ("\"file\":\"%s\"", fn);
if (dbg) dbg = R_IO_WRITE | R_IO_EXEC;
if (cf->desc) {
2015-04-07 20:03:13 +02:00
/*r_cons_printf (",\"uri\":\"%s\"", cf->desc->uri);*/
2014-09-10 02:21:10 +02:00
r_cons_printf (",\"fd\":%d", cf->desc->fd);
r_cons_printf (",\"size\":%"PFMT64d, r_io_desc_size (core->io, cf->desc));
r_cons_printf (",\"mode\":\"%s\"", r_str_rwx_i (
cf->desc->flags & 7 ));
if (cf->desc->referer && *cf->desc->referer)
2014-11-07 10:52:44 +01:00
r_cons_printf ("\"referer\":\"%s\"", cf->desc->referer);
}
2012-12-23 20:51:23 +01:00
r_cons_printf (",\"block\":%d", core->blocksize);
2014-05-06 11:17:03 +02:00
if (binfile) {
if (binfile->curxtr)
r_cons_printf (",\"packet\":\"%s\"",
binfile->curxtr->name);
if (plugin)
2014-05-06 11:17:03 +02:00
r_cons_printf (",\"format\":\"%s\"",
plugin->name);
2014-05-06 11:17:03 +02:00
}
2012-12-23 20:51:23 +01:00
r_cons_printf ("}");
} else if (cf && mode != R_CORE_BIN_SIMPLE) {
//r_cons_printf ("# Core file info\n");
pair ("file", fn);
2012-12-23 20:51:23 +01:00
if (dbg) dbg = R_IO_WRITE | R_IO_EXEC;
if (cf->desc) {
if (cf->desc->referer && *cf->desc->referer)
pair ("referer", cf->desc->referer);
pair ("fd", sdb_fmt (0, "%d", cf->desc->fd));
pair ("size", sdb_fmt (0,"0x%"PFMT64x, r_io_desc_size (core->io, cf->desc)));
2015-04-01 03:33:12 +02:00
pair ("blksz", sdb_fmt (0, "0x%"PFMT64x,
2015-02-16 22:40:05 +01:00
(ut64)core->io->desc->obsz));
pair ("mode", r_str_rwx_i (cf->desc->flags & 7));
2015-04-07 20:03:13 +02:00
/*pair ("uri", cf->desc->uri);*/
}
pair ("block", sdb_fmt (0, "0x%x", core->blocksize));
if (binfile && binfile->curxtr)
pair ("packet", binfile->curxtr->name);
if (plugin)
pair ("format", plugin->name);
2012-12-23 20:51:23 +01:00
}
}
2015-04-09 15:30:36 +02:00
static int bin_is_executable (RBinObject *obj){
RListIter *it;
RBinSection* sec;
r_list_foreach (obj->sections, it, sec){
if (R_BIN_SCN_EXECUTABLE & sec->srwx)
return R_TRUE;
}
return R_FALSE;
}
static void cmd_info_bin(RCore *core, ut64 offset, int va, int mode) {
2015-04-09 11:34:36 +02:00
RBinObject *obj = r_bin_cur_object (core->bin);
if (core->file) {
if (mode == R_CORE_BIN_JSON)
2015-04-07 20:03:13 +02:00
r_cons_printf ("{\"core\":");
r_core_file_info (core, mode);
2015-04-09 15:30:36 +02:00
if (bin_is_executable (obj)){
2015-04-07 20:03:13 +02:00
if (mode == R_CORE_BIN_JSON)
r_cons_printf (",\"bin\":");
r_core_bin_info (core, R_CORE_BIN_ACC_INFO,
mode, va, NULL, offset, NULL);
}
if (mode == R_CORE_BIN_JSON)
r_cons_printf ("}\n");
} else eprintf ("No selected file\n");
}
static int cmd_info(void *data, const char *input) {
RCore *core = (RCore *)data;
int newline = r_config_get_i (core->config, "scr.interactive");
ut64 offset = r_bin_get_offset (core->bin);
RBinObject *o = r_bin_cur_object (core->bin);
RCoreFile *cf = core->file;
int i, va = core->io->va || core->io->debug;
int mode = 0; //R_CORE_BIN_SIMPLE;
int is_array = 0;
Sdb *db;
2012-12-23 20:51:23 +01:00
2015-01-24 02:11:14 +01:00
for (i = 0; input[i] && i<2; i++) {
switch (input[i]) {
case '*': mode = R_CORE_BIN_RADARE; break;
case 'j': mode = R_CORE_BIN_JSON; break;
case 'q': mode = R_CORE_BIN_SIMPLE; break;
}
}
if (mode == R_CORE_BIN_JSON) {
if (strlen (input+1)>1)
is_array = 1;
}
if (is_array)
r_cons_printf ("{");
if (!*input)
cmd_info_bin (core, offset, va, mode);
2015-04-01 04:14:10 +02:00
/* i* is an alias for iI* */
if (!strcmp (input, "*")) {
input = "I*";
}
while (*input) {
switch (*input) {
case 'b':
{
ut64 baddr = r_config_get_i (core->config, "bin.baddr");
if (input[1]==' ')
baddr = r_num_math (core->num, input+1);
// XXX: this will reload the bin using the buffer.
// An assumption is made that assumes there is an underlying
// plugin that will be used to load the bin (e.g. malloc://)
// TODO: Might be nice to reload a bin at a specified offset?
r_core_bin_reload (core, NULL, baddr);
r_core_block_read (core, 0);
}
break;
case 'k':
db = o ? o->kv : NULL;
//:eprintf ("db = %p\n", db);
switch (input[1]) {
case 'v':
2014-09-17 15:23:56 +02:00
if (db) {
char *o = sdb_querys (db, NULL, 0, input+3);
if (o && *o) r_cons_printf ("%s", o);
free (o);
}
break;
case '.':
case ' ':
2014-09-17 15:23:56 +02:00
if (db) {
char *o = sdb_querys (db, NULL, 0, input+2);
if (o && *o) r_cons_printf ("%s", o);
free (o);
}
break;
case '\0':
2014-09-17 15:23:56 +02:00
if (db) {
char *o = sdb_querys (db, NULL, 0, "*");
if (o && *o) r_cons_printf ("%s", o);
free (o);
}
break;
case '?':
default:
eprintf ("Usage: ik [sdb-query]\n");
}
break;
2014-09-24 23:01:03 +02:00
case 'o':
{
if (!cf) {
eprintf ("Core file not open\n");
return 0;
}
2014-09-09 17:01:04 +02:00
const char *fn = input[1]==' '? input+2: cf->desc->name;
ut64 laddr = UT64_MAX;
laddr = r_config_get_i (core->config, "bin.baddr");
r_core_bin_load (core, fn, laddr);
}
break;
#define RBININFO(n,x) \
if (is_array) { \
if (is_array==1) is_array++; else r_cons_printf (","); \
r_cons_printf ("\"%s\":",n); \
}\
r_core_bin_info (core,x,mode,va,NULL,offset,NULL);
case 'A': newline=0; r_bin_list_archs (core->bin, 1); break;
case 'Z': RBININFO ("size",R_CORE_BIN_ACC_SIZE); break;
case 'S': RBININFO ("sections",R_CORE_BIN_ACC_SECTIONS); break;
case 'h': RBININFO ("fields", R_CORE_BIN_ACC_FIELDS); break;
case 'l': RBININFO ("libs", R_CORE_BIN_ACC_LIBS); break;
case 's': RBININFO ("symbols", R_CORE_BIN_ACC_SYMBOLS); break;
case 'R':
case 'r': RBININFO ("relocs", R_CORE_BIN_ACC_RELOCS); break;
case 'd': RBININFO ("dwarf", R_CORE_BIN_ACC_DWARF); break;
case 'i': RBININFO ("imports",R_CORE_BIN_ACC_IMPORTS); break;
case 'I': RBININFO ("info", R_CORE_BIN_ACC_INFO); break;
case 'e': RBININFO ("entries",R_CORE_BIN_ACC_ENTRIES); break;
case 'm': RBININFO ("memory",R_CORE_BIN_ACC_MEM); break;
2014-09-24 23:01:03 +02:00
case 'z':
2014-09-15 23:47:23 +02:00
if (input[1] == 'z') {
/* TODO: reimplement in C to avoid forks */
if (!core->file) {
eprintf ("Core file not open\n");
return 0;
}
2014-09-15 23:49:51 +02:00
char *ret;
switch (input[2]) {
case '*':
ret = r_sys_cmd_strf ("rabin2 -rzz '%s'", core->file->desc->name);
break;
case 'q':
ret = r_sys_cmd_strf ("rabin2 -qzz '%s'", core->file->desc->name);
break;
2014-09-15 23:49:51 +02:00
case 'j':
ret = r_sys_cmd_strf ("rabin2 -jzz '%s'", core->file->desc->name);
break;
default:
ret = r_sys_cmd_strf ("rabin2 -zz '%s'", core->file->desc->name);
break;
}
2014-09-15 23:47:23 +02:00
if (ret && *ret) {
r_cons_strcat (ret);
}
free (ret);
input++;
} else {
2014-09-15 23:49:51 +02:00
RBININFO ("strings", R_CORE_BIN_ACC_STRINGS);
2014-09-15 23:47:23 +02:00
}
break;
case 'c':
2014-09-15 23:49:51 +02:00
case 'C': RBININFO ("classes", R_CORE_BIN_ACC_CLASSES); break;
case 'D':
if (input[1]!=' ' || !demangle (core, input+2)) {
eprintf ("|Usage: iD lang symbolname\n");
}
return 0;
case 'a':
{
switch (mode) {
case R_CORE_BIN_RADARE: cmd_info (core, "i*IiesSz"); break;
2014-08-14 21:47:38 +02:00
case R_CORE_BIN_JSON: cmd_info (core, "iIiesSzj"); break;
default:
2015-03-19 00:53:46 +01:00
case R_CORE_BIN_SIMPLE: cmd_info (core, "iIiesSmz"); break;
}
}
break;
2014-06-30 12:25:46 -04:00
case '?': {
const char * help_message[] = {
"Usage: i", "", "Get info from opened file",
"Output mode:", "", "",
"'*'", "", "Output in radare commands",
"'j'", "", "Output in json",
"'q'", "", "Simple quiet output",
"Actions:", "", "",
"i|ij", "", "Show info of current file (in JSON)",
"iA", "", "List archs",
"ia", "", "Show all info (imports, exports, sections..)",
"ib", "", "Reload the current buffer for setting of the bin (use once only)",
"ic", "", "List classes",
"id", "", "Debug information (source lines)",
2015-01-29 03:19:32 +01:00
"iD", " lang sym", "demangle symbolname for given language",
2014-06-30 12:25:46 -04:00
"ie", "", "Entrypoint",
"ih", "", "Headers",
"ii", "", "Imports",
"iI", "", "Binary info",
"ik", " [query]", "Key-value database from RBinObject",
"il", "", "Libraries",
"im", "", "Show info about predefined memory allocation",
2014-06-30 12:25:46 -04:00
"io", " [file]", "Load info from file (or last opened) use bin.baddr",
"ir|iR", "", "Relocs",
"is", "", "Symbols",
"iS", "", "Sections",
2014-09-24 23:01:03 +02:00
"iz", "", "Strings in data sections",
"izz", "", "Search for Strings in the whole binary",
2014-06-30 12:25:46 -04:00
NULL
};
r_core_cmd_help(core, help_message);
}
goto done;
case '*':
mode = R_CORE_BIN_RADARE;
goto done;
case 'q':
mode = R_CORE_BIN_SIMPLE;
cmd_info_bin (core, offset, va, mode);
goto done;
case 'j':
mode = R_CORE_BIN_JSON;
2014-05-13 00:38:06 +02:00
cmd_info_bin (core, offset, va, mode);
goto done;
default:
cmd_info_bin (core, offset, va, mode);
2014-05-13 00:38:06 +02:00
break;
}
input++;
if (!strcmp (input, "j"))
break;
if (!strcmp (input, "q"))
break;
}
done:
if (is_array)
r_cons_printf ("}\n");
if (newline) r_cons_newline();
return 0;
}