2011-01-21 00:21:32 +01:00
|
|
|
/* radare - LGPL - Copyright 2009-2011 pancake<nopcode.org> */
|
2009-02-05 22:08:46 +01:00
|
|
|
|
|
|
|
#include <r_core.h>
|
|
|
|
|
2010-02-22 02:42:29 +01:00
|
|
|
R_API ut64 r_core_file_resize(struct r_core_t *core, ut64 newsize) {
|
2010-02-01 11:55:56 +01:00
|
|
|
if (newsize==0 && core->file)
|
2009-02-05 22:08:46 +01:00
|
|
|
return core->file->size;
|
|
|
|
return 0LL;
|
|
|
|
}
|
|
|
|
|
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.
|
|
|
|
R_API void r_core_sysenv_help() {
|
|
|
|
r_cons_printf (
|
|
|
|
"Usage: !<cmd>\n"
|
|
|
|
" !ls ; execute 'ls' in shell\n"
|
|
|
|
" .!rabin2 -ri ${FILE} ; run each output line as a r2 cmd\n"
|
|
|
|
" !echo $SIZE ; display file size\n"
|
|
|
|
"Environment:\n"
|
|
|
|
" FILE file name\n"
|
|
|
|
" SIZE file size\n"
|
|
|
|
" OFFSET 10base offset 64bit value\n"
|
|
|
|
" XOFFSET same as above, but in 16 base\n"
|
|
|
|
" BSIZE block size\n"
|
|
|
|
" ENDIAN 'big' or 'little'\n"
|
|
|
|
" ARCH value of asm.arch\n"
|
|
|
|
" DEBUG debug mode enabled? (1,0)\n"
|
|
|
|
" IOVA is io.va true? virtual addressing (1,0)\n"
|
|
|
|
" BLOCK TODO: dump current block to tmp file\n"
|
|
|
|
" BYTES TODO: variable with bytes in curblock\n"
|
|
|
|
);
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API void r_core_sysenv_end(RCore *core, const char *cmd) {
|
|
|
|
// TODO: remove tmpfilez
|
|
|
|
if (strstr (cmd, "BLOCK")) {
|
|
|
|
// remove temporary BLOCK file
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
R_API char *r_core_sysenv_begin(RCore *core, const char *cmd) {
|
|
|
|
char buf[64], *ret;
|
2010-08-19 20:28:25 +02:00
|
|
|
#if DISCUSS
|
2011-02-04 11:30:08 +01:00
|
|
|
// EDITOR cfg.editor (vim or so)
|
2010-08-19 20:28:25 +02:00
|
|
|
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
|
|
|
|
#endif
|
|
|
|
if (!core->file)
|
2011-02-04 11:30:08 +01:00
|
|
|
return NULL;
|
|
|
|
ret = strdup (cmd);
|
|
|
|
if (strstr (cmd, "BLOCK")) {
|
|
|
|
// replace BLOCK in RET string
|
|
|
|
}
|
2010-08-19 20:28:25 +02:00
|
|
|
if (core->file->filename)
|
|
|
|
r_sys_setenv ("FILE", core->file->filename);
|
|
|
|
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);
|
|
|
|
snprintf (buf, sizeof (buf), "%"PFMT64d, core->file->size);
|
|
|
|
r_sys_setenv ("SIZE", 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
|
|
|
}
|
|
|
|
|
2010-10-04 10:55:43 +02:00
|
|
|
R_API int r_core_bin_load(RCore *r, const char *file) {
|
2011-01-20 23:28:20 +01:00
|
|
|
RBinInfo *info;
|
|
|
|
RBinAddr *binmain;
|
2010-10-04 10:55:43 +02:00
|
|
|
RBinObj *obj;
|
2010-10-18 00:00:17 +02:00
|
|
|
RList *list;
|
2010-10-11 17:11:43 +02:00
|
|
|
RListIter *iter;
|
2011-01-20 23:28:20 +01:00
|
|
|
RBinAddr *entry;
|
|
|
|
RBinSymbol *symbol;
|
|
|
|
RBinReloc *reloc;
|
|
|
|
RBinString *string;
|
|
|
|
RBinImport *import;
|
|
|
|
RBinSection *section;
|
2010-10-11 17:11:43 +02:00
|
|
|
ut64 baddr;
|
2010-10-13 01:23:27 +02:00
|
|
|
int va = r->io->va || r->io->debug;
|
2010-10-11 17:11:43 +02:00
|
|
|
int i = 0;
|
|
|
|
char str[R_FLAG_NAME_SIZE];
|
2010-10-04 10:55:43 +02:00
|
|
|
|
2011-01-20 23:28:20 +01:00
|
|
|
if (file == NULL)
|
|
|
|
file = r->file->filename;
|
2010-10-04 10:55:43 +02:00
|
|
|
if (!r_bin_load (r->bin, file, 0))
|
|
|
|
return R_FALSE;
|
|
|
|
r->file->obj = obj = r_bin_get_object (r->bin, 0);
|
2010-10-11 17:11:43 +02:00
|
|
|
baddr = r_bin_get_baddr (r->bin);
|
|
|
|
|
|
|
|
// I -> Binary info
|
|
|
|
if ((info = r_bin_get_info (r->bin)) != NULL) {
|
|
|
|
r_config_set (r->config, "file.type", info->rclass);
|
|
|
|
r_config_set (r->config, "cfg.bigendian", info->big_endian?"true":"false");
|
2011-05-12 09:52:40 +02:00
|
|
|
if (!strcmp (info->rclass, "fs")) {
|
|
|
|
r_config_set (r->config, "asm.arch", info->arch);
|
|
|
|
r_core_cmdf (r, "m %s /root 0", info->arch);
|
|
|
|
} else {
|
|
|
|
r_config_set (r->config, "asm.os", info->os);
|
|
|
|
r_config_set (r->config, "asm.arch", info->arch);
|
|
|
|
r_config_set (r->config, "anal.plugin", info->arch);
|
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "%i", info->bits);
|
|
|
|
r_config_set (r->config, "asm.bits", str);
|
|
|
|
r_config_set (r->config, "asm.dwarf", R_BIN_DBG_STRIPPED (info->dbg_info)?"false":"true");
|
|
|
|
}
|
2010-10-04 10:55:43 +02:00
|
|
|
}
|
2010-10-11 17:11:43 +02:00
|
|
|
|
|
|
|
// M -> Main
|
2010-10-23 14:27:13 +02:00
|
|
|
r_flag_space_set (r->flags, "symbols");
|
2010-11-18 11:41:17 +01:00
|
|
|
if ((binmain = r_bin_get_sym (r->bin, R_BIN_SYM_MAIN)) != NULL)
|
2010-10-11 17:11:43 +02:00
|
|
|
r_flag_set (r->flags, "main", va?baddr+binmain->rva:binmain->offset,
|
|
|
|
r->blocksize, 0);
|
|
|
|
|
|
|
|
// e -> Entrypoints
|
|
|
|
i = 0;
|
2010-10-18 00:00:17 +02:00
|
|
|
if ((list = r_bin_get_entries (r->bin)) != NULL) {
|
|
|
|
r_list_foreach (list, iter, entry) {
|
2010-10-11 17:11:43 +02:00
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "entry%i", i++);
|
|
|
|
r_flag_set (r->flags, str, va?baddr+entry->rva:entry->offset,
|
|
|
|
r->blocksize, 0);
|
|
|
|
}
|
|
|
|
/* Seek to the last entry point */
|
2010-10-28 00:19:10 +02:00
|
|
|
r_core_seek (r, va?baddr+entry->rva:entry->offset, 0);
|
2010-10-04 10:55:43 +02:00
|
|
|
}
|
2010-10-11 17:11:43 +02:00
|
|
|
|
|
|
|
// s -> Symbols
|
2010-10-18 00:00:17 +02:00
|
|
|
if ((list = r_bin_get_symbols (r->bin)) != NULL) {
|
2011-02-27 20:30:41 +01:00
|
|
|
char *name, *dname;
|
2011-02-28 17:27:08 +01:00
|
|
|
r_flag_space_set (r->flags, "symbols");
|
2010-10-18 00:00:17 +02:00
|
|
|
r_list_foreach (list, iter, symbol) {
|
2011-02-27 20:30:41 +01:00
|
|
|
name = strdup (symbol->name);
|
|
|
|
r_flag_name_filter (name);
|
2011-02-28 17:27:08 +01:00
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "sym.%s", name);
|
|
|
|
if (!strncmp (symbol->type,"OBJECT", 6))
|
2011-03-02 00:02:50 +01:00
|
|
|
r_meta_add (r->anal->meta, R_META_TYPE_DATA, va?baddr+symbol->rva:symbol->offset,
|
2011-02-27 20:30:41 +01:00
|
|
|
(va?baddr+symbol->rva:symbol->offset)+symbol->size, name);
|
2011-02-28 17:27:08 +01:00
|
|
|
r_flag_set (r->flags, str, va?baddr+symbol->rva:symbol->offset,
|
2010-10-11 17:11:43 +02:00
|
|
|
symbol->size, 0);
|
2011-02-27 20:30:41 +01:00
|
|
|
dname = r_bin_demangle (r->bin, symbol->name);
|
|
|
|
if (dname) {
|
2011-03-02 00:02:50 +01:00
|
|
|
r_meta_add (r->anal->meta, R_META_TYPE_COMMENT, va?baddr+symbol->rva:symbol->offset,
|
2011-02-27 20:30:41 +01:00
|
|
|
symbol->size, dname);
|
|
|
|
free (dname);
|
2011-02-25 04:19:30 +01:00
|
|
|
}
|
2011-02-27 20:30:41 +01:00
|
|
|
free (name);
|
2010-10-11 17:11:43 +02:00
|
|
|
}
|
2010-10-04 10:55:43 +02:00
|
|
|
}
|
2010-10-11 17:11:43 +02:00
|
|
|
|
|
|
|
// R -> Relocations
|
2010-10-18 00:00:17 +02:00
|
|
|
if ((list = r_bin_get_relocs (r->bin)) != NULL) {
|
2011-02-28 17:27:08 +01:00
|
|
|
r_flag_space_set (r->flags, "relocs");
|
2010-10-18 00:00:17 +02:00
|
|
|
r_list_foreach (list, iter, reloc) {
|
2010-10-11 17:11:43 +02:00
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "reloc.%s", reloc->name);
|
|
|
|
r_flag_set (r->flags, str, va?baddr+reloc->rva:reloc->offset,
|
|
|
|
r->blocksize, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// z -> Strings
|
2010-10-18 00:00:17 +02:00
|
|
|
if ((list = r_bin_get_strings (r->bin)) != NULL) {
|
2011-05-22 02:45:59 +02:00
|
|
|
/*
|
|
|
|
// load all strings ALWAYS!! rhashtable is fast
|
|
|
|
if (r_list_length (list) > 102400) {
|
2011-02-12 01:52:41 +01:00
|
|
|
eprintf ("rabin2: too many strings. not importing string info\n");
|
2011-02-27 20:30:41 +01:00
|
|
|
} else {
|
2011-05-22 02:45:59 +02:00
|
|
|
*/
|
2011-02-27 20:30:41 +01:00
|
|
|
r_flag_space_set (r->flags, "strings");
|
|
|
|
r_list_foreach (list, iter, string) {
|
|
|
|
/* Jump the withespaces before the string */
|
|
|
|
for (i=0;*(string->string+i)==' ';i++);
|
2011-03-02 00:02:50 +01:00
|
|
|
r_meta_add (r->anal->meta, R_META_TYPE_STRING, va?baddr+string->rva:string->offset,
|
2011-02-27 20:30:41 +01:00
|
|
|
(va?baddr+string->rva:string->offset)+string->size, string->string+i);
|
|
|
|
r_flag_name_filter (string->string);
|
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "str.%s", string->string);
|
|
|
|
r_flag_set (r->flags, str, va?baddr+string->rva:string->offset,
|
|
|
|
string->size, 0);
|
|
|
|
}
|
2011-05-22 02:45:59 +02:00
|
|
|
//}
|
2010-10-11 17:11:43 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
// i -> Imports
|
2010-10-18 00:00:17 +02:00
|
|
|
if ((list = r_bin_get_imports (r->bin)) != NULL) {
|
2011-02-28 17:27:08 +01:00
|
|
|
r_flag_space_set (r->flags, "imports");
|
2010-10-18 00:00:17 +02:00
|
|
|
r_list_foreach (list, iter, import) {
|
2010-10-11 17:11:43 +02:00
|
|
|
r_flag_name_filter (import->name);
|
2011-02-28 17:27:08 +01:00
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "imp.%s", import->name);
|
2010-10-11 17:11:43 +02:00
|
|
|
if (import->size)
|
|
|
|
if (!r_anal_fcn_add (r->anal, va?baddr+import->rva:import->offset,
|
2011-02-28 00:03:26 +01:00
|
|
|
import->size, str, R_ANAL_FCN_TYPE_IMP, NULL))
|
2010-10-11 17:11:43 +02:00
|
|
|
eprintf ("Cannot add function: %s (duplicated)\n", import->name);
|
|
|
|
r_flag_set (r->flags, str, va?baddr+import->rva:import->offset,
|
|
|
|
import->size, 0);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// S -> Sections
|
|
|
|
i = 0;
|
2010-10-18 00:00:17 +02:00
|
|
|
if ((list = r_bin_get_sections (r->bin)) != NULL) {
|
2010-10-11 17:11:43 +02:00
|
|
|
r_flag_space_set (r->flags, "sections");
|
2010-10-18 00:00:17 +02:00
|
|
|
r_list_foreach (list, iter, section) {
|
2010-10-11 17:11:43 +02:00
|
|
|
r_flag_name_filter (section->name);
|
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "section.%s", section->name);
|
|
|
|
r_flag_set (r->flags, str, va?baddr+section->rva:section->offset,
|
|
|
|
section->size, 0);
|
|
|
|
r_io_section_add (r->io, section->offset, baddr+section->rva,
|
|
|
|
section->size, section->vsize, section->srwx, section->name);
|
2011-02-28 17:27:08 +01:00
|
|
|
snprintf (str, R_FLAG_NAME_SIZE, "[%i] va=0x%08"PFMT64x" pa=0x%08"PFMT64x" sz=%"
|
2010-10-11 17:11:43 +02:00
|
|
|
PFMT64d" vsz=%"PFMT64d" rwx=%c%c%c%c %s",
|
2011-02-28 17:27:08 +01:00
|
|
|
i++, baddr+section->rva, section->offset, section->size, section->vsize,
|
2010-10-11 17:11:43 +02:00
|
|
|
R_BIN_SCN_SHAREABLE (section->srwx)?'s':'-',
|
|
|
|
R_BIN_SCN_READABLE (section->srwx)?'r':'-',
|
|
|
|
R_BIN_SCN_WRITABLE (section->srwx)?'w':'-',
|
|
|
|
R_BIN_SCN_EXECUTABLE (section->srwx)?'x':'-',
|
|
|
|
section->name);
|
2011-03-02 00:02:50 +01:00
|
|
|
r_meta_add (r->anal->meta, R_META_TYPE_COMMENT, va?baddr+section->rva:section->offset,
|
2010-10-11 17:11:43 +02:00
|
|
|
va?baddr+section->rva:section->offset, str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2010-10-04 10:55:43 +02:00
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
|
2011-02-12 01:52:41 +01:00
|
|
|
R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int mode, ut64 loadaddr) {
|
2010-04-11 01:46:07 +02:00
|
|
|
RCoreFile *fh;
|
2010-02-01 11:55:56 +01:00
|
|
|
const char *cp;
|
|
|
|
char *p;
|
2011-01-20 22:52:16 +01:00
|
|
|
RIODesc *fd = r_io_open (r->io, file, mode, 0644);
|
|
|
|
if (fd == NULL)
|
2009-02-05 22:08:46 +01:00
|
|
|
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
|
|
|
|
2010-03-12 13:35:10 +01:00
|
|
|
fh = R_NEW (RCoreFile);
|
2009-02-05 22:08:46 +01:00
|
|
|
fh->fd = fd;
|
2011-02-07 09:46:01 +01:00
|
|
|
fh->map = NULL;
|
2010-02-01 11:55:56 +01:00
|
|
|
fh->uri = strdup (file);
|
2011-02-07 09:46:01 +01:00
|
|
|
fh->filename = strdup (fh->uri);
|
2010-02-01 11:55:56 +01:00
|
|
|
p = strstr (fh->filename, "://");
|
2009-02-05 22:08:46 +01:00
|
|
|
if (p != NULL)
|
|
|
|
fh->filename = p+3;
|
|
|
|
fh->rwx = mode;
|
|
|
|
r->file = fh;
|
2011-01-21 00:21:32 +01:00
|
|
|
r->io->plugin = fd->plugin;
|
|
|
|
fh->size = r_io_size (r->io);
|
2011-02-07 09:46:01 +01:00
|
|
|
r_list_append (r->files, fh);
|
2009-02-18 01:43:57 +01:00
|
|
|
|
2011-01-20 23:28:20 +01:00
|
|
|
// r_core_bin_load (r, fh->filename);
|
2010-02-01 11:55:56 +01:00
|
|
|
r_core_block_read (r, 0);
|
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);
|
2011-02-17 00:58:54 +01:00
|
|
|
r_config_set_i (r->config, "zoom.to", loadaddr+fh->size);
|
2011-02-12 01:52:41 +01:00
|
|
|
fh->map = r_io_map_add (r->io, fh->fd->fd, mode, 0, loadaddr, fh->size);
|
2009-02-05 22:08:46 +01:00
|
|
|
return fh;
|
|
|
|
}
|
|
|
|
|
2011-02-07 09:46:01 +01:00
|
|
|
R_API void r_core_file_free(RCoreFile *cf) {
|
|
|
|
free (cf->uri);
|
|
|
|
cf->uri = NULL;
|
|
|
|
free (cf->filename);
|
|
|
|
cf->filename = NULL;
|
|
|
|
cf->fd = NULL;
|
|
|
|
}
|
|
|
|
|
2010-02-22 02:42:29 +01:00
|
|
|
R_API int r_core_file_close(struct r_core_t *r, struct r_core_file_t *fh) {
|
2010-05-20 00:59:42 +02:00
|
|
|
int ret = r_io_close (r->io, fh->fd);
|
2010-10-04 10:55:43 +02:00
|
|
|
// TODO: free fh->obj
|
2011-02-07 09:46:01 +01:00
|
|
|
//r_list_delete (fh);
|
|
|
|
//list_del (&(fh->list));
|
2010-02-01 11:55:56 +01:00
|
|
|
// TODO: set previous opened file as current one
|
2009-02-05 22:08:46 +01:00
|
|
|
return ret;
|
|
|
|
}
|
|
|
|
|
2011-02-07 09:46:01 +01:00
|
|
|
R_API RCoreFile *r_core_file_get_fd(RCore *core, int fd) {
|
|
|
|
RCoreFile *file;
|
|
|
|
RListIter *iter;
|
|
|
|
r_list_foreach (core->files, iter, file) {
|
2011-01-20 22:52:16 +01:00
|
|
|
if (file->fd->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) {
|
|
|
|
if (f->map)
|
2011-02-16 09:29:09 +01:00
|
|
|
eprintf ("%c %d %s 0x%"PFMT64x"\n",
|
|
|
|
core->io->raised == f->fd->fd?'*':' ',
|
|
|
|
f->fd->fd, f->uri, f->map->from);
|
|
|
|
else eprintf (" %d %s\n", f->fd->fd, f->uri);
|
2010-02-01 11:55:56 +01:00
|
|
|
count++;
|
|
|
|
}
|
|
|
|
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) {
|
|
|
|
if (file->fd->fd == fd) {
|
|
|
|
r_io_close (core->io, file->fd);
|
|
|
|
r_list_delete (core->files, iter);
|
|
|
|
if (r_list_empty (core->files))
|
|
|
|
core->file = NULL;
|
|
|
|
return R_TRUE;
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return R_FALSE;
|
2009-02-05 22:08:46 +01:00
|
|
|
}
|