Initial working implementation of bin.libs ##bin

This commit is contained in:
pancake 2019-07-05 18:43:15 +02:00 committed by radare
parent 3e27998e9f
commit baa91ca899
14 changed files with 99 additions and 88 deletions

View File

@ -777,8 +777,11 @@ R_IPI RList *r_bin_file_get_strings(RBinFile *bf, int min, int dump, int raw) {
return ret;
}
R_API ut64 r_bin_file_get_baddr(RBinFile *binfile) {
return binfile? r_bin_object_get_baddr (binfile->o): UT64_MAX;
R_API ut64 r_bin_file_get_baddr(RBinFile *bf) {
if (bf && bf->o) {
return bf->o->baddr;
}
return UT64_MAX;
}
R_API bool r_bin_file_close(RBin *bin, int bd) {

View File

@ -659,8 +659,7 @@ R_API void r_bin_list(RBin *bin, int format) {
/* returns the base address of bin or UT64_MAX in case of errors */
R_API ut64 r_bin_get_baddr(RBin *bin) {
r_return_val_if_fail (bin, UT64_MAX);
RBinObject *o = r_bin_cur_object (bin);
return o ? r_bin_object_get_baddr (o) : UT64_MAX;
return r_bin_file_get_baddr (bin->cur);
}
/* returns the load address of bin or UT64_MAX in case of errors */
@ -1435,11 +1434,16 @@ R_API RBinFile *r_bin_file_at(RBin *bin, ut64 at) {
RBinFile *bf;
RBinSection *s;
r_list_foreach (bin->binfiles, it, bf) {
// chk for baddr + size of no section is covering anything
// we should honor maps not sections imho
r_list_foreach (bf->o->sections, it2, s) {
if (at >= s->vaddr && at < (s->vaddr + s->vsize)) {
return bf;
}
}
if (at >= bf->o->baddr && at < (bf->o->baddr + bf->size)) {
return bf;
}
}
return NULL;
}

View File

@ -435,9 +435,7 @@ R_IPI RBinObject *r_bin_object_get_cur(RBin *bin) {
R_IPI RBinObject *r_bin_object_find_by_arch_bits(RBinFile *bf, const char *arch, int bits, const char *name) {
r_return_val_if_fail (bf && arch && name, NULL);
if (!bf->o) {
return NULL;
}
if (bf->o) {
RBinInfo *info = bf->o->info;
if (info && info->arch && info->file &&
(bits == info->bits) &&
@ -445,14 +443,10 @@ R_IPI RBinObject *r_bin_object_find_by_arch_bits(RBinFile *bf, const char *arch,
!strcmp (info->file, name)) {
return bf->o;
}
}
return NULL;
}
R_IPI ut64 r_bin_object_get_baddr(RBinObject *o) {
r_return_val_if_fail (o, UT64_MAX);
return o->baddr; // + o->baddr_shift;
}
R_API bool r_bin_object_delete(RBin *bin, ut32 bf_id) {
r_return_val_if_fail (bin, false);

View File

@ -44,6 +44,9 @@ static bool check_buffer(RBuffer *buf) {
bool one = r == sizeof (tmp) && !memcmp (tmp, "\x00\x00\x01\x00\x00\x00", sizeof (tmp));
if (one) {
int r = r_buf_read_at (buf, 6, tmp, sizeof (tmp));
if (r != 6) {
return false;
}
return sizeof (tmp) && !memcmp (tmp, "\x00\x00\x00\x00\x00\x00", sizeof (tmp));
}
return false;

View File

@ -3778,9 +3778,6 @@ static bool r_core_bin_file_print(RCore *core, RBinFile *bf, int mode) {
ut32 bin_sz = bf ? bf->size : 0;
// TODO: handle mode to print in json and r2 commands
if (!bf) {
return false;
}
switch (mode) {
case '*':
r_cons_printf ("oba 0x%08"PFMT64x" %s # %d\n", bf->o->boffset, name, bf->id);

View File

@ -3156,6 +3156,7 @@ R_API int r_core_config_init(RCore *core) {
}
SETCB ("dir.source", "", &cb_dirsrc, "Path to find source files");
SETPREF ("dir.types", "/usr/include", "Default path to look for cparse type files");
SETPREF ("dir.libs", "", "Specify path to find libraries to load when bin.libs=true");
SETCB ("dir.home", r_sys_getenv (R_SYS_HOME), &cb_dirhome, "Path for the home directory");
SETCB ("dir.tmp", r_sys_getenv (R_SYS_TMP), &cb_dirtmp, "Path of the tmp directory");
#if __ANDROID__

View File

@ -435,11 +435,20 @@ static int r_core_file_do_load_for_io_plugin(RCore *r, ut64 baseaddr, ut64 loada
}
static bool try_loadlib(RCore *core, const char *lib, ut64 addr) {
return r_core_file_open (core, lib, 0, addr) != NULL;
if (r_core_file_open (core, lib, 0, addr) != NULL) {
r_core_bin_load (core, lib, addr);
return true;
}
return false;
}
R_API bool r_core_file_loadlib(RCore *core, const char *lib, ut64 libaddr) {
const char *dirlibs = r_config_get (core->config, "dir.libs");
if (!dirlibs || !*dirlibs) {
dirlibs = "./";
}
const char *ldlibrarypath[] = {
dirlibs,
R2_LIBDIR,
"/usr/local/lib",
"/usr/lib",
@ -505,15 +514,27 @@ static void load_scripts_for(RCore *core, const char *name) {
free (hdir);
}
typedef struct {
const char *name;
bool found;
} RCoreFileData;
static bool filecb(void *user, void *data, ut32 id) {
RCoreFileData *fd = user;
RIODesc *desc = (RIODesc *)data;
if (!strcmp (desc->name, fd->name)) {
fd->found = true;
}
return true;
}
R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
RCoreFile *cf = r_core_file_cur (r);
RIODesc *desc = cf ? r_io_desc_get (r->io, cf->fd) : NULL;
int va = 1;
ut64 laddr = r_config_get_i (r->config, "bin.laddr");
RBinFile *binfile = NULL;
RBinPlugin *plugin = NULL;
RBinObject *obj = NULL;
int is_io_load;
bool is_io_load;
const char *cmd_load;
if (!cf) {
return false;
@ -523,15 +544,6 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
is_io_load = desc && desc->plugin;
if (!filenameuri || !*filenameuri) {
filenameuri = desc->name;
#if 0
} else if (desc->name && strcmp (filenameuri, desc->name)) {
// 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.
eprintf ("Error: The filenameuri '%s' is not the same as in RCoreFile: %s\n",
filenameuri, desc->name);
#endif
}
} else {
is_io_load = false;
@ -550,10 +562,10 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
if ((desc->plugin && desc->plugin->isdbg) || r_config_get_i (r->config, "cfg.debug")) {
r_core_file_do_load_for_debug (r, baddr, filenameuri);
} else {
r_core_file_do_load_for_io_plugin (r, baddr, laddr);
r_core_file_do_load_for_io_plugin (r, baddr, 0LL);
}
// Restore original desc
r_io_use_fd (r->io, desc->fd);
// Restore original desc
}
if (cf && binfile && desc) {
binfile->fd = desc->fd;
@ -589,9 +601,9 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
r->bin->minstrlen = r_config_get_i (r->config, "bin.minstr");
r->bin->maxstrbuf = r_config_get_i (r->config, "bin.maxstrbuf");
} else if (binfile) {
obj = r_bin_cur_object (r->bin);
RBinObject *obj = r_bin_cur_object (r->bin);
if (obj) {
va = obj->info ? obj->info->has_va : va;
bool va = obj->info ? obj->info->has_va : 0;
if (!va) {
r_config_set_i (r->config, "io.va", 0);
}
@ -599,7 +611,6 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
if (r_io_desc_is_dbg (desc) || (!obj->sections || !va)) {
r_io_map_new (r->io, desc->fd, desc->perm, 0, laddr, r_io_desc_size (desc));
}
RBinInfo *info = obj->info;
if (info) {
r_core_bin_set_arch_bits (r, binfile->file, info->arch, info->bits);
@ -631,15 +642,25 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
loadGP (r);
}
if (r_config_get_i (r->config, "bin.libs")) {
ut64 libaddr = (r->assembler->bits == 64)? 0x00007fff00000000LL: 0x7f000000;
const char *lib;
RListIter *iter;
RList *libs = r_bin_get_libs (r->bin);
r_list_foreach (libs, iter, lib) {
eprintf ("Opening %s\n", lib);
r_core_file_loadlib (r, lib, libaddr);
libaddr += 0x2000000;
eprintf ("[bin.libs] Opening %s\n", lib);
RCoreFileData filedata = {lib, false};
r_id_storage_foreach (r->io->files, filecb, &filedata);
if (filedata.found) {
eprintf ("Already opened\n");
continue;
}
ut64 baddr = r_io_map_location (r->io, 0x200000);
if (r_io_map_get (r->io, baddr)) {
eprintf ("WTF\n");
}
r_core_file_loadlib (r, lib, baddr);
}
r_core_cmd0 (r, "obb 0;s entry0");
r_config_set_i (r->config, "bin.at", true);
}
//If type == R_BIN_TYPE_CORE, we need to create all the maps
@ -651,9 +672,7 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
// Setting the right arch and bits, so regstate will be shown correctly
if (plugin->info) {
RBinInfo *inf = plugin->info (binfile);
eprintf ("Setting up coredump: asm.arch <-> %s and asm.bits <-> %d\n",
inf->arch,
inf->bits);
eprintf ("Setting up coredump arch-bits to: %s-%d\n", inf->arch, inf->bits);
r_config_set (r->config, "asm.arch", inf->arch);
r_config_set_i (r->config, "asm.bits", inf->bits);
r_bin_info_free (inf);
@ -702,13 +721,12 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) {
eprintf ("Setting up coredump: %d maps have been found and created\n", map);
goto beach;
}
beach:
return true;
}
R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int perm, ut64 loadaddr) {
bool openmany = r_config_get_i (r->config, "file.openmany");
const bool openmany = r_config_get_i (r->config, "file.openmany");
int opened_count = 0;
RListIter *fd_iter, *iter2;
RIODesc *fd;
@ -722,7 +740,7 @@ R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int perm, ut6
r_list_foreach_safe (list_fds, fd_iter, iter2, fd) {
opened_count++;
if (opened_count > openmany) {
if (openmany && opened_count > 1) {
// 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.
@ -731,29 +749,26 @@ R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int perm, ut6
continue;
}
RCoreFile *fh = R_NEW0 (RCoreFile);
if (!fh) {
break;
}
if (fh) {
fh->alive = 1;
fh->core = r;
fh->fd = fd->fd;
r->file = fh;
r_bin_bind (r->bin, &(fh->binb));
r_list_append (r->files, fh);
r_core_bin_load (r, fd->name, 0LL);
r_core_bin_load (r, fd->name, loadaddr);
}
}
return NULL;
}
/* loadaddr is r2 -m (mapaddr) */
R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int flags, ut64 loadaddr) {
r_return_val_if_fail (r && file, NULL);
ut64 prev = r_sys_now ();
const int openmany = r_config_get_i (r->config, "file.openmany");
const bool openmany = r_config_get_i (r->config, "file.openmany");
RCoreFile *fh = NULL;
if (!file || !*file) {
goto beach;
}
if (!strcmp (file, "-")) {
file = "malloc://512";
}
@ -763,7 +778,7 @@ R_API RCoreFile *r_core_file_open(RCore *r, const char *file, int flags, ut64 lo
}
r->io->bits = r->assembler->bits; // TODO: we need an api for this
RIODesc *fd = r_io_open_nomap (r->io, file, flags, 0644);
if (!fd && openmany > 2) {
if (!fd && openmany) {
// XXX - make this an actual option somewhere?
fh = r_core_file_open_many (r, file, flags, loadaddr);
if (fh) {
@ -832,13 +847,6 @@ beach:
return fh;
}
R_API int r_core_files_free(const RCore *core, RCoreFile *cf) {
if (!core || !core->files || !cf) {
return false;
}
return r_list_delete_data (core->files, cf);
}
R_API void r_core_file_free(RCoreFile *cf) {
int res = 1;
@ -848,7 +856,7 @@ R_API void r_core_file_free(RCoreFile *cf) {
free (cf);
return;
}
res = r_core_files_free (cf->core, cf);
res = r_list_delete_data (cf->core->files, cf);
if (res && cf->alive) {
// double free libr/io/io.c:70 performs free
RIO *io = cf->core->io;

View File

@ -295,6 +295,7 @@ R_API bool r_core_seek(RCore *core, ut64 addr, bool rb) {
if (bf) {
core->bin->cur = bf;
r_bin_select_bfid (core->bin, bf->id);
// XXX r_core_cmdf (core, "obb %d", bf->id);
} else {
core->bin->cur = NULL;
}
@ -304,7 +305,6 @@ R_API bool r_core_seek(RCore *core, ut64 addr, bool rb) {
R_API int r_core_seek_delta(RCore *core, st64 addr) {
ut64 tmp = core->offset;
int ret;
if (addr == 0) {
return true;
}
@ -320,12 +320,7 @@ R_API int r_core_seek_delta(RCore *core, st64 addr) {
}
}
core->offset = addr;
ret = r_core_seek (core, addr, 1);
//ret = r_core_block_read (core);
//if (ret == -1)
// memset (core->block, 0xff, core->blocksize);
// core->offset = tmp;
return ret;
return r_core_seek (core, addr, 1);
}
// TODO: kill this wrapper

View File

@ -535,7 +535,7 @@ static void cmd_open_map(RCore *core, const char *input) {
const char *P;
switch (input[1]) {
case '.':
case '.': // "om."
map = r_io_map_get (core->io, core->offset);
if (map) {
core->print->cb_printf ("map: %i fd: %i +0x%"PFMT64x" 0x%"PFMT64x

View File

@ -670,9 +670,10 @@ R_API RBinPlugin *r_bin_get_binplugin_by_buffer(RBin *bin, RBuffer *buf);
R_API void r_bin_force_plugin(RBin *bin, const char *pname);
// get/set various bin information
R_API ut64 r_bin_get_baddr(RBin *bin);
R_API ut64 r_bin_file_get_baddr(RBinFile *bf);
R_API void r_bin_set_user_ptr(RBin *bin, void *user);
R_API RBinInfo *r_bin_get_info(RBin *bin);
R_API ut64 r_bin_get_baddr(RBin *bin);
R_API void r_bin_set_baddr(RBin *bin, ut64 baddr);
R_API ut64 r_bin_get_laddr(RBin *bin);
R_API ut64 r_bin_get_size(RBin *bin);

View File

@ -473,7 +473,6 @@ R_API int r_core_file_set_by_name(RCore *core, const char * name);
R_API int r_core_file_set_by_file (RCore * core, RCoreFile *cf);
R_API int r_core_setup_debugger (RCore *r, const char *debugbackend, bool attach);
R_API int r_core_files_free(const RCore *core, RCoreFile *cf);
R_API void r_core_file_free(RCoreFile *cf);
R_API RCoreFile *r_core_file_open(RCore *core, const char *file, int flags, ut64 loadaddr);
R_API RCoreFile *r_core_file_open_many(RCore *r, const char *file, int flags, ut64 loadaddr);

View File

@ -289,6 +289,7 @@ R_API ut64 r_io_map_next_address(RIO* io, ut64 addr);
R_API void r_io_map_init (RIO *io);
R_API bool r_io_map_remap (RIO *io, ut32 id, ut64 addr);
R_API bool r_io_map_remap_fd (RIO *io, int fd, ut64 addr);
R_API ut64 r_io_map_location(RIO *io, ut64 size);
R_API bool r_io_map_exists (RIO *io, RIOMap *map);
R_API bool r_io_map_exists_for_id (RIO *io, ut32 id);
R_API RIOMap *r_io_map_resolve (RIO *io, ut32 id);

View File

@ -79,20 +79,16 @@ R_API bool r_io_fd_is_dbg(RIO *io, int fd) {
}
R_API int r_io_fd_get_pid(RIO *io, int fd) {
RIODesc *desc;
if (!io || !io->files) {
return -2;
}
desc = r_io_desc_get (io, fd);
RIODesc *desc = r_io_desc_get (io, fd);
return r_io_desc_get_pid (desc);
}
R_API int r_io_fd_get_tid(RIO *io, int fd) {
RIODesc *desc;
if (!io || !io->files) {
return -2;
}
desc = r_io_desc_get (io, fd);
r_return_val_if_fail (io && io->files, -2);
RIODesc *desc = r_io_desc_get (io, fd);
return r_io_desc_get_tid (desc);
}

View File

@ -605,3 +605,12 @@ R_API bool r_io_map_resize(RIO *io, ut32 id, ut64 newsize) {
return true;
}
// find a location that can hold enough bytes without overlapping
// XXX this function is buggy and doesnt works as expected, but i need it for a PoC for now
R_API ut64 r_io_map_location(RIO *io, ut64 size) {
ut64 base = (io->bits == 64)? 0x60000000000LL: 0x60000000;
while (r_io_map_get (io, base)) {
base += 0x200000;
}
return base;
}