- 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:
Nibble 2010-10-04 03:46:58 +02:00
parent ee39ba239a
commit cec1f3fa73
13 changed files with 298 additions and 262 deletions

View File

@ -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;

View File

@ -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;
}

View File

@ -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;

View File

@ -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);
}

View File

@ -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)&sects[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)&sects[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;
}

View File

@ -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);

View 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;
}

View File

@ -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);

View 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,
};

View File

@ -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,
};

View File

@ -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;
}

View File

@ -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;
}

View File

@ -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 */