From 6da28493f5c186cc7f4b7413b66ca13042602060 Mon Sep 17 00:00:00 2001 From: radare Date: Tue, 22 May 2018 17:48:34 +0200 Subject: [PATCH] Initial work on using idpool+idstorage from RBin + initial new RBin.open() api (#10160) --- libr/bin/Makefile | 2 +- libr/bin/bin.c | 4 +- libr/bin/file.c | 21 ++-- libr/bin/filter.c | 4 +- libr/bin/obj.c | 7 +- libr/bin/open.c | 95 +++++++++++++++++++ libr/core/cmd_open.c | 10 +- libr/core/core.c | 14 ++- libr/include/r_bin.h | 35 +++++-- libr/include/r_io.h | 2 +- libr/include/r_util.h | 2 +- .../r_util/{r_id_storage.h => r_idpool.h} | 0 libr/util/idpool.c | 6 +- 13 files changed, 164 insertions(+), 38 deletions(-) create mode 100644 libr/bin/open.c rename libr/include/r_util/{r_id_storage.h => r_idpool.h} (100%) diff --git a/libr/bin/Makefile b/libr/bin/Makefile index 33e5a4014d..b4dc277fda 100644 --- a/libr/bin/Makefile +++ b/libr/bin/Makefile @@ -19,7 +19,7 @@ include $(SHLR)/java/deps.mk include $(SHLR)/ar/deps.mk STATIC_OBJS=$(addprefix $(LTOP)/bin/p/, $(STATIC_OBJ)) -OBJS=bin.o dbginfo.o bin_ldr.o bin_write.o demangle.o dwarf.o filter.o file.o obj.o +OBJS=bin.o dbginfo.o bin_ldr.o bin_write.o demangle.o dwarf.o filter.o file.o obj.o open.o OBJS+=mangling/cxx/cp-demangle.o ${STATIC_OBJS} OBJS+=mangling/demangler.o OBJS+=mangling/microsoft_demangle.o diff --git a/libr/bin/bin.c b/libr/bin/bin.c index 57304a3fc1..9892ec51f5 100644 --- a/libr/bin/bin.c +++ b/libr/bin/bin.c @@ -629,7 +629,7 @@ R_API void *r_bin_free(RBin *bin) { r_list_free (bin->plugins); r_list_free (bin->binldrs); sdb_free (bin->sdb); - r_id_pool_free (bin->file_ids); + r_id_storage_free (bin->ids); memset (bin, 0, sizeof (RBin)); free (bin); return NULL; @@ -1018,7 +1018,7 @@ R_API RBin *r_bin_new() { bin->want_dbginfo = true; bin->cur = NULL; bin->io_owned = false; - bin->file_ids = r_id_pool_new (0, 0xffffffff); + bin->ids = r_id_storage_new (0, ST32_MAX); /* bin parsers */ bin->binfiles = r_list_newf ((RListFree)r_bin_file_free); diff --git a/libr/bin/file.c b/libr/bin/file.c index 5b4e18e759..779db7b79c 100644 --- a/libr/bin/file.c +++ b/libr/bin/file.c @@ -73,7 +73,7 @@ static int string_scan_range(RList *list, RBinFile *bf, int min, type = R_STRING_TYPE_DETECT; } if (from >= to) { - eprintf ("Invalid range to find strings 0x%llx .. 0x%llx\n", from, to); + eprintf ("Invalid range to find strings 0x%"PFMT64x" .. 0x%"PFMT64x"\n", from, to); return -1; } int len = to - from; @@ -296,7 +296,8 @@ R_API RBinFile *r_bin_file_new(RBin *bin, const char *file, const ut8 *bytes, ut if (!binfile) { return NULL; } - if (!r_id_pool_grab_id (bin->file_ids, &binfile->id)) { + // TODO: use r_id_storage api + if (!r_id_pool_grab_id (bin->ids->pool, &binfile->id)) { if (steal_ptr) { // we own the ptr, free on error free ((void*) bytes); } @@ -512,7 +513,6 @@ R_API RBinFile *r_bin_file_new_from_bytes(RBin *bin, const char *file, const ut8 bf->narch = 1; } #endif - /* free unnecessary rbuffer (???) */ return bf; } @@ -762,7 +762,6 @@ R_API int r_bin_file_ref(RBin *bin, RBinFile *a) { R_API void r_bin_file_free(void /*RBinFile*/ *bf_) { RBinFile *a = bf_; RBinPlugin *plugin = r_bin_file_cur_plugin (a); - if (!a) { return; } @@ -781,14 +780,14 @@ R_API void r_bin_file_free(void /*RBinFile*/ *bf_) { sdb_free (a->sdb_addrinfo); a->sdb_addrinfo = NULL; } - R_FREE (a->file); + free (a->file); a->o = NULL; r_list_free (a->objs); r_list_free (a->xtr_data); if (a->id != -1) { - r_id_pool_kick_id (a->rbin->file_ids, a->id); + // TODO: use r_storage api + r_id_pool_kick_id (a->rbin->ids->pool, a->id); } - memset (a, 0, sizeof (RBinFile)); free (a); } @@ -861,7 +860,7 @@ R_API int r_bin_file_set_bytes(RBinFile *binfile, const ut8 *bytes, ut64 sz, boo r_buf_set_bytes (binfile->buf, bytes, sz); } #endif - return binfile->buf != NULL; + return binfile->buf; } R_API RBinPlugin *r_bin_file_cur_plugin(RBinFile *binfile) { @@ -872,11 +871,8 @@ static int is_data_section(RBinFile *a, RBinSection *s) { if (s->has_strings || s->is_data) { return true; } - if (s->is_data) { - return true; - } // Rust - return (strstr (s->name, "_const") != NULL); + return strstr (s->name, "_const"); } R_API RList *r_bin_file_get_strings(RBinFile *a, int min, int dump) { @@ -1008,4 +1004,3 @@ R_API void r_bin_file_get_strings_range(RBinFile *bf, RList *list, int min, ut64 R_API ut64 r_bin_file_get_baddr(RBinFile *binfile) { return binfile? r_bin_object_get_baddr (binfile->o): UT64_MAX; } - diff --git a/libr/bin/filter.c b/libr/bin/filter.c index f6e3a795cd..18ff59c5f9 100644 --- a/libr/bin/filter.c +++ b/libr/bin/filter.c @@ -102,7 +102,9 @@ R_API void r_bin_filter_sections(RList *list) { r_list_foreach (list, iter, sec) { r_bin_filter_name (db, sec->vaddr, sec->name, maxlen); } - } else eprintf ("SectionName is not dynamic\n"); + } else { + eprintf ("SectionName is not dynamic\n"); + } sdb_free (db); } diff --git a/libr/bin/obj.c b/libr/bin/obj.c index 9a62926b88..a34bc2fc30 100644 --- a/libr/bin/obj.c +++ b/libr/bin/obj.c @@ -23,11 +23,12 @@ R_API RBinObject *r_bin_object_new(RBinFile *binfile, RBinPlugin *plugin, ut64 b if (!o) { return NULL; } - //ut8 *bytes = calloc (80000, 1); - //r_buf_read_at (binfile->buf, 0, bytes, 80000); o->obj_size = bytes && (bytes_sz >= sz + offset)? sz: 0; o->boffset = offset; - o->id = r_num_rand (0xfffff000); + if (!r_id_pool_grab_id (binfile->rbin->ids->pool, &o->id)) { + free (o); + return NULL; + } o->kv = sdb_new0 (); o->baddr = baseaddr; o->baddr_shift = 0; diff --git a/libr/bin/open.c b/libr/bin/open.c new file mode 100644 index 0000000000..d05ab91dce --- /dev/null +++ b/libr/bin/open.c @@ -0,0 +1,95 @@ +/* radare2 - LGPL - Copyright 2018 - pancake */ + +#include + +R_API RBinOptions *r_bin_options_new (ut64 offset, ut64 baddr, int rawstr) { + RBinOptions *bo = R_NEW0 (RBinOptions); + if (bo) { + bo->offset = offset; + bo->baseaddr = baddr; + bo->rawstr = rawstr; + } + return bo; +} + +R_API void r_bin_options_free(RBinOptions *bo) { + free (bo->name); + free (bo); +} + +R_API int r_bin_open(RBin *bin, const char *filename, RBinOptions *bo) { + ut64 baddr = 0LL; + int iofd = -1, rawstr = 0; + if (bo) { + baddr = bo->baseaddr; + iofd = bo->iofd; + rawstr = bo->rawstr; + } + if (r_bin_load (bin, filename, baddr, 0, 0, iofd, rawstr)) { + int id = bin->cur->id; + r_id_storage_set (bin->ids, bin->cur, id); + return id; + } + return -1; +} + +R_API RBinFile *r_bin_get_file (RBin *bin, int bd) { + return r_id_storage_take (bin->ids, bd); +} + +R_API bool r_bin_close(RBin *bin, int bd) { + RBinFile *bf = r_bin_get_file (bin, bd); + if (bf) { + // file_free removes the fd already.. maybe its unnecessary + r_id_storage_delete (bin->ids, bd); + r_bin_file_free (bf); + } + return false; +} + +#if 0 +// usage example + +var bin = new RBin (); +int fd = bin.open("/bin/ls", null); +var binfile = bin.get_file(fd); +binfile.symbols.foreach(sym => { + print(sym.name); +}); +bin.close(fd); +// binfile is invalid here + +int bd = bin->cur; +r_list_foreach (r_bin_list (bin, bd, R_BIN_REQ_SYMBOLS), iter, sym) { + eprintf ("Symbol: %s\n", sym->name); +} + +bool cb(void *user, void *data) { +} +r_bin_foreach (bin, bd, R_BIN_REQ_SYMBOLS, cb, user); +#if 0 +// TODO: rename to r_bin_cmd() to match r2 commands ? +// TODO: use this api in r2 +// TODO: add queryf api (or cmdf) +R_API bool r_bin_query(RBin *bin, const char *query) { + bool ret = false; + char *q = strdup (query); + const char *at = strchr (q, '@'); + if (at) { + *at++ = 0; + } + if (!strcmp (q, "s")) { + // symbols + ret = true; + } else { + eprintf ("Unknown command\n"); + } + return ret; + // r_bin_query (bin, "o@0x8048080"); // return symbol at given address + // r_bin_query (bin, "s@0x8048080"); // return symbol at given address + // r_bin_query (bin, "z/str/"); // return list subset of strings matching + // r_bin_query (bin, "i\"printf\""); // imports +} +#endif + +#endif diff --git a/libr/core/cmd_open.c b/libr/core/cmd_open.c index 586acde6dc..0eb8998fd4 100644 --- a/libr/core/cmd_open.c +++ b/libr/core/cmd_open.c @@ -378,10 +378,12 @@ static void cmd_open_bin(RCore *core, const char *input) { r_core_cmd0 (core, ".is*"); break; case 'f': - // TODO: specify path to file? - r_core_bin_load (core, NULL, UT64_MAX); - value = input[2] ? input + 2 : NULL; - // r2_obf (core, value); + if (input[2] == ' ') { + r_core_cmdf (core, "oba 0 %s", input + 3); + } else { + r_core_bin_load (core, NULL, UT64_MAX); + value = input[2] ? input + 2 : NULL; + } break; case 'o': // "obo" value = input[2] ? input + 2 : NULL; diff --git a/libr/core/core.c b/libr/core/core.c index 647f52344a..e94cbfe30e 100644 --- a/libr/core/core.c +++ b/libr/core/core.c @@ -2551,9 +2551,17 @@ R_API char *r_core_editor (const RCore *core, const char *file, const char *str) } /* weak getters */ -R_API RCons *r_core_get_cons (RCore *core) { return core->cons; } -R_API RConfig *r_core_get_config (RCore *core) { return core->config; } -R_API RBin *r_core_get_bin (RCore *core) { return core->bin; } +R_API RCons *r_core_get_cons (RCore *core) { + return core->cons; +} + +R_API RConfig *r_core_get_config (RCore *core) { + return core->config; +} + +R_API RBin *r_core_get_bin (RCore *core) { + return core->bin; +} R_API RBuffer *r_core_syscallf (RCore *core, const char *name, const char *fmt, ...) { char str[1024]; diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index 432ffd2525..d6df921a44 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -277,7 +277,7 @@ typedef struct r_bin_t { ut64 maxstrbuf; int rawstr; Sdb *sdb; - RIDPool *file_ids; + RIDStorage *ids; RList/**/ *plugins; RList/**/ *binxtrs; RList/**/ *binldrs; @@ -575,19 +575,42 @@ typedef struct r_bin_bind_t { #ifdef R_API -/* bin.c */ -R_API void r_bin_load_filter(RBin *bin, ut64 rules); +/* fd api */ + +typedef struct r_bin_options_t { + ut64 offset; // starting physical address to read from the target file + ut64 baseaddr; // where the linker maps the binary in memory + ut64 size; // restrict the size of the target fd + // ut64 loadaddr; // DEPRECATED ? + int xtr_idx; // load Nth binary + int rawstr; + int iofd; + char *name; // or comment :? +} RBinOptions; + +R_API RBinOptions *r_bin_options_new (ut64 offset, ut64 baddr, int rawstr); +R_API void r_bin_options_free(RBinOptions *bo); +R_API int r_bin_open(RBin *bin, const char *filename, RBinOptions *bo); +R_API RBinFile *r_bin_get_file (RBin *bin, int bd); +R_API bool r_bin_close(RBin *bin, int bd); +R_API bool r_bin_query(RBin *bin, const char *query); + +/* load */ R_API int r_bin_load(RBin *bin, const char *file, ut64 baseaddr, ut64 loadaddr, int xtr_idx, int fd, int rawstr); -R_API int r_bin_reload(RBin *bin, int fd, ut64 baseaddr); R_API int r_bin_load_as(RBin *bin, const char *file, ut64 baseaddr, ut64 loadaddr, int xtr_idx, int fd, int rawstr, int fileoffset, const char *name); R_API int r_bin_load_io(RBin *bin, int fd, ut64 baseaddr, ut64 loadaddr, int xtr_idx); R_API int r_bin_load_io_at_offset_as_sz(RBin *bin, int fd, ut64 baseaddr, ut64 loadaddr, int xtr_idx, ut64 offset, const char *name, ut64 sz); + +/* bin.c */ +R_API void r_bin_load_filter(RBin *bin, ut64 rules); +R_API int r_bin_load_languages(RBinFile *binfile); + +R_API int r_bin_reload(RBin *bin, int fd, ut64 baseaddr); R_API void r_bin_bind(RBin *b, RBinBind *bnd); R_API bool r_bin_add(RBin *bin, RBinPlugin *foo); R_API bool r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo); R_API bool r_bin_ldr_add(RBin *bin, RBinLdrPlugin *foo); R_API void* r_bin_free(RBin *bin); -R_API int r_bin_load_languages(RBinFile *binfile); R_API int r_bin_dump_strings(RBinFile *a, int min); R_API RList* r_bin_raw_strings(RBinFile *a, int min); //io-wrappers @@ -719,7 +742,7 @@ R_API int r_bin_io_load(RBin *bin, RIO *io, int fd, ut64 baseaddr, ut64 loadaddr R_API int r_bin_select(RBin *bin, const char *arch, int bits, const char *name); R_API int r_bin_select_idx(RBin *bin, const char *name, int idx); -R_API int r_bin_select_by_ids(RBin *bin, ut32 binfile_id, ut32 binobj_id ); +R_API int r_bin_select_by_ids(RBin *bin, ut32 binfile_id, ut32 binobj_id); R_API int r_bin_use_arch(RBin *bin, const char *arch, int bits, const char *name); R_API RBinFile * r_bin_file_find_by_arch_bits(RBin *bin, const char *arch, int bits, const char *name); R_API void r_bin_list_archs(RBin *bin, int mode); diff --git a/libr/include/r_io.h b/libr/include/r_io.h index fd9859feea..43ec1a1a04 100644 --- a/libr/include/r_io.h +++ b/libr/include/r_io.h @@ -4,7 +4,7 @@ #define R2_IO_H #include "r_list.h" -#include +#include #include #include #include "r_socket.h" diff --git a/libr/include/r_util.h b/libr/include/r_util.h index 4e590cca03..d71a76a49d 100644 --- a/libr/include/r_util.h +++ b/libr/include/r_util.h @@ -65,7 +65,7 @@ int gettimeofday (struct timeval* p, void* tz); #include "r_util/r_utf8.h" #include "r_util/r_utf16.h" #include "r_util/r_utf32.h" -#include "r_util/r_id_storage.h" +#include "r_util/r_idpool.h" #include "r_util/r_asn1.h" #include "r_util/r_json.h" #include "r_util/r_x509.h" diff --git a/libr/include/r_util/r_id_storage.h b/libr/include/r_util/r_idpool.h similarity index 100% rename from libr/include/r_util/r_id_storage.h rename to libr/include/r_util/r_idpool.h diff --git a/libr/util/idpool.c b/libr/util/idpool.c index 7c02c1fb38..ba3ce75bb2 100644 --- a/libr/util/idpool.c +++ b/libr/util/idpool.c @@ -1,9 +1,9 @@ -/* radare2 - LGPL - Copyright 2017 - condret */ +/* radare2 - LGPL - Copyright 2017-2018 - condret */ #include #include -ut32 get_msb(ut32 v) { +static ut32 get_msb(ut32 v) { int i; for (i = 31; i > (-1); i--) { if (v & (0x1U << i)) { @@ -147,7 +147,7 @@ R_API void r_id_storage_delete(RIDStorage* storage, ut32 id) { storage->top_id--; } if (!storage->top_id) { - if(storage->data[storage->top_id]) { + if (storage->data[storage->top_id]) { id_storage_reallocate (storage, 2); } else { RIDPool* pool = r_id_pool_new (storage->pool->start_id, storage->pool->last_id);