* 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() {
|
static void rabin_list_archs() {
|
||||||
|
RBinInfo *info;
|
||||||
int i;
|
int i;
|
||||||
|
|
||||||
for (i=0; i<bin->narch; i++)
|
for (i=0; i<bin->narch; i++) {
|
||||||
printf ("%s_%i %s (%s endian)\n", bin->arch[i].info->arch,
|
bin->curarch = &bin->arch[i];
|
||||||
bin->arch[i].info->bits, bin->arch[i].info->machine,
|
if ((info = r_bin_get_info (bin)) == NULL)
|
||||||
bin->arch[i].info->big_endian?"big":"litle");
|
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() {
|
static int rabin_show_fields() {
|
||||||
|
|
|
@ -125,6 +125,8 @@ static void r_bin_free_items(RBinArch *arch) {
|
||||||
r_list_free (arch->symbols);
|
r_list_free (arch->symbols);
|
||||||
if (arch->main)
|
if (arch->main)
|
||||||
free (arch->main);
|
free (arch->main);
|
||||||
|
if (arch->file)
|
||||||
|
free (arch->file);
|
||||||
}
|
}
|
||||||
|
|
||||||
static int r_bin_extract(RBin *bin, const char* 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)
|
if (bin->curxtr && bin->curxtr->extract)
|
||||||
n = bin->curxtr->extract (bin);
|
n = bin->curxtr->extract (bin);
|
||||||
else {
|
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)))
|
if (!(buf = (ut8*)r_file_slurp (bin->file, &bin->arch[0].size)))
|
||||||
return 0;
|
return 0;
|
||||||
bin->arch[0].buf = r_buf_new ();
|
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;
|
int i;
|
||||||
|
|
||||||
if (bin->hdr.nfat_arch < 0)
|
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));
|
ret = malloc ((bin->hdr.nfat_arch+1) * sizeof(struct r_bin_fatmach0_arch_t));
|
||||||
for (i = 0; i < bin->hdr.nfat_arch; i++) {
|
for (i = 0; i < bin->hdr.nfat_arch; i++) {
|
||||||
if (bin->archs[i].size == 0 || bin->archs[i].size > bin->size) {
|
if (bin->archs[i].size == 0 || bin->archs[i].size > bin->size) {
|
||||||
|
|
|
@ -1747,4 +1747,17 @@ struct fat_arch {
|
||||||
uint32_t align;
|
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_ */
|
#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)
|
if (!archs)
|
||||||
return 0;
|
return 0;
|
||||||
for (i = 0; !archs[i].last; i++) {
|
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].buf = archs[i].b;
|
||||||
bin->arch[i].size = archs[i].size;
|
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_DBG_RELOCS(x) x & 0x10
|
||||||
|
|
||||||
#define R_BIN_SIZEOF_STRINGS 256
|
#define R_BIN_SIZEOF_STRINGS 256
|
||||||
#define R_BIN_MAX_ARCH 32
|
#define R_BIN_MAX_ARCH 1024
|
||||||
|
|
||||||
typedef struct r_bin_arch_t {
|
typedef struct r_bin_arch_t {
|
||||||
const char *file;
|
char *file;
|
||||||
int size;
|
int size;
|
||||||
ut64 baddr;
|
ut64 baddr;
|
||||||
struct r_bin_addr_t *main;
|
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_java;
|
||||||
extern RBinPlugin r_bin_plugin_dummy;
|
extern RBinPlugin r_bin_plugin_dummy;
|
||||||
extern RBinXtrPlugin r_bin_xtr_plugin_fatmach0;
|
extern RBinXtrPlugin r_bin_xtr_plugin_fatmach0;
|
||||||
|
extern RBinXtrPlugin r_bin_xtr_plugin_dyldcache;
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -23,6 +23,7 @@ bin.pe64
|
||||||
bin.mach0
|
bin.mach0
|
||||||
bin.mach064
|
bin.mach064
|
||||||
bin_xtr.fatmach0
|
bin_xtr.fatmach0
|
||||||
|
bin_xtr.dyldcache
|
||||||
bp.arm
|
bp.arm
|
||||||
bp.x86
|
bp.x86
|
||||||
bp.mips
|
bp.mips
|
||||||
|
|
Loading…
Reference in New Issue