* Initial dex-files format support

This commit is contained in:
earada 2011-04-28 01:54:54 +02:00
parent fad6bc0886
commit ee7fefb41f
6 changed files with 290 additions and 1 deletions

77
libr/bin/format/dex/dex.c Normal file
View File

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

63
libr/bin/format/dex/dex.h Normal file
View File

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

View File

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

138
libr/bin/p/bin_dex.c Normal file
View File

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

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

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

View File

@ -29,6 +29,7 @@ anal.ppc
bin.elf
bin.elf64
bin.java
bin.dex
bin.pe
bin.pe64
bin.mach0