* Initial dex-files format support
This commit is contained in:
parent
fad6bc0886
commit
ee7fefb41f
|
@ -0,0 +1,77 @@
|
|||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include "dex.h"
|
||||
|
||||
char* r_bin_dex_get_version(struct r_bin_dex_obj_t* bin) {
|
||||
char *version = malloc (8);
|
||||
|
||||
memset (version, 0, 8);
|
||||
memcpy (version, bin->b->buf+4, 3);
|
||||
return version;
|
||||
}
|
||||
|
||||
struct r_bin_dex_obj_t* r_bin_dex_new_buf(struct r_buf_t *buf) {
|
||||
struct r_bin_dex_obj_t *bin;
|
||||
|
||||
if (!(bin = malloc(sizeof(struct r_bin_dex_obj_t))))
|
||||
return NULL;
|
||||
memset (bin, 0, sizeof (struct r_bin_dex_obj_t));
|
||||
bin->b = buf;
|
||||
bin->size = buf->length;
|
||||
r_buf_read_at(bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t));
|
||||
return bin;
|
||||
}
|
||||
|
||||
// Move to r_util ??
|
||||
int dex_read_uleb128 (const char *ptr) {
|
||||
int cur, result = *(ptr++);
|
||||
|
||||
if (result > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result = (result & 0x7f) | ((cur & 0x7f) << 7);
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 14;
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 21;
|
||||
if (cur > 0x7f) {
|
||||
cur = *(ptr++);
|
||||
result |= cur << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
#define SIG_EXTEND(X,Y) X = (X << Y) >> Y
|
||||
int dex_read_sleb128 (const char *ptr) {
|
||||
int cur, result = *(ptr++);
|
||||
|
||||
if (result <= 0x7f) {
|
||||
SIG_EXTEND (result, 25);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result = (result & 0x7f) | ((cur & 0x7f) << 7);
|
||||
if (cur <= 0x7f) {
|
||||
SIG_EXTEND (result, 18);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 14;
|
||||
if (cur <= 0x7f) {
|
||||
SIG_EXTEND (result, 11);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= (cur & 0x7f) << 21;
|
||||
if (cur <= 0x7f) {
|
||||
SIG_EXTEND (result, 4);
|
||||
} else {
|
||||
cur = *(ptr++);
|
||||
result |= cur << 28;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
|
@ -0,0 +1,63 @@
|
|||
#include <r_types.h>
|
||||
|
||||
#define R_BIN_DEX_MAXSTR 256
|
||||
|
||||
struct dex_header_t {
|
||||
ut8 magic[8];
|
||||
ut32 checksum;
|
||||
ut8 signature[20];
|
||||
ut32 size;
|
||||
ut32 header_size;
|
||||
ut32 endian;
|
||||
ut32 linksection_size;
|
||||
ut32 linksection_offset;
|
||||
ut32 map_offset;
|
||||
ut32 strings_size;
|
||||
ut32 strings_offset;
|
||||
ut32 types_size;
|
||||
ut32 types_offset;
|
||||
ut32 prototypes_size;
|
||||
ut32 prototypes_offset;
|
||||
ut32 fields_size;
|
||||
ut32 fields_offset;
|
||||
ut32 method_size;
|
||||
ut32 method_offset;
|
||||
ut32 class_size;
|
||||
ut32 class_offset;
|
||||
ut32 data_size;
|
||||
ut32 data_offset;
|
||||
};
|
||||
|
||||
struct dex_class_t {
|
||||
ut32 class_id;
|
||||
ut32 access_flags;
|
||||
ut32 super_class;
|
||||
ut32 interfaces_offset;
|
||||
ut32 source_file;
|
||||
ut32 anotations_offset;
|
||||
ut32 class_data_offset;
|
||||
ut32 static_values_offset;
|
||||
};
|
||||
|
||||
struct r_bin_dex_obj_t {
|
||||
int size;
|
||||
const char* file;
|
||||
struct r_buf_t* b;
|
||||
struct dex_header_t header;
|
||||
};
|
||||
|
||||
struct r_bin_dex_str_t {
|
||||
char str[R_BIN_DEX_MAXSTR];
|
||||
ut64 offset;
|
||||
ut64 ordinal;
|
||||
ut64 size;
|
||||
int last;
|
||||
};
|
||||
|
||||
char* r_bin_dex_get_version(struct r_bin_dex_obj_t* bin);
|
||||
struct r_bin_dex_obj_t* r_bin_dex_new_buf(struct r_buf_t *buf);
|
||||
struct r_bin_dex_str_t *r_bin_dex_get_strings (struct r_bin_dex_obj_t* bin);
|
||||
|
||||
|
||||
int dex_read_uleb128 (const char *ptr);
|
||||
int dex_read_sleb128 (const char *ptr);
|
|
@ -9,7 +9,7 @@ CFLAGS+=-L../../util -lr_util
|
|||
foo: all
|
||||
|
||||
ALL_TARGETS=
|
||||
FORMATS=elf.mk elf64.mk pe.mk pe64.mk mach0.mk mach064.mk fatmach0.mk dyldcache.mk java.mk
|
||||
FORMATS=elf.mk elf64.mk pe.mk pe64.mk mach0.mk mach064.mk fatmach0.mk dyldcache.mk java.mk dex.mk
|
||||
include $(FORMATS)
|
||||
|
||||
all: ${ALL_TARGETS}
|
||||
|
|
|
@ -0,0 +1,138 @@
|
|||
/* radare - LGPL - Copyright 2011 pancake<nopcode.org> */
|
||||
|
||||
#include <r_types.h>
|
||||
#include <r_util.h>
|
||||
#include <r_lib.h>
|
||||
#include <r_bin.h>
|
||||
#include "dex/dex.h"
|
||||
|
||||
static int load(RBinArch *arch) {
|
||||
if(!(arch->bin_obj = r_bin_dex_new_buf(arch->buf)))
|
||||
return R_FALSE;
|
||||
return R_TRUE;
|
||||
}
|
||||
|
||||
static ut64 baddr(RBinArch *arch) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int check(RBinArch *arch) {
|
||||
if (!memcmp (arch->buf->buf, "dex\n035\0", 8))
|
||||
return R_TRUE;
|
||||
else if (!memcmp (arch->buf->buf, "dex\n009\0", 8)) // M3 (Nov-Dec 07)
|
||||
return R_TRUE;
|
||||
else if (!memcmp (arch->buf->buf, "dex\n009\0", 8)) // M5 (Feb-Mar 08)
|
||||
return R_TRUE;
|
||||
return R_FALSE;
|
||||
}
|
||||
|
||||
static RBinInfo * info(RBinArch *arch) {
|
||||
RBinInfo *ret = NULL;
|
||||
char *version;
|
||||
|
||||
if (!(ret = R_NEW (RBinInfo)))
|
||||
return NULL;
|
||||
memset (ret, '\0', sizeof (RBinInfo));
|
||||
strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS);
|
||||
strncpy (ret->rpath, "NONE", R_BIN_SIZEOF_STRINGS);
|
||||
strncpy (ret->type, "DEX CLASS", R_BIN_SIZEOF_STRINGS);
|
||||
version = r_bin_dex_get_version (arch->bin_obj);
|
||||
strncpy (ret->bclass, version, R_BIN_SIZEOF_STRINGS);
|
||||
free (version);
|
||||
strncpy (ret->rclass, "class", R_BIN_SIZEOF_STRINGS);
|
||||
strncpy (ret->os, "linux", R_BIN_SIZEOF_STRINGS);
|
||||
strncpy (ret->subsystem, "any", R_BIN_SIZEOF_STRINGS);
|
||||
strncpy (ret->machine, "Dalvik VM", R_BIN_SIZEOF_STRINGS);
|
||||
strncpy (ret->arch, "dalvik", R_BIN_SIZEOF_STRINGS);
|
||||
ret->bits = 32;
|
||||
ret->big_endian= 0;
|
||||
ret->dbg_info = 4 | 8; /* LineNums | Syms */
|
||||
return ret;
|
||||
}
|
||||
|
||||
static RList* strings(RBinArch *arch) {
|
||||
RList *ret = NULL;
|
||||
RBinString *ptr = NULL;
|
||||
struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj;
|
||||
ut32 i, *string;
|
||||
char len, buf[6];
|
||||
|
||||
string = (ut32 *) malloc (bin->header.strings_size * sizeof (ut32));
|
||||
r_buf_read_at(bin->b, bin->header.strings_offset, (ut8*)string,
|
||||
bin->header.strings_size * sizeof (ut32));
|
||||
if (!(ret = r_list_new ()))
|
||||
return NULL;
|
||||
ret->free = free;
|
||||
for (i = 0; i < bin->header.strings_size; i++) {
|
||||
if (!(ptr = R_NEW (RBinString)))
|
||||
break;
|
||||
r_buf_read_at (bin->b, string[i], (ut8*)&buf, 6);
|
||||
len = dex_read_uleb128 (buf);
|
||||
if (len >= R_BIN_SIZEOF_STRINGS)
|
||||
len = R_BIN_SIZEOF_STRINGS-1;
|
||||
r_buf_read_at(bin->b, string[i]+1, (ut8*)&ptr->string, len);
|
||||
ptr->string[(int) len]='\0';
|
||||
ptr->rva = ptr->offset = string[i]+1;
|
||||
ptr->size = len;
|
||||
ptr->ordinal = i+1;
|
||||
r_list_append (ret, ptr);
|
||||
}
|
||||
free (string);
|
||||
return ret;
|
||||
}
|
||||
|
||||
//TODO
|
||||
static RList* classes (RBinArch *arch) {
|
||||
RList *ret = NULL;
|
||||
RBinAddr *ptr = NULL;
|
||||
struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj;
|
||||
struct dex_class_t entry;
|
||||
int i;
|
||||
|
||||
if (!(ret = r_list_new ()))
|
||||
return NULL;
|
||||
ret->free = free;
|
||||
for (i = 0; i < bin->header.class_size; i++) {
|
||||
r_buf_read_at(bin->b, bin->header.class_offset, (ut8*)&entry,
|
||||
bin->header.class_size * sizeof (struct dex_class_t));
|
||||
eprintf ("ut32 class_id = %08x;\n", entry.class_id);
|
||||
eprintf ("ut32 access_flags = %08x;\n", entry.access_flags);
|
||||
eprintf ("ut32 super_class = %08x;\n", entry.super_class);
|
||||
eprintf ("ut32 interfaces_offset = %08x;\n", entry.interfaces_offset);
|
||||
eprintf ("ut32 source_file = %08x;\n", entry.source_file);
|
||||
eprintf ("ut32 anotations_offset = %08x;\n", entry.anotations_offset);
|
||||
eprintf ("ut32 class_data_offset = %08x;\n", entry.class_data_offset);
|
||||
eprintf ("ut32 static_values_offset = %08x;\n", entry.static_values_offset);
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
struct r_bin_plugin_t r_bin_plugin_dex = {
|
||||
.name = "dex",
|
||||
.desc = "dex format bin plugin",
|
||||
.init = NULL,
|
||||
.fini = NULL,
|
||||
.load = &load,
|
||||
.destroy = NULL,
|
||||
.check = &check,
|
||||
.baddr = &baddr,
|
||||
.binsym = NULL,
|
||||
.entries = &classes,
|
||||
.sections = NULL,
|
||||
.symbols = NULL,
|
||||
.imports = NULL,
|
||||
.strings = &strings,
|
||||
.info = &info,
|
||||
.fields = NULL,
|
||||
.libs = NULL,
|
||||
.relocs = NULL,
|
||||
.meta = NULL,
|
||||
.write = NULL,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
struct r_lib_struct_t radare_plugin = {
|
||||
.type = R_LIB_TYPE_BIN,
|
||||
.data = &r_bin_plugin_dex
|
||||
};
|
||||
#endif
|
|
@ -0,0 +1,10 @@
|
|||
OBJ_DEX=bin_dex.o ../format/dex/dex.o
|
||||
|
||||
STATIC_OBJ+=${OBJ_DEX}
|
||||
TARGET_DEX=bin_dex.${EXT_SO}
|
||||
|
||||
ALL_TARGETS+=${TARGET_DEX}
|
||||
|
||||
${TARGET_DEX}: ${OBJ_DEX}
|
||||
${CC} -shared ${CFLAGS} -o ${TARGET_DEX} ${OBJ_DEX}
|
||||
@#strip -s ${TARGET_DEX}
|
|
@ -29,6 +29,7 @@ anal.ppc
|
|||
bin.elf
|
||||
bin.elf64
|
||||
bin.java
|
||||
bin.dex
|
||||
bin.pe
|
||||
bin.pe64
|
||||
bin.mach0
|
||||
|
|
Loading…
Reference in New Issue