2014-01-18 02:10:50 +01:00
|
|
|
/* radare - LGPL - Copyright 2009-2014 - pancake */
|
2009-02-05 22:08:46 +01:00
|
|
|
|
|
|
|
#include <r_core.h>
|
2014-01-25 18:06:17 -06:00
|
|
|
#include <stdlib.h>
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
|
|
|
|
static int r_core_file_do_load_for_debug (RCore *r, ut64 loadaddr, const char *filenameuri);
|
|
|
|
static int r_core_file_do_load_for_io_plugin (RCore *r, ut64 baseaddr, ut64 loadaddr);
|
2014-04-29 11:10:35 -05:00
|
|
|
// After June 2014, if no problems delete r_core_file_do_load_for_hex
|
|
|
|
//static int r_core_file_do_load_for_hex (RCore *r, ut64 baddr, ut64 loadaddr, const char *filenameuri);
|
2014-05-03 09:57:50 -05:00
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
|
2011-12-05 02:42:06 +01:00
|
|
|
// TODO: add support for args
|
2014-10-17 00:36:00 +02:00
|
|
|
R_API int r_core_file_reopen(RCore *core, const char *args, int perm, int loadbin) {
|
2014-08-18 18:06:27 +02:00
|
|
|
int isdebug = r_config_get_i (core->config, "cfg.debug");
|
2011-12-05 02:42:06 +01:00
|
|
|
char *path;
|
2014-06-25 04:11:43 +02:00
|
|
|
ut64 ofrom = 0, baddr = 0; // XXX ? check file->map ?
|
2014-08-18 18:06:27 +02:00
|
|
|
RCoreFile *file = NULL;
|
|
|
|
RCoreFile *ofile = core->file;
|
|
|
|
RBinFile *bf = (ofile && ofile->desc) ?
|
|
|
|
r_bin_file_find_by_fd (core->bin, ofile->desc->fd) : NULL;
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *odesc = ofile ? ofile->desc : NULL;
|
2014-11-03 10:47:02 +01:00
|
|
|
char *ofilepath, *obinfilepath = bf ? strdup (bf->file) : NULL;
|
2012-10-22 10:12:13 +02:00
|
|
|
int newpid, ret = R_FALSE;
|
2014-10-17 00:04:52 +02:00
|
|
|
ut64 origoff = core->offset;
|
2014-11-03 10:47:02 +01:00
|
|
|
if (odesc) {
|
|
|
|
if (odesc->referer) {
|
|
|
|
ofilepath = odesc->referer;
|
|
|
|
} else if (odesc->uri) {
|
|
|
|
ofilepath = odesc->uri;
|
|
|
|
}
|
|
|
|
}
|
2014-11-03 11:47:51 +01:00
|
|
|
|
2012-10-22 10:43:10 +02:00
|
|
|
if (r_sandbox_enable (0)) {
|
|
|
|
eprintf ("Cannot reopen in sandbox\n");
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
2014-11-03 11:47:51 +01:00
|
|
|
#if 0
|
2014-10-07 17:53:04 +02:00
|
|
|
if (isdebug) {
|
|
|
|
// if its in debugger mode we have to respawn a new process
|
|
|
|
// instead of reattaching
|
|
|
|
free (ofilepath);
|
|
|
|
ofilepath = r_str_newf ("dbg://%s", odesc->name);
|
|
|
|
}
|
2014-11-03 11:47:51 +01:00
|
|
|
#endif
|
2011-12-05 02:42:06 +01:00
|
|
|
if (!core->file) {
|
|
|
|
eprintf ("No file opened to reopen\n");
|
Fixed some issues in bin/dwarf.c and Fixed 1205194, 1205193, 1205192, 1205202, 1205203, 1205204, 1205205, 1205209, 1205208, 1205207, 1205206
2014-04-25 15:14:49 -05:00
|
|
|
free (ofilepath);
|
|
|
|
free (obinfilepath);
|
2011-12-05 02:42:06 +01:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
newpid = odesc ? odesc->fd : -1;
|
|
|
|
|
2014-08-18 18:06:27 +02:00
|
|
|
if (isdebug) {
|
|
|
|
r_debug_kill (core->dbg, core->dbg->pid,
|
|
|
|
core->dbg->tid, 9); // KILL
|
2014-10-17 00:04:52 +02:00
|
|
|
perm = 7;
|
|
|
|
} else {
|
|
|
|
if (!perm) {
|
|
|
|
perm = 4; //R_IO_READ;
|
|
|
|
}
|
|
|
|
}
|
2014-11-03 11:47:51 +01:00
|
|
|
if (!ofilepath) {
|
2014-10-17 00:04:52 +02:00
|
|
|
eprintf ("Unknown file path");
|
|
|
|
return R_FALSE;
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
2014-02-21 10:58:31 +01:00
|
|
|
|
|
|
|
// HACK: move last mapped address to higher place
|
2014-04-23 18:04:25 -05:00
|
|
|
// XXX - why does this hack work?
|
|
|
|
if (ofile->map) {
|
|
|
|
ofrom = ofile->map->from;
|
2014-10-17 00:04:52 +02:00
|
|
|
ofile->map->from = UT32_MAX;
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
2014-04-22 23:02:46 -05:00
|
|
|
// closing the file to make sure there are no collisions
|
|
|
|
// when the new memory maps are created.
|
2014-11-03 11:47:51 +01:00
|
|
|
path = strdup (ofilepath);
|
|
|
|
obinfilepath = strdup(ofilepath);
|
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
file = r_core_file_open (core, path, perm, baddr);
|
2011-12-05 02:42:06 +01:00
|
|
|
if (file) {
|
2014-10-17 00:36:00 +02:00
|
|
|
int had_rbin_info = 0;
|
2014-10-17 00:04:52 +02:00
|
|
|
ofile->map->from = ofrom;
|
2014-10-17 00:36:00 +02:00
|
|
|
if (r_bin_file_delete (core->bin, ofile->desc->fd)) {
|
|
|
|
had_rbin_info = 1;
|
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
r_core_file_close (core, ofile);
|
2014-04-25 14:21:20 -05:00
|
|
|
r_core_file_set_by_file (core, file);
|
2014-10-17 00:04:52 +02:00
|
|
|
r_core_file_set_by_fd (core, file->desc->fd);
|
2014-04-23 18:04:25 -05:00
|
|
|
ofile = NULL;
|
|
|
|
odesc = NULL;
|
2014-10-17 00:04:52 +02:00
|
|
|
// core->file = file;
|
2012-10-22 10:12:13 +02:00
|
|
|
eprintf ("File %s reopened in %s mode\n", path,
|
2014-10-17 00:04:52 +02:00
|
|
|
(perm&R_IO_WRITE)? "read-write": "read-only");
|
2014-04-23 18:04:25 -05:00
|
|
|
|
2014-10-17 00:36:00 +02:00
|
|
|
if (loadbin && (loadbin==2 || had_rbin_info)) {
|
|
|
|
ret = r_core_bin_load (core, obinfilepath, baddr);
|
|
|
|
if (!ret) {
|
|
|
|
eprintf ("Error: Failed to reload rbin for: %s", path);
|
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
/*
|
2014-05-28 04:34:12 +02:00
|
|
|
if (core->bin->cur && file->desc) {
|
|
|
|
core->bin->cur->fd = file->desc->fd;
|
2014-04-23 18:04:25 -05:00
|
|
|
ret = R_TRUE;
|
|
|
|
}*/
|
2012-10-22 10:12:13 +02:00
|
|
|
// close old file
|
2014-08-18 18:06:27 +02:00
|
|
|
} else if (ofile) {
|
2014-04-22 23:02:46 -05:00
|
|
|
eprintf ("r_core_file_reopen: Cannot reopen file: %s with perms 0x%04x,"
|
|
|
|
" attempting to open read-only.\n", path, perm);
|
2014-02-21 10:58:31 +01:00
|
|
|
// lower it down back
|
2014-04-22 23:02:46 -05:00
|
|
|
//ofile = r_core_file_open (core, path, R_IO_READ, addr);
|
2014-04-25 14:21:20 -05:00
|
|
|
r_core_file_set_by_file (core, ofile);
|
2014-02-21 10:58:31 +01:00
|
|
|
ofile->map->from = ofrom;
|
2014-10-17 00:04:52 +02:00
|
|
|
} else {
|
|
|
|
eprintf ("Cannot reopen\n");
|
2011-12-05 02:42:06 +01:00
|
|
|
}
|
2014-08-18 18:06:27 +02:00
|
|
|
if (isdebug) {
|
2014-04-23 18:04:25 -05:00
|
|
|
// XXX - select the right backend
|
2014-05-28 04:34:12 +02:00
|
|
|
if (core->file && core->file->desc)
|
|
|
|
newpid = core->file->desc->fd;
|
2014-04-23 18:04:25 -05:00
|
|
|
r_core_setup_debugger (core, "native");
|
2014-08-18 18:06:27 +02:00
|
|
|
r_debug_select (core->dbg, newpid, newpid);
|
2011-12-05 02:42:06 +01:00
|
|
|
}
|
2014-04-22 23:02:46 -05:00
|
|
|
|
2014-04-25 14:21:20 -05:00
|
|
|
if (core->file) {
|
|
|
|
RCoreFile * cf = core->file;
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = cf ? cf->desc : NULL;
|
2014-10-17 00:04:52 +02:00
|
|
|
if (desc) {
|
|
|
|
#if 0
|
2014-04-27 02:06:50 -05:00
|
|
|
r_io_raise (core->io, desc->fd);
|
|
|
|
core->switch_file_view = 1;
|
2014-10-17 00:04:52 +02:00
|
|
|
#endif
|
2014-04-27 02:06:50 -05:00
|
|
|
r_core_block_read (core, 0);
|
|
|
|
} else {
|
2014-09-09 17:01:04 +02:00
|
|
|
const char *name = (cf && cf->desc) ? cf->desc->name : "ERROR";
|
2014-04-27 02:06:50 -05:00
|
|
|
eprintf ("Error: Unable to switch the view to file: %s\n", name);
|
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
2014-10-20 22:48:50 +02:00
|
|
|
r_core_seek (core, origoff, 1);
|
2014-08-19 10:15:46 +02:00
|
|
|
if (isdebug) {
|
|
|
|
r_core_cmd0 (core, ".dr*");
|
|
|
|
r_core_cmd0 (core, "sr pc");
|
|
|
|
}
|
2014-05-03 04:26:07 +04:00
|
|
|
// This is done to ensure that the file is correctly
|
2014-04-22 23:02:46 -05:00
|
|
|
// loaded into the view
|
2014-04-23 18:04:25 -05:00
|
|
|
free (obinfilepath);
|
2014-11-03 11:47:51 +01:00
|
|
|
//free (ofilepath);
|
2011-12-05 02:42:06 +01:00
|
|
|
free (path);
|
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-02-04 11:30:08 +01:00
|
|
|
// NOTE: probably not all environment vars takes sesnse
|
|
|
|
// because they can be replaced by commands in the given
|
|
|
|
// command.. we should only expose the most essential and
|
|
|
|
// unidirectional ones.
|
2014-06-20 13:25:17 +02:00
|
|
|
R_API void r_core_sysenv_help(const RCore* core) {
|
|
|
|
const char* help_msg[] = {
|
|
|
|
"Usage:", "!<cmd>", "Run given command as in system(3)",
|
|
|
|
"!", "", "list all historic commands",
|
|
|
|
"!", "ls", "execute 'ls' in shell",
|
|
|
|
"!!", "", "save command history to hist file",
|
|
|
|
"!!", "ls~txt", "print output of 'ls' and grep for 'txt'",
|
2014-08-24 10:41:32 +02:00
|
|
|
".!", "rabin2 -rpsei ${FILE}", "run each output line as a r2 cmd",
|
2014-06-20 13:25:17 +02:00
|
|
|
"!", "echo $SIZE", "display file size",
|
|
|
|
"\nEnvironment:", "", "",
|
|
|
|
"FILE", "", "file name",
|
|
|
|
"SIZE", "","file size",
|
|
|
|
"OFFSET", "", "10base offset 64bit value",
|
|
|
|
"XOFFSET", "", "same as above, but in 16 base",
|
|
|
|
"BSIZE", "", "block size",
|
|
|
|
"ENDIAN", "", "'big' or 'little'",
|
|
|
|
"ARCH", "", "value of asm.arch",
|
|
|
|
"DEBUG", "", "debug mode enabled? (1,0)",
|
|
|
|
"IOVA", "", "is io.va true? virtual addressing (1,0)",
|
|
|
|
"BLOCK", "", "TODO: dump current block to tmp file",
|
|
|
|
"BYTES", "", "TODO: variable with bytes in curblock",
|
|
|
|
NULL
|
|
|
|
};
|
|
|
|
r_core_cmd_help (core, help_msg);
|
2011-02-04 11:30:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API void r_core_sysenv_end(RCore *core, const char *cmd) {
|
|
|
|
// TODO: remove tmpfilez
|
|
|
|
if (strstr (cmd, "BLOCK")) {
|
|
|
|
// remove temporary BLOCK file
|
2012-02-09 01:38:16 +01:00
|
|
|
char *f = r_sys_getenv ("BLOCK");
|
|
|
|
if (f) {
|
|
|
|
r_file_rm (f);
|
|
|
|
r_sys_setenv ("BLOCK", NULL);
|
2014-05-03 04:26:07 +04:00
|
|
|
free (f);
|
2012-02-09 01:38:16 +01:00
|
|
|
}
|
2011-02-04 11:30:08 +01:00
|
|
|
}
|
2012-02-09 01:38:16 +01:00
|
|
|
r_sys_setenv ("BYTES", NULL);
|
|
|
|
r_sys_setenv ("OFFSET", NULL);
|
2011-02-04 11:30:08 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API char *r_core_sysenv_begin(RCore *core, const char *cmd) {
|
2013-02-11 10:51:45 +01:00
|
|
|
char buf[64], *ret, *f;
|
2010-08-19 20:28:25 +02:00
|
|
|
#if DISCUSS
|
2011-05-24 15:25:52 +02:00
|
|
|
// EDITOR cfg.editor (vim or so)
|
|
|
|
CURSOR cursor position (offset from curseek)
|
|
|
|
COLOR scr.color?1:0
|
|
|
|
VERBOSE cfg.verbose
|
|
|
|
// only if cmd matches BYTES or BLOCK ?
|
|
|
|
BYTES hexpairs of current block
|
|
|
|
BLOCK temporally file with contents of current block
|
2010-08-19 20:28:25 +02:00
|
|
|
#endif
|
2011-02-04 11:30:08 +01:00
|
|
|
ret = strdup (cmd);
|
2012-02-09 01:38:16 +01:00
|
|
|
if (strstr (cmd, "BYTES")) {
|
|
|
|
char *s = r_hex_bin2strdup (core->block, core->blocksize);
|
|
|
|
r_sys_setenv ("BYTES", s);
|
|
|
|
free (s);
|
2011-02-04 11:30:08 +01:00
|
|
|
}
|
2014-09-26 17:58:17 +02:00
|
|
|
if (core->file && core->file->desc && core->file->desc->name) {
|
2014-09-09 17:01:04 +02:00
|
|
|
r_sys_setenv ("FILE", core->file->desc->name);
|
2014-09-28 00:05:20 +02:00
|
|
|
snprintf (buf, sizeof (buf), "%"PFMT64d, r_io_desc_size (core->io, core->file->desc));
|
2014-09-26 17:58:17 +02:00
|
|
|
r_sys_setenv ("SIZE", buf);
|
|
|
|
if (strstr (cmd, "BLOCK")) {
|
|
|
|
// replace BLOCK in RET string
|
|
|
|
if ((f = r_file_temp ("r2block"))) {
|
|
|
|
if (r_file_dump (f, core->block, core->blocksize))
|
|
|
|
r_sys_setenv ("BLOCK", f);
|
|
|
|
free (f);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2010-08-19 20:28:25 +02:00
|
|
|
snprintf (buf, sizeof (buf), "%"PFMT64d, core->offset);
|
|
|
|
r_sys_setenv ("OFFSET", buf);
|
|
|
|
snprintf (buf, sizeof (buf), "0x%08"PFMT64x, core->offset);
|
|
|
|
r_sys_setenv ("XOFFSET", buf);
|
|
|
|
r_sys_setenv ("ENDIAN", core->assembler->big_endian?"big":"little");
|
|
|
|
snprintf (buf, sizeof (buf), "%d", core->blocksize);
|
|
|
|
r_sys_setenv ("BSIZE", buf);
|
|
|
|
r_sys_setenv ("ARCH", r_config_get (core->config, "asm.arch"));
|
|
|
|
r_sys_setenv ("DEBUG", r_config_get_i (core->config, "cfg.debug")?"1":"0");
|
|
|
|
r_sys_setenv ("IOVA", r_config_get_i (core->config, "io.va")?"1":"0");
|
2011-02-04 11:30:08 +01:00
|
|
|
return ret;
|
2010-08-19 20:28:25 +02:00
|
|
|
}
|
|
|
|
|
2013-12-17 02:10:13 +01:00
|
|
|
static ut64 get_base_from_maps(RCore *core, const char *file) {
|
|
|
|
RDebugMap *map;
|
|
|
|
RListIter *iter;
|
|
|
|
ut64 b = 0LL;
|
2014-01-09 16:57:04 -06:00
|
|
|
|
2013-12-17 02:10:13 +01:00
|
|
|
r_debug_map_sync (core->dbg); // update process memory maps
|
|
|
|
r_list_foreach (core->dbg->maps, iter, map) {
|
|
|
|
if ((map->perm & 5)==5) {
|
2014-01-11 00:56:02 -06:00
|
|
|
// TODO: make this more flexible
|
|
|
|
// XXX - why "copy/" here?
|
|
|
|
if (map->name && strstr (map->name, "copy/")) return map->addr;
|
|
|
|
if (map->file && !strcmp (map->file, file)) return map->addr;
|
|
|
|
if (map->name && !strcmp (map->name, file)) return map->addr;
|
|
|
|
// XXX - Commented out, as this could unexpected results
|
|
|
|
//b = map->addr;
|
2013-12-17 02:10:13 +01:00
|
|
|
}
|
|
|
|
}
|
|
|
|
return b;
|
|
|
|
}
|
|
|
|
|
2014-01-11 00:56:02 -06:00
|
|
|
R_API int r_core_bin_reload(RCore *r, const char *file, ut64 baseaddr) {
|
2014-01-09 16:57:04 -06:00
|
|
|
int result = 0;
|
2014-05-08 18:35:04 -05:00
|
|
|
RCoreFile *cf = r_core_file_cur (r);
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = cf ? cf->desc : NULL;
|
2014-05-08 18:35:04 -05:00
|
|
|
RBinFile *bf = NULL;
|
|
|
|
|
|
|
|
if (desc) result = r_bin_reload (r->bin, desc, baseaddr);
|
|
|
|
bf = r_bin_cur (r->bin);
|
|
|
|
r_core_bin_set_env (r, bf);
|
2014-01-09 16:57:04 -06:00
|
|
|
return result;
|
2014-01-03 21:36:02 -06:00
|
|
|
}
|
|
|
|
|
2014-04-27 02:06:50 -05:00
|
|
|
// XXX - need to handle index selection during debugging
|
2014-04-23 18:04:25 -05:00
|
|
|
static int r_core_file_do_load_for_debug (RCore *r, ut64 loadaddr, const char *filenameuri) {
|
2014-04-29 11:10:35 -05:00
|
|
|
RCoreFile *cf = r_core_file_cur (r);
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = cf ? cf->desc : NULL;
|
2014-04-27 02:06:50 -05:00
|
|
|
RBinFile *binfile = NULL;
|
2014-05-04 10:03:15 -05:00
|
|
|
RBinPlugin *plugin;
|
2014-04-23 18:04:25 -05:00
|
|
|
ut64 baseaddr = 0;
|
2014-05-08 17:38:29 +02:00
|
|
|
//int va = r->io->va || r->io->debug;
|
2014-04-27 02:06:50 -05:00
|
|
|
int xtr_idx = 0; // if 0, load all if xtr is used
|
|
|
|
int treat_as_rawstr = R_FALSE;
|
2014-04-23 18:04:25 -05:00
|
|
|
|
|
|
|
if (!desc) return R_FALSE;
|
2014-04-29 11:10:35 -05:00
|
|
|
if (cf && desc) {
|
2014-04-23 18:04:25 -05:00
|
|
|
int newpid = desc->fd;
|
|
|
|
r_debug_select (r->dbg, newpid, newpid);
|
|
|
|
}
|
|
|
|
baseaddr = get_base_from_maps (r, filenameuri);
|
2014-08-25 03:58:22 +02:00
|
|
|
if (baseaddr != UT64_MAX) {
|
|
|
|
// eprintf ("LOADING AT 0x%08llx\n", baseaddr);
|
|
|
|
r_config_set_i (r->config, "bin.laddr", baseaddr);
|
|
|
|
}
|
2014-04-27 02:06:50 -05:00
|
|
|
|
|
|
|
if (!r_bin_load (r->bin, filenameuri, baseaddr, loadaddr, xtr_idx, desc->fd, treat_as_rawstr)) {
|
2014-09-08 23:29:01 +02:00
|
|
|
if (r_config_get_i (r->config, "bin.rawstr")) {
|
|
|
|
treat_as_rawstr = R_TRUE;
|
|
|
|
if (!r_bin_load (r->bin, filenameuri, baseaddr, loadaddr, xtr_idx, desc->fd, treat_as_rawstr)) {
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
2014-05-04 10:03:15 -05:00
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
|
|
|
|
2014-05-04 10:03:15 -05:00
|
|
|
binfile = r_bin_cur (r->bin);
|
|
|
|
r_core_bin_set_env (r, binfile);
|
2014-05-08 18:35:04 -05:00
|
|
|
plugin = r_bin_file_cur_plugin (binfile);
|
2014-05-04 10:03:15 -05:00
|
|
|
if ( plugin && strncmp (plugin->name, "any", 5)==0 ) {
|
|
|
|
// set use of raw strings
|
|
|
|
r_config_set_i (r->config, "io.va", 0);
|
2014-09-08 23:29:01 +02:00
|
|
|
//\\ r_config_set (r->config, "bin.rawstr", "true");
|
2014-05-04 10:03:15 -05:00
|
|
|
// get bin.minstr
|
|
|
|
r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
|
|
|
|
} else if (binfile) {
|
|
|
|
RBinObject *obj = r_bin_get_object (r->bin);
|
|
|
|
RBinInfo * info = obj ? obj->info : NULL;
|
|
|
|
if (plugin && strcmp (plugin->name, "any") && info) {
|
2014-05-04 22:08:46 -05:00
|
|
|
r_core_bin_set_arch_bits (r, binfile->file, info->arch, info->bits);
|
2014-05-04 10:03:15 -05:00
|
|
|
}
|
2014-04-27 02:06:50 -05:00
|
|
|
}
|
|
|
|
|
2014-05-04 10:03:15 -05:00
|
|
|
if (plugin && !strcmp (plugin->name, "dex")) {
|
|
|
|
r_core_cmd0 (r, "\"(fix-dex,wx `#sha1 $s-32 @32` @12 ; wx `#adler32 $s-12 @12` @8)\"\n");
|
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
|
2014-05-04 10:03:15 -05:00
|
|
|
if (r_config_get_i (r->config, "file.analyze")) r_core_cmd0 (r, "aa");
|
2014-04-23 18:04:25 -05:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
|
|
|
static int r_core_file_do_load_for_io_plugin (RCore *r, ut64 baseaddr, ut64 loadaddr) {
|
2014-04-29 11:10:35 -05:00
|
|
|
RCoreFile *cf = r_core_file_cur (r);
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = cf ? cf->desc : NULL;
|
2014-04-23 18:04:25 -05:00
|
|
|
RBinFile *binfile = NULL;
|
2014-04-27 02:06:50 -05:00
|
|
|
int xtr_idx = 0; // if 0, load all if xtr is used
|
2014-05-04 10:03:15 -05:00
|
|
|
RBinPlugin * plugin;
|
2014-04-23 18:04:25 -05:00
|
|
|
|
|
|
|
if (!desc) return R_FALSE;
|
2014-05-28 04:34:12 +02:00
|
|
|
r_io_use_desc (r->io, desc);
|
2014-04-29 11:10:35 -05:00
|
|
|
if ( !r_bin_load_io (r->bin, desc, baseaddr, loadaddr, xtr_idx)) {
|
|
|
|
//eprintf ("Failed to load the bin with an IO Plugin.\n");
|
2014-04-27 02:06:50 -05:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
2014-05-04 10:03:15 -05:00
|
|
|
binfile = r_bin_cur (r->bin);
|
|
|
|
r_core_bin_set_env (r, binfile);
|
2014-05-08 18:35:04 -05:00
|
|
|
plugin = r_bin_file_cur_plugin (binfile);
|
2014-05-04 10:03:15 -05:00
|
|
|
if ( plugin && strncmp (plugin->name, "any", 5)==0 ) {
|
2014-04-23 18:04:25 -05:00
|
|
|
// set use of raw strings
|
2014-05-04 10:03:15 -05:00
|
|
|
r_config_set_i (r->config, "io.va", 0);
|
2014-09-08 23:29:01 +02:00
|
|
|
// r_config_set (r->config, "bin.rawstr", "true");
|
2014-04-23 18:04:25 -05:00
|
|
|
// get bin.minstr
|
|
|
|
r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
|
2014-05-04 10:03:15 -05:00
|
|
|
} else if (binfile) {
|
|
|
|
RBinObject *obj = r_bin_get_object (r->bin);
|
|
|
|
RBinInfo * info = obj ? obj->info : NULL;
|
|
|
|
if (plugin && strcmp (plugin->name, "any") && info) {
|
2014-08-27 23:51:17 +02:00
|
|
|
r_core_bin_set_arch_bits (r, binfile->file,
|
|
|
|
info->arch, info->bits);
|
2014-05-04 10:03:15 -05:00
|
|
|
} else {
|
|
|
|
r_config_set_i (r->config, "io.va", 0);
|
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
|
|
|
|
2014-05-04 10:03:15 -05:00
|
|
|
if (plugin && !strcmp (plugin->name, "dex")) {
|
|
|
|
r_core_cmd0 (r, "\"(fix-dex,wx `#sha1 $s-32 @32` @12 ; wx `#adler32 $s-12 @12` @8)\"\n");
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
2014-04-29 11:10:35 -05:00
|
|
|
|
2014-05-04 10:03:15 -05:00
|
|
|
if (r_config_get_i (r->config, "file.analyze"))
|
|
|
|
r_core_cmd0 (r, "aa");
|
2014-04-23 18:04:25 -05:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
2014-05-03 04:26:07 +04:00
|
|
|
#if 0
|
2014-04-29 11:10:35 -05:00
|
|
|
// XXX - remove this code after June 2014, because current code setup is sufficient
|
2014-04-23 18:04:25 -05:00
|
|
|
static int r_core_file_do_load_for_hex (RCore *r, ut64 baddr, ut64 loadaddr, const char *filenameuri) {
|
|
|
|
// HEXEDITOR
|
|
|
|
RBinFile * binfile = NULL;
|
2014-04-27 02:06:50 -05:00
|
|
|
ut64 fd = r_core_file_cur_fd (r);
|
2014-04-23 18:04:25 -05:00
|
|
|
int i = 0;
|
2014-04-27 02:06:50 -05:00
|
|
|
int xtr_idx = 0; // if 0, load all if xtr is used
|
|
|
|
int treat_as_rawstr = R_FALSE;
|
2014-04-23 18:04:25 -05:00
|
|
|
|
2014-04-27 02:06:50 -05:00
|
|
|
if (!r_bin_load (r->bin, filenameuri, baddr, loadaddr, xtr_idx, fd, treat_as_rawstr)) {
|
|
|
|
treat_as_rawstr = R_TRUE;
|
|
|
|
if (!r_bin_load (r->bin, filenameuri, baddr, loadaddr, xtr_idx, fd, treat_as_rawstr))
|
2014-04-23 18:04:25 -05:00
|
|
|
return R_FALSE;
|
|
|
|
}
|
|
|
|
|
|
|
|
binfile = r_core_bin_cur (r);
|
2014-04-27 02:06:50 -05:00
|
|
|
if (binfile) {
|
|
|
|
r_core_bin_bind (r, binfile);
|
|
|
|
}
|
|
|
|
|
|
|
|
// binary files should be treated as views into a file
|
|
|
|
// not the actual file
|
|
|
|
/*
|
|
|
|
{
|
|
|
|
RListIter *iter;
|
|
|
|
RIOMap *im;
|
|
|
|
|
|
|
|
r_list_foreach (r->io->maps, iter, im) {
|
|
|
|
if (binfile->size > 0) {
|
|
|
|
im->delta = binfile->offset;
|
|
|
|
im->to = im->from + binfile->size;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}*/
|
2014-04-23 18:04:25 -05:00
|
|
|
|
2014-04-27 02:06:50 -05:00
|
|
|
if (binfile->narch>1 && r_config_get_i (r->config, "scr.prompt")) {
|
|
|
|
int narch = binfile->narch;
|
2014-04-23 18:04:25 -05:00
|
|
|
eprintf ("NOTE: Fat binary found. Selected sub-bin is: -a %s -b %d\n",
|
2014-04-27 02:06:50 -05:00
|
|
|
r->assembler->cur->arch, r->assembler->bits);
|
2014-04-23 18:04:25 -05:00
|
|
|
eprintf ("NOTE: Use -a and -b to select sub binary in fat binary\n");
|
2014-04-27 02:06:50 -05:00
|
|
|
|
|
|
|
for (i=0; i<narch; i++) {
|
|
|
|
RBinFile *lbinfile = r_bin_file_find_by_name_n (r->bin, binfile->file, i);
|
|
|
|
RBinObject *lbinobj = lbinfile ? lbinfile->o : NULL;
|
|
|
|
if (lbinobj && lbinobj->info) {
|
2014-04-23 18:04:25 -05:00
|
|
|
eprintf (" $ r2 -a %s -b %d %s # 0x%08"PFMT64x"\n",
|
2014-04-27 02:06:50 -05:00
|
|
|
lbinobj->info->arch,
|
|
|
|
lbinobj->info->bits,
|
|
|
|
binfile->file,
|
|
|
|
lbinobj->boffset);
|
2014-04-23 18:04:25 -05:00
|
|
|
} else eprintf ("No extract info found.\n");
|
|
|
|
}
|
|
|
|
}
|
2014-04-27 02:06:50 -05:00
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
2014-04-29 11:10:35 -05:00
|
|
|
#endif
|
2010-10-04 10:55:43 +02:00
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
R_API int r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
|
|
|
|
const char *suppress_warning = r_config_get (r->config, "file.nowarn");
|
|
|
|
ut64 loadaddr = 0;
|
2014-04-29 11:10:35 -05:00
|
|
|
RCoreFile *cf = r_core_file_cur (r);
|
2014-04-23 18:04:25 -05:00
|
|
|
RBinFile *binfile = NULL;
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = cf ? cf->desc : NULL;
|
2014-05-04 10:03:15 -05:00
|
|
|
RBinPlugin *plugin = NULL;
|
2014-04-23 18:04:25 -05:00
|
|
|
|
|
|
|
int is_io_load = desc && desc->plugin;
|
|
|
|
|
2014-06-05 23:07:02 +02:00
|
|
|
if (cf) {
|
|
|
|
if ((filenameuri == NULL || !*filenameuri))
|
2014-09-09 17:01:04 +02:00
|
|
|
filenameuri = cf->desc->name;
|
|
|
|
else if (cf->desc->name && strcmp (filenameuri, cf->desc->name) ) {
|
2014-06-05 23:07:02 +02:00
|
|
|
// XXX - this needs to be handled appropriately
|
|
|
|
// if the cf does not match the filenameuri then
|
|
|
|
// either that RCoreFIle * needs to be loaded or a
|
|
|
|
// new RCoreFile * should be opened.
|
|
|
|
if (!strcmp (suppress_warning, "false"))
|
|
|
|
eprintf ("Error: The filenameuri %s is not the same as the current RCoreFile: %s\n",
|
2014-09-09 17:01:04 +02:00
|
|
|
filenameuri, cf->desc->name);
|
2014-06-05 23:07:02 +02:00
|
|
|
}
|
2014-09-09 17:01:04 +02:00
|
|
|
if (cf->map) //XXX: a file can have more then 1 map
|
2014-06-05 23:07:02 +02:00
|
|
|
loadaddr = cf->map->from;
|
2014-04-23 18:04:25 -05:00
|
|
|
}
|
2014-01-11 00:56:02 -06:00
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
if (!filenameuri) {
|
2013-04-24 09:46:57 +02:00
|
|
|
eprintf ("r_core_bin_load: no file specified\n");
|
|
|
|
return R_FALSE;
|
2011-11-15 23:26:45 +01:00
|
|
|
}
|
2013-11-09 17:15:30 -06:00
|
|
|
|
2013-12-09 04:56:13 +01:00
|
|
|
r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
|
2013-12-17 02:10:13 +01:00
|
|
|
if (is_io_load) {
|
2014-09-09 17:01:04 +02:00
|
|
|
// TODO? necessary to restore the desc back?
|
2014-06-05 23:07:02 +02:00
|
|
|
// RIODesc *oldesc = desc;
|
2014-01-11 00:56:02 -06:00
|
|
|
// Fix to select pid before trying to load the binary
|
2014-06-05 23:07:02 +02:00
|
|
|
if ( (desc->plugin && desc->plugin->debug) \
|
|
|
|
|| r_config_get_i (r->config, "cfg.debug")) {
|
2014-04-23 18:04:25 -05:00
|
|
|
r_core_file_do_load_for_debug (r, loadaddr, filenameuri);
|
2014-01-11 00:56:02 -06:00
|
|
|
} else {
|
2014-04-23 18:04:25 -05:00
|
|
|
r_core_file_do_load_for_io_plugin (r, baddr, loadaddr);
|
2011-11-22 00:59:20 +01:00
|
|
|
}
|
2014-05-28 15:03:31 +02:00
|
|
|
// Restore original desc
|
|
|
|
r_io_use_desc (r->io, desc);
|
2014-05-04 10:03:15 -05:00
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
|
2014-08-28 03:11:13 +02:00
|
|
|
if (cf && binfile && desc)
|
|
|
|
binfile->fd = desc->fd;
|
2014-05-04 10:03:15 -05:00
|
|
|
binfile = r_bin_cur (r->bin);
|
|
|
|
r_core_bin_set_env (r, binfile);
|
2014-05-08 18:35:04 -05:00
|
|
|
plugin = r_bin_file_cur_plugin (binfile);
|
2014-07-07 16:09:03 +02:00
|
|
|
if (plugin && plugin->name && !strncmp (plugin->name, "any", 3)) {
|
2014-05-04 10:03:15 -05:00
|
|
|
// set use of raw strings
|
2014-09-08 23:29:01 +02:00
|
|
|
//r_config_set (r->config, "bin.rawstr", "true");
|
2014-05-04 10:03:15 -05:00
|
|
|
r_config_set_i (r->config, "io.va", 0);
|
|
|
|
// get bin.minstr
|
|
|
|
r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
|
|
|
|
} else if (binfile) {
|
|
|
|
RBinObject *obj = r_bin_get_object (r->bin);
|
|
|
|
RBinInfo * info = obj ? obj->info : NULL;
|
2014-06-07 11:23:14 +02:00
|
|
|
if (plugin && plugin->name)
|
|
|
|
if (strcmp (plugin->name, "any") && info)
|
|
|
|
r_core_bin_set_arch_bits (r, binfile->file,
|
|
|
|
info->arch, info->bits);
|
2013-04-24 09:46:57 +02:00
|
|
|
}
|
2013-02-07 09:41:05 +01:00
|
|
|
|
2014-07-07 16:09:03 +02:00
|
|
|
if (plugin && plugin->name && !strcmp (plugin->name, "dex")) {
|
2014-08-28 03:11:13 +02:00
|
|
|
r_core_cmd0 (r, "\"(fix-dex,wx `#sha1 $s-32 @32` @12 ;"
|
|
|
|
" wx `#adler32 $s-12 @12` @8)\"\n");
|
2013-04-12 01:15:00 +02:00
|
|
|
}
|
2014-01-18 09:26:09 -06:00
|
|
|
|
2012-08-08 10:31:17 +02:00
|
|
|
if (r_config_get_i (r->config, "file.analyze"))
|
|
|
|
r_core_cmd0 (r, "aa");
|
2010-10-04 10:55:43 +02:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
2014-01-20 03:00:16 +01:00
|
|
|
|
2014-01-25 18:06:17 -06:00
|
|
|
R_API RIOMap *r_core_file_get_next_map (RCore *core, RCoreFile * fh, int mode, ut64 loadaddr) {
|
2014-03-25 17:11:11 +01:00
|
|
|
const char *loadmethod = r_config_get (core->config, "file.loadmethod");
|
2014-01-31 02:02:51 +01:00
|
|
|
const char *suppress_warning = r_config_get (core->config, "file.nowarn");
|
2014-03-25 17:11:11 +01:00
|
|
|
ut64 load_align = r_config_get_i (core->config, "file.loadalign");
|
|
|
|
RIOMap *map = NULL;
|
|
|
|
if (!strcmp (loadmethod, "overwrite"))
|
2014-09-28 00:05:20 +02:00
|
|
|
map = r_io_map_new (core->io, fh->desc->fd, mode, 0, loadaddr, r_io_desc_size (core->io, fh->desc));
|
2014-03-25 17:11:11 +01:00
|
|
|
if (!strcmp (loadmethod, "fail"))
|
2014-09-28 00:05:20 +02:00
|
|
|
map = r_io_map_add (core->io, fh->desc->fd, mode, 0, loadaddr, r_io_desc_size (core->io, fh->desc));
|
2014-10-07 01:58:42 +02:00
|
|
|
if (!strcmp (loadmethod, "append") && load_align) {
|
2014-09-28 00:05:20 +02:00
|
|
|
map = r_io_map_add_next_available (core->io, fh->desc->fd, mode, 0, loadaddr, r_io_desc_size (core->io, fh->desc), load_align);
|
2014-10-07 01:58:42 +02:00
|
|
|
}
|
2014-03-25 17:11:11 +01:00
|
|
|
if (!strcmp (suppress_warning, "false")) {
|
|
|
|
if (!map)
|
|
|
|
eprintf ("r_core_file_get_next_map: Unable to load specified file to 0x%08"PFMT64x"\n", loadaddr);
|
|
|
|
else {
|
|
|
|
if (map->from != loadaddr)
|
|
|
|
eprintf ("r_core_file_get_next_map: Unable to load specified file to 0x%08"PFMT64x",\n"
|
|
|
|
"but loaded to 0x%08"PFMT64x"\n", loadaddr, map->from);
|
2014-01-25 18:06:17 -06:00
|
|
|
}
|
|
|
|
}
|
2014-03-25 17:11:11 +01:00
|
|
|
r_io_sort_maps (core->io); //necessary ???
|
2014-01-25 18:06:17 -06:00
|
|
|
return map;
|
|
|
|
}
|
|
|
|
|
|
|
|
|
2014-10-08 00:44:31 +02:00
|
|
|
R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int flags, ut64 loadaddr) {
|
2014-01-23 21:05:35 -06:00
|
|
|
RIODesc *fd;
|
2014-10-17 00:04:52 +02:00
|
|
|
RList *list_fds = NULL;
|
|
|
|
const char *cp = NULL;
|
|
|
|
char *loadmethod = NULL;
|
2014-04-29 11:10:35 -05:00
|
|
|
RListIter *fd_iter, *iter2;
|
2014-10-17 00:04:52 +02:00
|
|
|
RCoreFile *fh, *top_file = NULL;
|
2014-01-25 18:06:17 -06:00
|
|
|
ut64 current_loadaddr = loadaddr;
|
2014-01-31 02:02:51 +01:00
|
|
|
const char *suppress_warning = r_config_get (r->config, "file.nowarn");
|
2014-04-29 11:10:35 -05:00
|
|
|
int openmany = r_config_get_i (r->config, "file.openmany"), opened_count = 0;
|
|
|
|
|
|
|
|
|
2014-10-08 00:44:31 +02:00
|
|
|
list_fds = r_io_open_many (r->io, file, flags, 0644);
|
2014-01-25 18:06:17 -06:00
|
|
|
|
2014-01-26 01:29:17 -06:00
|
|
|
if (!list_fds || r_list_length (list_fds) == 0 ) {
|
|
|
|
r_list_free (list_fds);
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2014-01-25 18:06:17 -06:00
|
|
|
cp = r_config_get (r->config, "file.loadmethod");
|
|
|
|
if (cp) loadmethod = strdup (cp);
|
|
|
|
r_config_set (r->config, "file.loadmethod", "append");
|
2014-01-23 21:05:35 -06:00
|
|
|
|
2014-04-29 11:10:35 -05:00
|
|
|
r_list_foreach_safe (list_fds, fd_iter, iter2, fd) {
|
|
|
|
opened_count++;
|
|
|
|
if (opened_count > openmany) {
|
|
|
|
// XXX - Open Many should limit the number of files
|
|
|
|
// loaded in io plugin area this needs to be more premptive
|
|
|
|
// like down in the io plugin layer.
|
|
|
|
// start closing down descriptors
|
|
|
|
r_list_delete (list_fds, fd_iter);
|
|
|
|
continue;
|
|
|
|
}
|
2014-01-23 21:05:35 -06:00
|
|
|
fh = R_NEW0 (RCoreFile);
|
2014-01-27 08:24:44 -06:00
|
|
|
if (!fh) {
|
|
|
|
eprintf ("file.c:r_core_many failed to allocate new RCoreFile.\n");
|
|
|
|
break;
|
|
|
|
}
|
2014-04-22 23:02:46 -05:00
|
|
|
fh->alive = 1;
|
|
|
|
fh->core = r;
|
2014-05-28 04:34:12 +02:00
|
|
|
fh->desc = fd;
|
2014-01-23 21:05:35 -06:00
|
|
|
r->file = fh;
|
|
|
|
r->io->plugin = fd->plugin;
|
|
|
|
// XXX - load addr should be at a set offset
|
2014-10-08 00:44:31 +02:00
|
|
|
fh->map = r_core_file_get_next_map (r, fh, flags, current_loadaddr);
|
2014-01-25 18:06:17 -06:00
|
|
|
|
|
|
|
if (!fh->map) {
|
|
|
|
r_core_file_free(fh);
|
|
|
|
if (!strcmp (suppress_warning, "false"))
|
|
|
|
eprintf("Unable to load file due to failed mapping.\n");
|
|
|
|
continue;
|
|
|
|
}
|
|
|
|
|
|
|
|
current_loadaddr = fh->map->to;
|
|
|
|
if (!top_file) {
|
|
|
|
top_file = fh;
|
|
|
|
// check load addr to make sure its still valid
|
2014-01-27 08:24:44 -06:00
|
|
|
loadaddr = top_file->map->from;
|
2014-01-25 18:06:17 -06:00
|
|
|
}
|
2014-05-07 14:04:04 -05:00
|
|
|
r_bin_bind (r->bin, &(fh->binb));
|
2014-01-23 21:05:35 -06:00
|
|
|
r_list_append (r->files, fh);
|
2014-09-09 17:01:04 +02:00
|
|
|
r_core_bin_load (r, fh->desc->name, fh->map->from);
|
2014-01-23 21:05:35 -06:00
|
|
|
}
|
2014-01-27 08:24:44 -06:00
|
|
|
if (!top_file) {
|
|
|
|
free (loadmethod);
|
|
|
|
return top_file;
|
|
|
|
}
|
2014-01-23 21:05:35 -06:00
|
|
|
cp = r_config_get (r->config, "cmd.open");
|
|
|
|
if (cp && *cp) r_core_cmd (r, cp, 0);
|
|
|
|
|
2014-09-09 17:01:04 +02:00
|
|
|
r_config_set (r->config, "file.path", top_file->desc->name);
|
2014-09-28 00:05:20 +02:00
|
|
|
r_config_set_i (r->config, "zoom.to", top_file->map->from + r_io_desc_size (r->io, top_file->desc));
|
2014-01-25 18:06:17 -06:00
|
|
|
if (loadmethod) r_config_set (r->config, "file.loadmethod", loadmethod);
|
|
|
|
free (loadmethod);
|
2014-01-23 21:05:35 -06:00
|
|
|
|
|
|
|
return top_file;
|
|
|
|
}
|
|
|
|
|
2014-10-08 00:44:31 +02:00
|
|
|
R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int flags, ut64 loadaddr) {
|
2014-05-21 23:03:09 +02:00
|
|
|
const char *suppress_warning = r_config_get (r->config, "file.nowarn");
|
|
|
|
const int openmany = r_config_get_i (r->config, "file.openmany");
|
2010-02-01 11:55:56 +01:00
|
|
|
const char *cp;
|
2013-02-07 09:41:05 +01:00
|
|
|
RCoreFile *fh;
|
2012-02-07 00:44:46 +01:00
|
|
|
RIODesc *fd;
|
2014-01-25 18:06:17 -06:00
|
|
|
|
2014-05-21 23:03:09 +02:00
|
|
|
if (!file)
|
|
|
|
return NULL;
|
2012-08-09 12:42:44 +02:00
|
|
|
if (!strcmp (file, "-")) {
|
2012-02-07 00:44:46 +01:00
|
|
|
file = "malloc://512";
|
2014-10-08 00:44:31 +02:00
|
|
|
flags = 4|2;
|
2012-08-09 12:42:44 +02:00
|
|
|
}
|
2012-05-30 01:35:41 +02:00
|
|
|
r->io->bits = r->assembler->bits; // TODO: we need an api for this
|
2014-10-08 00:44:31 +02:00
|
|
|
fd = r_io_open_nomap (r->io, file, flags, 0644);
|
2014-04-29 11:10:35 -05:00
|
|
|
if (fd == NULL && openmany > 2) {
|
2014-01-23 21:05:35 -06:00
|
|
|
// XXX - make this an actual option somewhere?
|
2014-10-08 00:44:31 +02:00
|
|
|
fh = r_core_file_open_many (r, file, flags, loadaddr);
|
2014-01-23 21:05:35 -06:00
|
|
|
if (fh) return fh;
|
|
|
|
}
|
2012-07-06 02:17:44 +02:00
|
|
|
if (fd == NULL) {
|
2014-10-08 00:44:31 +02:00
|
|
|
if (flags & 2) {
|
2012-07-06 02:17:44 +02:00
|
|
|
if (!r_io_create (r->io, file, 0644, 0))
|
|
|
|
return NULL;
|
2014-10-08 00:44:31 +02:00
|
|
|
if (!(fd = r_io_open_nomap (r->io, file, flags, 0644)))
|
2012-07-06 02:17:44 +02:00
|
|
|
return NULL;
|
|
|
|
} else return NULL;
|
|
|
|
}
|
2011-02-05 00:20:28 +01:00
|
|
|
if (r_io_is_listener (r->io)) {
|
2011-04-17 20:58:32 +02:00
|
|
|
r_core_serve (r, fd);
|
2011-02-05 00:20:28 +01:00
|
|
|
return NULL;
|
|
|
|
}
|
2009-02-05 22:08:46 +01:00
|
|
|
|
2013-12-17 02:10:13 +01:00
|
|
|
fh = R_NEW0 (RCoreFile);
|
2014-01-27 08:24:44 -06:00
|
|
|
if (!fh) {
|
2014-05-28 18:58:53 +02:00
|
|
|
eprintf ("core/file.c: r_core_open failed to allocate RCoreFile.\n");
|
2014-01-27 08:24:44 -06:00
|
|
|
//r_io_close (r->io, fd);
|
|
|
|
return NULL;
|
|
|
|
}
|
2014-04-22 23:02:46 -05:00
|
|
|
fh->alive = 1;
|
|
|
|
fh->core = r;
|
2014-05-28 04:34:12 +02:00
|
|
|
fh->desc = fd;
|
2009-02-18 01:43:57 +01:00
|
|
|
|
2010-05-20 00:59:42 +02:00
|
|
|
cp = r_config_get (r->config, "cmd.open");
|
2010-02-01 11:55:56 +01:00
|
|
|
if (cp && *cp)
|
|
|
|
r_core_cmd (r, cp, 0);
|
2010-05-24 18:51:01 +02:00
|
|
|
r_config_set (r->config, "file.path", file);
|
2014-10-08 00:44:31 +02:00
|
|
|
fh->map = r_core_file_get_next_map (r, fh, flags, loadaddr);
|
2014-01-25 18:06:17 -06:00
|
|
|
if (!fh->map) {
|
2014-02-21 10:58:31 +01:00
|
|
|
r_core_file_free (fh);
|
2014-01-27 08:24:44 -06:00
|
|
|
fh = NULL;
|
2014-01-25 18:06:17 -06:00
|
|
|
if (!strcmp (suppress_warning, "false"))
|
|
|
|
eprintf("Unable to load file due to failed mapping.\n");
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
// check load addr to make sure its still valid
|
2014-05-07 14:04:04 -05:00
|
|
|
r_bin_bind (r->bin, &(fh->binb));
|
2014-01-25 18:06:17 -06:00
|
|
|
r_list_append (r->files, fh);
|
2014-04-27 02:06:50 -05:00
|
|
|
r_core_file_set_by_file (r, fh);
|
2014-09-28 00:05:20 +02:00
|
|
|
r_config_set_i (r->config, "zoom.to", fh->map->from + r_io_desc_size (r->io, fh->desc));
|
2009-02-05 22:08:46 +01:00
|
|
|
return fh;
|
|
|
|
}
|
|
|
|
|
2014-04-22 23:02:46 -05:00
|
|
|
R_API int r_core_files_free (const RCore *core, RCoreFile *cf) {
|
|
|
|
if (!core || !core->files || !cf) return R_FALSE;
|
|
|
|
return r_list_delete_data (core->files, cf);
|
|
|
|
}
|
|
|
|
|
2011-02-07 09:46:01 +01:00
|
|
|
R_API void r_core_file_free(RCoreFile *cf) {
|
2014-05-22 13:52:16 +02:00
|
|
|
int res = 1;
|
|
|
|
if (cf)
|
|
|
|
res = r_core_files_free (cf->core, cf);
|
|
|
|
if (!res && cf->alive) {
|
2014-01-18 09:26:09 -06:00
|
|
|
// double free libr/io/io.c:70 performs free
|
2014-09-16 21:58:02 +02:00
|
|
|
RIO *io = (RIO*)(cf->desc ? cf->desc->io : NULL);
|
2014-04-22 23:02:46 -05:00
|
|
|
|
2014-09-05 23:08:44 +02:00
|
|
|
if (io && cf->map) r_io_map_del_all (io, cf->map->fd);
|
2014-05-28 04:34:12 +02:00
|
|
|
if (io) r_io_close ((RIO *) io, cf->desc);
|
2014-04-22 23:02:46 -05:00
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
r_bin_file_deref_by_bind (&cf->binb);
|
2014-04-03 14:02:52 -05:00
|
|
|
free (cf);
|
2013-11-09 17:15:30 -06:00
|
|
|
}
|
|
|
|
cf = NULL;
|
2011-02-07 09:46:01 +01:00
|
|
|
}
|
|
|
|
|
2014-02-21 10:58:31 +01:00
|
|
|
R_API int r_core_file_close(RCore *r, RCoreFile *fh) {
|
2014-11-03 11:47:51 +01:00
|
|
|
int ret;
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = fh && fh->desc? fh->desc : NULL;
|
2014-07-22 00:24:37 +02:00
|
|
|
RCoreFile *prev_cf = r && r->file != fh ? r->file : NULL;
|
2014-09-16 21:58:02 +02:00
|
|
|
|
|
|
|
// TODO: This is not correclty done. because map and iodesc are
|
|
|
|
// still referenced // we need to fully clear all R_IO structs
|
|
|
|
// related to a file as well as the ones needed for RBin.
|
|
|
|
//
|
2014-04-22 23:02:46 -05:00
|
|
|
// XXX -these checks are intended to *try* and catch
|
|
|
|
// stale objects. Unfortunately, if the file handle
|
|
|
|
// (fh) is stale and freed, and there is more than 1
|
|
|
|
// fh in the r->files list, we are hosed. (design flaw)
|
|
|
|
// TODO maybe using sdb to keep track of the allocated and
|
|
|
|
// deallocated files might be a good solutions
|
2014-10-17 00:04:52 +02:00
|
|
|
if (!r || !desc || r_list_empty (r->files))
|
|
|
|
return R_FALSE;
|
2014-04-22 23:02:46 -05:00
|
|
|
|
2014-04-23 18:04:25 -05:00
|
|
|
if (fh == r->file) r->file = NULL;
|
2014-10-17 00:04:52 +02:00
|
|
|
|
|
|
|
r_core_file_set_by_fd (r, fh->desc->fd);
|
|
|
|
r_core_bin_set_by_fd (r, fh->desc->fd);
|
|
|
|
|
|
|
|
/* delete filedescriptor from io descs here */
|
|
|
|
r_io_desc_del (r->io, fh->desc->fd);
|
|
|
|
|
2014-11-03 11:47:51 +01:00
|
|
|
// AVOID DOUBLE FREE HERE
|
|
|
|
r->files->free = NULL;
|
|
|
|
|
|
|
|
ret = r_list_delete_data (r->files, fh);
|
2014-04-22 23:02:46 -05:00
|
|
|
if (ret) {
|
2014-04-23 18:04:25 -05:00
|
|
|
if (!prev_cf && r_list_length (r->files) > 0)
|
|
|
|
prev_cf = (RCoreFile *) r_list_get_n (r->files, 0);
|
|
|
|
|
|
|
|
if (prev_cf) {
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = prev_cf->desc;
|
2014-04-23 18:04:25 -05:00
|
|
|
if (!desc)
|
|
|
|
eprintf ("Error: RCoreFile's found with out a supporting RIODesc.\n");
|
|
|
|
ret = r_core_file_set_by_file (r, prev_cf);
|
2014-04-22 23:02:46 -05:00
|
|
|
}
|
|
|
|
}
|
2014-10-17 00:04:52 +02:00
|
|
|
#if 0
|
|
|
|
{
|
|
|
|
RListIter *iter;
|
|
|
|
RIODesc *iod;
|
|
|
|
RCoreFile *mcf;
|
|
|
|
r_list_foreach (r->files, iter, mcf) {
|
|
|
|
r_cons_printf ("[cf]--> %p %p %d\n", mcf, mcf->desc, mcf->desc->fd);
|
|
|
|
}
|
|
|
|
r_list_foreach (r->io->files, iter, iod) {
|
|
|
|
r_cons_printf ("[io]--> %p %d\n", iod, iod->fd);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
#endif
|
2009-02-05 22:08:46 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2014-04-27 02:06:50 -05:00
|
|
|
R_API RCoreFile *r_core_file_get_by_fd(RCore *core, int fd) {
|
2011-02-07 09:46:01 +01:00
|
|
|
RCoreFile *file;
|
|
|
|
RListIter *iter;
|
|
|
|
r_list_foreach (core->files, iter, file) {
|
2014-05-28 04:34:12 +02:00
|
|
|
if (file->desc->fd == fd)
|
2010-02-01 11:55:56 +01:00
|
|
|
return file;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
|
|
|
return NULL;
|
|
|
|
}
|
|
|
|
|
2011-02-16 09:29:09 +01:00
|
|
|
R_API int r_core_file_list(RCore *core) {
|
2010-02-01 11:55:56 +01:00
|
|
|
int count = 0;
|
2011-02-07 09:46:01 +01:00
|
|
|
RCoreFile *f;
|
|
|
|
RListIter *iter;
|
|
|
|
r_list_foreach (core->files, iter, f) {
|
2014-10-07 03:07:45 +02:00
|
|
|
if (f->map) {
|
|
|
|
int overlapped = r_io_map_overlaps (core->io, f->desc, f->map);
|
|
|
|
r_cons_printf ("%c %d %s @ 0x%"PFMT64x" ; %s size=%d %s\n",
|
2014-05-28 04:34:12 +02:00
|
|
|
core->io->raised == f->desc->fd?'*':'-',
|
2014-09-25 18:04:07 +02:00
|
|
|
f->desc->fd, f->desc->uri, f->map->from,
|
2014-10-07 03:07:45 +02:00
|
|
|
f->desc->flags & R_IO_WRITE? "rw": "r",
|
|
|
|
r_io_desc_size (core->io, f->desc),
|
|
|
|
overlapped?"overlaps":"");
|
|
|
|
} else r_cons_printf ("- %d %s\n", f->desc->fd, f->desc->uri);
|
2010-02-01 11:55:56 +01:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2014-05-08 18:35:04 -05:00
|
|
|
// XXX - needs to account for binfile index and bin object index
|
2014-04-27 02:06:50 -05:00
|
|
|
R_API int r_core_file_bin_raise (RCore *core, ut32 binfile_idx) {
|
|
|
|
RBin *bin = core->bin;
|
|
|
|
int v = binfile_idx > 1 ? binfile_idx : 1;
|
|
|
|
RBinFile *bf = r_list_get_n (bin->binfiles, v);
|
|
|
|
int res = R_FALSE;
|
|
|
|
if (bf) {
|
|
|
|
res = r_bin_file_set_cur_binfile (bin, bf);
|
|
|
|
if (res) r_io_raise (core->io, bf->fd);
|
|
|
|
res = res ? r_core_file_set_by_fd (core, bf->fd) : res;
|
|
|
|
if (res) core->switch_file_view = 1;
|
|
|
|
}
|
|
|
|
return res;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_core_file_binlist(RCore *core) {
|
|
|
|
int count = 0;
|
|
|
|
RListIter *iter;
|
2014-05-08 18:35:04 -05:00
|
|
|
RCoreFile *cur_cf = core->file, *cf = NULL;
|
2014-05-16 04:07:03 +02:00
|
|
|
RBinFile *binfile = NULL;
|
2014-04-27 02:06:50 -05:00
|
|
|
RBin *bin = core->bin;
|
|
|
|
const RList *binfiles = bin ? bin->binfiles: NULL;
|
|
|
|
|
|
|
|
if (!binfiles) return R_FALSE;
|
|
|
|
|
|
|
|
r_list_foreach (binfiles, iter, binfile) {
|
2014-05-28 04:34:12 +02:00
|
|
|
int fd = binfile->fd;
|
2014-05-08 18:35:04 -05:00
|
|
|
cf = r_core_file_get_by_fd (core, fd);
|
|
|
|
if (cf && cf->map) {
|
2014-04-27 02:06:50 -05:00
|
|
|
r_cons_printf ("%c %d %s @ 0x%"PFMT64x" ; %s\n",
|
2014-05-28 04:34:12 +02:00
|
|
|
core->io->raised == cf->desc->fd?'*':'-',
|
2014-09-25 18:04:07 +02:00
|
|
|
fd, cf->desc->uri, cf->map->from,
|
2014-05-28 04:34:12 +02:00
|
|
|
cf->desc->flags & R_IO_WRITE? "rw": "r");
|
2014-04-27 02:06:50 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
r_core_file_set_by_file (core, cur_cf);
|
2014-05-04 10:03:15 -05:00
|
|
|
//r_core_bin_bind (core, cur_bf);
|
2014-04-27 02:06:50 -05:00
|
|
|
return count;
|
|
|
|
}
|
|
|
|
|
2011-02-07 09:46:01 +01:00
|
|
|
R_API int r_core_file_close_fd(RCore *core, int fd) {
|
|
|
|
RCoreFile *file;
|
|
|
|
RListIter *iter;
|
|
|
|
r_list_foreach (core->files, iter, file) {
|
2014-05-28 04:34:12 +02:00
|
|
|
if (file->desc->fd == fd) {
|
2014-04-22 23:02:46 -05:00
|
|
|
r_core_file_close (core, file);
|
2014-01-21 15:40:10 +01:00
|
|
|
#if 0
|
2011-02-07 09:46:01 +01:00
|
|
|
if (r_list_empty (core->files))
|
|
|
|
core->file = NULL;
|
2014-01-21 15:40:10 +01:00
|
|
|
#endif
|
2011-02-07 09:46:01 +01:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return R_FALSE;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|
2011-07-13 17:41:26 +02:00
|
|
|
|
|
|
|
R_API int r_core_hash_load(RCore *r, const char *file) {
|
|
|
|
const ut8 *md5, *sha1;
|
|
|
|
char hash[128], *p;
|
2014-09-28 01:37:56 +02:00
|
|
|
int i;
|
2014-09-30 12:06:37 +02:00
|
|
|
int buf_len = 0;
|
2013-02-07 09:41:05 +01:00
|
|
|
ut8 *buf = NULL;
|
2011-07-13 17:41:26 +02:00
|
|
|
RHash *ctx;
|
|
|
|
ut64 limit;
|
2014-04-29 11:10:35 -05:00
|
|
|
RCoreFile *cf = r_core_file_cur (r);
|
2011-07-13 17:41:26 +02:00
|
|
|
|
|
|
|
limit = r_config_get_i (r->config, "cfg.hashlimit");
|
2014-09-28 00:05:20 +02:00
|
|
|
if (r_io_desc_size (r->io, cf->desc) > limit)
|
2011-07-13 17:41:26 +02:00
|
|
|
return R_FALSE;
|
2011-11-14 00:21:25 +01:00
|
|
|
buf = (ut8*)r_file_slurp (file, &buf_len);
|
2011-07-13 17:41:26 +02:00
|
|
|
if (buf==NULL)
|
|
|
|
return R_FALSE;
|
|
|
|
ctx = r_hash_new (R_TRUE, R_HASH_MD5);
|
|
|
|
md5 = r_hash_do_md5 (ctx, buf, buf_len);
|
|
|
|
p = hash;
|
|
|
|
for (i=0; i<R_HASH_SIZE_MD5; i++) {
|
|
|
|
sprintf (p, "%02x", md5[i]);
|
2011-11-11 17:14:09 +01:00
|
|
|
p += 2;
|
2011-07-13 17:41:26 +02:00
|
|
|
}
|
2011-11-11 17:14:09 +01:00
|
|
|
*p = 0;
|
2011-07-13 17:41:26 +02:00
|
|
|
r_config_set (r->config, "file.md5", hash);
|
|
|
|
r_hash_free (ctx);
|
|
|
|
ctx = r_hash_new (R_TRUE, R_HASH_SHA1);
|
|
|
|
sha1 = r_hash_do_sha1 (ctx, buf, buf_len);
|
|
|
|
p = hash;
|
2012-08-04 23:48:06 +02:00
|
|
|
for (i=0; i<R_HASH_SIZE_SHA1; i++) {
|
2011-07-13 17:41:26 +02:00
|
|
|
sprintf (p, "%02x", sha1[i]);
|
2012-08-04 23:48:06 +02:00
|
|
|
p += 2;
|
2011-07-13 17:41:26 +02:00
|
|
|
}
|
2012-08-04 23:48:06 +02:00
|
|
|
*p = 0;
|
2011-07-13 17:41:26 +02:00
|
|
|
r_config_set (r->config, "file.sha1", hash);
|
|
|
|
r_hash_free (ctx);
|
2011-11-11 17:14:09 +01:00
|
|
|
free (buf);
|
2011-07-13 17:41:26 +02:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
2014-04-23 18:04:25 -05:00
|
|
|
|
|
|
|
R_API RCoreFile * r_core_file_find_by_fd (RCore *core, ut64 fd) {
|
|
|
|
RListIter *iter;
|
|
|
|
RCoreFile *cf = NULL;
|
|
|
|
|
|
|
|
r_list_foreach (core->files, iter, cf) {
|
2014-05-28 04:34:12 +02:00
|
|
|
if (cf && cf->desc && cf->desc->fd == fd) break;
|
2014-04-23 18:04:25 -05:00
|
|
|
cf = NULL;
|
|
|
|
}
|
|
|
|
return cf;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API RCoreFile * r_core_file_find_by_name (RCore * core, const char * name) {
|
|
|
|
RListIter *iter;
|
|
|
|
RCoreFile *cf = NULL;
|
|
|
|
|
|
|
|
r_list_foreach (core->files, iter, cf) {
|
2014-09-09 17:01:04 +02:00
|
|
|
if (cf && cf->desc && !strcmp (cf->desc->name, name)) break;
|
2014-04-23 18:04:25 -05:00
|
|
|
cf = NULL;
|
|
|
|
}
|
|
|
|
return cf;
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_core_file_set_by_fd (RCore * core, ut64 fd) {
|
|
|
|
RCoreFile *cf = r_core_file_find_by_fd (core, fd);
|
|
|
|
return r_core_file_set_by_file (core, cf);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_core_file_set_by_name (RCore * core, const char * name) {
|
|
|
|
RCoreFile *cf = r_core_file_find_by_name (core, name);
|
|
|
|
return r_core_file_set_by_file (core, cf);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API int r_core_file_set_by_file (RCore * core, RCoreFile *cf) {
|
|
|
|
if (cf) {
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = cf->desc;
|
2014-10-17 00:04:52 +02:00
|
|
|
core->offset = cf && cf->map ? cf->map->from : 0LL;
|
2014-04-23 18:04:25 -05:00
|
|
|
core->file = cf;
|
|
|
|
if (desc) {
|
2014-09-09 16:04:57 +02:00
|
|
|
r_io_use_desc (core->io, desc);
|
2014-04-23 18:04:25 -05:00
|
|
|
r_core_bin_set_by_fd (core, desc->fd);
|
|
|
|
}
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
return R_FALSE;
|
|
|
|
}
|
2014-04-27 02:06:50 -05:00
|
|
|
|
|
|
|
R_API ut32 r_core_file_cur_fd (RCore *core) {
|
2014-05-28 04:34:12 +02:00
|
|
|
RIODesc *desc = core->file ? core->file->desc : NULL;
|
2014-05-08 18:35:04 -05:00
|
|
|
if (desc) {
|
2014-04-27 02:06:50 -05:00
|
|
|
return desc->fd;
|
2014-05-08 18:35:04 -05:00
|
|
|
}
|
2014-09-17 23:31:34 +02:00
|
|
|
return (ut32)-1; //WTF
|
2014-04-29 11:10:35 -05:00
|
|
|
}
|
|
|
|
|
|
|
|
R_API RCoreFile * r_core_file_cur (RCore *r) {
|
|
|
|
// Add any locks here
|
|
|
|
return r->file;
|
2014-05-16 04:07:03 +02:00
|
|
|
}
|