* r_bin
- Refactor r_bin to work better with big fatbins - Don't load all sub-bins in memory Only load the fatbin and the selected sub-bin - Add r_bin_set_archidx() and r_bin_list_archs() - Update t/{rpathdel.c, test_meta.c} * rabin2 - Use '-f str' to select sub-bin by name
This commit is contained in:
parent
ee39ba239a
commit
cec1f3fa73
|
@ -45,8 +45,9 @@ static char *name = NULL;
|
|||
|
||||
static int rabin_show_help() {
|
||||
printf ("rabin2 [options] [file]\n"
|
||||
" -a [arch_bits] Set arch\n"
|
||||
" -A List archs\n"
|
||||
" -a [arch_bits] Set arch\n"
|
||||
" -f [str] Select sub-bin named str\n"
|
||||
" -b [addr] Override baddr\n"
|
||||
" -e Entrypoint\n"
|
||||
" -M Main\n"
|
||||
|
@ -66,7 +67,6 @@ static int rabin_show_help() {
|
|||
" -L List supported bin plugins\n"
|
||||
" -@ [addr] Show section, symbol or import at addr\n"
|
||||
" -n [str] Show section, symbol or import named str\n"
|
||||
" or extract, analyze arch named str\n"
|
||||
" -x Extract bins contained in file\n"
|
||||
" -V Show version information\n"
|
||||
" -h This help\n");
|
||||
|
@ -120,6 +120,7 @@ static int rabin_show_main() {
|
|||
}
|
||||
|
||||
static int rabin_extract(int all) {
|
||||
#if 0
|
||||
char out[512], *ptr;
|
||||
int i = 0;
|
||||
|
||||
|
@ -154,6 +155,7 @@ static int rabin_extract(int all) {
|
|||
} else printf ("%s created (%i)\n", out, bin->curarch->size);
|
||||
}
|
||||
}
|
||||
#endif
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
|
@ -452,17 +454,6 @@ static int rabin_show_info() {
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
static void rabin_list_archs() {
|
||||
int i;
|
||||
|
||||
for (i=0; i<bin->narch; i++) {
|
||||
if (bin->arch[i].info)
|
||||
printf ("%s_%i %s (%s)\n", bin->arch[i].info->arch,
|
||||
bin->arch[i].info->bits, bin->arch[i].file,
|
||||
bin->arch[i].info->machine);
|
||||
}
|
||||
}
|
||||
|
||||
static int rabin_show_fields() {
|
||||
RList *fields;
|
||||
RListIter *iter;
|
||||
|
@ -515,7 +506,7 @@ static int rabin_dump_symbols(int len) {
|
|||
|
||||
if (!(buf = malloc (len)) || !(ret = malloc(len*2+1)))
|
||||
return R_FALSE;
|
||||
r_buf_read_at (bin->curarch->buf, symbol->offset, buf, len);
|
||||
r_buf_read_at (bin->curarch.buf, symbol->offset, buf, len);
|
||||
r_hex_bin2str (buf, len, ret);
|
||||
printf ("%s %s\n", symbol->name, ret);
|
||||
free (buf);
|
||||
|
@ -540,7 +531,7 @@ static int rabin_dump_sections(char *scnname) {
|
|||
if (!(buf = malloc (section->size)) ||
|
||||
!(ret = malloc (section->size*2+1)))
|
||||
return R_FALSE;
|
||||
r_buf_read_at (bin->curarch->buf, section->offset, buf, section->size);
|
||||
r_buf_read_at (bin->curarch.buf, section->offset, buf, section->size);
|
||||
r_hex_bin2str (buf, section->size, ret);
|
||||
printf ("%s\n", ret);
|
||||
free (buf);
|
||||
|
@ -646,7 +637,7 @@ int main(int argc, char **argv) {
|
|||
int c, bits = 0;
|
||||
int action = ACTION_UNK;
|
||||
const char *op = NULL;
|
||||
char *arch = NULL;
|
||||
char *arch = NULL, *arch_name = NULL;
|
||||
|
||||
bin = r_bin_new ();
|
||||
l = r_lib_new ("radare_plugin");
|
||||
|
@ -662,7 +653,7 @@ int main(int argc, char **argv) {
|
|||
r_lib_opendir (l, LIBDIR"/radare2/");
|
||||
}
|
||||
|
||||
while ((c = getopt (argc, argv, "Aa:B:b:Mm:n:@:VisSzIHelRwO:o:rvLhx")) != -1) {
|
||||
while ((c = getopt (argc, argv, "Af:a:B:b:Mm:n:@:VisSzIHelRwO:o:rvLhx")) != -1) {
|
||||
switch(c) {
|
||||
case 'A':
|
||||
action |= ACTION_LISTARCHS;
|
||||
|
@ -670,6 +661,9 @@ int main(int argc, char **argv) {
|
|||
case 'a':
|
||||
if (optarg) arch = strdup (optarg);
|
||||
break;
|
||||
case 'f':
|
||||
if (optarg) arch_name = strdup (optarg);
|
||||
break;
|
||||
case 'B':
|
||||
bits = r_num_math (NULL, optarg);
|
||||
break;
|
||||
|
@ -764,8 +758,10 @@ int main(int argc, char **argv) {
|
|||
bits = r_num_math (NULL, ptr+1);
|
||||
}
|
||||
}
|
||||
if (action&ACTION_LISTARCHS || !r_bin_set_arch (bin, arch, bits, name)) {
|
||||
rabin_list_archs ();
|
||||
if (action&ACTION_LISTARCHS ||
|
||||
((arch || bits || arch_name) &&
|
||||
!r_bin_set_arch (bin, arch, bits, arch_name))) {
|
||||
r_bin_list_archs (bin);
|
||||
free (arch);
|
||||
r_bin_free (bin);
|
||||
return 1;
|
||||
|
|
159
libr/bin/bin.c
159
libr/bin/bin.c
|
@ -75,9 +75,22 @@ static RList* get_strings(RBinArch *arch, int min) {
|
|||
return ret;
|
||||
}
|
||||
|
||||
static void r_bin_init_items(RBinArch *arch) {
|
||||
if (!arch->curplugin)
|
||||
return;
|
||||
static int r_bin_init_items(RBin *bin, int dummy) {
|
||||
struct list_head *pos;
|
||||
RBinArch *arch = &bin->curarch;
|
||||
|
||||
arch->curplugin = NULL;
|
||||
list_for_each (pos, &bin->bins) {
|
||||
RBinPlugin *h = list_entry (pos, RBinPlugin, list);
|
||||
if ((dummy && !strncmp (h->name, "dummy", 5)) ||
|
||||
(!dummy && (h->check && h->check (&bin->curarch)))) {
|
||||
bin->curarch.curplugin = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!arch->curplugin || !arch->curplugin->load ||
|
||||
!arch->curplugin->load (arch))
|
||||
return R_FALSE;
|
||||
if (arch->curplugin->baddr)
|
||||
arch->baddr = arch->curplugin->baddr (arch);
|
||||
if (arch->curplugin->main)
|
||||
|
@ -101,10 +114,13 @@ static void r_bin_init_items(RBinArch *arch) {
|
|||
else arch->strings = get_strings (arch, 4);
|
||||
if (arch->curplugin->symbols)
|
||||
arch->symbols = arch->curplugin->symbols (arch);
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
/* TODO: Free plugins */
|
||||
static void r_bin_free_items(RBinArch *arch) {
|
||||
static void r_bin_free_items(RBin *bin) {
|
||||
RBinArch *arch = &bin->curarch;
|
||||
|
||||
if (arch->entries)
|
||||
r_list_free (arch->entries);
|
||||
if (arch->fields)
|
||||
|
@ -127,27 +143,37 @@ static void r_bin_free_items(RBinArch *arch) {
|
|||
free (arch->main);
|
||||
if (arch->file)
|
||||
free (arch->file);
|
||||
if (bin->curarch.curplugin && bin->curarch.curplugin->destroy)
|
||||
bin->curarch.curplugin->destroy (&bin->curarch);
|
||||
}
|
||||
|
||||
static int r_bin_extract(RBin *bin, const char* file) {
|
||||
static void r_bin_init(RBin *bin) {
|
||||
struct list_head *pos;
|
||||
ut8 *buf;
|
||||
int n = 1;
|
||||
|
||||
bin->curxtr = NULL;
|
||||
bin->file = r_file_abspath (file);
|
||||
list_for_each (pos, &bin->binxtrs) {
|
||||
RBinXtrPlugin *h = list_entry (pos, RBinXtrPlugin, list);
|
||||
if (h->check && h->check (bin))
|
||||
if (h->check && h->check (bin)) {
|
||||
bin->curxtr = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bin->curxtr && bin->curxtr->load)
|
||||
bin->curxtr->load (bin);
|
||||
}
|
||||
|
||||
static int r_bin_extract(RBin *bin, int idx) {
|
||||
ut8 *buf;
|
||||
int n = 1;
|
||||
|
||||
if (bin->curxtr && bin->curxtr->extract)
|
||||
n = bin->curxtr->extract (bin);
|
||||
n = bin->curxtr->extract (bin, idx);
|
||||
else {
|
||||
bin->arch[0].file = strdup (bin->file);
|
||||
if (!(buf = (ut8*)r_file_slurp (bin->file, &bin->arch[0].size)))
|
||||
bin->curarch.file = strdup (bin->file);
|
||||
if (!(buf = (ut8*)r_file_slurp (bin->file, &bin->curarch.size)))
|
||||
return 0;
|
||||
bin->arch[0].buf = r_buf_new ();
|
||||
if (!r_buf_set_bytes (bin->arch[0].buf, buf, bin->arch[0].size)) {
|
||||
bin->curarch.buf = r_buf_new ();
|
||||
if (!r_buf_set_bytes (bin->curarch.buf, buf, bin->curarch.size)) {
|
||||
free (buf);
|
||||
return 0;
|
||||
}
|
||||
|
@ -158,6 +184,7 @@ static int r_bin_extract(RBin *bin, const char* file) {
|
|||
|
||||
R_API int r_bin_add(RBin *bin, RBinPlugin *foo) {
|
||||
struct list_head *pos;
|
||||
|
||||
if (foo->init)
|
||||
foo->init (bin->user);
|
||||
list_for_each_prev (pos, &bin->bins) {
|
||||
|
@ -171,6 +198,7 @@ R_API int r_bin_add(RBin *bin, RBinPlugin *foo) {
|
|||
|
||||
R_API int r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo) {
|
||||
struct list_head *pos;
|
||||
|
||||
if (foo->init)
|
||||
foo->init (bin->user);
|
||||
list_for_each_prev (pos, &bin->binxtrs) {
|
||||
|
@ -183,15 +211,11 @@ R_API int r_bin_xtr_add(RBin *bin, RBinXtrPlugin *foo) {
|
|||
}
|
||||
|
||||
R_API void* r_bin_free(RBin *bin) {
|
||||
int i;
|
||||
|
||||
if (!bin)
|
||||
return NULL;
|
||||
for (i = 0; i < bin->narch; i++) {
|
||||
r_bin_free_items (&bin->arch[i]);
|
||||
if (bin->arch[i].curplugin && bin->arch[i].curplugin->destroy)
|
||||
bin->arch[i].curplugin->destroy (&bin->arch[i]);
|
||||
}
|
||||
r_bin_free_items (bin);
|
||||
if (bin->curxtr && bin->curxtr->destroy)
|
||||
bin->curxtr->destroy (bin);
|
||||
free (bin);
|
||||
return NULL;
|
||||
}
|
||||
|
@ -211,67 +235,51 @@ R_API int r_bin_list(RBin *bin) {
|
|||
}
|
||||
|
||||
R_API int r_bin_load(RBin *bin, const char *file, int dummy) {
|
||||
struct list_head *pos;
|
||||
int i;
|
||||
if (!bin || !file)
|
||||
return R_FALSE;
|
||||
bin->narch = r_bin_extract (bin, file);
|
||||
bin->file = r_file_abspath (file);
|
||||
r_bin_init (bin);
|
||||
bin->narch = r_bin_extract (bin, 0);
|
||||
if (bin->narch == 0)
|
||||
return R_FALSE;
|
||||
bin->curarch = &bin->arch[0];
|
||||
for (i = 0; i < bin->narch; i++) {
|
||||
bin->arch[i].curplugin = NULL;
|
||||
list_for_each (pos, &bin->bins) {
|
||||
RBinPlugin *h = list_entry (pos, RBinPlugin, list);
|
||||
if ((dummy && !strncmp (h->name, "dummy", 5)) ||
|
||||
(!dummy && (h->check && h->check (&bin->arch[i])))) {
|
||||
bin->arch[i].curplugin = h;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (bin->arch[i].curplugin && bin->arch[i].curplugin->load &&
|
||||
bin->arch[i].curplugin->load (&bin->arch[i]))
|
||||
r_bin_init_items (&bin->arch[i]);
|
||||
else return R_FALSE;
|
||||
}
|
||||
return R_TRUE;
|
||||
return r_bin_init_items (bin, dummy);
|
||||
}
|
||||
|
||||
// remove this getters.. we have no threads or mutexes to protect here
|
||||
R_API ut64 r_bin_get_baddr(RBin *bin) {
|
||||
return bin->curarch->baddr;
|
||||
return bin->curarch.baddr;
|
||||
}
|
||||
|
||||
R_API RBinAddr* r_bin_get_main(RBin *bin) {
|
||||
return bin->curarch->main;
|
||||
return bin->curarch.main;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_entries(RBin *bin) {
|
||||
return bin->curarch->entries;
|
||||
return bin->curarch.entries;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_fields(RBin *bin) {
|
||||
return bin->curarch->fields;
|
||||
return bin->curarch.fields;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_imports(RBin *bin) {
|
||||
return bin->curarch->imports;
|
||||
return bin->curarch.imports;
|
||||
}
|
||||
|
||||
R_API RBinInfo* r_bin_get_info(RBin *bin) {
|
||||
return bin->curarch->info;
|
||||
return bin->curarch.info;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_libs(RBin *bin) {
|
||||
return bin->curarch->libs;
|
||||
return bin->curarch.libs;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_relocs(RBin *bin) {
|
||||
return bin->curarch->relocs;
|
||||
return bin->curarch.relocs;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_sections(RBin *bin) {
|
||||
return bin->curarch->sections;
|
||||
return bin->curarch.sections;
|
||||
}
|
||||
|
||||
R_API RBinSection* r_bin_get_section_at(RBin *bin, ut64 off, int va) {
|
||||
|
@ -279,10 +287,10 @@ R_API RBinSection* r_bin_get_section_at(RBin *bin, ut64 off, int va) {
|
|||
RListIter *iter;
|
||||
ut64 from, to;
|
||||
|
||||
if (bin->curarch->sections)
|
||||
r_list_foreach (bin->curarch->sections, iter, section) {
|
||||
from = va ? bin->curarch->baddr+section->rva : section->offset;
|
||||
to = va ? bin->curarch->baddr+section->rva+section->vsize :
|
||||
if (bin->curarch.sections)
|
||||
r_list_foreach (bin->curarch.sections, iter, section) {
|
||||
from = va ? bin->curarch.baddr+section->rva : section->offset;
|
||||
to = va ? bin->curarch.baddr+section->rva+section->vsize :
|
||||
section->offset + section->size;
|
||||
if (off >= from && off < to)
|
||||
return section;
|
||||
|
@ -291,36 +299,36 @@ R_API RBinSection* r_bin_get_section_at(RBin *bin, ut64 off, int va) {
|
|||
}
|
||||
|
||||
R_API RList* r_bin_get_strings(RBin *bin) {
|
||||
return bin->curarch->strings;
|
||||
return bin->curarch.strings;
|
||||
}
|
||||
|
||||
R_API RList* r_bin_get_symbols(RBin *bin) {
|
||||
return bin->curarch->symbols;
|
||||
return bin->curarch.symbols;
|
||||
}
|
||||
|
||||
R_API int r_bin_is_big_endian (RBin *bin) {
|
||||
return bin->curarch->info->big_endian;
|
||||
return bin->curarch.info->big_endian;
|
||||
}
|
||||
|
||||
R_API int r_bin_is_stripped (RBin *bin) {
|
||||
return R_BIN_DBG_STRIPPED (bin->curarch->info->dbg_info);
|
||||
return R_BIN_DBG_STRIPPED (bin->curarch.info->dbg_info);
|
||||
}
|
||||
|
||||
R_API int r_bin_is_static (RBin *bin) {
|
||||
return R_BIN_DBG_STATIC (bin->curarch->info->dbg_info);
|
||||
return R_BIN_DBG_STATIC (bin->curarch.info->dbg_info);
|
||||
}
|
||||
|
||||
/* XXX Implement in r_bin_meta and deprecate? */
|
||||
R_API int r_bin_has_dbg_linenums (RBin *bin) {
|
||||
return R_BIN_DBG_LINENUMS (bin->curarch->info->dbg_info);
|
||||
return R_BIN_DBG_LINENUMS (bin->curarch.info->dbg_info);
|
||||
}
|
||||
|
||||
R_API int r_bin_has_dbg_syms (RBin *bin) {
|
||||
return R_BIN_DBG_SYMS (bin->curarch->info->dbg_info);
|
||||
return R_BIN_DBG_SYMS (bin->curarch.info->dbg_info);
|
||||
}
|
||||
|
||||
R_API int r_bin_has_dbg_relocs (RBin *bin) {
|
||||
return R_BIN_DBG_RELOCS (bin->curarch->info->dbg_info);
|
||||
return R_BIN_DBG_RELOCS (bin->curarch.info->dbg_info);
|
||||
}
|
||||
|
||||
R_API RBin* r_bin_new() {
|
||||
|
@ -352,17 +360,34 @@ R_API int r_bin_set_arch(RBin *bin, const char *arch, int bits, const char *name
|
|||
int i;
|
||||
|
||||
for (i = 0; i < bin->narch; i++) {
|
||||
if (!bin->arch[i].info ||
|
||||
(arch && !strstr (bin->arch[i].info->arch, arch)) ||
|
||||
(bits && bits != bin->arch[i].info->bits) ||
|
||||
(name && !strstr (bin->arch[i].file, name)))
|
||||
r_bin_set_archidx (bin, i);
|
||||
if (!bin->curarch.info || !bin->curarch.file ||
|
||||
(arch && !strstr (bin->curarch.info->arch, arch)) ||
|
||||
(bits && bits != bin->curarch.info->bits) ||
|
||||
(name && !strstr (bin->curarch.file, name)))
|
||||
continue;
|
||||
bin->curarch = &bin->arch[i];
|
||||
return R_TRUE;
|
||||
}
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_bin_set_archidx(RBin *bin, int idx) {
|
||||
r_bin_free_items (bin);
|
||||
if (r_bin_extract (bin, idx))
|
||||
return r_bin_init_items (bin, R_FALSE);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API void r_bin_list_archs(RBin *bin) {
|
||||
int i;
|
||||
|
||||
for (i = 0; i < bin->narch; i++)
|
||||
if (r_bin_set_archidx (bin, i) && bin->curarch.info)
|
||||
printf ("%03i %s %s_%i (%s)\n", i, bin->curarch.file,
|
||||
bin->curarch.info->arch, bin->curarch.info->bits,
|
||||
bin->curarch.info->machine);
|
||||
}
|
||||
|
||||
R_API void r_bin_set_user_ptr(RBin *bin, void *user) {
|
||||
bin->user = user;
|
||||
}
|
||||
|
|
|
@ -4,11 +4,11 @@
|
|||
#include <r_bin.h>
|
||||
|
||||
R_API int r_bin_meta_get_line(RBin *bin, ut64 addr, char *file, int len, int *line) {
|
||||
if (bin->curarch && bin->curarch->curplugin && bin->curarch->curplugin->meta) {
|
||||
if (bin->curarch.curplugin && bin->curarch.curplugin->meta) {
|
||||
// XXX quick hack to not show lines out of opened bin
|
||||
if (addr >= bin->curarch->baddr && addr < (bin->curarch->baddr+bin->curarch->size))
|
||||
if (bin->curarch->curplugin->meta->get_line)
|
||||
return bin->curarch->curplugin->meta->get_line (bin->arch, addr,
|
||||
if (addr >= bin->curarch.baddr && addr < (bin->curarch.baddr+bin->curarch.size))
|
||||
if (bin->curarch.curplugin->meta->get_line)
|
||||
return bin->curarch.curplugin->meta->get_line (&bin->curarch, addr,
|
||||
file, len, line);
|
||||
}
|
||||
return R_FALSE;
|
||||
|
|
|
@ -6,23 +6,21 @@
|
|||
|
||||
/* XXX Implement r__bin_wr_scn_{set, del} instead */
|
||||
R_API ut64 r_bin_wr_scn_resize(RBin *bin, const char *name, ut64 size) {
|
||||
if (bin->curarch && bin->curarch->curplugin &&
|
||||
bin->curarch->curplugin->write &&
|
||||
bin->curarch->curplugin->write->scn_resize)
|
||||
return bin->curarch->curplugin->write->scn_resize (bin->curarch,
|
||||
if (bin->curarch.curplugin && bin->curarch.curplugin->write &&
|
||||
bin->curarch.curplugin->write->scn_resize)
|
||||
return bin->curarch.curplugin->write->scn_resize (&bin->curarch,
|
||||
name, size);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_bin_wr_rpath_del(RBin *bin) {
|
||||
if (bin->curarch && bin->curarch->curplugin &&
|
||||
bin->curarch->curplugin->write &&
|
||||
bin->curarch->curplugin->write->rpath_del)
|
||||
return bin->curarch->curplugin->write->rpath_del (bin->curarch);
|
||||
if (bin->curarch.curplugin && bin->curarch.curplugin->write &&
|
||||
bin->curarch.curplugin->write->rpath_del)
|
||||
return bin->curarch.curplugin->write->rpath_del (&bin->curarch);
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
R_API int r_bin_wr_output(RBin *bin, const char *filename) {
|
||||
return r_file_dump (filename, bin->curarch->buf->buf,
|
||||
bin->curarch->buf->length);
|
||||
return r_file_dump (filename, bin->curarch.buf->buf,
|
||||
bin->curarch.buf->length);
|
||||
}
|
||||
|
|
|
@ -22,116 +22,122 @@ static int r_bin_dyldcache_apply_patch (struct r_buf_t* buf, ut32 data, ut64 off
|
|||
#define NZ_OFFSET(x) if(x > 0) r_bin_dyldcache_apply_patch (dbuf, x - linkedit_offset, (ut64)&x - (ut64)data)
|
||||
|
||||
/* TODO: Needs more testing and ERROR HANDLING */
|
||||
struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj_t* bin) {
|
||||
struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj_t* bin, int idx, int *nlib) {
|
||||
struct r_bin_dyldcache_lib_t *ret = NULL;
|
||||
struct mach_header *mh;
|
||||
struct r_buf_t *dbuf;
|
||||
ut64 curoffset, liboff, libla, libpath, linkedit_offset;
|
||||
ut8 *data, *cmdptr;
|
||||
char *libname;
|
||||
int i, j, cmd, libsz;
|
||||
int cmd, libsz = 0;
|
||||
|
||||
if (bin->nlibs < 0)
|
||||
if (bin->nlibs < 0 || idx < 0 || idx > bin->nlibs)
|
||||
return NULL;
|
||||
if (!(ret = malloc ((bin->nlibs+1) * sizeof(struct r_bin_dyldcache_lib_t))))
|
||||
*nlib = bin->nlibs;
|
||||
if (!(ret = malloc (sizeof(struct r_bin_dyldcache_lib_t)))) {
|
||||
perror ("malloc (ret)");
|
||||
return NULL;
|
||||
memset (ret, 0, (bin->nlibs+1) * sizeof(struct r_bin_dyldcache_lib_t));
|
||||
for (i = j = 0, curoffset = bin->hdr.startaddr; i < bin->nlibs; i++, curoffset+=32) {
|
||||
libla = *(ut64*)(bin->b->buf+curoffset);
|
||||
liboff = libla - *(ut64*)&bin->b->buf[bin->hdr.baseaddroff];
|
||||
if (liboff < 0 || liboff > bin->size)
|
||||
continue;
|
||||
libpath = *(ut64*)(bin->b->buf+curoffset + 24);
|
||||
libsz = 0;
|
||||
|
||||
/* Locate lib hdr in cache */
|
||||
data = bin->b->buf+liboff;
|
||||
mh = (struct mach_header *)data;
|
||||
/* Check it is mach-o */
|
||||
if (mh->magic != 0xfeedface)
|
||||
continue;
|
||||
/* Write mach-o hdr */
|
||||
if (!(dbuf = r_buf_new ()))
|
||||
continue;
|
||||
r_buf_set_bytes (dbuf, data, sizeof (struct mach_header));
|
||||
cmdptr = data + sizeof(struct mach_header);
|
||||
/* Write load commands */
|
||||
for(cmd = 0; cmd < mh->ncmds; cmd++) {
|
||||
struct load_command *lc = (struct load_command *)cmdptr;
|
||||
cmdptr += lc->cmdsize;
|
||||
r_buf_append_bytes (dbuf, (ut8*)lc, lc->cmdsize);
|
||||
}
|
||||
/* Write segments */
|
||||
for(cmd = linkedit_offset = 0, cmdptr = data + sizeof(struct mach_header); cmd < mh->ncmds; cmd++) {
|
||||
struct load_command *lc = (struct load_command *)cmdptr;
|
||||
cmdptr += lc->cmdsize;
|
||||
switch(lc->cmd) {
|
||||
case LC_SEGMENT:
|
||||
{
|
||||
/* Write segment and patch offset */
|
||||
struct segment_command *seg = (struct segment_command *)lc;
|
||||
int t = seg->filesize;
|
||||
if (seg->fileoff+seg->filesize > bin->b->length)
|
||||
t = bin->b->length - seg->fileoff;
|
||||
r_buf_append_bytes (dbuf, bin->b->buf+seg->fileoff, t);
|
||||
r_bin_dyldcache_apply_patch (dbuf, dbuf->length, (ut64)&seg->fileoff - (ut64)data);
|
||||
/* Patch section offsets */
|
||||
int sect_offset = seg->fileoff - libsz;
|
||||
libsz = dbuf->length;
|
||||
if(!strcmp(seg->segname, "__LINKEDIT")) {
|
||||
linkedit_offset = sect_offset;
|
||||
}
|
||||
if(seg->nsects > 0) {
|
||||
struct section *sects = (struct section *)((ut8 *)seg + sizeof(struct segment_command));
|
||||
int nsect;
|
||||
for(nsect = 0; nsect < seg->nsects; nsect++) {
|
||||
if(sects[nsect].offset > libsz) {
|
||||
r_bin_dyldcache_apply_patch (dbuf, sects[nsect].offset - sect_offset, (ut64)§s[nsect].offset - (ut64)data);
|
||||
}
|
||||
}
|
||||
memset (ret, 0, sizeof(struct r_bin_dyldcache_lib_t));
|
||||
curoffset = bin->hdr.startaddr+idx*32;
|
||||
libla = *(ut64*)(bin->b->buf+curoffset);
|
||||
liboff = libla - *(ut64*)&bin->b->buf[bin->hdr.baseaddroff];
|
||||
if (liboff < 0 || liboff > bin->size) {
|
||||
eprintf ("Corrupted file\n");
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
libpath = *(ut64*)(bin->b->buf+curoffset + 24);
|
||||
/* Locate lib hdr in cache */
|
||||
data = bin->b->buf+liboff;
|
||||
mh = (struct mach_header *)data;
|
||||
/* Check it is mach-o */
|
||||
if (mh->magic != 0xfeedface) {
|
||||
eprintf ("Not mach-o\n");
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
/* Write mach-o hdr */
|
||||
if (!(dbuf = r_buf_new ())) {
|
||||
eprintf ("new (dbuf)\n");
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
r_buf_set_bytes (dbuf, data, sizeof (struct mach_header));
|
||||
cmdptr = data + sizeof(struct mach_header);
|
||||
/* Write load commands */
|
||||
for(cmd = 0; cmd < mh->ncmds; cmd++) {
|
||||
struct load_command *lc = (struct load_command *)cmdptr;
|
||||
cmdptr += lc->cmdsize;
|
||||
r_buf_append_bytes (dbuf, (ut8*)lc, lc->cmdsize);
|
||||
}
|
||||
/* Write segments */
|
||||
for(cmd = linkedit_offset = 0, cmdptr = data + sizeof(struct mach_header); cmd < mh->ncmds; cmd++) {
|
||||
struct load_command *lc = (struct load_command *)cmdptr;
|
||||
cmdptr += lc->cmdsize;
|
||||
switch(lc->cmd) {
|
||||
case LC_SEGMENT:
|
||||
{
|
||||
/* Write segment and patch offset */
|
||||
struct segment_command *seg = (struct segment_command *)lc;
|
||||
int t = seg->filesize;
|
||||
if (seg->fileoff+seg->filesize > bin->b->length)
|
||||
t = bin->b->length - seg->fileoff;
|
||||
r_buf_append_bytes (dbuf, bin->b->buf+seg->fileoff, t);
|
||||
r_bin_dyldcache_apply_patch (dbuf, dbuf->length, (ut64)&seg->fileoff - (ut64)data);
|
||||
/* Patch section offsets */
|
||||
int sect_offset = seg->fileoff - libsz;
|
||||
libsz = dbuf->length;
|
||||
if(!strcmp(seg->segname, "__LINKEDIT")) {
|
||||
linkedit_offset = sect_offset;
|
||||
}
|
||||
if(seg->nsects > 0) {
|
||||
struct section *sects = (struct section *)((ut8 *)seg + sizeof(struct segment_command));
|
||||
int nsect;
|
||||
for(nsect = 0; nsect < seg->nsects; nsect++) {
|
||||
if(sects[nsect].offset > libsz) {
|
||||
r_bin_dyldcache_apply_patch (dbuf, sects[nsect].offset - sect_offset, (ut64)§s[nsect].offset - (ut64)data);
|
||||
}
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LC_SYMTAB:
|
||||
{
|
||||
struct symtab_command *st = (struct symtab_command *)lc;
|
||||
NZ_OFFSET(st->symoff);
|
||||
NZ_OFFSET(st->stroff);
|
||||
}
|
||||
break;
|
||||
case LC_DYSYMTAB:
|
||||
{
|
||||
struct dysymtab_command *st = (struct dysymtab_command *)lc;
|
||||
NZ_OFFSET(st->tocoff);
|
||||
NZ_OFFSET(st->modtaboff);
|
||||
NZ_OFFSET(st->extrefsymoff);
|
||||
NZ_OFFSET(st->indirectsymoff);
|
||||
NZ_OFFSET(st->extreloff);
|
||||
NZ_OFFSET(st->locreloff);
|
||||
}
|
||||
break;
|
||||
case LC_DYLD_INFO:
|
||||
case LC_DYLD_INFO_ONLY:
|
||||
{
|
||||
struct dyld_info_32 *st = (struct dyld_info_32 *)lc;
|
||||
NZ_OFFSET(st->rebase_off);
|
||||
NZ_OFFSET(st->bind_off);
|
||||
NZ_OFFSET(st->weak_bind_off);
|
||||
NZ_OFFSET(st->lazy_bind_off);
|
||||
NZ_OFFSET(st->export_off);
|
||||
}
|
||||
break;
|
||||
}
|
||||
}
|
||||
break;
|
||||
case LC_SYMTAB:
|
||||
{
|
||||
struct symtab_command *st = (struct symtab_command *)lc;
|
||||
NZ_OFFSET(st->symoff);
|
||||
NZ_OFFSET(st->stroff);
|
||||
}
|
||||
break;
|
||||
case LC_DYSYMTAB:
|
||||
{
|
||||
struct dysymtab_command *st = (struct dysymtab_command *)lc;
|
||||
NZ_OFFSET(st->tocoff);
|
||||
NZ_OFFSET(st->modtaboff);
|
||||
NZ_OFFSET(st->extrefsymoff);
|
||||
NZ_OFFSET(st->indirectsymoff);
|
||||
NZ_OFFSET(st->extreloff);
|
||||
NZ_OFFSET(st->locreloff);
|
||||
}
|
||||
break;
|
||||
case LC_DYLD_INFO:
|
||||
case LC_DYLD_INFO_ONLY:
|
||||
{
|
||||
struct dyld_info_32 *st = (struct dyld_info_32 *)lc;
|
||||
NZ_OFFSET(st->rebase_off);
|
||||
NZ_OFFSET(st->bind_off);
|
||||
NZ_OFFSET(st->weak_bind_off);
|
||||
NZ_OFFSET(st->lazy_bind_off);
|
||||
NZ_OFFSET(st->export_off);
|
||||
}
|
||||
break;
|
||||
}
|
||||
/* Fill r_bin_dyldcache_lib_t array */
|
||||
ret[j].b = dbuf;
|
||||
libname = (char*)(bin->b->buf+libpath);
|
||||
strncpy (ret[j].path, libname, sizeof (ret[j].path));
|
||||
ret[j].size = libsz;
|
||||
ret[j].last = 0;
|
||||
j++;
|
||||
}
|
||||
ret[j].last = 1;
|
||||
/* Fill r_bin_dyldcache_lib_t ret */
|
||||
ret->b = dbuf;
|
||||
libname = (char*)(bin->b->buf+libpath);
|
||||
strncpy (ret->path, libname, sizeof (ret->path));
|
||||
ret->size = libsz;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ struct r_bin_dyldcache_lib_t {
|
|||
int last;
|
||||
};
|
||||
|
||||
struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj_t* bin);
|
||||
struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj_t* bin, int idx, int *nlib);
|
||||
void *r_bin_dyldcache_free(struct r_bin_dyldcache_obj_t* bin);
|
||||
struct r_bin_dyldcache_obj_t* r_bin_dyldcache_new(const char* file);
|
||||
|
||||
|
|
|
@ -28,42 +28,46 @@ static int r_bin_fatmach0_init(struct r_bin_fatmach0_obj_t* bin) {
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
struct r_bin_fatmach0_arch_t *r_bin_fatmach0_extract(struct r_bin_fatmach0_obj_t* bin) {
|
||||
struct r_bin_fatmach0_arch_t *r_bin_fatmach0_extract(struct r_bin_fatmach0_obj_t* bin, int idx, int *narch) {
|
||||
ut8 *buf = NULL;
|
||||
struct r_bin_fatmach0_arch_t *ret;
|
||||
int i;
|
||||
|
||||
if (bin->hdr.nfat_arch < 0)
|
||||
if (bin->hdr.nfat_arch < 0 || idx < 0 || idx > bin->hdr.nfat_arch)
|
||||
return NULL;
|
||||
*narch = bin->hdr.nfat_arch;
|
||||
if (!(ret = malloc (sizeof(struct r_bin_fatmach0_arch_t)))) {
|
||||
perror ("malloc (ret)");
|
||||
return NULL;
|
||||
ret = malloc ((bin->hdr.nfat_arch+1) * sizeof(struct r_bin_fatmach0_arch_t));
|
||||
for (i = 0; i < bin->hdr.nfat_arch; i++) {
|
||||
if (bin->archs[i].size == 0 || bin->archs[i].size > bin->size) {
|
||||
eprintf ("Corrupted file\n");
|
||||
return NULL;
|
||||
}
|
||||
if (!(buf = malloc (bin->archs[i].size))) {
|
||||
perror ("malloc (buf)");
|
||||
return NULL;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, bin->archs[i].offset, buf, bin->archs[i].size) == -1) {
|
||||
perror ("read (buf)");
|
||||
free (buf);
|
||||
return NULL;
|
||||
}
|
||||
if (!(ret[i].b = r_buf_new ())) {
|
||||
free (buf);
|
||||
return NULL;
|
||||
}
|
||||
if (!r_buf_set_bytes (ret[i].b, buf, bin->archs[i].size)) {
|
||||
free (buf);
|
||||
r_buf_free (ret[i].b);
|
||||
return NULL;
|
||||
}
|
||||
free (buf);
|
||||
ret[i].size = bin->archs[i].size;
|
||||
ret[i].last = 0;
|
||||
}
|
||||
ret[i].last = 1;
|
||||
if (bin->archs[idx].size == 0 || bin->archs[idx].size > bin->size) {
|
||||
eprintf ("Corrupted file\n");
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
if (!(buf = malloc (bin->archs[idx].size))) {
|
||||
perror ("malloc (buf)");
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
if (r_buf_read_at (bin->b, bin->archs[idx].offset, buf, bin->archs[idx].size) == -1) {
|
||||
perror ("read (buf)");
|
||||
free (buf);
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
if (!(ret->b = r_buf_new ())) {
|
||||
free (buf);
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
if (!r_buf_set_bytes (ret->b, buf, bin->archs[idx].size)) {
|
||||
free (buf);
|
||||
r_buf_free (ret->b);
|
||||
free (ret);
|
||||
return NULL;
|
||||
}
|
||||
free (buf);
|
||||
ret->size = bin->archs[idx].size;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
|
|
@ -21,7 +21,7 @@ struct r_bin_fatmach0_arch_t {
|
|||
int last;
|
||||
};
|
||||
|
||||
struct r_bin_fatmach0_arch_t *r_bin_fatmach0_extract(struct r_bin_fatmach0_obj_t* bin);
|
||||
struct r_bin_fatmach0_arch_t *r_bin_fatmach0_extract(struct r_bin_fatmach0_obj_t* bin, int idx, int *narch);
|
||||
void* r_bin_fatmach0_free(struct r_bin_fatmach0_obj_t* bin);
|
||||
struct r_bin_fatmach0_obj_t* r_bin_fatmach0_new(const char* file);
|
||||
|
||||
|
|
|
@ -24,22 +24,24 @@ static int destroy(RBin *bin) {
|
|||
return R_TRUE;
|
||||
}
|
||||
|
||||
static int extract(RBin *bin) {
|
||||
struct r_bin_dyldcache_lib_t *libs;
|
||||
int i;
|
||||
static int load(RBin *bin) {
|
||||
if((bin->bin_obj = r_bin_dyldcache_new (bin->file)))
|
||||
return R_TRUE;
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
if(!(bin->bin_obj = r_bin_dyldcache_new (bin->file)))
|
||||
static int extract(RBin *bin, int idx) {
|
||||
struct r_bin_dyldcache_lib_t *lib;
|
||||
int nlib;
|
||||
|
||||
lib = r_bin_dyldcache_extract ((struct r_bin_dyldcache_obj_t*)bin->bin_obj, idx, &nlib);
|
||||
if (!lib)
|
||||
return 0;
|
||||
libs = r_bin_dyldcache_extract ((struct r_bin_dyldcache_obj_t*)bin->bin_obj);
|
||||
if (!libs)
|
||||
return 0;
|
||||
for (i = 0; !libs[i].last; i++) {
|
||||
bin->arch[i].file = strdup (libs[i].path);
|
||||
bin->arch[i].buf = libs[i].b;
|
||||
bin->arch[i].size = libs[i].size;
|
||||
}
|
||||
free (libs);
|
||||
return i;
|
||||
bin->curarch.file = strdup (lib->path);
|
||||
bin->curarch.buf = lib->b;
|
||||
bin->curarch.size = lib->size;
|
||||
free (lib);
|
||||
return nlib;
|
||||
}
|
||||
|
||||
struct r_bin_xtr_plugin_t r_bin_xtr_plugin_dyldcache = {
|
||||
|
@ -48,6 +50,7 @@ struct r_bin_xtr_plugin_t r_bin_xtr_plugin_dyldcache = {
|
|||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.check = &check,
|
||||
.load = &load,
|
||||
.extract = &extract,
|
||||
.destroy = &destroy,
|
||||
};
|
||||
|
|
|
@ -32,23 +32,24 @@ static int destroy(RBin *bin) {
|
|||
r_bin_fatmach0_free ((struct r_bin_fatmach0_obj_t*)bin->bin_obj);
|
||||
return R_TRUE;
|
||||
}
|
||||
static int load(RBin *bin) {
|
||||
if((bin->bin_obj = r_bin_fatmach0_new(bin->file)))
|
||||
return R_TRUE;
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
static int extract(RBin *bin) {
|
||||
struct r_bin_fatmach0_arch_t *archs;
|
||||
int i;
|
||||
static int extract(RBin *bin, int idx) {
|
||||
struct r_bin_fatmach0_arch_t *arch;
|
||||
int narch;
|
||||
|
||||
if(!(bin->bin_obj = r_bin_fatmach0_new(bin->file)))
|
||||
arch = r_bin_fatmach0_extract ((struct r_bin_fatmach0_obj_t*)bin->bin_obj, idx, &narch);
|
||||
if (!arch)
|
||||
return 0;
|
||||
archs = r_bin_fatmach0_extract ((struct r_bin_fatmach0_obj_t*)bin->bin_obj);
|
||||
if (!archs)
|
||||
return 0;
|
||||
for (i = 0; !archs[i].last; i++) {
|
||||
bin->arch[i].file = strdup (bin->file);
|
||||
bin->arch[i].buf = archs[i].b;
|
||||
bin->arch[i].size = archs[i].size;
|
||||
}
|
||||
free (archs);
|
||||
return i;
|
||||
bin->curarch.file = strdup (bin->file);
|
||||
bin->curarch.buf = arch->b;
|
||||
bin->curarch.size = arch->size;
|
||||
free (arch);
|
||||
return narch;
|
||||
}
|
||||
|
||||
struct r_bin_xtr_plugin_t r_bin_xtr_plugin_fatmach0 = {
|
||||
|
@ -57,6 +58,7 @@ struct r_bin_xtr_plugin_t r_bin_xtr_plugin_fatmach0 = {
|
|||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.check = &check,
|
||||
.load = &load,
|
||||
.extract = &extract,
|
||||
.destroy = &destroy,
|
||||
};
|
||||
|
|
|
@ -15,7 +15,7 @@ int main(int argc, char **argv) {
|
|||
output = argv[2];
|
||||
|
||||
bin = r_bin_new ();
|
||||
if (!r_bin_load (bin, input, NULL)) {
|
||||
if (!r_bin_load (bin, input, R_FALSE)) {
|
||||
fprintf (stderr, "Error: Cannot open file '%s'\n", input);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -16,7 +16,7 @@ int main(int argc, char **argv)
|
|||
}
|
||||
|
||||
bin = r_bin_new ();
|
||||
if (!r_bin_load (bin, argv[1], NULL)) {
|
||||
if (!r_bin_load (bin, argv[1], R_FALSE)) {
|
||||
eprintf ("r_bin: Cannot open '%s'\n", argv[1]);
|
||||
return 1;
|
||||
}
|
||||
|
|
|
@ -43,8 +43,7 @@ typedef struct r_bin_arch_t {
|
|||
|
||||
typedef struct r_bin_t {
|
||||
const char *file;
|
||||
struct r_bin_arch_t arch[R_BIN_MAX_ARCH];
|
||||
struct r_bin_arch_t *curarch;
|
||||
struct r_bin_arch_t curarch;
|
||||
int narch;
|
||||
void *user;
|
||||
void *bin_obj;
|
||||
|
@ -59,7 +58,8 @@ typedef struct r_bin_xtr_plugin_t {
|
|||
int (*init)(void *user);
|
||||
int (*fini)(void *user);
|
||||
int (*check)(RBin *bin);
|
||||
int (*extract)(RBin *bin);
|
||||
int (*extract)(RBin *bin, int idx);
|
||||
int (*load)(RBin *bin);
|
||||
int (*destroy)(RBin *bin);
|
||||
struct list_head list;
|
||||
} RBinXtrPlugin;
|
||||
|
@ -204,6 +204,8 @@ R_API int r_bin_has_dbg_syms (RBin *bin);
|
|||
R_API int r_bin_has_dbg_relocs (RBin *bin);
|
||||
R_API RBin* r_bin_new();
|
||||
R_API int r_bin_set_arch(RBin *bin, const char *arch, int bits, const char *name);
|
||||
R_API int r_bin_set_archidx(RBin *bin, int idx);
|
||||
R_API void r_bin_list_archs(RBin *bin);
|
||||
R_API void r_bin_set_user_ptr(RBin *bin, void *user);
|
||||
|
||||
/* bin_meta.c */
|
||||
|
|
Loading…
Reference in New Issue