* Initial implementation of the RBin extractor for dyld cache

* Add bin_xtr_dyldcache to plugins.def.cfg
* Show bin name in the output of 'rabin2 -A'
* Minor fix in rabin_list_archs() in rabin2
This commit is contained in:
Nibble 2010-10-01 04:26:52 +02:00
parent e02c81ddf1
commit 987d8599f9
11 changed files with 227 additions and 9 deletions

View File

@ -436,12 +436,16 @@ static int rabin_show_info() {
}
static void rabin_list_archs() {
RBinInfo *info;
int i;
for (i=0; i<bin->narch; i++)
printf ("%s_%i %s (%s endian)\n", bin->arch[i].info->arch,
bin->arch[i].info->bits, bin->arch[i].info->machine,
bin->arch[i].info->big_endian?"big":"litle");
for (i=0; i<bin->narch; i++) {
bin->curarch = &bin->arch[i];
if ((info = r_bin_get_info (bin)) == NULL)
return;
printf ("%s_%i %s (%s - %s endian)\n", info->arch, info->bits, bin->curarch->file,
info->machine, info->big_endian?"big":"litle");
}
}
static int rabin_show_fields() {

View File

@ -125,6 +125,8 @@ static void r_bin_free_items(RBinArch *arch) {
r_list_free (arch->symbols);
if (arch->main)
free (arch->main);
if (arch->file)
free (arch->file);
}
static int r_bin_extract(RBin *bin, const char* file) {
@ -142,7 +144,7 @@ static int r_bin_extract(RBin *bin, const char* file) {
if (bin->curxtr && bin->curxtr->extract)
n = bin->curxtr->extract (bin);
else {
bin->arch[0].file = bin->file;
bin->arch[0].file = strdup (bin->file);
if (!(buf = (ut8*)r_file_slurp (bin->file, &bin->arch[0].size)))
return 0;
bin->arch[0].buf = r_buf_new ();

View File

@ -0,0 +1,99 @@
/* radare - LGPL - Copyright 2010 nibble at develsec.org */
#include <stdio.h>
#include <r_types.h>
#include <r_util.h>
#include "dyldcache.h"
static int r_bin_dyldcache_init(struct r_bin_dyldcache_obj_t* bin) {
int len;
len = r_buf_fread_at(bin->b, 0, (ut8*)&bin->hdr, "16c4il", 1);
if (len == -1) {
perror ("read (cache_header)");
return R_FALSE;
}
bin->nlibs = bin->hdr.numlibs;
return R_TRUE;
}
struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj_t* bin) {
struct r_bin_dyldcache_lib_t *ret;
ut64 curoffset, liboff, libla, libpath, nextliboff;
ut8 *buf;
char *ptr, *libname;
int i, j, libsz;
if (bin->nlibs < 0)
return NULL;
if (!(ret = malloc ((bin->nlibs+1) * sizeof(struct r_bin_dyldcache_lib_t))))
return NULL;
for (i = 0, 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];
libpath = *(ut64*)(bin->b->buf+curoffset + 24);
if (i != bin->nlibs-1) {
nextliboff = *(ut64*)(bin->b->buf+curoffset+32) - *(ut64*)&bin->b->buf[bin->hdr.baseaddroff];
libsz = nextliboff - liboff;
} else libsz = bin->size - liboff;
if (libsz <= 0)
libsz = 10240;
if (!(buf = malloc (libsz))) {
perror ("malloc (buf)");
return NULL;
}
if (r_buf_read_at (bin->b, liboff, buf, libsz) == -1) {
perror ("read (buf)");
free (buf);
return NULL;
}
if (!(ret[j].b = r_buf_new ())) {
free (buf);
return NULL;
}
if (!r_buf_set_bytes (ret[j].b, buf, libsz)) {
free (buf);
r_buf_free (ret[j].b);
return NULL;
}
free (buf);
libname = (char*)(bin->b->buf+libpath);
if ((ptr = strrchr (libname, '/')))
libname = ptr+1;
strncpy (ret[i].path, libname, sizeof (ret[j].path));
ret[j].size = libsz;
ret[j].last = 0;
j = j+1;
//printf("0x%08llx -> %i -> %s\n", liboff, libsz, libname);
}
ret[i].last = 1;
return ret;
}
void* r_bin_dyldcache_free(struct r_bin_dyldcache_obj_t* bin) {
if (!bin)
return NULL;
if (bin->b)
r_buf_free (bin->b);
free(bin);
return NULL;
}
struct r_bin_dyldcache_obj_t* r_bin_dyldcache_new(const char* file) {
struct r_bin_dyldcache_obj_t *bin;
ut8 *buf;
if (!(bin = malloc(sizeof(struct r_bin_dyldcache_obj_t))))
return NULL;
memset (bin, 0, sizeof (struct r_bin_dyldcache_obj_t));
bin->file = file;
if (!(buf = (ut8*)r_file_slurp(file, &bin->size)))
return r_bin_dyldcache_free(bin);
bin->b = r_buf_new();
if (!r_buf_set_bytes(bin->b, buf, bin->size))
return r_bin_dyldcache_free(bin);
free (buf);
if (!r_bin_dyldcache_init(bin))
return r_bin_dyldcache_free(bin);
return bin;
}

View File

@ -0,0 +1,28 @@
/* radare - GPL3 - Copyright 2009-2010 nibble<.ds@gmail.com> */
#include <r_types.h>
#include "mach0_specs.h"
#ifndef _INCLUDE_R_BIN_DYLDCACHE_H_
#define _INCLUDE_R_BIN_DYLDCACHE_H_
struct r_bin_dyldcache_obj_t {
const char *file;
int size;
int nlibs;
struct cache_header hdr;
struct r_buf_t* b;
};
struct r_bin_dyldcache_lib_t {
char path[1024];
int size;
struct r_buf_t *b;
int last;
};
struct r_bin_dyldcache_lib_t *r_bin_dyldcache_extract(struct r_bin_dyldcache_obj_t* bin);
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);
#endif

View File

@ -34,7 +34,7 @@ struct r_bin_fatmach0_arch_t *r_bin_fatmach0_extract(struct r_bin_fatmach0_obj_t
int i;
if (bin->hdr.nfat_arch < 0)
return R_FALSE;
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) {

View File

@ -1747,4 +1747,17 @@ struct fat_arch {
uint32_t align;
};
/* Cache header */
struct cache_header {
char version[16];
uint32_t baseaddroff;
uint32_t unk2;
uint32_t startaddr;
uint32_t numlibs;
uint64_t dyldaddr;
//uint64_t codesignoff;
};
#endif /* _MACHO_LOADER_H_ */

View File

@ -0,0 +1,60 @@
/* radare - GPL3 - Copyright 2009-2010 nibble<.ds@gmail.com> */
#include <r_types.h>
#include <r_util.h>
#include <r_lib.h>
#include <r_bin.h>
#include "mach0/dyldcache.h"
static int check(RBin *bin) {
ut8 *filebuf;
int size, ret = R_FALSE;
filebuf = (ut8*)r_file_slurp_range (bin->file, 0, 4, &size);
if (filebuf && size == 4) {
if (!memcmp (filebuf, "\x64\x79\x6c\x64", 4))
ret = R_TRUE;
free (filebuf);
}
return ret;
}
static int destroy(RBin *bin) {
r_bin_dyldcache_free ((struct r_bin_dyldcache_obj_t*)bin->bin_obj);
return R_TRUE;
}
static int extract(RBin *bin) {
struct r_bin_dyldcache_lib_t *libs;
int i;
if(!(bin->bin_obj = r_bin_dyldcache_new(bin->file)))
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;
}
struct r_bin_xtr_plugin_t r_bin_xtr_plugin_dyldcache = {
.name = "dyldcache",
.desc = "dyld cache bin extractor plugin",
.init = NULL,
.fini = NULL,
.check = &check,
.extract = &extract,
.destroy = &destroy,
};
#ifndef CORELIB
struct r_lib_struct_t radare_plugin = {
.type = R_LIB_TYPE_BIN_XTR,
.data = &r_bin_xtr_plugin_dyldcache
};
#endif

View File

@ -43,7 +43,7 @@ static int extract(RBin *bin) {
if (!archs)
return 0;
for (i = 0; !archs[i].last; i++) {
bin->arch[i].file = bin->file;
bin->arch[i].file = strdup (bin->file);
bin->arch[i].buf = archs[i].b;
bin->arch[i].size = archs[i].size;
}

10
libr/bin/p/dyldcache.mk Normal file
View File

@ -0,0 +1,10 @@
OBJ_DYLDCACHE=bin_xtr_dyldcache.o ../format/mach0/dyldcache.o
STATIC_OBJ+=${OBJ_DYLDCACHE}
TARGET_DYLDCACHE=bin_xtr_dyldcache.${EXT_SO}
ALL_TARGETS+=${TARGET_DYLDCACHE}
${TARGET_DYLDCACHE}: ${OBJ_DYLDCACHE}
${CC} -shared ${CFLAGS} -o ${TARGET_DYLDCACHE} ${OBJ_DYLDCACHE}
@#strip -s ${TARGET_DYLDCACHE}

View File

@ -20,10 +20,10 @@
#define R_BIN_DBG_RELOCS(x) x & 0x10
#define R_BIN_SIZEOF_STRINGS 256
#define R_BIN_MAX_ARCH 32
#define R_BIN_MAX_ARCH 1024
typedef struct r_bin_arch_t {
const char *file;
char *file;
int size;
ut64 baddr;
struct r_bin_addr_t *main;
@ -225,6 +225,7 @@ extern RBinPlugin r_bin_plugin_mach064;
extern RBinPlugin r_bin_plugin_java;
extern RBinPlugin r_bin_plugin_dummy;
extern RBinXtrPlugin r_bin_xtr_plugin_fatmach0;
extern RBinXtrPlugin r_bin_xtr_plugin_dyldcache;
#endif
#endif

View File

@ -23,6 +23,7 @@ bin.pe64
bin.mach0
bin.mach064
bin_xtr.fatmach0
bin_xtr.dyldcache
bp.arm
bp.x86
bp.mips