* 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:
parent
e02c81ddf1
commit
987d8599f9
|
@ -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() {
|
||||
|
|
|
@ -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 ();
|
||||
|
|
|
@ -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;
|
||||
}
|
|
@ -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
|
|
@ -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) {
|
||||
|
|
|
@ -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_ */
|
||||
|
|
|
@ -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
|
|
@ -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;
|
||||
}
|
||||
|
|
|
@ -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}
|
|
@ -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
|
||||
|
|
|
@ -23,6 +23,7 @@ bin.pe64
|
|||
bin.mach0
|
||||
bin.mach064
|
||||
bin_xtr.fatmach0
|
||||
bin_xtr.dyldcache
|
||||
bp.arm
|
||||
bp.x86
|
||||
bp.mips
|
||||
|
|
Loading…
Reference in New Issue