Some rework on RBin.baddr and laddr to make it work again

Not all fileformats return correct data in Sections, this is
why sometimes the relocation with baddr (needed for aslr) fails
on mach0 for example. This code needs to be redesigned and fixed.
This commit is contained in:
pancake 2014-05-29 00:49:28 +02:00
parent 70744a1ad9
commit 8d663ceb94
8 changed files with 73 additions and 30 deletions

View File

@ -312,6 +312,7 @@ static int r_bin_object_set_items(RBinFile *binfile, RBinObject *o) {
minlen = cp->minstrlen;
binfile->o = o;
if (cp->baddr) o->baddr = cp->baddr (binfile);
binfile->loadaddr = o->baddr;
if (cp->boffset) o->boffset = cp->boffset (binfile);
// XXX: no way to get info from xtr pluginz?
// Note, object size can not be set from here due to potential inconsistencies
@ -1049,6 +1050,7 @@ R_API RList* r_bin_get_sections(RBin *bin) {
return NULL;
}
// TODO: MOve into section.c and rename it to r_io_section_get_at ()
R_API RBinSection* r_bin_get_section_at(RBin *bin, ut64 off, int va) {
RBinSection *section;
RListIter *iter;
@ -1535,9 +1537,46 @@ R_API ut64 r_bin_get_offset (RBin *bin) {
}
R_API ut64 r_binfile_get_vaddr (RBinFile *binfile, ut64 baddr, ut64 paddr, ut64 vaddr) {
#if 0
This function is not right at all, the problem appears when using
a user specified baddr, when loadaddr is 0, the rebasing doesnt works
in all file formats. We have to refactor this to proper define the
load address from the plugin side, and check all places where laddr
and baddr is used.
#endif
//eprintf ("LADDR %llx\tVADDR %llx\tBADDR %llx\tPADDR %llx\n",
// binfile->loadaddr, vaddr, baddr, paddr);
//eprintf ("BADDR %llx\n", baddr);
if (baddr) {
/* Load object files which have no base load address specified */
if (!binfile->loadaddr) {
//return baddr+vaddr;
return baddr; // XXX: vaddr ignored here??
}
if (vaddr<binfile->loadaddr) {
vaddr += binfile->loadaddr;
if (baddr != binfile->loadaddr) {
return vaddr - (binfile->loadaddr-baddr);
}
/* other cases */
st64 delta = 0; //binfile->loadaddr-vaddr;
//ut64 plus = (baddr && binfile->loadaddr == baddr)? baddr:0;
// eprintf ("--> b:%llx l:%llx\n", baddr, binfile->loadaddr);
return vaddr-binfile->loadaddr+baddr+delta; //binfile->loadaddr+delta;
}
//return vaddr+baddr;
if (binfile->loadaddr == baddr)
return vaddr;
}
// wtf case
ut32 delta;
RBinPlugin *cp = r_bin_file_cur_plugin (binfile);
// XXX hack to recover lost baddr
#if 0
if (vaddr>=baddr)
return vaddr;
#endif
baddr = binfile->o->baddr;
//baddr = 0xf00000;
if (!cp) return UT64_MAX;
@ -1547,7 +1586,7 @@ R_API ut64 r_binfile_get_vaddr (RBinFile *binfile, ut64 baddr, ut64 paddr, ut64
}
#endif
if (!baddr) return vaddr;
delta = (paddr & 0xffff0000) | (vaddr & 0xffff);
delta = (paddr & 0xfffff000) | (vaddr & 0xfff);
return baddr + delta;
}
@ -1587,7 +1626,6 @@ R_API RBinFile * r_bin_file_find_by_name (RBin * bin, const char * name) {
return bf;
}
R_API RBinFile * r_bin_file_find_by_name_n (RBin * bin, const char * name, int idx) {
RListIter *iter;
RBinFile *bf = NULL;

View File

@ -171,8 +171,8 @@ static RList* sections(RBinFile *arch) {
// add entry for ehdr
ptr = R_NEW0 (RBinSection);
if (ptr) {
RBinSection *t_sec = NULL;
RListIter *iter = 0;
//RBinSection *t_sec = NULL;
// RListIter *iter = 0;
ut64 ehdr_size = sizeof (obj->ehdr);
//r_list_foreach (ret, iter, t_sec) {
@ -188,9 +188,6 @@ static RList* sections(RBinFile *arch) {
r_list_append (ret, ptr);
}
return ret;
}
@ -404,21 +401,22 @@ static RList* relocs(RBinFile *arch) {
if (!(ret = r_list_new ()))
return NULL;
ret->free = free;
#if 0
#if 1
if ((got_addr = Elf_ (r_bin_elf_get_section_addr) (arch->o->bin_obj, ".got")) == -1 &&
(got_addr = Elf_ (r_bin_elf_get_section_addr) (arch->o->bin_obj, ".got.plt")) == -1)
{
return ret;
}
#endif
if (!(relocs = Elf_(r_bin_elf_get_relocs) (arch->o->bin_obj)))
return ret;
for (i = 0; !relocs[i].last; i++) {
if (!(ptr = reloc_convert(arch->o->bin_obj, &relocs[i], got_addr)))
if (!(ptr = reloc_convert (arch->o->bin_obj,
&relocs[i], got_addr)))
break;
r_list_append (ret, ptr);
}
free (relocs);
#endif
return ret;
}
@ -568,8 +566,11 @@ static RBuffer* create(RBin* bin, const ut8 *code, int codelen, const ut8 *data,
int is_arm = !strcmp (bin->cur->o->info->arch, "arm");
RBuffer *buf = r_buf_new ();
// XXX: hardcoded
if (is_arm) baddr = 0x40000;
else baddr = 0x8048000;
if (is_arm) {
baddr = 0x40000;
} else {
baddr = 0x8048000;
}
#define B(x,y) r_buf_append_bytes(buf,(const ut8*)x,y)
#define D(x) r_buf_append_ut32(buf,x)

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2013 - nibble, pancake */
/* radare - LGPL - Copyright 2009-2014 - nibble, pancake */
#define R_BIN_MACH064 1
#include "bin_mach0.c"

View File

@ -852,7 +852,6 @@ static int bin_sections (RCore *r, int mode, ut64 baddr, int va, ut64 at, const
int i = 0;
st64 delta = 0LL;
if ((sections = r_bin_get_sections (r->bin)) == NULL)
return R_FALSE;

View File

@ -1416,11 +1416,12 @@ R_API int r_core_cmd(RCore *core, const char *cstr, int log) {
}
core->cmd_depth --;
for (rcmd = cmd;;) {
ptr = strstr (rcmd, "\n");
ptr = strchr (rcmd, '\n');
if (ptr) *ptr = '\0';
ret = r_core_cmd_subst (core, rcmd);
if (ret == -1) {
eprintf ("|ERROR| Invalid command '%s'\n", rcmd);
eprintf ("|ERROR| Invalid command '%s' (0x%02x)\n",
rcmd, *rcmd);
break;
}
if (!ptr) break;

View File

@ -2,6 +2,12 @@
#include <r_cmd.h>
#include <r_util.h>
#include <stdio.h>
#include <r_cons.h>
#include <r_cmd.h>
#include <r_util.h>
static int value = 0;
#define NCMDS (sizeof (cmd->cmds)/sizeof(*cmd->cmds))
R_LIB_VERSION (r_cmd);
@ -202,15 +208,6 @@ R_API int r_cmd_call_long(RCmd *cmd, const char *input) {
/** macro.c **/
/* radare - LGPL - Copyright 2008-2013 - pancake */
#include <stdio.h>
#include <r_cons.h>
#include <r_cmd.h>
#include <r_util.h>
static int value = 0;
R_API void r_cmd_macro_init(RCmdMacro *mac) {
mac->counter = 0;
mac->_brk_value = 0;

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2013 - pancake */
/* radare - LGPL - Copyright 2009-2014 - pancake */
static void flagbars(RCore *core) {
int total = 0;

View File

@ -86,6 +86,7 @@ static ut64 findNextVaddr (RIO *io, RIOmaddr *ma) {
if (checkSectionHit (s->vaddr+s->vsize))
foundSectionHit ();
}
#if 0
/* or map */
r_list_foreach (io->maps, iter, m) {
if (cur<m->from) {
@ -99,6 +100,7 @@ static ut64 findNextVaddr (RIO *io, RIOmaddr *ma) {
hit = diff;
}
}
#endif
/* if not found */
if (hit == UT64_MAX) {
ma->has_next = R_FALSE;
@ -150,7 +152,7 @@ R_API int r_io_vread (RIO *io, ut64 vaddr, ut8 *buf, int len) {
int left = len;
int ret, skip = 0;
RIOmaddr pat;
memset (&pat, 0, sizeof (pat));
memset (&pat, 0xff, sizeof (pat));
if (io->raw)
return r_io_pread (io, vaddr, buf, len);
io->ff = 1;
@ -170,11 +172,15 @@ R_API int r_io_vread (RIO *io, ut64 vaddr, ut8 *buf, int len) {
return skip;
return -1; // fix invalid memreads. RCore expects this from vaddr
}
memset (buf+skip, 0xff, bufsz);
memset (buf+skip, 0xff, left);
//memset (buf+skip, 0xff, bufsz);
}
}
} else ret = 1; // avoid infinite loopz
} else {
ret = 0; // avoid infinite loopz
break;
}
skip += ret;
left -= ret;
if (!pat.has_next)
@ -183,8 +189,9 @@ R_API int r_io_vread (RIO *io, ut64 vaddr, ut8 *buf, int len) {
vaddr = pat.next_vaddr;
}
if (io->ff) {
if (left>0)
if (left>0) {
memset (buf+skip, 0xff, left);
}
r_io_cache_read (io, vaddr, buf, len);
return len;
}