From baa91ca8990622e91171d1dee785e6c2ba4bc3bf Mon Sep 17 00:00:00 2001 From: pancake Date: Fri, 5 Jul 2019 18:43:15 +0200 Subject: [PATCH] Initial working implementation of bin.libs ##bin --- libr/bin/bfile.c | 7 ++- libr/bin/bin.c | 8 +++- libr/bin/bobj.c | 22 ++++----- libr/bin/p/bin_dol.c | 3 ++ libr/core/cbin.c | 3 -- libr/core/cconfig.c | 1 + libr/core/cfile.c | 108 +++++++++++++++++++++++------------------- libr/core/cio.c | 9 +--- libr/core/cmd_open.c | 2 +- libr/include/r_bin.h | 3 +- libr/include/r_core.h | 1 - libr/include/r_io.h | 1 + libr/io/fd.c | 10 ++-- libr/io/map.c | 9 ++++ 14 files changed, 99 insertions(+), 88 deletions(-) diff --git a/libr/bin/bfile.c b/libr/bin/bfile.c index d9c6726dd9..e3f0309935 100644 --- a/libr/bin/bfile.c +++ b/libr/bin/bfile.c @@ -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) { diff --git a/libr/bin/bin.c b/libr/bin/bin.c index ed125227df..e372345e97 100644 --- a/libr/bin/bin.c +++ b/libr/bin/bin.c @@ -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; } diff --git a/libr/bin/bobj.c b/libr/bin/bobj.c index 96b9b48ada..1b56cb194c 100644 --- a/libr/bin/bobj.c +++ b/libr/bin/bobj.c @@ -435,24 +435,18 @@ 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; - } - RBinInfo *info = bf->o->info; - if (info && info->arch && info->file && - (bits == info->bits) && - !strcmp (info->arch, arch) && - !strcmp (info->file, name)) { - return bf->o; + if (bf->o) { + RBinInfo *info = bf->o->info; + if (info && info->arch && info->file && + (bits == info->bits) && + !strcmp (info->arch, 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); diff --git a/libr/bin/p/bin_dol.c b/libr/bin/p/bin_dol.c index 6b5e248763..c443476f58 100644 --- a/libr/bin/p/bin_dol.c +++ b/libr/bin/p/bin_dol.c @@ -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; diff --git a/libr/core/cbin.c b/libr/core/cbin.c index d63f5cb5e3..f1d7839b5d 100644 --- a/libr/core/cbin.c +++ b/libr/core/cbin.c @@ -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); diff --git a/libr/core/cconfig.c b/libr/core/cconfig.c index 539887beda..d14fdd8a79 100644 --- a/libr/core/cconfig.c +++ b/libr/core/cconfig.c @@ -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__ diff --git a/libr/core/cfile.c b/libr/core/cfile.c index eb85e3bafe..e1232e62fb 100644 --- a/libr/core/cfile.c +++ b/libr/core/cfile.c @@ -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, loadaddr); } - 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); } 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; diff --git a/libr/core/cio.c b/libr/core/cio.c index 09042ef9cd..70c2963729 100644 --- a/libr/core/cio.c +++ b/libr/core/cio.c @@ -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 diff --git a/libr/core/cmd_open.c b/libr/core/cmd_open.c index e3ca9c3e8c..daa7629c91 100644 --- a/libr/core/cmd_open.c +++ b/libr/core/cmd_open.c @@ -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 diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index 3c39b5b3c7..b286dc542b 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -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); diff --git a/libr/include/r_core.h b/libr/include/r_core.h index 2838732565..1845c18281 100644 --- a/libr/include/r_core.h +++ b/libr/include/r_core.h @@ -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); diff --git a/libr/include/r_io.h b/libr/include/r_io.h index 55f003d3b5..99b339ae35 100644 --- a/libr/include/r_io.h +++ b/libr/include/r_io.h @@ -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); diff --git a/libr/io/fd.c b/libr/io/fd.c index 3333120d82..18bfca67df 100644 --- a/libr/io/fd.c +++ b/libr/io/fd.c @@ -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); } diff --git a/libr/io/map.c b/libr/io/map.c index 37c5c64f56..0d475919f5 100644 --- a/libr/io/map.c +++ b/libr/io/map.c @@ -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; +}