Rewrite DEX parser

This commit is contained in:
pancake 2013-04-25 03:42:17 +02:00
parent 870696bbde
commit 26a7854dd6
12 changed files with 396 additions and 140 deletions

View File

@ -293,6 +293,10 @@ int main(int argc, char **argv) {
}
}
if (!r_core_bin_load (&r, file)) {
RBinObject *obj = r_bin_get_object (r.bin);
eprintf ("bits %d\n", obj->info->bits);
}
fh = r_core_file_open (&r, file, perms, mapaddr);
if (fh != NULL) {
//const char *arch = r_config_get (r.config, "asm.arch");

View File

@ -136,3 +136,6 @@ ilo ni li pona li pali e lipu. mi wile e ni: sina kama jo e musi
Radare for FideOS, now with extra potato
Your project name should contain an uppercase letter, 8 vowels, some numbers and the 5 first numbers of your private bitcoin key
This computer has gone to sleep
Did you ever ordered a pizza using radare2?
I thought we were friends. :_
Welcome back, lazy human!

View File

@ -87,7 +87,7 @@ static int dalvik_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int l
*/
case 0x27: // throw
case 0xed: // throw-verification-error
op->type = R_ANAL_OP_TYPE_TRAP;
op->type = R_ANAL_OP_TYPE_SWI;
break;
case 0x00: // nop
op->type = R_ANAL_OP_TYPE_NOP;

View File

@ -1,4 +1,4 @@
/* radare - LGPL - Copyright 2009-2012 nibble<.ds@gmail.com> */
/* radare - LGPL - Copyright 2009-2013 - nibble */
#include <r_types.h>
#include <r_util.h>

View File

@ -11,25 +11,36 @@ char* r_bin_dex_get_version(struct r_bin_dex_obj_t* bin) {
}
struct r_bin_dex_obj_t* r_bin_dex_new_buf(RBuffer *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));
struct r_bin_dex_obj_t *bin = R_NEW0 (struct r_bin_dex_obj_t);;
if (!bin) return NULL;
bin->b = buf;
bin->size = buf->length;
// XXX: use r_buf_getc()
// XXX: this is not endian safe
/* header */
r_buf_read_at (bin->b, 0, (ut8*)&bin->header, sizeof (struct dex_header_t));
/* strings */
bin->strings = (ut32 *) malloc (bin->header.strings_size * sizeof (ut32) + 1);
r_buf_read_at (bin->b, bin->header.strings_offset, (ut8*)bin->strings,
bin->header.strings_size * sizeof (ut32));
/* classes */
bin->classes = (struct dex_class_t *) malloc (bin->header.class_size *
sizeof (struct dex_class_t) + 1);
r_buf_read_at (bin->b, bin->header.class_offset, (ut8*)bin->classes,
bin->header.class_size * sizeof (struct dex_class_t));
//{ ut8 *b = (ut8*)&bin->methods; eprintf ("CLASS %02x %02x %02x %02x\n", b[0], b[1], b[2], b[3]); }
/* methods */
bin->methods = (struct dex_method_t *) malloc (bin->header.method_size *
sizeof (struct dex_method_t) + 1);
r_buf_read_at (bin->b, bin->header.method_offset, (ut8*)bin->methods,
bin->header.method_size * sizeof (struct dex_method_t));
/* types */
bin->types = (struct dex_type_t *) malloc (bin->header.types_size *
sizeof (struct dex_type_t) + 1);
r_buf_read_at (bin->b, bin->header.types_offset, (ut8*)bin->types,
bin->header.types_size * sizeof (struct dex_type_t));
/* fields */
bin->fields = (struct dex_field_t *) malloc (bin->header.fields_size *
sizeof (struct dex_field_t) + 1);
r_buf_read_at (bin->b, bin->header.fields_offset, (ut8*)bin->fields,

View File

@ -2,7 +2,7 @@
#define R_BIN_DEX_MAXSTR 256
#pragma pack(1)
#pragma pack(4)
struct dex_header_t {
ut8 magic[8];
ut32 checksum;
@ -29,17 +29,21 @@ struct dex_header_t {
ut32 data_offset;
};
#pragma pack(1)
#pragma pack(4)
struct dex_proto_t {
ut32 shorty_id;
ut32 return_type_id;
ut32 params_id;
};
#pragma pack(1)
struct dex_type_t {
ut32 descriptor_id;
};
#pragma pack(4)
struct dex_field_t {
ut8 class_id;
ut8 type_id;
ut16 class_id;
ut16 type_id;
ut32 name_id;
};
@ -51,15 +55,15 @@ struct dex_method_t {
};
#endif
#pragma pack(1)
struct dex_method_t {
typedef struct dex_method_t {
ut16 class_id;
ut16 proto_id;
ut32 name_id;
};
} RBinDexMethod;
#pragma pack(1)
struct dex_class_t {
ut32 class_id;
typedef struct dex_class_t {
ut32 class_id; // index into typeids
ut32 access_flags;
ut32 super_class;
ut32 interfaces_offset;
@ -67,24 +71,29 @@ struct dex_class_t {
ut32 anotations_offset;
ut32 class_data_offset;
ut32 static_values_offset;
};
} RBinDexClass;
struct r_bin_dex_obj_t {
typedef struct r_bin_dex_obj_t {
int size;
const char *file;
struct r_buf_t *b;
struct dex_header_t header;
ut32 *strings;
struct dex_class_t *classes;
struct dex_method_t *methods;
struct dex_type_t *types;
struct dex_field_t *fields;
RList *methods_list;
};
RList *imports_list;
ut64 code_from;
ut64 code_to;
} RBinDexObj;
struct r_bin_dex_str_t {
char str[R_BIN_DEX_MAXSTR];
ut64 offset;
ut64 ordinal;
ut64 size;
int size;
int last;
};

View File

@ -8,16 +8,63 @@
#define r_hash_adler32 __adler32
#include "../../hash/adler32.c"
#define DEBUG_PRINTF 0
#if DEBUG_PRINTF
#define dprintf eprintf
#else
#define dprintf //
#endif
static int load(RBinArch *arch) {
if(!(arch->bin_obj = r_bin_dex_new_buf (arch->buf)))
return R_FALSE;
return R_TRUE;
arch->bin_obj = r_bin_dex_new_buf (arch->buf);
return arch->bin_obj ? R_TRUE: R_FALSE;
}
static ut64 baddr(RBinArch *arch) {
return 0;
}
static char *flagname (const char *class, const char *method) {
char *p, *str, *s = malloc (strlen (class) + strlen (method)+2);
str = s;
p = r_str_lchr (class, '$');
if (!p) p = r_str_lchr (class, '/');
//eprintf ("D=%d (%s)\n", p, p?p:".");
p = r_str_rchr (class, p, '/');
#if 1
//if (!p) p = class; else p--;
//if (p) p = r_str_lchr (p, '/');
//eprintf ("P=%d\n", p);
#if 0
if (!p) {
char *q = r_str_lchr (p-1, '/');
if (q) p = q;
}
#endif
if (p) class = p+1;
#endif
//eprintf ("NAME (%s)\n", class);
for (str=s; *class; class++) {
switch (*class) {
case '$':
case '/': *s++ = '_'; break;
case ';': *s++ = '.'; break;
default: *s++ = *class; break;
}
}
for (*s++='.'; *method; method++) {
switch (*method) {
case '<': case '>':
case '/': *s++ = '_'; break;
case ';': *s++ = '.'; break;
default: *s++ = *method; break;
}
}
*s = 0;
return str;
}
static int check(RBinArch *arch) {
if (!arch->buf || !arch->buf->buf)
return R_FALSE;
@ -41,7 +88,7 @@ static int check(RBinArch *arch) {
static RBinInfo *info(RBinArch *arch) {
char *version;
RBinHash *h;
RBinHash *h;
RBinInfo *ret = R_NEW0 (RBinInfo);
if (!ret) return NULL;
strncpy (ret->file, arch->file, R_BIN_SIZEOF_STRINGS);
@ -52,10 +99,9 @@ RBinHash *h;
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);
strcpy (ret->os, "linux");
strcpy (ret->subsystem, "any");
strcpy (ret->machine, "Dalvik VM");
h = &ret->sum[0];
h->type = "sha1";
@ -75,17 +121,18 @@ RBinHash *h;
{
ut32 *fc = (ut32 *)(arch->buf->buf + 8);
ut32 cc = __adler32 (arch->buf->buf + h->from, h->to);
ut8 *fb = (ut8*)fc, *cb = (ut8*)&cc;
//ut8 *fb = (ut8*)fc, *cb = (ut8*)&cc;
if (*fc != cc) {
eprintf ("# adler32 checksum doesn't match. Type this to fix it:\n");
eprintf ("wx `#sha1 $s-32 @32` @12 ; wx `#adler32 $s-12 @12` @8\n");
dprintf ("# adler32 checksum doesn't match. Type this to fix it:\n");
dprintf ("wx `#sha1 $s-32 @32` @12 ; wx `#adler32 $s-12 @12` @8\n");
}
}
strcpy (ret->arch, "dalvik");
ret->lang = "java";
ret->bits = 32;
ret->big_endian = 0;
ret->dbg_info = 1 | 4 | 8; /* Stripped | LineNums | Syms */
ret->dbg_info = 0; //1 | 4 | 8; /* Stripped | LineNums | Syms */
return ret;
}
@ -108,12 +155,12 @@ static RList* strings (RBinArch *arch) {
if (len>0 && len < R_BIN_SIZEOF_STRINGS) {
r_buf_read_at (bin->b, bin->strings[i]+dex_uleb128_len (buf),
(ut8*)&ptr->string, len);
ptr->string[(int) len]='\0';
ptr->string[(int) len+1]='\0';
ptr->rva = ptr->offset = bin->strings[i];
ptr->size = len;
ptr->ordinal = i+1;
r_list_append (ret, ptr);
} //else eprintf ("dex_read_uleb128: invalid read\n");
} //else dprintf ("dex_read_uleb128: invalid read\n");
}
return ret;
}
@ -140,94 +187,248 @@ static ut32 getmethodoffset (struct r_bin_dex_obj_t *bin, int n, ut32 *size) {
return off;
}
static RList* methods (RBinArch *arch) {
struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj;
static char *get_string (struct r_bin_dex_obj_t *bin, int idx) {
char buf[128], *buf2;
int len, uleblen;
r_buf_read_at (bin->b, bin->strings[idx], (ut8*)&buf, 8);
len = dex_read_uleb128 (buf);
buf2 = r_uleb128 (buf, &len);
uleblen = (size_t)(buf2 - buf);
// XXX what about 0 length strings?
if (len>0 && len < R_BIN_SIZEOF_STRINGS) {
char *str = malloc (len+1);
if (!str) return NULL;
r_buf_read_at (bin->b, (bin->strings[idx])+uleblen,
(ut8*)str, len+uleblen);
str[len] = 0;
return str;
}
return NULL;
}
/* TODO: check boundaries */
static char *dex_method_name (RBinDexObj *bin, int idx) {
int tid, sid;
if (idx<0 || idx>bin->header.method_size)
return NULL;
tid = bin->methods[idx].name_id;
if (tid<0 || tid>bin->header.strings_size)
return NULL;
sid = bin->strings[tid];
return get_string (bin, tid);
}
static char *dex_class_name (RBinDexObj *bin, RBinDexClass *c) {
int cid = c->class_id;
int tid = bin->types [cid].descriptor_id;
int sid = bin->strings[tid];
return get_string (bin, tid);
}
static char *dex_class_super_name (RBinDexObj *bin, RBinDexClass *c) {
int cid = c->super_class;
int tid = bin->types [cid].descriptor_id;
int sid = bin->strings[tid];
return get_string (bin, tid);
}
static int dex_loadcode(RBinArch *arch, RBinDexObj *bin) {
int *methods;
int i, j, len, left;
char *name, *buf;
RList *ret = NULL;
RBinSymbol *ptr;
ut8 *p;
// doublecheck??
if (bin->methods_list)
return bin->methods_list;
return R_FALSE;
bin->code_from = UT64_MAX;
bin->code_to = 0;
bin->methods_list = r_list_new ();
bin->methods_list->free = free;
bin->imports_list = r_list_new ();
bin->imports_list->free = free;
methods = malloc (sizeof (int) * bin->header.method_size);
for (i=0;i<bin->header.method_size;i++) { methods[i] = 0; }
dprintf ("Walking %d classes\n", bin->header.class_size);
for (i=0; i<bin->header.class_size; i++) {
struct dex_class_t *c = &bin->classes[i];
char *super_name = dex_class_super_name (bin, c);
char *class_name = dex_class_name (bin, c);
dprintf ("{\n");
dprintf (" class: %d,\n", c->class_id); // indexed by ordinal
dprintf (" super: \"%s\",\n", super_name); // indexed by name
dprintf (" name: \"%s\",\n", class_name);
dprintf (" methods: [\n");
// sdb_queryf ("(-1)classes=%s", class_name)
// sdb_queryf ("class.%s.super=%s", super_name)
// sdb_queryf ("class.%s.methods=%d", class_name, DM);
p = r_buf_get_at (arch->buf, c->class_data_offset, NULL);
/* data header */
{
int SF, IF, DM, VM;
p = r_uleb128 (p, &SF);
p = r_uleb128 (p, &IF);
p = r_uleb128 (p, &DM);
p = r_uleb128 (p, &VM);
dprintf (" static fields: %d\n", SF);
/* static fields */
for (j=0; j<SF; j++) {
int FI, FA;
p = r_uleb128 (p, &FI);
p = r_uleb128 (p, &FA);
dprintf (" field_idx: %d\n", FI);
dprintf (" field access_flags: %d\n", FA);
}
/* instance fields */
dprintf (" instance fields: %d\n", IF);
for (j=0; j<IF; j++) {
int FI, FA;
p = r_uleb128 (p, &FI);
p = r_uleb128 (p, &FA);
dprintf (" field_idx: %d,\n", FI);
dprintf (" field access_flags: %d,\n", FA);
}
/* direct methods */
dprintf (" direct methods: %d\n", DM);
for (j=0; j<DM; j++) {
char *method_name, *flag_name;
int MI, MA, MC;
p = r_uleb128 (p, &MI);
p = r_uleb128 (p, &MA);
p = r_uleb128 (p, &MC);
if (MI>=0&&MI<bin->header.method_size) methods[MI] = 1;
if (MC>0 && bin->code_from>MC) bin->code_from = MC;
if (MC>0 && bin->code_to<MC) bin->code_to = MC;
method_name = dex_method_name (bin, MI);
dprintf ("METHOD NAME %d\n", MI);
if (!method_name) method_name = strdup ("unknown");
flag_name = flagname (class_name, method_name);
dprintf ("f %s @ 0x%x\n", flag_name, MC);
dprintf (" { name: %s,\n", method_name);
dprintf (" idx: %d,\n", MI);
dprintf (" access_flags: 0x%x,\n", MA);
dprintf (" code_offset: 0x%x },\n", MC);
/* add symbol */
{
RBinSymbol *sym = R_NEW0 (RBinSymbol);
strncpy (sym->name, flag_name, R_BIN_SIZEOF_STRINGS);
strcpy (sym->type, "FUNC");
sym->offset = sym->rva = MC;
r_list_append (bin->methods_list, sym);
}
free (method_name);
free (flag_name);
}
/* virtual methods */
dprintf (" virtual methods: %d\n", VM);
for (j=0; j<VM; j++) {
char *name, *flag;
int MI, MA, MC;
p = r_uleb128 (p, &MI);
p = r_uleb128 (p, &MA);
p = r_uleb128 (p, &MC);
if (MI>=0&&MI<bin->header.method_size) methods[MI] = 1;
if (bin->code_from>MC) bin->code_from = MC;
if (bin->code_to<MC) bin->code_to = MC;
name = dex_method_name (bin, MI);
dprintf (" method name: %s\n", name);
dprintf (" method_idx: %d\n", MI);
dprintf (" method access_flags: %d\n", MA);
dprintf (" method code_offset: %d\n", MC);
free (name);
}
}
dprintf (" ],\n");
dprintf ("},");
free (class_name);
free (super_name);
}
dprintf ("imports: \n");
for (i = 0; i<bin->header.method_size; i++) {
RBinDexMethod *method = &bin->methods[i];
if (!methods[i]) {
char *method_name = dex_method_name (bin, i);
dprintf ("import %d (%s)\n", i, method_name);
{
RBinSymbol *sym = R_NEW0 (RBinSymbol);
strncpy (sym->name, method_name, R_BIN_SIZEOF_STRINGS);
strcpy (sym->type, "FUNC");
sym->offset = sym->rva = 0; // UNKNOWN
r_list_append (bin->imports_list, sym);
}
free (method_name);
}
}
free (methods);
return R_TRUE;
}
static RList* imports (RBinArch *arch) {
RBinDexObj *bin = (RBinDexObj*) arch->bin_obj;
if (bin->imports_list)
return bin->imports_list;
dex_loadcode (arch, bin);
return bin->imports_list;
#if 0
struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj;
int i;
RList *ret = NULL;
RBinImport *ptr;
if (!(ret = r_list_new ()))
return NULL;
ret->free = free;
eprintf ("Loading %d methods... ", bin->header.method_size);
dprintf ("Importing %d methods... \n", bin->header.method_size);
for (i = 0; i<bin->header.method_size; i++) {
int idx = bin->methods[i].name_id;
if (!(ptr = R_NEW (RBinSymbol)))
if (!(ptr = R_NEW (RBinImport)))
break;
if (idx >= bin->header.strings_size) // workaround
continue;
buf = (char*)r_buf_get_at (bin->b, bin->strings[idx], &left);
len = dex_read_uleb128 (buf);
if (len<1) continue;
name = (char *) r_buf_get_at (bin->b,
bin->strings[bin->methods[i].name_id]+
dex_uleb128_len (buf), &left);
if (!name) {
eprintf ("string index out of range\n");
char *methodname = get_string (bin, bin->methods[i].name_id);
char *classname = get_string (bin, bin->methods[i].class_id);
//char *typename = get_string (bin, bin->methods[i].type_id);
dprintf ("----> %d\n", bin->methods[i].name_id);
if (!methodname) {
dprintf ("string index out of range\n");
break;
}
if (len > left) {
eprintf ("string length reaches out of file\n");
len = left; // workaround
//break;
}
snprintf (ptr->name, sizeof (ptr->name), "method.%d.%.*s",
bin->methods[i].class_id, len, name);
strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS);
strncpy (ptr->bind, "NONE", R_BIN_SIZEOF_STRINGS);
snprintf (ptr->name, sizeof (ptr->name), "import.%s.%s",
classname, methodname);
ptr->ordinal = i+1;
ptr->size = 0;
ptr->rva = ptr->offset = getmethodoffset (bin,
(int)ptr->ordinal, (ut32*)&ptr->size);
strncpy (ptr->type, ptr->rva? "FUNC":"IMPORT", R_BIN_SIZEOF_STRINGS);
r_list_append (ret, ptr);
}
eprintf ("Done\n");
j = i;
eprintf ("Loading %d fields... ", bin->header.fields_size);
for (i = 0; i<bin->header.fields_size; i++) {
int idx = bin->fields[i].name_id;
if (!(ptr = R_NEW (RBinSymbol)))
break;
if (idx >= bin->header.strings_size) // workaround
continue;
buf = (char*)r_buf_get_at (bin->b, bin->strings[idx], &left);
//r_buf_read_at (bin->b, bin->strings[idx], (ut8*)&buf, 6);
// TODO: use r_buf_get_at here
len = dex_read_uleb128 (buf);
name = (char *)r_buf_get_at (bin->b,
bin->strings[bin->methods[i].name_id]+
dex_uleb128_len (buf), &left);
if (!name) {
eprintf ("string index out of range\n");
break;
}
if (len > left) {
eprintf ("string length reaches out of file\n");
len = left; // workaround
//break;
}
//r_buf_read_at (bin->b, bin->strings[bin->fields[i].name_id]+
// dex_uleb128_len (buf), (ut8*)name, len);
snprintf (ptr->name, sizeof (ptr->name), "field.%d.%.*s",
bin->fields[i].class_id, len, name);
//free (name);
strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS);
dprintf ("____%s__%s____ (%d) %llx\n", classname,
methodname, bin->methods[i].name_id, ptr->rva);
free (classname);
free (methodname);
//strncpy (ptr->forwarder, "NONE", R_BIN_SIZEOF_STRINGS);
strncpy (ptr->bind, "NONE", R_BIN_SIZEOF_STRINGS);
strncpy (ptr->type, "FUNC", R_BIN_SIZEOF_STRINGS);
ptr->rva = ptr->offset = bin->header.fields_offset +
(sizeof (struct dex_field_t) * i);
ptr->size = sizeof (struct dex_field_t);
ptr->ordinal = j+i+1;
if (ptr->rva) {
free (ptr);
continue;
}
strncpy (ptr->type, "IMPORT", R_BIN_SIZEOF_STRINGS);
r_list_append (ret, ptr);
}
eprintf ("Done\n");
bin->methods_list = ret;
dprintf ("Done\n");
return ret;
#endif
}
static RList* methods (RBinArch *arch) {
RBinDexObj *bin = (RBinDexObj*) arch->bin_obj;
if (bin->methods_list)
return bin->methods_list;
dex_loadcode (arch, bin);
return bin->methods_list;
}
static void __r_bin_class_free(RBinClass *p) {
@ -255,7 +456,7 @@ static RList* classes (RBinArch *arch) {
len = 100;
name = malloc (len);
if (!name) {
eprintf ("error malloc string length %d\n", len);
dprintf ("error malloc string length %d\n", len);
break;
}
if (entry.source_file> bin->header.strings_size || entry.source_file<0)
@ -267,16 +468,15 @@ static RList* classes (RBinArch *arch) {
class->name = strdup (name[0]<0x41? name+1: name); // TODO: use RConstr here
class->index = entry.class_id;
r_list_append (ret, class);
#if VERBOSE
eprintf ("class.%s=%d\n", name[0]==12?name+1:name, entry.class_id);
eprintf ("# access_flags = %x;\n", entry.access_flags);
eprintf ("# super_class = %d;\n", entry.super_class);
eprintf ("# interfaces_offset = %08x;\n", entry.interfaces_offset);
//eprintf ("ut32 source_file = %08x;\n", entry.source_file);
eprintf ("# anotations_offset = %08x;\n", entry.anotations_offset);
eprintf ("# class_data_offset = %08x;\n", entry.class_data_offset);
eprintf ("# static_values_offset = %08x;\n\n", entry.static_values_offset);
#endif
dprintf ("class.%s=%d\n", name[0]==12?name+1:name, entry.class_id);
dprintf ("# access_flags = %x;\n", entry.access_flags);
dprintf ("# super_class = %d;\n", entry.super_class);
dprintf ("# interfaces_offset = %08x;\n", entry.interfaces_offset);
//dprintf ("ut32 source_file = %08x;\n", entry.source_file);
dprintf ("# anotations_offset = %08x;\n", entry.anotations_offset);
dprintf ("# class_data_offset = %08x;\n", entry.class_data_offset);
dprintf ("# static_values_offset = %08x;\n\n", entry.static_values_offset);
free (name);
}
}
@ -284,11 +484,21 @@ static RList* classes (RBinArch *arch) {
}
static RList* entries(RBinArch *arch) {
struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->bin_obj;
RBinAddr *ptr = R_NEW0 (RBinAddr);
RListIter *iter;
RBinDexObj *bin = (RBinDexObj*) arch->bin_obj;
RList *ret = r_list_new ();
ptr->offset = ptr->rva = bin->header.method_offset;
r_list_append (ret, ptr);
RBinAddr *ptr = R_NEW0 (RBinAddr);
RBinSymbol *m;
if (!bin->methods_list)
dex_loadcode (arch, bin);
// XXX: entry + main???
r_list_foreach (bin->methods_list, iter, m) {
if (strlen (m->name)>=4 && !strcmp (m->name+strlen (m->name)-4, "main")) {
dprintf ("ENTRY -> %s\n", m->name);
ptr->offset = ptr->rva = m->offset;
r_list_append (ret, ptr);
}
}
return ret;
}
@ -298,13 +508,15 @@ static int getoffset (RBinArch *arch, int type, int idx) {
switch (type) {
case 'm': // methods
if (dex->header.method_size > idx)
return dex->header.method_offset+(sizeof (struct dex_method_t)*idx);
return dex->header.method_offset +
(sizeof (struct dex_method_t)*idx);
break;
case 'c': // class
break;
case 'f': // fields
if (dex->header.fields_size > idx)
return dex->header.fields_offset+(sizeof (struct dex_field_t)*idx);
return dex->header.fields_offset +
(sizeof (struct dex_field_t)*idx);
break;
case 'o': // objects
break;
@ -319,16 +531,15 @@ static int getoffset (RBinArch *arch, int type, int idx) {
}
static RList* sections(RBinArch *arch) {
struct r_bin_java_sym_t *s = NULL;
struct r_bin_dex_obj_t *bin = arch->bin_obj;
RList *ml = methods (arch);
RBinSection *ptr = NULL;
int ns, fsymsz = 0;
RList *ret = NULL;
RListIter *iter;
RBinSymbol *m;
int fsym = 0;
RList *ml;
ml = methods (arch);
r_list_foreach (ml, iter, m) {
if (fsym == 0 || m->offset<fsym)
fsym = m->offset;
@ -345,8 +556,8 @@ static RList* sections(RBinArch *arch) {
ret->free = free;
if ((ptr = R_NEW0 (RBinSection))) {
strcpy (ptr->name, "code");
ptr->size = ptr->vsize = fsymsz;
ptr->offset = ptr->rva = fsym;
ptr->size = bin->code_to-bin->code_from; //ptr->vsize = fsymsz;
ptr->offset = bin->code_from; //ptr->rva = fsym;
ptr->srwx = 4|1;
r_list_append (ret, ptr);
}
@ -365,13 +576,12 @@ static RList* sections(RBinArch *arch) {
} else {
ptr->size = ptr->vsize = ptr->rva - arch->buf->length;
// hacky workaround
eprintf ("Hack\n");
dprintf ("Hack\n");
//ptr->size = ptr->vsize = 1024;
}
ptr->srwx = 4; //|2;
r_list_append (ret, ptr);
}
free (s);
return ret;
}
@ -389,7 +599,7 @@ struct r_bin_plugin_t r_bin_plugin_dex = {
.classes = classes,
.sections = sections,
.symbols = methods,
.imports = NULL,
.imports = imports,
.strings = strings,
.info = &info,
.fields = NULL,

View File

@ -19,7 +19,7 @@
#define R_BIN_DBG_SYMS(x) x & 0x08
#define R_BIN_DBG_RELOCS(x) x & 0x10
#define R_BIN_SIZEOF_STRINGS 256
#define R_BIN_SIZEOF_STRINGS 512
#define R_BIN_MAX_ARCH 1024
enum {

View File

@ -13,9 +13,9 @@
#include <r_util.h>
#include <r_list.h>
#define R_FLAG_NAME_SIZE 128
#define R_FLAG_BUF_SIZE 128
#define R_FLAG_SPACES_MAX 128
#define R_FLAG_NAME_SIZE 256
#define R_FLAG_BUF_SIZE 256
#define R_FLAG_SPACES_MAX 256
typedef struct r_flag_item_t {
char name[R_FLAG_NAME_SIZE];

View File

@ -326,6 +326,7 @@ R_API int r_base64_decode(ut8 *bout, const ut8 *bin, int len);
/* strings */
#define r_str_array(x,y) ((y>=0 && y<(sizeof(x)/sizeof(*x)))?x[y]:"")
R_API const char *r_str_rchr(const char *base, const char *p, int ch);
R_API void r_str_unescape (char *s);
R_API int r_str_len_utf8 (const char *s);
R_API void r_str_filter_zeroline(char *str, int len);
@ -372,6 +373,7 @@ R_API int r_str_ccmp(const char *dst, const char *orig, int ch);
R_API int r_str_cmp(const char *dst, const char *orig, int len);
R_API int r_str_ccpy(char *dst, char *orig, int ch);
R_API const char *r_str_get(const char *str);
R_API char *r_str_ndup(const char *ptr, int len);
R_API char *r_str_dup(char *ptr, const char *string);
R_API char *r_str_dup_printf(const char *fmt, ...);
R_API void *r_str_free(void *ptr);

View File

@ -310,13 +310,23 @@ R_API char *r_str_ichr(char *str, char chr) {
// find last char
R_API char *r_str_lchr(char *str, char chr) {
int len = strlen (str)+1;
for (;len>=0;len--)
if (str[len]==chr)
return str+len;
if (str) {
int len = strlen (str);
for (;len>=0;len--)
if (str[len]==chr)
return str+len;
}
return NULL;
}
R_API const char *r_str_rchr(const char *base, const char *p, int ch) {
if (!base||!p) return NULL;
for (; p>base; p--)
if (ch == *p)
break;
return p;
}
R_API int r_str_nchr(const char *str, char chr) {
int n;
for (n = 0; *str; str++)
@ -475,6 +485,13 @@ R_API const char *r_str_get(const char *str) {
return str;
}
R_API char *r_str_ndup(const char *ptr, int len) {
char *out = malloc (len+1);
memcpy (out, ptr, len);
out[len] = 0;
return out;
}
R_API char *r_str_dup(char *ptr, const char *string) {
if (ptr) free (ptr);
if (!string) return NULL;

View File

@ -5,9 +5,9 @@
R_API const ut8 *r_uleb128 (const ut8 *data, ut32 *v) {
ut8 c;
ut32 s, sum;
for (s = sum = 0; ; s+= 7) {
for (s = sum = 0; ; s += 7) {
c = *(data++) & 0xff;
sum |= ((ut32) (c&0x7f)<<s);
sum |= ((ut32) (c&0x7f) << s);
if (!(c&0x80)) break;
}
if (v) *v = sum;
@ -17,7 +17,7 @@ R_API const ut8 *r_uleb128 (const ut8 *data, ut32 *v) {
R_API const ut8 *r_leb128 (const ut8 *data, st32 *v) {
ut8 c;
st32 s, sum;
for (s = sum = 0; ; s+= 7) {
for (s = sum = 0; ; s+= 7) {
c = *data++ & 0x0ff;
sum |= ((st32) ((*data++) & 0x7f) << s);
if (!(c&0x80)) break;