Initial draft implementation of the loader plugins for RBin

This commit is contained in:
pancake 2018-01-07 21:54:41 +01:00
parent 3a91bf0e97
commit 7f40f36c3a
17 changed files with 210 additions and 42 deletions

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2017 - nibble, pancake */
/* radare - LGPL - Copyright 2009-2018 - nibble, pancake */
#include <getopt.c>
#include <r_core.h>
@ -276,16 +276,19 @@ static int rabin_dump_symbols(int len) {
} else {
len = olen;
}
if (!(buf = malloc (len))) {
if (!(buf = calloc (1, len))) {
return false;
}
if (!(ret = malloc (len * 2 + 1))) {
if (!(ret = malloc ((len * 2) + 1))) {
free (buf);
return false;
}
r_buf_read_at (bin->cur->buf, symbol->paddr, buf, len);
r_hex_bin2str (buf, len, ret);
printf ("%s %s\n", symbol->name, ret);
if (r_buf_read_at (bin->cur->buf, symbol->paddr, buf, len) == len) {
r_hex_bin2str (buf, len, ret);
printf ("%s %s\n", symbol->name, ret);
} else {
eprintf ("Cannot read from buffer\n");
}
free (buf);
free (ret);
}
@ -483,26 +486,38 @@ static int rabin_show_srcline(ut64 at) {
}
/* bin callback */
static int __lib_bin_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
static int __lib_bin_cb(RLibPlugin *pl, void *user, void *data) {
struct r_bin_plugin_t *hand = (struct r_bin_plugin_t *)data;
//printf(" * Added (dis)assembly plugin\n");
r_bin_add (bin, hand);
return true;
}
static int __lib_bin_dt(struct r_lib_plugin_t *pl, void *p, void *u) {
static int __lib_bin_dt(RLibPlugin *pl, void *p, void *u) {
return true;
}
/* binxtr callback */
static int __lib_bin_xtr_cb(struct r_lib_plugin_t *pl, void *user, void *data) {
static int __lib_bin_xtr_cb(RLibPlugin *pl, void *user, void *data) {
struct r_bin_xtr_plugin_t *hand = (struct r_bin_xtr_plugin_t *)data;
//printf(" * Added (dis)assembly plugin\n");
r_bin_xtr_add (bin, hand);
return true;
}
static int __lib_bin_xtr_dt(struct r_lib_plugin_t *pl, void *p, void *u) {
static int __lib_bin_xtr_dt(RLibPlugin *pl, void *p, void *u) {
return true;
}
/* binldr callback */
static int __lib_bin_ldr_cb(RLibPlugin *pl, void *user, void *data) {
struct r_bin_ldr_plugin_t *hand = (struct r_bin_ldr_plugin_t *)data;
//printf(" * Added (dis)assembly plugin\n");
r_bin_ldr_add (bin, hand);
return true;
}
static int __lib_bin_ldr_dt(RLibPlugin *pl, void *p, void *u) {
return true;
}
@ -561,11 +576,12 @@ int main(int argc, char **argv) {
if (!(tmp = r_sys_getenv ("RABIN2_NOPLUGINS"))) {
char *homeplugindir = r_str_home (R2_HOMEDIR "/plugins");
l = r_lib_new ("radare_plugin");
r_lib_add_handler (l, R_LIB_TYPE_BIN, "bin plugins",
&__lib_bin_cb, &__lib_bin_dt, NULL);
&__lib_bin_cb, &__lib_bin_dt, NULL);
r_lib_add_handler (l, R_LIB_TYPE_BIN_XTR, "bin xtr plugins",
&__lib_bin_xtr_cb, &__lib_bin_xtr_dt, NULL);
&__lib_bin_xtr_cb, &__lib_bin_xtr_dt, NULL);
r_lib_add_handler (l, R_LIB_TYPE_BIN_LDR, "bin ldr plugins",
&__lib_bin_ldr_cb, &__lib_bin_ldr_dt, NULL);
/* load plugins everywhere */
path = r_sys_getenv (R_LIB_ENV);

View File

@ -14,11 +14,12 @@ CFLAGS+=-DCORELIB -Iformat -Imangling
include ${STATIC_BIN_PLUGINS}
include ${STATIC_BIN_XTR_PLUGINS}
include ${STATIC_BIN_LDR_PLUGINS}
include $(SHLR)/java/deps.mk
include $(SHLR)/ar/deps.mk
STATIC_OBJS=$(addprefix $(LTOP)/bin/p/, $(STATIC_OBJ))
OBJS=bin.o dbginfo.o bin_write.o demangle.o dwarf.o filter.o
OBJS=bin.o dbginfo.o bin_ldr.o bin_write.o demangle.o dwarf.o filter.o
OBJS+=mangling/cxx/cp-demangle.o ${STATIC_OBJS}
OBJS+=mangling/demangler.o
OBJS+=mangling/microsoft_demangle.o

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2017 - pancake, nibble, dso */
/* radare2 - LGPL - Copyright 2009-2018 - pancake, nibble, dso */
// TODO: dlopen library and show address
@ -35,9 +35,13 @@ R_LIB_VERSION (r_bin);
#if !defined(R_BIN_XTR_STATIC_PLUGINS)
#define R_BIN_XTR_STATIC_PLUGINS 0
#endif
#if !defined(R_BIN_LDR_STATIC_PLUGINS)
#define R_BIN_LDR_STATIC_PLUGINS 0
#endif
static RBinPlugin *bin_static_plugins[] = { R_BIN_STATIC_PLUGINS, NULL };
static RBinXtrPlugin *bin_xtr_static_plugins[] = { R_BIN_XTR_STATIC_PLUGINS, NULL };
static RBinLdrPlugin *bin_ldr_static_plugins[] = { R_BIN_LDR_STATIC_PLUGINS, NULL };
static int is_data_section(RBinFile *a, RBinSection *s);
static RList *get_strings(RBinFile *a, int min, int dump);
@ -1597,7 +1601,7 @@ static void plugin_free(RBinPlugin *p) {
}
// rename to r_bin_plugin_add like the rest
R_API int r_bin_add(RBin *bin, RBinPlugin *foo) {
R_API bool r_bin_add(RBin *bin, RBinPlugin *foo) {
RListIter *it;
RBinPlugin *plugin;
if (foo->init) {
@ -1614,7 +1618,24 @@ R_API int r_bin_add(RBin *bin, RBinPlugin *foo) {
return true;
}
R_API int r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo) {
R_API bool r_bin_ldr_add(RBin *bin, RBinLdrPlugin *foo) {
RListIter *it;
RBinLdrPlugin *ldr;
if (foo->init) {
foo->init (bin->user);
}
// avoid duplicates
r_list_foreach (bin->binldrs, it, ldr) {
if (!strcmp (ldr->name, foo->name)) {
return false;
}
}
r_list_append (bin->binldrs, foo);
return true;
}
R_API bool r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo) {
RListIter *it;
RBinXtrPlugin *xtr;
@ -1652,7 +1673,7 @@ R_API void *r_bin_free(RBin *bin) {
return NULL;
}
static int r_bin_print_plugin_details(RBin *bin, RBinPlugin *bp, int json) {
static bool r_bin_print_plugin_details(RBin *bin, RBinPlugin *bp, int json) {
if (json == 'q') {
bin->cb_printf ("%s\n", bp->name);
} else if (json) {
@ -1698,6 +1719,7 @@ R_API int r_bin_list(RBin *bin, int json) {
RListIter *it;
RBinPlugin *bp;
RBinXtrPlugin *bx;
RBinLdrPlugin *ld;
if (json == 'q') {
r_list_foreach (bin->plugins, it, bp) {
@ -1728,6 +1750,16 @@ R_API int r_bin_list(RBin *bin, int json) {
i? ",": "", bx->name, bx->desc, bx->license? bx->license: "???");
i++;
}
i = 0;
bin->cb_printf ("],\"ldr\":[");
r_list_foreach (bin->binxtrs, it, ld) {
bin->cb_printf (
"%s{\"name\":\"%s\",\"description\":\"%s\","
"\"license\":\"%s\"}",
i? ",": "", ld->name, ld->desc, ld->license? ld->license: "???");
i++;
}
bin->cb_printf ("]}\n");
} else {
r_list_foreach (bin->plugins, it, bp) {
@ -1737,9 +1769,15 @@ R_API int r_bin_list(RBin *bin, int json) {
bp->author? bp->author: "");
}
r_list_foreach (bin->binxtrs, it, bx) {
bin->cb_printf ("xtr %-11s %s (%s)\n", bx->name,
const char *name = strncmp (bx->name, "xtr.", 4)? bx->name : bx->name + 3;
bin->cb_printf ("xtr %-11s %s (%s)\n", name,
bx->desc, bx->license? bx->license: "???");
}
r_list_foreach (bin->binldrs, it, ld) {
const char *name = strncmp (ld->name, "ldr.", 4)? ld->name : ld->name + 3;
bin->cb_printf ("ldr %-11s %s (%s)\n", name,
ld->desc, ld->license? ld->license: "???");
}
}
return false;
}
@ -2012,6 +2050,7 @@ R_API int r_bin_has_dbg_relocs(RBin *bin) {
R_API RBin *r_bin_new() {
int i;
RBinXtrPlugin *static_xtr_plugin;
RBinLdrPlugin *static_ldr_plugin;
RBin *bin = R_NEW0 (RBin);
if (!bin) {
return NULL;
@ -2025,11 +2064,14 @@ 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 parsers */
bin->binfiles = r_list_newf ((RListFree)r_bin_file_free);
for (i = 0; bin_static_plugins[i]; i++) {
r_bin_add (bin, bin_static_plugins[i]);
}
/* extractors */
bin->binxtrs = r_list_new ();
bin->binxtrs->free = free;
for (i = 0; bin_xtr_static_plugins[i]; i++) {
@ -2041,7 +2083,18 @@ R_API RBin *r_bin_new() {
*static_xtr_plugin = *bin_xtr_static_plugins[i];
r_bin_xtr_add (bin, static_xtr_plugin);
}
bin->file_ids = r_id_pool_new (0, 0xffffffff);
/* loaders */
bin->binldrs = r_list_new ();
bin->binldrs->free = free;
for (i = 0; bin_ldr_static_plugins[i]; i++) {
static_ldr_plugin = R_NEW0 (RBinLdrPlugin);
if (!static_ldr_plugin) {
free (bin);
return NULL;
}
*static_ldr_plugin = *bin_ldr_static_plugins[i];
r_bin_ldr_add (bin, static_ldr_plugin);
}
return bin;
}

30
libr/bin/bin_ldr.c Normal file
View File

@ -0,0 +1,30 @@
/* radare2 - LGPL - Copyright 2018 - pancake */
#include <r_bin.h>
R_API bool r_bin_loader(RBin *bin, ut32 boid, int options) {
// uses a plugin from bin.loader eval var and loads the selected binobj
// options must be used to specify if we want to load the libraries of the libraries recursively
// or resolve the PLT from the binary or not
// this requires io.cache
return false;
}
R_API bool r_bin_loader_library(RBin *bin, const char *name, int options) {
// options specify if we want to resolve the symbols and fill the PLT
// this is obviously a problem if we have multiple libs that depend
// on symbols recursively, and thats where the LD_BIND_NOW option comes to the action
// the plt must be modified by using io.cache writes
return false;
}
R_API bool r_bin_loader_option(RBin *bin, const char *key, const char *data) {
// key value storage to specify LD_LIBRARY_PATH LD_BIND_NOW and other useful options
// RCore or radare2 can set those vars from the environment if desired
return false;
}
R_API bool r_bin_loader_unload(RBin *bin) {
// unload all libraries and drop PLT changes
return false;
}

View File

@ -17,11 +17,15 @@ foo: all
ALL_TARGETS=
FORMATS=any.mk elf.mk elf64.mk pe.mk pe64.mk te.mk mach0.mk
FORMATS+=bios.mk mach064.mk fatmach0.mk dyldcache.mk java.mk
FORMATS+=bios.mk mach064.mk dyldcache.mk java.mk
FORMATS+=dex.mk fs.mk ningb.mk coff.mk ningba.mk xbe.mk zimg.mk
FORMATS+=omf.mk cgc.mk dol.mk nes.mk mbn.mk psxexe.mk spc700.mk
FORMATS+=vsf.mk nin3ds.mk xtr_dyldcache.mk bflt.mk wasm.mk sfc.mk
FORMATS+=vsf.mk nin3ds.mk bflt.mk wasm.mk sfc.mk
FORMATS+=mdmp.mk z64.mk
FORMATS+=xtr_dyldcache.mk
FORMATS+=xtr_fatmach0.mk
include $(FORMATS)
all: ${ALL_TARGETS}

View File

@ -52,6 +52,7 @@ static RBinInfo *info(RBinFile *bf) {
if (!(ret = R_NEW0 (RBinInfo))) {
return NULL;
}
eprintf ("IS INFO\n");
ret->file = strdup (bf->file);
ret->bclass = strdup ("dyldcache");
ret->rclass = strdup ("ios");

View File

@ -0,0 +1,35 @@
/* radare - LGPL - Copyright 2018 pancake */
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_bin.h>
static bool load(RBin *bin) {
if (!bin || !bin->cur) {
return false;
}
if (!bin->cur->xtr_obj) {
bin->cur->xtr_obj = r_bin_dyldcache_new (bin->cur->file);
}
if (!bin->file) {
bin->file = bin->cur->file;
}
return bin->cur->xtr_obj? true : false;
}
RBinLdrPlugin r_bin_ldr_plugin_ldr_linux = {
.name = "ldr.linux",
.desc = "Linux loader plugin for RBin",
.license = "MIT",
.load = &load,
};
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_LDR,
.data = &r_bin_ldr_plugin_ldr_linux,
.version = R2_VERSION
};
#endif

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2016 nibble, pancake */
/* radare - LGPL - Copyright 2009-2018 nibble, pancake */
#include <r_types.h>
#include <r_util.h>
@ -167,8 +167,8 @@ static RList * oneshotall(RBin *bin, const ut8* buf, ut64 size) {
return res;
}
struct r_bin_xtr_plugin_t r_bin_xtr_plugin_xtr_dyldcache = {
.name = "xtr_dyldcache",
RBinXtrPlugin r_bin_xtr_plugin_xtr_dyldcache = {
.name = "xtr.dyldcache",
.desc = "dyld cache bin extractor plugin",
.license = "LGPL3",
.load = &load,
@ -184,7 +184,7 @@ struct r_bin_xtr_plugin_t r_bin_xtr_plugin_xtr_dyldcache = {
#ifndef CORELIB
RLibStruct radare_plugin = {
.type = R_LIB_TYPE_BIN_XTR,
.data = &r_bin_xtr_plugin_xtr_dyldcache,
.data = &r_bin_xtr_plugin_dyldcache,
.version = R2_VERSION
};
#endif

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2017 - nibble, pancake */
/* radare - LGPL - Copyright 2009-2018 - nibble, pancake */
#include <r_types.h>
#include <r_util.h>
@ -182,8 +182,8 @@ static RList * oneshotall(RBin *bin, const ut8 *buf, ut64 size) {
return res;
}
RBinXtrPlugin r_bin_xtr_plugin_fatmach0 = {
.name = "fatmach0",
RBinXtrPlugin r_bin_xtr_plugin_xtr_fatmach0 = {
.name = "xtr.fatmach0",
.desc = "fat mach0 bin extractor plugin",
.license = "LGPL3",
.load = &load,

View File

@ -1,5 +1,4 @@
OBJ_DYLDCACHE=bin_dyldcache.o
# ../format/mach0/dyldcache.o
STATIC_OBJ+=${OBJ_DYLDCACHE}
TARGET_DYLDCACHE=bin_dyldcache.${EXT_SO}

12
libr/bin/p/ldr_linux.mk Normal file
View File

@ -0,0 +1,12 @@
OBJ_LDR_LINUX=bin_ldr_linux.o
STATIC_OBJ+=${OBJ_LDR_LINUX}
TARGET_LDR_LINUX=bin_ldr_linux.${EXT_SO}
ifeq ($(WITHPIC),1)
ALL_TARGETS+=${TARGET_LDR_LINUX}
${TARGET_LDR_LINUX}: ${OBJ_LDR_LINUX}
-${CC} $(call libname,bin_ldr_linux) -shared ${CFLAGS} \
-o ${TARGET_LDR_LINUX} ${OBJ_LDR_LINUX} $(LINK) $(LDFLAGS)
endif

View File

@ -6543,11 +6543,13 @@ static int cmd_anal(void *data, const char *input) {
break;
default:
r_core_cmd_help (core, help_msg_a);
#if 0
r_cons_printf ("Examples:\n"
" f ts @ `S*~text:0[3]`; f t @ section..text\n"
" f ds @ `S*~data:0[3]`; f d @ section..data\n"
" .ad t t+ts @ d:ds\n",
NULL);
#endif
break;
}
if (tbs != core->blocksize) {

View File

@ -262,6 +262,7 @@ typedef struct r_bin_t {
RIDPool *file_ids;
RList/*<RBinPlugin>*/ *plugins;
RList/*<RBinXtrPlugin>*/ *binxtrs;
RList/*<RBinLdrPlugin>*/ *binldrs;
RList/*<RBinFile>*/ *binfiles;
PrintfCallback cb_printf;
int loadany;
@ -317,16 +318,27 @@ typedef struct r_bin_xtr_plugin_t {
int (*fini)(void *user);
// XXX: ut64 for size is maybe too much, what about st64? signed sizes are useful for detecting errors
bool (*check_bytes)(const ut8 *bytes, ut64 sz);
RBinXtrData * (*extract_from_bytes)(RBin *bin, const ut8 *buf, ut64 size, int idx);
RList * (*extractall_from_bytes)(RBin *bin, const ut8 *buf, ut64 size);
RBinXtrData * (*extract)(RBin *bin, int idx);
RList * (*extractall)(RBin *bin);
bool (*load)(RBin *bin);
int (*size)(RBin *bin);
int (*destroy)(RBin *bin);
int (*free_xtr)(void *xtr_obj);
} RBinXtrPlugin;
typedef struct r_bin_ldr_plugin_t {
char *name;
char *desc;
char *license;
int (*init)(void *user);
int (*fini)(void *user);
bool (*load)(RBin *bin);
} RBinLdrPlugin;
typedef struct r_bin_plugin_t {
char *name;
char *desc;
@ -533,8 +545,9 @@ R_API int r_bin_load_io(RBin *bin, int fd, ut64 baseaddr, ut64 loadaddr, int xtr
R_API bool r_bin_load_io_at_offset_as(RBin *bin, int fd, ut64 baseaddr, ut64 loadaddr, int xtr_idx, ut64 offset, const char *name);
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);
R_API void r_bin_bind(RBin *b, RBinBind *bnd);
R_API int r_bin_add(RBin *bin, RBinPlugin *foo);
R_API int r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo);
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);
@ -548,8 +561,7 @@ R_API int r_bin_file_deref_by_bind (RBinBind * binb);
R_API int r_bin_file_deref (RBin *bin, RBinFile * a);
R_API int r_bin_file_ref_by_bind (RBinBind * binb);
R_API int r_bin_file_ref (RBin *bin, RBinFile * a);
R_API bool r_bin_file_object_new_from_xtr_data(RBin *bin, RBinFile *bf,
ut64 baseaddr, ut64 loadaddr,
R_API bool r_bin_file_object_new_from_xtr_data(RBin *bin, RBinFile *bf, ut64 baseaddr, ut64 loadaddr,
RBinXtrData *xtr_data);
R_API int r_bin_list(RBin *bin, int json);
R_API int r_bin_list_plugin(RBin *bin, const char* name, int json);
@ -698,8 +710,9 @@ extern RBinPlugin r_bin_plugin_ninds;
extern RBinPlugin r_bin_plugin_nin3ds;
extern RBinPlugin r_bin_plugin_xbe;
extern RBinPlugin r_bin_plugin_bflt;
extern RBinXtrPlugin r_bin_xtr_plugin_fatmach0;
extern RBinXtrPlugin r_bin_xtr_plugin_xtr_fatmach0;
extern RBinXtrPlugin r_bin_xtr_plugin_xtr_dyldcache;
extern RBinLdrPlugin r_bin_ldr_plugin_ldr_linux;
extern RBinPlugin r_bin_plugin_zimg;
extern RBinPlugin r_bin_plugin_omf;
extern RBinPlugin r_bin_plugin_art;

View File

@ -64,8 +64,9 @@ enum {
R_LIB_TYPE_ASM, /* assembler */
R_LIB_TYPE_ANAL, /* analysis */
R_LIB_TYPE_PARSE, /* parsers */
R_LIB_TYPE_BIN, /* bins */
R_LIB_TYPE_BIN, /* bin headers */
R_LIB_TYPE_BIN_XTR, /* bin extractors */
R_LIB_TYPE_BIN_LDR, /* bin loaders */
R_LIB_TYPE_BP, /* breakpoint */
R_LIB_TYPE_SYSCALL, /* syscall */
R_LIB_TYPE_FASTCALL,/* fastcall */
@ -102,11 +103,11 @@ R_API int r_lib_opendir(RLib *lib, const char *path);
R_API int r_lib_open_ptr (RLib *lib, const char *file, void *handler, RLibStruct *stru);
R_API char *r_lib_path(const char *libname);
R_API void r_lib_list(RLib *lib);
R_API int r_lib_add_handler(RLib *lib, int type, const char *desc,
R_API bool r_lib_add_handler(RLib *lib, int type, const char *desc,
int (*cb)(RLibPlugin *, void *, void *),
int (*dt)(RLibPlugin *, void *, void *),
void *user );
R_API int r_lib_del_handler(RLib *lib, int type);
R_API bool r_lib_del_handler(RLib *lib, int type);
R_API int r_lib_close(RLib *lib, const char *file);
R_API const char *r_lib_types_get(int idx);

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2008-2016 - pancake */
/* radare - LGPL - Copyright 2008-2018 - pancake */
#include "r_types.h"
#include "r_util.h"
@ -407,7 +407,7 @@ R_API int r_lib_opendir(RLib *lib, const char *path) {
return true;
}
R_API int r_lib_add_handler(RLib *lib,
R_API bool r_lib_add_handler(RLib *lib,
int type, const char *desc,
int (*cb)(RLibPlugin *, void *, void *), /* constructor */
int (*dt)(RLibPlugin *, void *, void *), /* destructor */
@ -439,7 +439,7 @@ R_API int r_lib_add_handler(RLib *lib,
return true;
}
R_API int r_lib_del_handler(RLib *lib, int type) {
R_API bool r_lib_del_handler(RLib *lib, int type) {
RLibHandler *h;
RListIter *iter;
// TODO: remove all handlers for that type? or only one?

View File

@ -147,7 +147,8 @@ bin.vsf
bin.xbe
bin.dyldcache
bin_xtr.xtr_dyldcache
bin_xtr.fatmach0
bin_xtr.xtr_fatmach0
bin_ldr.ldr_linux
bin.zimg
bin.psxexe
bp.arm