From f58f3522f393125c8edd2660d0b629574e78597f Mon Sep 17 00:00:00 2001 From: pancake Date: Tue, 9 Jul 2024 21:41:20 +0200 Subject: [PATCH] Initial support for RBin->RIO redirections ##bin --- dist/plugins-cfg/plugins.def.cfg | 1 + libr/bin/p/Makefile | 5 ++- libr/bin/p/bin_uf2.c | 52 ++++++++++++++++++++++++++++++++ libr/bin/p/uf2.mk | 10 ++++++ libr/core/cfile.c | 46 +++++++++++++++++++--------- libr/include/r_bin.h | 1 + 6 files changed, 97 insertions(+), 18 deletions(-) create mode 100644 libr/bin/p/bin_uf2.c create mode 100644 libr/bin/p/uf2.mk diff --git a/dist/plugins-cfg/plugins.def.cfg b/dist/plugins-cfg/plugins.def.cfg index 8851d3ecb6c77..83624757c5f2e 100644 --- a/dist/plugins-cfg/plugins.def.cfg +++ b/dist/plugins-cfg/plugins.def.cfg @@ -86,6 +86,7 @@ arch.xtensa arch.z80 asm.null bin.any +bin.uf2 bin.art bin.avr bin.bf diff --git a/libr/bin/p/Makefile b/libr/bin/p/Makefile index 307d34f6909f7..17e24bc4f9b69 100644 --- a/libr/bin/p/Makefile +++ b/libr/bin/p/Makefile @@ -21,9 +21,8 @@ FORMATS=any.mk elf.mk elf64.mk pe.mk pe64.mk te.mk mach0.mk FORMATS+=bios.mk mach064.mk dyldcache.mk xnu_kernelcache.mk java.mk FORMATS+=dex.mk fs.mk ningb.mk coff.mk xcoff64.mk ningba.mk xbe.mk zimg.mk FORMATS+=omf.mk cgc.mk dol.mk rel.mk nes.mk mbn.mk psxexe.mk -FORMATS+=vsf.mk nin3ds.mk bflt.mk wasm.mk sfc.mk -FORMATS+=mdmp.mk z64.mk qnx.mk prg.mk dmp64.mk -FORMATS+=xtac.mk +FORMATS+=vsf.mk nin3ds.mk bflt.mk wasm.mk sfc.mk uf2.mk +FORMATS+=mdmp.mk z64.mk qnx.mk prg.mk dmp64.mk xtac.mk FORMATS+=xtr_dyldcache.mk FORMATS+=xtr_fatmach0.mk diff --git a/libr/bin/p/bin_uf2.c b/libr/bin/p/bin_uf2.c new file mode 100644 index 0000000000000..51bd9ba744460 --- /dev/null +++ b/libr/bin/p/bin_uf2.c @@ -0,0 +1,52 @@ +/* radare - MIT - 2024 - pancake */ + +#include + +static bool check(RBinFile *bf, RBuffer *b) { + if (r_buf_size (b) > 0x10) { + ut8 buf[5] ={0}; + r_buf_read_at (b, 0, buf, sizeof (buf)); + return !memcmp (buf, "UF2\n", 4); + } + return false; +} + +static bool load(RBinFile *bf, RBuffer *b, ut64 loadaddr) { + return check (bf, b); +} + +static RBinInfo *info(RBinFile *bf) { + RBinInfo *ret = R_NEW0 (RBinInfo); + if (!ret) { + return NULL; + } + ret->file = strdup (bf->file); + ret->type = strdup ("io"); // requires IO redirection to work + ret->machine = strdup ("Microsoft UF2"); // XXX + ret->bclass = strdup ("uf2://"); + ret->os = strdup ("hw"); // aka baremetal + ret->arch = strdup ("arm"); + ret->bits = 32; + ret->has_va = 1; + ret->big_endian = 1; + return ret; +} + +RBinPlugin r_bin_plugin_uf2 = { + .meta = { + .name = "uf2", + .desc = "Microsoft Unified Firmware v2", + .license = "MIT", + }, + .load = &load, + .check = &check, + .info = &info, +}; + +#ifndef R2_PLUGIN_INCORE +R_API RLibStruct radare_plugin = { + .type = R_LIB_TYPE_BIN, + .data = &r_bin_plugin_uf2, + .version = R2_VERSION +}; +#endif diff --git a/libr/bin/p/uf2.mk b/libr/bin/p/uf2.mk new file mode 100644 index 0000000000000..5176f1ab797eb --- /dev/null +++ b/libr/bin/p/uf2.mk @@ -0,0 +1,10 @@ +OBJ_UF2=bin_uf2.o + +STATIC_OBJ+=${OBJ_UF2} +TARGET_UF2=bin_uf2.${EXT_SO} + +ALL_TARGETS+=${TARGET_UF2} + +${TARGET_UF2}: ${OBJ_UF2} + ${CC} $(call libname,bin_uf2) -shared ${CFLAGS} \ + -o ${TARGET_UF2} ${OBJ_UF2} $(LINK) $(LDFLAGS) diff --git a/libr/core/cfile.c b/libr/core/cfile.c index da53b3ed8abb7..3de4e76872ffa 100644 --- a/libr/core/cfile.c +++ b/libr/core/cfile.c @@ -361,7 +361,7 @@ static bool setbpint(RCore *r, const char *mode, const char *sym) { // XXX - need to handle index selection during debugging static int r_core_file_load_for_debug(RCore *r, ut64 baseaddr, R_NULLABLE const char *filenameuri) { RIODesc *desc = r->io->desc; - RBinFile *binfile = NULL; + RBinFile *bf = NULL; RBinPlugin *plugin; int xtr_idx = 0; // if 0, load all if xtr is used @@ -412,9 +412,9 @@ static int r_core_file_load_for_debug(RCore *r, ut64 baseaddr, R_NULLABLE const setbpint (r, "dbg.libs", "sym._dlclose"); #endif } - binfile = r_bin_cur (r->bin); - r_core_bin_set_env (r, binfile); - plugin = r_bin_file_cur_plugin (binfile); + bf = r_bin_cur (r->bin); + r_core_bin_set_env (r, bf); + plugin = r_bin_file_cur_plugin (bf); const char *plugin_name = plugin? plugin->meta.name: ""; if (!strcmp (plugin_name, "any")) { // set use of raw strings @@ -423,11 +423,11 @@ static int r_core_file_load_for_debug(RCore *r, ut64 baseaddr, R_NULLABLE const // get bin.str.min r->bin->minstrlen = r_config_get_i (r->config, "bin.str.min"); r->bin->maxstrbuf = r_config_get_i (r->config, "bin.str.maxbuf"); - } else if (binfile) { + } else if (bf) { RBinObject *obj = r_bin_cur_object (r->bin); RBinInfo *info = obj? obj->info: NULL; if (plugin && info) { - r_core_bin_set_arch_bits (r, binfile->file, info->arch, info->bits); + r_core_bin_set_arch_bits (r, bf->file, info->arch, info->bits); } } if (!strcmp (plugin_name, "dex")) { @@ -456,13 +456,27 @@ static int r_core_file_load_for_io_plugin(RCore *r, ut64 baseaddr, ut64 loadaddr R_CRITICAL_LEAVE (r); return false; } - RBinFile *binfile = r_bin_cur (r->bin); - if (r_core_bin_set_env (r, binfile)) { + RBinFile *bf = r_bin_cur (r->bin); + if (r_core_bin_set_env (r, bf)) { if (r->anal->verbose && !sdb_const_get (r->anal->sdb_cc, "default.cc", 0)) { R_LOG_WARN ("No calling convention defined for this file, analysis may be inaccurate"); } } - plugin = r_bin_file_cur_plugin (binfile); + if (bf) { + const char *bclass = R_UNWRAP4 (bf, bo, info, bclass); + if (bclass && strstr (bclass, "://")) { + // perform a redirection! + char *uri = r_str_newf ("%s%s\n", bclass, bf->file); + r_core_cmdf (r, "ob-*"); + r_core_cmdf (r, "o %s", uri); + // r_core_cmdf (r, "o-%d", fd); // XXX segfault + free (uri); + // r_io_close_fd (r->io, fd); + // r_bin_file_close (r->bin, bf); + return false; + } + } + plugin = r_bin_file_cur_plugin (bf); if (plugin && !strcmp (plugin->meta.name, "any")) { RBinObject *obj = r_bin_cur_object (r->bin); RBinInfo *info = obj? obj->info: NULL; @@ -472,13 +486,13 @@ static int r_core_file_load_for_io_plugin(RCore *r, ut64 baseaddr, ut64 loadaddr } info->bits = r->rasm->config->bits; // set use of raw strings - r_core_bin_set_arch_bits (r, binfile->file, info->arch, info->bits); + r_core_bin_set_arch_bits (r, bf->file, info->arch, info->bits); // r_config_set_i (r->config, "io.va", false); // r_config_set_b (r->config, "bin.str.raw", true); // get bin.str.min r->bin->minstrlen = r_config_get_i (r->config, "bin.str.min"); r->bin->maxstrbuf = r_config_get_i (r->config, "bin.str.maxbuf"); - } else if (binfile) { + } else if (bf) { RBinObject *obj = r_bin_cur_object (r->bin); RBinInfo *info = obj? obj->info: NULL; if (!info) { @@ -486,8 +500,7 @@ static int r_core_file_load_for_io_plugin(RCore *r, ut64 baseaddr, ut64 loadaddr return false; } if (plugin) { - r_core_bin_set_arch_bits (r, binfile->file, - info->arch, info->bits); + r_core_bin_set_arch_bits (r, bf->file, info->arch, info->bits); } } @@ -657,6 +670,7 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) { r->bin->maxstrbuf = r_config_get_i (r->config, "bin.str.maxbuf"); R_CRITICAL_LEAVE (r); if (desc && is_io_load) { + int desc_fd = desc->fd; // TODO? necessary to restore the desc back? // Fix to select pid before trying to load the binary if ((desc->plugin && desc->plugin->isdbg) || r_config_get_b (r->config, "cfg.debug")) { @@ -666,12 +680,14 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) { r_core_file_open (r, filenameuri, 0, baddr); } r_core_file_load_for_io_plugin (r, baddr, 0LL); + desc = r->io->desc; } - r_io_use_fd (r->io, desc->fd); + r_io_use_fd (r->io, desc_fd); } else if (desc != NULL) { r_io_use_fd (r->io, desc->fd); r_io_map_add (r->io, desc->fd, R_PERM_RWX, 0LL, 0, r_io_desc_size (desc)); } + desc = r->io->desc; RBinFile *binfile = r_bin_cur (r->bin); if (r->bin->cur && r->bin->cur->bo && r->bin->cur->bo->plugin && r->bin->cur->bo->plugin->strfilter) { char msg[2]; @@ -692,7 +708,7 @@ R_API bool r_core_bin_load(RCore *r, const char *filenameuri, ut64 baddr) { r_core_cmd (r, cmd_load, 0); } - if (plugin && plugin->meta.name) { + if (desc && plugin && plugin->meta.name) { if (!strcmp (plugin->meta.name, "any")) { ut64 size = (desc->name && (r_str_startswith (desc->name, "rap") && strstr (desc->name, "://"))) ? UT64_MAX : r_io_desc_size (desc); diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index e346c3c2fe7e9..41aa009ef8750 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -998,6 +998,7 @@ extern RBinPlugin r_bin_plugin_lua; extern RBinPlugin r_bin_plugin_xtac; extern RBinPlugin r_bin_plugin_pdp11; extern RBinPlugin r_bin_plugin_pcap; +extern RBinPlugin r_bin_plugin_uf2; extern RBinPlugin r_bin_plugin_io; #ifdef __cplusplus