radare2/libr/core/cmd_open.c

923 lines
24 KiB
C
Raw Normal View History

2017-08-23 12:18:29 +02:00
/* radare - LGPL - Copyright 2009-2017 - pancake */
2016-05-02 22:52:41 -04:00
#include "r_list.h"
#include "r_config.h"
#include "r_core.h"
#include "r_print.h"
#include "r_bin.h"
2017-06-14 12:18:46 +05:30
#include "r_debug.h"
2012-02-27 02:40:27 +01:00
static const char *help_msg_o[] = {
"Usage: o","[com- ] [file] ([offset])","",
"o","","list opened files",
"o=","","list opened files (ascii-art bars)",
"o*","","list opened files in r2 commands",
"oa","[?] [addr]","Open bin info from the given address",
"ob","[?] [lbdos] [...]","list open binary files backed by fd",
"oc"," [file]","open core file, like relaunching r2",
"oi","[-|idx]","alias for o, but using index instead of fd",
"oj","[?] ","list opened files in JSON format",
"oL","","list all IO plugins registered",
"om","[?]","create, list, remove IO maps",
"on"," [file] 0x4000","map raw file at 0x4000 (no r_bin involved)",
"oo","[?]","reopen current file (kill+fork in debugger)",
"oo","+","reopen current file in read-write",
"ood"," [args]","reopen in debugger mode (with args)",
"oo[bnm]"," [...]","see oo? for help",
"op"," ["R_LIB_EXT"]","open r2 native plugin (asm, bin, core, ..)",
"o"," 4","Switch to open file on fd 4",
"o","-1","close file descriptor 1",
"o-","*","close all opened files",
"o--","","close all files, analysis, binfiles, flags, same as !r2 --",
"o"," [file]","open [file] file in read-only",
"o","+ [file]","open file in read-write mode",
"o"," [file] 0x4000","map file at 0x4000",
"ox", " fd fdx", "exchange the descs of fd and fdx and keep the mapping",
NULL
};
static const char *help_msg_o_star[] = {
"Usage:", "o* [> files.r2]", "",
"o*", "", "list opened files in r2 commands", NULL
};
static const char *help_msg_oa[] = {
"Usage:", "oa [addr] ([filename])", " # load bininfo and update flags",
"oa", " [addr]", "Open bin info from the given address",
"oa", " [addr] [filename]", "Open file and load bin info at given address",NULL
};
static const char *help_msg_ob[] = {
"Usage:", "ob", " # List open binary files backed by fd",
"ob", "", "List opened binary files and objid",
"ob", " [fd objid]", "Switch to open binary file by fd number and objid",
"obb", " [fd]", "Switch to open binfile by fd number",
"obr", " [baddr]", "Rebase current bin object",
"ob-", " [fd]", "Delete binfile by fd",
"obd", " [objid]", "Delete binary file by objid. Do nothing if only one loaded.",
"obo", " [objid]", "Switch to open binary file by objid",
NULL
};
static const char *help_msg_oj[] = {
"Usage:", "oj [~{}]", " # Use ~{} to indent the JSON",
"oj", "", "list opened files in JSON format", NULL
};
static const char *help_msg_om[] = {
"Usage:", "om[-] [arg]", " # map opened files",
"om", "", "list all defined IO maps",
2017-08-23 12:18:29 +02:00
"om*", "", "list all maps in r2 commands format",
"omj", "", "list all maps in json format",
"om", " [fd]", "list all defined IO maps for a specific fd",
"om", "-mapid", "remove the map with corresponding id",
"om", " fd addr [size] [delta]", "create new io map",
"om.", "", "show map, that is mapped to current offset",
"omr", " mapid addr", "relocate map with corresponding id",
"omp", " mapid", "priorize map with corresponding id",
"omsp", " sectionid", "priorize maps of mapped section with sectionid",
"ombp", " binid", "priorize maps of mapped bin with binid",
"om*", "", "show r2 commands to restore mapaddr",
NULL
};
static const char *help_msg_oo[] = {
"Usage:", "oo[-] [arg]", " # map opened files",
"oo", "", "reopen current file",
"oo+", "", "reopen in read-write",
"oob", "", "reopen loading rbin info",
"ood", "", "reopen in debug mode",
"oom", "", "reopen in malloc://",
"oon", "", "reopen without loading rbin info",
"oon+", "", "reopen in read-write mode without loading rbin info",
"oonn", "", "reopen without loading rbin info, but with header flags",
"oonn+", "", "reopen in read-write mode without loading rbin info, but with",
NULL
};
static const char *help_msg_oo_plus[] = {
"oo+", "", "reopen in read-write",
NULL
};
static const char *help_msg_oob[] = {
"oob", "", "reopen loading rbin info",
NULL
};
static const char *help_msg_ood[] = {
"ood"," [args]","reopen in debugger mode (with args)",
NULL
};
static const char *help_msg_oon[] = {
"oon", "", "reopen without loading rbin info",
NULL
};
static const char *help_msg_oonn[] = {
"oonn", "", "reopen without loading rbin info, but with header flags",
NULL
};
2015-11-09 15:14:41 +01:00
static inline ut32 find_binfile_id_by_fd (RBin *bin, ut32 fd) {
RListIter *it;
RBinFile *bf;
r_list_foreach (bin->binfiles, it, bf) {
if (bf->fd == fd) {
return bf->id;
}
2015-11-09 15:14:41 +01:00
}
return UT32_MAX;
}
static void cmd_open_init(RCore *core) {
DEFINE_CMD_DESCRIPTOR (core, o);
DEFINE_CMD_DESCRIPTOR_SPECIAL (core, o*, o_star);
DEFINE_CMD_DESCRIPTOR (core, oa);
DEFINE_CMD_DESCRIPTOR (core, ob);
DEFINE_CMD_DESCRIPTOR (core, oj);
DEFINE_CMD_DESCRIPTOR (core, om);
DEFINE_CMD_DESCRIPTOR (core, oo);
DEFINE_CMD_DESCRIPTOR_SPECIAL (core, oo+, oo_plus);
DEFINE_CMD_DESCRIPTOR (core, oob);
DEFINE_CMD_DESCRIPTOR (core, ood);
DEFINE_CMD_DESCRIPTOR (core, oon);
DEFINE_CMD_DESCRIPTOR (core, oonn);
}
static void cmd_open_bin(RCore *core, const char *input) {
const char *value = NULL;
ut32 binfile_num = -1, binobj_num = -1;
switch (input[1]) {
case 0:
case 'l':
case 'j':
case '*':
r_core_bin_list (core, input[1]);
break;
case 'b': // "obb"
2015-11-09 15:14:41 +01:00
{
ut32 fd;
value = *(input + 3) ? input + 3 : NULL;
if (!value) {
2015-11-09 15:14:41 +01:00
eprintf ("Invalid fd number.");
break;
}
2015-11-09 15:14:41 +01:00
binfile_num = UT32_MAX;
fd = *value && r_is_valid_input_num_value (core->num, value) ?
r_get_input_num_value (core->num, value) : UT32_MAX;
2015-11-09 15:14:41 +01:00
binfile_num = find_binfile_id_by_fd (core->bin, fd);
if (binfile_num == UT32_MAX) {
2015-11-09 15:14:41 +01:00
eprintf ("Invalid fd number.");
break;
}
2015-11-09 15:14:41 +01:00
r_core_bin_raise (core, binfile_num, -1);
break;
2015-11-09 15:14:41 +01:00
}
case ' ':
{
ut32 fd;
int n;
const char *tmp;
char *v;
v = input[2] ? strdup (input + 2) : NULL;
if (!v) {
eprintf ("Invalid arguments");
break;
}
2015-11-09 15:14:41 +01:00
n = r_str_word_set0 (v);
if (n < 2 || n > 2) {
eprintf ("Invalid arguments\n");
eprintf ("usage: ob fd obj\n");
free (v);
break;
}
2015-11-09 15:14:41 +01:00
tmp = r_str_word_get0 (v, 0);
fd = *v && r_is_valid_input_num_value (core->num, tmp) ?
r_get_input_num_value (core->num, tmp) : UT32_MAX;
tmp = r_str_word_get0 (v, 1);
binobj_num = *v && r_is_valid_input_num_value (core->num, tmp) ?
r_get_input_num_value (core->num, tmp) : UT32_MAX;
binfile_num = find_binfile_id_by_fd (core->bin, fd);
r_core_bin_raise (core, binfile_num, binobj_num);
free (v);
break;
2015-11-09 15:14:41 +01:00
}
case 'r':
r_core_bin_rebase (core, r_num_math (core->num, input + 3));
r_core_cmd0 (core, ".is*");
break;
case 'o':
2015-11-09 15:14:41 +01:00
value = input[3] ? input + 3 : NULL;
if (!value) {
2015-11-09 15:14:41 +01:00
eprintf ("Invalid argument");
break;
}
2015-11-09 15:14:41 +01:00
binobj_num = *value && r_is_valid_input_num_value (core->num, value) ?
r_get_input_num_value (core->num, value) : UT32_MAX;
if (binobj_num == UT32_MAX) {
2015-11-09 15:14:41 +01:00
eprintf ("Invalid binobj_num");
break;
}
r_core_bin_raise (core, -1, binobj_num);
break;
case '-': // "ob-"
2015-11-09 15:14:41 +01:00
//FIXME this command doesn't remove nothing
if (input[2] == '*') {
2015-11-09 15:14:41 +01:00
//FIXME this only delete from a list but it doesn't free any space
r_cons_printf ("[i] Deleted %d binfiles\n",
r_bin_file_delete_all (core->bin));
} else {
2015-11-09 15:14:41 +01:00
ut32 fd;
value = input[3] ? input + 3 : NULL;
if (!value) {
eprintf ("Invalid argument\n");
break;
}
fd = *value && r_is_valid_input_num_value (core->num, value) ?
r_get_input_num_value (core->num, value) : UT32_MAX;
binfile_num = find_binfile_id_by_fd (core->bin, fd);
if (binfile_num == UT32_MAX) {
eprintf ("Invalid fd\n");
break;
}
if (r_core_bin_delete (core, binfile_num, -1)){
if (!r_bin_file_delete (core->bin, fd))
eprintf ("Cannot find an RBinFile associated with that fd.\n");
2015-11-09 15:14:41 +01:00
} else {
eprintf ("Couldn't erase because there must be 1 bin object loaded\n");
}
}
break;
case 'd': // backward compat, must be deleted
2015-11-09 15:14:41 +01:00
value = input[2] ? input + 2 : NULL;
if (!value) {
2015-11-09 15:14:41 +01:00
eprintf ("Invalid bin object number.");
break;
}
binobj_num = *value && r_is_valid_input_num_value (core->num, value) ?
r_get_input_num_value (core->num, value) : UT32_MAX;
if (binobj_num == UT32_MAX) {
eprintf ("Invalid bin object number.");
break;
}
r_core_bin_delete (core, -1, binobj_num);
break;
case '?':
r_core_cmd_help (core, help_msg_ob);
break;
}
}
2017-08-23 12:18:29 +02:00
// TODO: discuss the output format
static void map_list(RIO *io, int mode, RPrint *print, int fd) {
SdbListIter *iter;
RIOMap *map;
if (!io || !io->maps || !print || !print->cb_printf) {
return;
}
2017-08-23 12:18:29 +02:00
if (mode == 'j') {
print->cb_printf ("[");
}
bool first = true;
ls_foreach (io->maps, iter, map) {
2017-08-23 12:18:29 +02:00
if (fd != -1 && map->fd != fd) {
continue;
}
switch (mode) {
2017-08-23 12:18:29 +02:00
case 'j':
if (!first) {
print->cb_printf (",");
}
first = false;
2017-08-23 12:18:29 +02:00
print->cb_printf ("{\"map\":%i,\"fd\":%d,\"delta\":%"PFMT64d",\"from\":%"PFMT64d
",\"to\":%"PFMT64d",\"flags\":\"%s\",\"name\":\"%s\"}", map->id, map->fd,
map->delta, map->from, map->to,
r_str_rwx_i (map->flags), (map->name ? map->name : ""));
break;
case 1:
2017-08-23 12:18:29 +02:00
case '*':
case 'r':
print->cb_printf ("om %d 0x%"PFMT64x" 0x%"PFMT64x" 0x%"PFMT64x"\n", map->fd,
map->from, map->to - map->from, map->delta);
break;
default:
print->cb_printf ("map: %i fd: %i +0x%"PFMT64x" 0x%"PFMT64x
" - 0x%"PFMT64x" ; %s : %s\n", map->id, map->fd,
map->delta, map->from, map->to,
r_str_rwx_i (map->flags), (map->name ? map->name : ""));
2017-08-23 12:18:29 +02:00
break;
}
}
2017-08-23 12:18:29 +02:00
if (mode == 'j') {
print->cb_printf ("]\n");
}
}
static void cmd_open_map (RCore *core, const char *input) {
ut64 fd = 0LL;
ut32 id = 0;
ut64 addr = 0LL;
ut64 size = 0LL;
ut64 delta = 0LL;
char *s, *p, *q;
ut64 new;
RIOMap *map = NULL;
const char *P;
switch (input[1]) {
case '.':
map = r_io_map_get (core->io, core->offset);
2017-08-23 21:38:25 +02:00
if (map) {
core->print->cb_printf ("map: %i fd: %i +0x%"PFMT64x" 0x%"PFMT64x
" - 0x%"PFMT64x" ; %s : %s\n", map->id, map->fd,
map->delta, map->from, map->to,
r_str_rwx_i (map->flags), map->name ? map->name : "");
}
break;
case 'r':
if (input[2] != ' ') {
break;
}
P = strchr (input+3, ' ');
if (P) {
id = (ut32)r_num_math (core->num, input+3); //mapid
new = r_num_math (core->num, P+1);
map = r_io_map_resolve (core->io, id); //the remapping should be done in the api
if (map) {
ut64 diff = map->to - map->from;
map->from = new;
map->to = new + diff; //this is so risky
2017-08-19 20:05:21 +02:00
} else {
eprintf ("Cannot find any map with mapid %d\n", id);
2017-08-19 20:05:21 +02:00
}
}
break;
case 's':
if (input[2] != 'p' || input[3] != ' ') {
break;
}
//sectionid
id = (ut32)r_num_math (core->num, input + 4);
if (!r_io_section_priorize (core->io, id)) {
eprintf ("Cannot priorize section with sectionid %d\n", id);
}
break;
case 'b':
if (input[2] != 'p' || input[3] != ' ') {
break;
}
//binid
id = (ut32)r_num_math (core->num, input + 4);
if (!r_io_section_priorize_bin (core->io, id)) {
eprintf ("Cannot priorize bin with binid %d\n", id);
}
break;
case 'f':
if (input[2] != 'p' || input[3] != ' ') {
break;
}
fd = r_num_math (core->num, input + 4);
if (!r_io_map_priorize_for_fd (core->io, (int)fd)) {
eprintf ("Cannot priorize any map for fd %d\n", (int)fd);
}
break;
case 'p':
if (input[2] != ' ') {
break;
}
id = r_num_math (core->num, input + 3); //mapid
if (r_io_map_exists_for_id (core->io, id)) {
r_io_map_priorize (core->io, id);
} else {
eprintf ("Cannot find any map with mapid %d\n", id);
}
break;
case ' ':
// i need to parse delta, offset, size
2017-08-19 20:05:21 +02:00
s = strdup (input + 2);
if (!s) {
break;
}
p = strchr (s, ' ');
if (p) {
RIODesc *desc;
q = strchr (p+1, ' ');
*p = 0;
fd = r_num_math (core->num, s);
if (!(desc = r_io_desc_get (core->io, fd))) {
free (s);
break;
}
2017-08-19 20:05:21 +02:00
addr = r_num_math (core->num, p + 1);
if (q) {
2017-08-19 20:05:21 +02:00
char *r = strchr (q + 1, ' ');
*q = 0;
if (r) {
*r = 0;
size = r_num_math (core->num, q + 1);
delta = r_num_math (core->num, r + 1);
} else {
size = r_num_math (core->num, q + 1);
}
2017-08-18 14:31:54 +00:00
} else {
size = r_io_desc_size (desc);
2017-08-23 12:18:29 +02:00
2017-08-18 14:31:54 +00:00
}
r_io_map_add (core->io, fd, desc->flags, delta, addr, size); //TODO:user should be able to set these
} else {
2017-08-23 12:18:29 +02:00
map_list (core->io, 0, core->print, r_num_math (core->num, s));
// eprintf ("Invalid use of om . See om? for help.");
}
free (s);
break;
case '-':
r_io_map_del (core->io, r_num_math (core->num, input+2));
break;
case '\0':
2017-08-23 12:18:29 +02:00
case 'j':
case '*':
2017-08-23 12:18:29 +02:00
map_list (core->io, input[1], core->print, -1);
break;
default:
case '?':
r_core_cmd_help (core, help_msg_om);
break;
}
r_core_block_read (core);
}
R_API void r_core_file_reopen_in_malloc (RCore *core) {
RCoreFile *f;
RListIter *iter;
r_list_foreach (core->files, iter, f) {
ut64 sz = r_io_fd_size (core->io, f->fd);
ut8 *buf = calloc (sz, 1);
if (!buf) {
eprintf ("Cannot allocate %d\n", (int)sz);
continue;
}
2017-05-03 17:19:49 +02:00
(void)r_io_pread_at (core->io, 0, buf, sz);
char *url = r_str_newf ("malloc://%d", (int)sz);
RIODesc *desc = r_io_open (core->io, url, R_IO_READ | R_IO_WRITE, 0); //use r_io_desc_exchange pls
if (desc) {
r_io_fd_close (core->io, f->fd);
f->fd = desc->fd;
(void)r_io_write_at (core->io, 0, buf, sz);
} else {
eprintf ("Cannot open %s\n", url);
}
2016-09-19 17:34:22 +02:00
free (buf);
2016-09-21 11:00:52 +02:00
free (url);
break;
}
}
R_API void r_core_file_reopen_debug (RCore *core, const char *args) {
2015-09-30 13:10:49 +02:00
RCoreFile *ofile = core->file;
RBinFile *bf = NULL;
RIODesc *desc;
2015-09-30 13:10:49 +02:00
char *binpath = NULL;
if (!ofile || !(desc = r_io_desc_get (core->io, ofile->fd)) || !desc->uri) {
2015-08-29 01:41:34 +02:00
eprintf ("No file open?\n");
return;
}
bf = r_bin_file_find_by_fd (core->bin, ofile->fd);
2015-09-30 13:10:49 +02:00
binpath = bf ? strdup (bf->file) : NULL;
2015-11-26 12:55:47 +01:00
if (!binpath) {
if (r_file_exists (desc->name)) {
binpath = strdup (desc->name);
2016-10-15 21:08:54 +02:00
}
2015-11-26 12:55:47 +01:00
}
2015-09-30 13:10:49 +02:00
if (!binpath) {
2016-10-15 21:08:54 +02:00
/* fallback to oo */
2016-10-15 23:42:12 +02:00
(void)r_core_cmd0 (core, "oo");
return;
2015-08-29 01:41:34 +02:00
}
2015-09-30 13:10:49 +02:00
int bits = core->assembler->bits;
char *oldname = r_file_abspath (binpath);
char *newfile = r_str_newf ("dbg://%s %s", oldname, args);
2015-11-05 13:38:58 +01:00
char *newfile2 = strdup (newfile);
desc->uri = newfile;
desc->referer = NULL;
//r_core_file_reopen (core, newfile, 0, 2);
2015-09-30 13:10:49 +02:00
r_config_set_i (core->config, "asm.bits", bits);
r_config_set_i (core->config, "cfg.debug", true);
r_core_file_reopen (core, newfile, 0, 2);
2015-11-05 13:38:58 +01:00
newfile = newfile2;
#if !__WINDOWS__
2017-06-14 12:18:46 +05:30
ut64 new_baddr = r_debug_get_baddr (core->dbg, newfile);
2015-10-19 04:33:06 -04:00
ut64 old_baddr = r_config_get_i (core->config, "bin.baddr");
if (old_baddr != new_baddr) {
r_bin_set_baddr (core->bin, new_baddr);
r_config_set_i (core->config, "bin.baddr", new_baddr);
r_core_bin_rebase (core, new_baddr);
// r_core_bin_load (core, newfile, new_baddr);
// reload symbols with new baddr
2017-05-16 21:52:28 +08:00
r_core_cmd0 (core, ".is*");
r_core_cmd0 (core, ".ir*");
r_core_cmd0 (core, ".iz*");
r_core_cmd0 (core, ".iM*");
2015-10-19 04:33:06 -04:00
}
#endif
2015-10-31 01:57:52 +01:00
r_core_cmd0 (core, "sr PC");
2015-09-30 13:10:49 +02:00
free (oldname);
2015-10-06 23:51:35 -04:00
free (binpath);
free (newfile);
2015-08-29 01:41:34 +02:00
}
2017-05-03 17:19:49 +02:00
static bool desc_list_cb(void *user, void *data, ut32 id) {
RPrint *p = (RPrint *)user;
RIODesc *desc = (RIODesc *)data;
p->cb_printf ("%2d %c %s : %s size=0x%"PFMT64x"\n", desc->fd,
(desc->io && (desc->io->desc == desc)) ? '*' : '-',
desc->uri, r_str_rwx_i (desc->flags), r_io_desc_size (desc));
#if 0
RIOMap *map;
SdbListIter *iter;
2017-05-03 17:19:49 +02:00
if (desc->io && desc->io->va && desc->io->maps) {
ls_foreach_prev (desc->io->maps, iter, map) {
if (map->fd == desc->fd) {
2017-08-14 00:55:47 +00:00
p->cb_printf (" +0x%"PFMT64x" 0x%"PFMT64x
" - 0x%"PFMT64x" : %s : %s : %s\n", map->delta,
map->from, map->to, r_str_rwx_i (map->flags), "",
map->name ? map->name : "");
2017-05-03 17:19:49 +02:00
}
}
}
#endif
2017-05-03 17:19:49 +02:00
return true;
}
2012-02-27 02:40:27 +01:00
static int cmd_open(void *data, const char *input) {
RCore *core = (RCore*)data;
int perms = R_IO_READ;
ut64 addr, baddr = r_config_get_i (core->config, "bin.baddr");
int nowarn = r_config_get_i (core->config, "file.nowarn");
2012-02-27 02:40:27 +01:00
RCoreFile *file;
2013-10-11 01:24:30 +02:00
int isn = 0;
2012-02-27 02:40:27 +01:00
char *ptr;
RListIter *iter;
2012-02-27 02:40:27 +01:00
switch (*input) {
#if 0 //TODO: reimplement me, but not in io, io is not for printing
2015-01-27 15:35:42 +01:00
case '=':
r_io_desc_list_visual (core->io, core->offset, core->blocksize,
r_cons_get_size (NULL), r_config_get_i (core->config, "scr.color"));
break;
2017-05-03 17:19:49 +02:00
#endif
2012-02-27 02:40:27 +01:00
case '\0':
2017-05-03 17:19:49 +02:00
r_id_storage_foreach (core->io->files, desc_list_cb, core->print);
break;
case '*':
if ('?' == input[1]) {
r_core_cmd_help (core, help_msg_o_star);
break;
}
case 'j':
if ('?' == input[1]) {
r_core_cmd_help (core, help_msg_oj);
break;
}
2015-01-24 23:26:17 +01:00
r_core_file_list (core, (int)(*input));
2012-02-27 02:40:27 +01:00
break;
case 'L':
r_io_plugin_list (core->io);
break;
case 'a': // "oa"
if ('?' == input[1]) {
r_core_cmd_help (core, help_msg_oa);
break;
}
addr = core->offset;
if (input[1]) {
char *arg = strdup (input + 2);
char *filename = strchr (arg, ' ');
if (filename) {
RIODesc *desc = r_io_open (core->io, filename + 1, R_IO_READ, 0);
if (desc) {
*filename = 0;
addr = r_num_math (core->num, arg);
2017-08-23 00:04:47 +00:00
r_bin_load_io (core->bin, desc->fd, addr, 0, 0);
r_io_desc_close (desc);
r_core_cmd0 (core, ".is*");
} else {
eprintf ("Cannot open %s\n", filename + 1);
}
} else {
addr = r_num_math (core->num, input + 1);
RCoreFile *cf = r_core_file_cur (core);
RIODesc *desc = r_io_desc_get (core->io, cf->fd);
if (cf && desc) {
2017-08-23 00:04:47 +00:00
r_bin_load_io (core->bin, desc->fd, addr, 0, 0);
r_core_cmd0 (core, ".is*");
} else {
eprintf ("No file to load bin from?\n");
}
}
free (arg);
} else {
/* reload all bininfo */
RIODesc *desc;
r_list_foreach (core->files, iter, file) {
desc = r_io_desc_get (core->io, file->fd);
2017-08-23 00:04:47 +00:00
r_bin_load_io (core->bin, desc->fd, addr, 0, 0);
r_core_cmd0 (core, ".is*");
break;
}
}
//r_bin_load_io_at_offset_as (core->bin, core->file->desc,
break;
case 'p':
if (r_sandbox_enable (0)) {
eprintf ("This command is disabled in sandbox mode\n");
return 0;
}
if (input[1]==' ') {
if (r_lib_open (core->lib, input+2) == R_FAIL) {
eprintf ("Oops\n");
}
} else {
eprintf ("Usage: op [r2plugin."R_LIB_EXT"]\n");
}
break;
case 'i': // "oi"
switch (input[1]) {
case ' ': // "oi "
{
RListIter *iter = NULL;
RCoreFile *f;
int nth = r_num_math (core->num, input + 2);
int count = 0;
r_list_foreach (core->files, iter, f) {
if (count == nth) {
r_io_use_fd (core->io, f->fd);
break;
}
count++;
}
}
break;
case '-': // "oi-"
{
RListIter *iter = NULL;
RCoreFile *f;
int nth = r_num_math (core->num, input + 2);
int count = 0;
r_list_foreach (core->files, iter, f) {
if (count == nth) {
r_core_file_close_fd (core, f->fd);
break;
}
count++;
}
}
break;
case 'j':
case '*':
case 0:
r_core_file_list (core, input[1]);
break;
}
break;
case '+':
perms = R_IO_READ|R_IO_WRITE;
/* fall through */
case 'f':
/* open file with spaces or special chars */
if (input[1] == ' ') {
const char *fn = input + 2;
file = r_core_file_open (core, fn, perms, 0);
if (file) {
r_core_bin_load (core, fn, UT64_MAX);
} else {
eprintf ("Cannot open (%s)\n", fn);
}
2012-02-27 02:40:27 +01:00
} else {
eprintf ("Usage: of [path-to-file]\n");
2012-02-27 02:40:27 +01:00
}
break;
2017-01-09 21:57:11 +01:00
case 'n': // "on"
// like in r2 -n
isn = 1;
if (input[1] == '*') {
r_core_file_list (core, 'n');
break;
}
2017-01-09 21:57:11 +01:00
/* fall through */
case ' ':
{
ut64 ba = 0L;
ut64 ma = 0L;
2017-01-09 21:57:11 +01:00
char *fn = strdup (input + (isn? 2:1));
2017-04-05 10:59:37 +02:00
if (!fn || !*fn) {
eprintf ("Usage: on [file]\n");
2017-04-05 10:59:37 +02:00
free (fn);
break;
}
2017-01-09 21:57:11 +01:00
ptr = strchr (fn, ' ');
if (ptr) {
*ptr++ = '\0';
char *ptr2 = strchr (ptr, ' ');
if (ptr2) {
*ptr2++ = 0;
ba = r_num_math (core->num, ptr2);
}
ma = r_num_math (core->num, ptr);
}
int num = atoi (input + 1);
if (num <= 0) {
if (fn && *fn) {
file = r_core_file_open (core, fn, perms, ma);
if (file) {
r_cons_printf ("%d\n", file->fd);
// MUST CLEAN BEFORE LOADING
if (!isn) {
r_core_bin_load (core, fn, ba);
}
} else if (!nowarn) {
eprintf ("Cannot open file '%s'\n", fn);
}
} else {
eprintf ("Usage: on [file] ([maddr]) ([baddr])\n");
}
} else {
RListIter *iter = NULL;
RCoreFile *f;
core->switch_file_view = 0;
r_list_foreach (core->files, iter, f) {
if (f->fd == num) {
2017-08-08 18:00:39 +02:00
r_io_use_fd (core->io, num);
//core->switch_file_view = 1;
// raise rbinobj too
int binfile_num = find_binfile_id_by_fd (core->bin, num);
r_core_bin_raise (core, binfile_num, -1);
break;
}
}
}
r_core_block_read (core);
2017-01-09 21:57:11 +01:00
free (fn);
}
2012-02-27 02:40:27 +01:00
break;
case 'b':
cmd_open_bin (core, input);
break;
2015-02-04 03:06:27 +01:00
case '-': // o-
switch (input[1]) {
2015-02-04 03:06:27 +01:00
case '*': // "o-*"
r_core_file_close_fd (core, -1);
r_io_close_all (core->io);
r_bin_file_delete_all (core->bin);
r_list_purge(core->files);
break;
2015-02-04 03:06:27 +01:00
case '-': // "o--"
eprintf ("All core files, io, anal and flags info purged.\n");
r_core_file_close_fd (core, -1);
r_io_close_all (core->io);
r_bin_file_delete_all (core->bin);
// TODO: Move to a-- ?
r_anal_purge (core->anal);
// TODO: Move to f-- ?
r_flag_unset_all (core->flags);
// TODO: rbin?
break;
2015-02-04 03:06:27 +01:00
default:
if (!r_core_file_close_fd (core, atoi (input + 1))) {
eprintf ("Unable to find filedescriptor %d\n",
atoi (input + 1));
}
break;
2015-02-04 03:06:27 +01:00
case '?':
eprintf ("Usage: o-# or o-*, where # is the filedescriptor number\n");
}
// hackaround to fix invalid read
//r_core_cmd0 (core, "oo");
2014-11-07 10:37:54 +01:00
// uninit deref
//r_core_block_read (core);
2012-02-27 02:40:27 +01:00
break;
case 'm':
cmd_open_map (core, input);
2012-02-27 02:40:27 +01:00
break;
case 'o':
switch (input[1]) {
case 'm': // "oom"
r_core_file_reopen_in_malloc (core);
break;
2015-08-19 15:13:08 +02:00
case 'd': // "ood" : reopen in debugger
if ('?' == input[2]) {
r_core_cmd_help (core, help_msg_ood);
} else {
r_core_file_reopen_debug (core, input + 2);
}
2015-08-19 15:13:08 +02:00
break;
case 'b': // "oob" : reopen with bin info
if ('?' == input[2]) {
r_core_cmd_help (core, help_msg_oob);
} else {
r_core_file_reopen (core, input + 2, 0, 2);
}
break;
case 'n':
if ('n' == input[2]) {
RIODesc *desc = r_io_desc_get (core->io, core->file->fd);
if ('?' == input[3]) {
r_core_cmd_help (core, help_msg_oonn);
break;
}
perms = (input[3] == '+')? R_IO_READ|R_IO_WRITE: 0;
2015-10-22 03:20:30 +02:00
r_core_file_reopen (core, input + 4, perms, 0);
2016-02-16 02:42:44 +01:00
// TODO: Use API instead of !rabin2 -rk
if (desc) {
r_core_cmdf (core, ".!rabin2 -rk '' '%s'", desc->name);
}
} else if ('?' == input[2]) {
r_core_cmd_help (core, help_msg_oon);
break;
2015-10-21 02:30:28 +02:00
}
perms = ('+' == input[2])? R_IO_READ|R_IO_WRITE: 0;
r_core_file_reopen (core, input + 3, perms, 0);
break;
case '+':
if ('?' == input[2]) {
r_core_cmd_help (core, help_msg_oo_plus);
} else if (core && core->io && core->io->desc) {
int fd;
if ((ptr = strrchr (input, ' ')) && ptr[1]) {
fd = (int)r_num_math (core->num, ptr + 1);
} else {
fd = core->io->desc->fd;
}
r_io_reopen (core->io , fd, R_IO_READ | R_IO_WRITE, 644);
}
break;
case '\0': // "oo"
if (core && core->io && core->io->desc) {
//does not work for debugging
int fd;
if ((ptr = strrchr (input, ' ')) && ptr[1]) {
fd = (int)r_num_math (core->num, ptr + 1);
} else {
fd = core->io->desc->fd;
}
r_io_reopen (core->io, fd, R_IO_READ, 644);
}
break;
case '?':
default:
r_core_cmd_help (core, help_msg_oo);
break;
}
2012-02-27 02:40:27 +01:00
break;
case 'c':
if (input[1] && input[2]) {
if (r_sandbox_enable (0)) {
eprintf ("This command is disabled in sandbox mode\n");
return 0;
}
// memleak? lose all settings wtf
// if load fails does not fallbacks to previous file
r_core_fini (core);
r_core_init (core);
if (!r_core_file_open (core, input + 2, R_IO_READ, 0)) {
eprintf ("Cannot open file\n");
}
(void)r_core_bin_load (core, NULL, baddr);
} else {
eprintf ("Missing argument\n");
}
break;
case 'x':
{
int fd, fdx;
fd = fdx = -1;
if ((ptr = strrchr (input, ' '))) {
fdx = (int)r_num_math (core->num, ptr + 1);
*ptr = '\0';
if ((ptr = strchr (input, ' '))) {
fd = r_num_math (core->num, ptr + 1);
}
}
if ((fdx == -1) || (fd == -1) || (fdx == fd)) {
break;
}
r_io_desc_exchange (core->io, fd, fdx);
r_core_block_read (core);
}
break;
2012-02-27 02:40:27 +01:00
case '?':
default:
r_core_cmd_help (core, help_msg_o);
2012-02-27 02:40:27 +01:00
break;
}
return 0;
}