diff --git a/libr/anal/p/anal_dalvik.c b/libr/anal/p/anal_dalvik.c index 424c1d13d5..ab3854a633 100644 --- a/libr/anal/p/anal_dalvik.c +++ b/libr/anal/p/anal_dalvik.c @@ -8,9 +8,7 @@ #include "../../asm/arch/dalvik/opcode.h" static int dalvik_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int len) { - int sz = 1; - - sz = dalvik_opcodes[data[0]].len; + int sz = dalvik_opcodes[data[0]].len; if (op == NULL) return sz; @@ -274,12 +272,20 @@ static int dalvik_op(RAnal *anal, RAnalOp *op, ut64 addr, const ut8 *data, int l case 0xb8: // invokestatic case 0xb6: // invokevirtual case 0x6e: // invoke-virtual - case 0xef: // execute-inline/range case 0xf0: // invoke-object-init-range case 0xf9: // invoke-virtual-quick/range case 0xfb: // invoke-super-quick/range + { + ut32 vB = (data[3]<<8) | data[2]; + op->jump = anal->binb.get_offset ( + anal->binb.bin, 'm', vB); + op->fail = addr + sz; + op->type = R_ANAL_OP_TYPE_CALL; + } + break; case 0x27: // throw case 0xee: // execute-inline + case 0xef: // execute-inline/range case 0xed: // throw-verification-error op->type = R_ANAL_OP_TYPE_SWI; break; diff --git a/libr/asm/p/asm_dalvik.c b/libr/asm/p/asm_dalvik.c index 645b167f3b..484d47e77a 100644 --- a/libr/asm/p/asm_dalvik.c +++ b/libr/asm/p/asm_dalvik.c @@ -337,16 +337,17 @@ static int dalvik_disassemble (RAsm *a, RAsmOp *op, const ut8 *buf, int len) { vC = (buf[5]<<8) | buf[4]; if (buf[0] == 0x25) { // filled-new-array/range offset = R_ASM_GET_OFFSET(a, 'c', vB); - if (offset == -1) + if (offset == UT64_MAX) sprintf (str, " {v%i..v%i}, class+%i", vC, vC+vA-1, vB); else sprintf (str, " {v%i..v%i}, 0x%"PFMT64x, vC, vC+vA-1, offset); } else { offset = R_ASM_GET_OFFSET(a, 'm', vB); - if (offset == -1) + if (offset == UT64_MAX) sprintf (str, " {v%i..v%i}, method+%i", vC, vC+vA-1, vB); - else + else { sprintf (str, " {v%i..v%i}, 0x%"PFMT64x, vC, vC+vA-1, offset); + } } strasm = r_str_concat (strasm, str); break; @@ -374,16 +375,18 @@ static int dalvik_disassemble (RAsm *a, RAsmOp *op, const ut8 *buf, int len) { strasm = r_str_concat (strasm, str); if (buf[0] == 0x24) { // filled-new-array offset = R_ASM_GET_OFFSET(a, 'c', vB); - if (offset == -1) + if (offset == UT64_MAX) { sprintf (str, ", class+%i", vB); - else + } else { sprintf (str, ", 0x%"PFMT64x" ; 0x%x", offset, vB); + } } else { offset = R_ASM_GET_OFFSET(a, 'm', vB); - if (offset == -1) + if (offset == UT64_MAX) { sprintf (str, ", method+%i", vB); - else + } else { sprintf (str, ", 0x%"PFMT64x" ; 0x%x", offset, vB); + } } strasm = r_str_concat (strasm, str); diff --git a/libr/asm/p/dalvik.mk b/libr/asm/p/dalvik.mk index 7686bb091f..d1b0a96736 100644 --- a/libr/asm/p/dalvik.mk +++ b/libr/asm/p/dalvik.mk @@ -6,4 +6,5 @@ TARGET_DALVIK=asm_dalvik.${EXT_SO} ALL_TARGETS+=${TARGET_DALVIK} ${TARGET_DALVIK}: ${OBJ_DALVIK} - ${CC} $(call libname,asm_dalvik) ${LDFLAGS} -I../arch/dalvik ${CFLAGS} -o asm_dalvik.${EXT_SO} ${OBJ_DALVIK} + ${CC} $(call libname,asm_dalvik) ${LDFLAGS} \ + -I../arch/dalvik ${CFLAGS} -o asm_dalvik.${EXT_SO} ${OBJ_DALVIK} diff --git a/libr/bin/bin.c b/libr/bin/bin.c index c414d1adcc..c64f80a118 100644 --- a/libr/bin/bin.c +++ b/libr/bin/bin.c @@ -1612,11 +1612,9 @@ R_API RBinObject *r_bin_get_object(RBin *bin) { return o; } - R_API RList* /**/r_bin_get_classes(RBin *bin) { RBinObject *o = r_bin_cur_object (bin); - if (o) - return o->classes; + if (o) return o->classes; return NULL; } @@ -1626,7 +1624,6 @@ R_API RBinClass *r_bin_class_new (RBinFile *binfile, const char *name, const cha RBinClass *c; if (!o) return NULL; - list = o->classes; if (!name) return NULL; c = r_bin_class_get (binfile, name); diff --git a/libr/bin/p/bin_dex.c b/libr/bin/p/bin_dex.c index f4dd18a4b0..0bb68afc95 100644 --- a/libr/bin/p/bin_dex.c +++ b/libr/bin/p/bin_dex.c @@ -16,6 +16,8 @@ #define dprintf if (0)eprintf #endif +static Sdb *mdb= NULL; + static int check(RBinFile *arch); static int check_bytes(const ut8 *buf, ut64 length); @@ -233,7 +235,7 @@ static char *getstr (RBinDexObj *bin, int idx) { buf2 = r_uleb128 (buf, sizeof (buf), &len); uleblen = (size_t)(buf2 - buf); if (len>0 && len < R_BIN_SIZEOF_STRINGS) { - char *str = malloc (len+1); + char *str = calloc (1, len+1); if (!str) return NULL; r_buf_read_at (bin->b, (bin->strings[idx])+uleblen, (ut8*)str, len); //uleblen); @@ -253,7 +255,15 @@ static char *get_string (RBinDexObj *bin, int cid, int idx) { return NULL; c_name = getstr (bin, cid); m_name = getstr (bin, idx); - res = r_str_newf ("%s.%s", c_name, m_name); + if (c_name && *c_name==',') { + res = r_str_newf ("%s", m_name); + } else { + if (c_name && m_name) { + res = r_str_newf ("%s.%s", c_name, m_name); + } else { + res = r_str_newf ("UNKNOWN"); + } + } free (c_name); free (m_name); return res; @@ -273,6 +283,18 @@ static char *dex_method_name (RBinDexObj *bin, int idx) { return get_string (bin, cid, tid); } +static char *dex_class_name_byid (RBinDexObj *bin, int cid) { + int tid; + if (!bin || !bin->types) + return NULL; + //cid = c->super_class; + if (cid<0 || cid >= bin->header.types_size) + return NULL; + tid = bin->types [cid].descriptor_id; + //int sid = bin->strings[tid]; + return get_string (bin, cid, tid); +} + static char *dex_class_name (RBinDexObj *bin, RBinDexClass *c) { int cid, tid; if (!bin || !c || !bin->types) @@ -451,6 +473,11 @@ encoded_catch_handler_list handlers #endif sym->paddr += 0x10; r_list_append (bin->methods_list, sym); + /* cache in sdb */ + if (!mdb) { + mdb = sdb_new0 (); + } + sdb_num_set (mdb, sdb_fmt(0, "method.%d", MI), sym->paddr, 0); } else { //r_list_append (bin->methods_list, sym); // XXX memleak sym @@ -564,6 +591,7 @@ static RList* methods (RBinFile *arch) { return bin->methods_list; } +// wtf? static void __r_bin_class_free(RBinClass *p) { r_bin_class_free (p); } @@ -571,11 +599,11 @@ static void __r_bin_class_free(RBinClass *p) { static RList* classes (RBinFile *arch) { struct r_bin_dex_obj_t *bin = (struct r_bin_dex_obj_t *) arch->o->bin_obj; struct dex_class_t entry; + const int len = 100; RList *ret = NULL; + char *name = NULL; RBinClass *class; int i; - const int len = 100; - char *name = NULL; if (bin->header.class_size>bin->size) { eprintf ("Too many classes %d\n", bin->header.class_size); @@ -585,10 +613,9 @@ static RList* classes (RBinFile *arch) { return NULL; ret->free = (RListFree)__r_bin_class_free; for (i = 0; i < bin->header.class_size; i++) { + ut64 class_addr = (ut64) bin->header.class_offset + (sizeof (struct dex_class_t)*i); // ETOOSLOW - r_buf_read_at (bin->b, (ut64) bin->header.class_offset - + (sizeof (struct dex_class_t)*i), (ut8*)&entry, - sizeof (struct dex_class_t)); + r_buf_read_at (bin->b, class_addr, (ut8*)&entry, sizeof (struct dex_class_t)); // TODO: implement sections.. each section specifies a class boundary { free (name); @@ -614,10 +641,12 @@ static RList* classes (RBinFile *arch) { class = R_NEW0 (RBinClass); // get source file name (ClassName.java) // TODO: use RConstr here - class->name = strdup (name[0]<0x41? name+1: name); - class->index = entry.class_id; + //class->name = strdup (name[0]<0x41? name+1: name); + class->name = dex_class_name_byid (bin, entry.class_id); + class->index = entry.class_id + bin->header.class_offset; +// find reference to this class instance + //class->addr = class_addr; r_list_append (ret, class); - 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); @@ -651,16 +680,36 @@ static RList* entries(RBinFile *arch) { return ret; } -//TODO +static ut64 offset_of_method_idx(RBinFile *arch, struct r_bin_dex_obj_t *dex, int idx) { + int off = dex->header.method_offset +idx; + //(sizeof (struct dex_method_t)*idx); + const char *name = dex_method_name (dex, idx); + //eprintf ("idx=%d off=%d (%s)\n", idx, off, name); + //off = sdb_num_get (mdb, name, NULL); + off = sdb_num_get (mdb, sdb_fmt(0, "method.%d", idx), 0); + //p = r_uleb128 (p, p_end-p, &MI); + // READ CODE + return off; +} + +//TODO must return ut64 imho static int getoffset (RBinFile *arch, int type, int idx) { struct r_bin_dex_obj_t *dex = arch->o->bin_obj; switch (type) { case 'm': // methods - if (dex->header.method_size > idx) - return dex->header.method_offset + - (sizeof (struct dex_method_t)*idx); + //if (dex->header.method_size > idx) + // return offset_of_method_idx (arch, dex, idx); + return offset_of_method_idx (arch, dex, idx); break; case 'c': // class + if (dex->header.class_size > idx) { + int off = dex->header.class_offset +idx; + //(sizeof (struct dex_class_t)*idx); + //const char *name = dex_class_name_byid (dex, idx); + //eprintf ("idx=%d off=%d (%s)\n", idx, off, name); + //p = r_uleb128 (p, p_end-p, &MI); + return off; + } break; case 'f': // fields if (dex->header.fields_size > idx) diff --git a/libr/core/bin.c b/libr/core/bin.c index 8222257366..fb545423f1 100644 --- a/libr/core/bin.c +++ b/libr/core/bin.c @@ -1449,19 +1449,30 @@ static int bin_classes (RCore *r, int mode) { iter->p?",":"", c->name, c->index); } r_cons_printf ("]"); - } else - if (mode & R_CORE_BIN_SIMPLE) { + } else if (mode & R_CORE_BIN_SIMPLE) { r_list_foreach (cs, iter, c) { r_cons_printf ("0x%08"PFMT64x" %s %s\n", c->index, c->name, c->super?c->super:""); } - } else - if (mode & R_CORE_BIN_SET) { + } else if (mode & R_CORE_BIN_SET) { // Nothing to set. - } else { + r_flag_space_set (r->flags, "classes"); r_list_foreach (cs, iter, c) { + char str[R_FLAG_NAME_SIZE+1]; + char *name = strdup (c->name); + ut64 addr = c->index; //c->addr? c->addr : c->index; + r_name_filter (name, 0); + snprintf (str, R_FLAG_NAME_SIZE, "class.%s", name); + r_flag_set (r->flags, str, addr, 1, 0); + } + } else { + r_cons_printf ("fs classes\n"); + r_list_foreach (cs, iter, c) { + char *name = strdup (c->name); + ut64 addr = c->index; //c->addr? c->addr : c->index; + r_name_filter (name, 0); if (mode) { - r_cons_printf ("f class.%s @ %d\n", c->name, c->index); + r_cons_printf ("f class.%s @ 0x%"PFMT64x"\n", name, addr); if (c->super) r_cons_printf ("f super.%s.%s @ %d\n", c->name, c->super, c->index); r_list_foreach (c->methods, iter2, methname) { @@ -1476,6 +1487,7 @@ static int bin_classes (RCore *r, int mode) { } } // TODO: show belonging methods and fields + free (name); } } return R_TRUE; @@ -1538,7 +1550,8 @@ static void bin_mem_print (RList *mems, int perms, int depth) { if (mem) { for (i=0; i < depth; i++) r_cons_printf (" "); - r_cons_printf ("%8s addr=0x%016"PFMT64x" size=%6d perms=[%s]\n", mem->name, mem->addr, mem->size, r_str_rwx_i (mem->perms & perms)); + r_cons_printf ("%8s addr=0x%016"PFMT64x" size=%6d perms=[%s]\n", + mem->name, mem->addr, mem->size, r_str_rwx_i (mem->perms & perms)); if (mem->mirrors) bin_mem_print (mem->mirrors, (mem->perms & perms), (depth + 1)); //sorry, but anything else would be inefficient } diff --git a/libr/debug/p/debug_native.c b/libr/debug/p/debug_native.c index b329db2f89..94bc1d4b39 100644 --- a/libr/debug/p/debug_native.c +++ b/libr/debug/p/debug_native.c @@ -970,6 +970,7 @@ eprintf ("++ EFL = 0x%08x %d\n", ctx.EFlags, r_offsetof (CONTEXT, EFlags)); unsigned int inferior_thread_count = 0; R_DEBUG_REG_T *regs = (R_DEBUG_REG_T*)buf; unsigned int gp_count = R_DEBUG_STATE_SZ; //sizeof (R_DEBUG_REG_T); + int tid = dbg->tid; #if 0 // if uncommented, it will break x86-32 debugging from x86-64 (ios simulator f.ex) diff --git a/libr/include/r_bin.h b/libr/include/r_bin.h index 42584a3116..5bdba59e71 100644 --- a/libr/include/r_bin.h +++ b/libr/include/r_bin.h @@ -274,6 +274,7 @@ typedef struct r_bin_class_t { char *super; char *visibility_str; int index; + //ut64 addr; RList *methods; // RList *fields; // int visibility;