Fix r2 -B, rabin2 -B, Implement `oa` command

- Now it is possible to load binfiles from debugger memory
* Base address is now honored properly. But it needs more testing
This commit is contained in:
pancake 2015-01-29 01:45:39 +01:00
parent c8dbff1374
commit 039858fd86
9 changed files with 78 additions and 22 deletions

View File

@ -35,6 +35,7 @@ static char* output = NULL;
static char* create = NULL;
static int rad = R_FALSE;
static ut64 laddr = 0LL;
static ut64 baddr = 0LL;
static char* file = NULL;
static char *name = NULL;
static int rw = R_FALSE;
@ -52,6 +53,7 @@ static int rabin_show_help(int v) {
" -A list archs\n"
" -a [arch] set arch (x86, arm, .. or <arch>_<bits>)\n"
" -b [bits] set bits (32, 64 ...)\n"
" -G [addr] load address . offset to header\n"
" -B [addr] override base address (pie bins)\n"
" -c [fmt:C:D] create [elf,mach0,pe] with Code and Data hexpairs (see -a)\n"
" -C list classes\n"
@ -390,7 +392,7 @@ int main(int argc, char **argv) {
#define is_active(x) (action&x)
#define set_action(x) actions++; action |= x
#define unset_action(x) action &= ~x
while ((c = getopt (argc, argv, "DjgqAf:F:a:B:b:c:Ck:K:dD:Mm:n:N:@:isSIHelRwO:o:pPrvLhxzZ")) != -1) {
while ((c = getopt (argc, argv, "DjgqAf:F:a:B:G:b:c:Ck:K:dD:Mm:n:N:@:isSIHelRwO:o:pPrvLhxzZ")) != -1) {
switch (c) {
case 'g':
set_action (ACTION_CLASSES);
@ -485,11 +487,14 @@ int main(int argc, char **argv) {
case 'r': rad = R_TRUE; break;
case 'v': return blob_version ("rabin2");
case 'L': r_bin_list (bin); return 1;
case 'B':
case 'G':
laddr = r_num_math (NULL, optarg);
if (laddr == 0LL)
va = R_FALSE;
break;
case 'B':
baddr = r_num_math (NULL, optarg);
break;
case '@': at = r_num_math (NULL, optarg); break;
case 'n': name = optarg; break;
case 'N': {
@ -618,6 +623,10 @@ int main(int argc, char **argv) {
return 1;
}
}
if (baddr != 0LL) {
bin->cur->o->baddr = baddr;
//bin->cur->o->baddr = laddr;
}
if (rawstr == 2) {
rawstr = R_FALSE;
r_bin_dump_strings (core.bin->cur, bin->minstrlen);

View File

@ -237,8 +237,8 @@ int main(int argc, char **argv, char **envp) {
r_sys_crash_handler ("gdb --pid %d");
if (argc<2) {
r_list_free(cmds);
r_list_free(evals);
r_list_free (cmds);
r_list_free (evals);
return main_help (1);
}
if (argc==2 && !strcmp (argv[1], "-p")) {
@ -529,8 +529,15 @@ int main(int argc, char **argv, char **envp) {
/* Load rbin info from r2 dbg:// or r2 /bin/ls */
/* the baddr should be set manually here */
if (!r_core_bin_load (&r, filepath, baddr))
r_config_set (r.config, "io.va", "false");
{
if (r_core_bin_load (&r, filepath, 0)) {
RBinFile *file = r_bin_cur (r.bin);
// use_baddr
file->o->baddr = baddr;
} else {
r_config_set (r.config, "io.va", "false");
}
}
}
} else {
if (run_anal<0) {

View File

@ -117,7 +117,7 @@ Now with more better English!
All your base are belong to r2
Ask not what r2 can do for you - ask what you can do for r2
Try with ASAN, and be amazed
bash: r3: command not found :D
bash: r3: command not found
R2 loves everyone, even Java coders, but less than others
It's not a bug, it's a work in progress
Stop swearing!

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2014 - nibble, pancake */
/* radare - LGPL - Copyright 2009-2015 - nibble, pancake */
#include <r_lib.h>
#include <r_types.h>

View File

@ -502,7 +502,7 @@ R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, RIODesc *desc, ut64 baseaddr,
RIOBind *iob = &(bin->iob);
RIO *io = iob ? iob->get_io(iob) : NULL;
RListIter *it;
ut8* buf_bytes;
ut8* buf_bytes = NULL;
RBinXtrPlugin *xtr;
ut64 file_sz = UT64_MAX;
RBinFile *binfile = NULL;
@ -512,6 +512,8 @@ R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, RIODesc *desc, ut64 baseaddr,
buf_bytes = NULL;
file_sz = iob->desc_size (io, desc);
#if 1
if (r_list_length (bin->binfiles)==0) {
if ((file_sz == 0 || file_sz == UT64_MAX) && is_debugger) {
int fail = 1;
/* get file path from desc name */
@ -528,6 +530,7 @@ R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, RIODesc *desc, ut64 baseaddr,
// stream based loaders
// NOTE: For RBin we dont need to open the file in read-write. This can be problematic
RIODesc *tdesc = iob->desc_open (io, filepath, R_IO_READ, 0); //desc->flags, R_IO_READ);
eprintf ("Asuming filepath %s\n", filepath);
if (tdesc) {
file_sz = iob->desc_size (io, tdesc);
if (file_sz != UT64_MAX) {
@ -541,11 +544,16 @@ R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, RIODesc *desc, ut64 baseaddr,
free (filepath);
if (fail)
return R_FALSE;
} else if (sz != UT64_MAX) {
sz = R_MIN (file_sz, sz);
buf_bytes = iob->desc_read (io, desc, &sz);
} else {
}
} else
#endif
if (sz == UT64_MAX)
return R_FALSE;
sz = R_MIN (file_sz, sz);
if (!buf_bytes) {
iob->desc_seek (io, desc, baseaddr);
buf_bytes = iob->desc_read (io, desc, &sz);
}
if (!name) {
@ -574,6 +582,7 @@ R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, RIODesc *desc, ut64 baseaddr,
desc->name, buf_bytes, sz, file_sz,
baseaddr, loadaddr, xtr_idx,
desc->fd, bin->rawstr);
binfile->o->baddr = baseaddr;
}
xtr = NULL;
}
@ -581,9 +590,13 @@ R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, RIODesc *desc, ut64 baseaddr,
}
if (!binfile) {
//eprintf ("LOAD BINFILE FROM BYTE %lld b=0x%08llx l=0x%08llx\n", sz, baseaddr, loadaddr);
binfile = r_bin_file_new_from_bytes (bin, desc->name,
buf_bytes, sz, file_sz, bin->rawstr, baseaddr, loadaddr,
desc->fd, name, NULL, offset);
/* hack to force baseaddr, looks like rbinfilenewfrombytes() ignores the value */
if (binfile && binfile->o)
binfile->o->baddr = baseaddr;
}
if (binfile) return r_bin_file_set_cur_binfile (bin, binfile);
@ -1625,6 +1638,11 @@ R_API ut64 r_binfile_get_vaddr (RBinFile *binfile, ut64 baddr, ut64 paddr, ut64
R_API ut64 r_bin_get_vaddr (RBin *bin, ut64 baddr, ut64 paddr, ut64 vaddr) {
if (!bin || !bin->cur)
return UT64_MAX;
if (1 || bin->is_debugger) {
if (baddr)
return baddr + paddr;
}
// autodetect thumb
if (bin->cur->o && bin->cur->o->info) {
if (!strcmp (bin->cur->o->info->arch, "arm")) {

View File

@ -21,6 +21,20 @@ static int cmd_open(void *data, const char *input) {
case 'j':
r_core_file_list (core, (int)(*input));
break;
case 'a':
{
RListIter *iter;
RCoreFile *file;
ut64 addr = r_num_math (core->num, input+1);
eprintf ("OP 0x%"PFMT64x"\n", addr);
r_list_foreach (core->files, iter, file) {
r_bin_load_io (
core->bin, file->desc, //r_core_file_cur (core)->desc, //core->file->desc,
addr, 0, 0); //, addr, "membin");
}
//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");
@ -133,6 +147,7 @@ static int cmd_open(void *data, const char *input) {
r_core_bin_raise (core, binfile_num, -1);
break;
case ' ':
case 'o':
value = *(input+2) ? input+3 : NULL;
if (!value) {
@ -175,6 +190,7 @@ static int cmd_open(void *data, const char *input) {
const char* help_msg[] = {
"Usage:", "ob", " # List open binary files backed by fd",
"ob", "", "List opened binfiles and bin objects",
"ob", " [binfile #]", "Same as obo.",
"obb", " [binfile #]", "Prioritize by binfile number with current selected object",
"ob-", " [binfile #]", "Delete binfile",
"obd", " [binobject #]", "Delete binfile object numbers, if more than 1 object is loaded",

View File

@ -332,6 +332,7 @@ static int cb_cfgdebug(void *user, void *data) {
core->io->debug = node->i_value;
if (core->dbg && node->i_value) {
const char *dbgbackend = r_config_get (core->config, "dbg.backend");
core->bin->is_debugger = R_TRUE;
r_debug_use (core->dbg, dbgbackend);
if (!strcmp (dbgbackend, "bf"))
r_config_set (core->config, "asm.arch", "bf");
@ -339,7 +340,10 @@ static int cb_cfgdebug(void *user, void *data) {
r_debug_select (core->dbg, core->file->desc->fd,
core->file->desc->fd);
}
} else if (core->dbg) r_debug_use (core->dbg, NULL);
} else {
if (core->dbg) r_debug_use (core->dbg, NULL);
core->bin->is_debugger = R_FALSE;
}
r_config_set (core->config, "io.raw", "true");
return R_TRUE;
}

View File

@ -178,6 +178,7 @@ typedef struct r_bin_t {
int loadany;
RIOBind iob;
char *force;
int is_debugger;
} RBin;
typedef int (*FREE_XTR)(void *xtr_obj);

View File

@ -892,7 +892,7 @@ R_API void r_io_sort_maps (RIO *io) {
// THIS IS pread.. a weird one
static ut8 * r_io_desc_read (RIO *io, RIODesc * desc, ut64 *out_sz) {
ut8 *buf_bytes = NULL;
ut8 *buf = NULL;
ut64 off = 0;
if (!io || !desc || !out_sz)
@ -900,23 +900,24 @@ static ut8 * r_io_desc_read (RIO *io, RIODesc * desc, ut64 *out_sz) {
if (*out_sz == UT64_MAX)
*out_sz = r_io_desc_size (io, desc);
if (*out_sz == 0x8000000) {
*out_sz = 1024 * 1024 * 1; // 2MB
}
off = io->off;
if (*out_sz == UT64_MAX) return buf;
if (*out_sz == UT64_MAX) return buf_bytes;
buf_bytes = malloc (*out_sz);
buf = malloc (*out_sz);
if (desc->plugin && desc->plugin->read) {
if (!buf_bytes || !desc->plugin->read (io, desc, buf_bytes, *out_sz)) {
free (buf_bytes);
if (!buf || !desc->plugin->read (io, desc, buf, *out_sz)) {
free (buf);
io->off = off;
return R_FALSE;
}
}
io->off = off;
return buf_bytes;
return buf;
}
static RIO * r_io_bind_get_io(RIOBind *bnd) {