mirror of
https://github.com/radareorg/radare2.git
synced 2025-01-13 09:11:49 +00:00
Enhance icj, ic and id in Dex (#7821)
This commit is contained in:
parent
5418e99fcf
commit
1c772a9672
@ -93,6 +93,7 @@ typedef struct r_bin_dex_obj_t {
|
||||
RList *methods_list;
|
||||
RList *imports_list;
|
||||
RList *classes_list;
|
||||
RList *lines_list;
|
||||
ut64 code_from;
|
||||
ut64 code_to;
|
||||
Sdb *kv;
|
||||
|
@ -31,7 +31,7 @@ extern struct r_bin_dbginfo_t r_bin_dbginfo_dex;
|
||||
static bool dexdump = false;
|
||||
static Sdb *mdb = NULL;
|
||||
|
||||
static void set_method_flags(RBinSymbol *sym, ut64 MA);
|
||||
static ut64 get_method_flags(ut64 MA);
|
||||
|
||||
static char *getstr(RBinDexObj *bin, int idx) {
|
||||
ut8 buf[6];
|
||||
@ -318,6 +318,7 @@ static void dex_parse_debug_item(RBinFile *binfile, RBinDexObj *bin,
|
||||
int insns_size, char *class_name, int regsz,
|
||||
int debug_info_off) {
|
||||
struct r_bin_t *rbin = binfile->rbin;
|
||||
struct r_bin_dex_obj_t *dex = binfile->o->bin_obj;
|
||||
const ut8 *p4 = r_buf_get_at (binfile->buf, debug_info_off, NULL);
|
||||
const ut8 *p4_end = p4 + binfile->buf->length - debug_info_off;
|
||||
ut64 line_start;
|
||||
@ -596,6 +597,14 @@ static void dex_parse_debug_item(RBinFile *binfile, RBinDexObj *bin,
|
||||
offset_ptr = sdb_itoa (pos->address + paddr, offset, 16);
|
||||
sdb_set (binfile->sdb_addrinfo, offset_ptr, fileline, 0);
|
||||
sdb_set (binfile->sdb_addrinfo, fileline, offset_ptr, 0);
|
||||
RBinDwarfRow *rbindwardrow = R_NEW0 (RBinDwarfRow);
|
||||
if (!rbindwardrow) {
|
||||
return;
|
||||
}
|
||||
rbindwardrow->file = strdup (getstr (bin, pos->source_file_idx));
|
||||
rbindwardrow->address = pos->address;
|
||||
rbindwardrow->line = pos->line;
|
||||
r_list_append (dex->lines_list, rbindwardrow);
|
||||
}
|
||||
|
||||
if (!dexdump) {
|
||||
@ -969,6 +978,9 @@ static const ut8 *parse_dex_class_fields(RBinFile *binfile, RBinDexObj *bin,
|
||||
tid = bin->types[field.type_id].descriptor_id;
|
||||
type_str = getstr (bin, tid);
|
||||
RBinSymbol *sym = R_NEW0 (RBinSymbol);
|
||||
if (!sym) {
|
||||
return NULL;
|
||||
}
|
||||
if (is_sfield) {
|
||||
sym->name = r_str_newf ("%s.sfield_%s:%s", cls->name,
|
||||
fieldName, type_str);
|
||||
@ -993,9 +1005,16 @@ static const ut8 *parse_dex_class_fields(RBinFile *binfile, RBinDexObj *bin,
|
||||
rbin->cb_printf (" access : 0x%04x (%s)\n",
|
||||
(unsigned int)accessFlags, accessStr);
|
||||
}
|
||||
|
||||
r_list_append (bin->methods_list, sym);
|
||||
r_list_append (cls->fields, sym);
|
||||
|
||||
RBinField *field = R_NEW0 (RBinField);
|
||||
if (!field) {
|
||||
return NULL;
|
||||
}
|
||||
field->vaddr = field->paddr = sym->paddr;
|
||||
field->name = strdup (sym->name);
|
||||
field->flags = get_method_flags (accessFlags);
|
||||
r_list_append (cls->fields, field);
|
||||
|
||||
lastIndex = fieldIndex;
|
||||
}
|
||||
@ -1201,6 +1220,9 @@ static const ut8 *parse_dex_class_method(RBinFile *binfile, RBinDexObj *bin,
|
||||
}
|
||||
if (*flag_name) {
|
||||
RBinSymbol *sym = R_NEW0 (RBinSymbol);
|
||||
if (!sym) {
|
||||
return NULL;
|
||||
}
|
||||
sym->name = flag_name;
|
||||
// is_direct is no longer used
|
||||
// if method has code *addr points to code
|
||||
@ -1220,7 +1242,7 @@ static const ut8 *parse_dex_class_method(RBinFile *binfile, RBinDexObj *bin,
|
||||
sym->bind = r_str_const ("LOCAL");
|
||||
}
|
||||
|
||||
set_method_flags (sym, MA);
|
||||
sym->method_flags = get_method_flags (MA);
|
||||
|
||||
sym->ordinal = (*sym_count)++;
|
||||
if (MC > 0) {
|
||||
@ -1297,52 +1319,54 @@ static const ut8 *parse_dex_class_method(RBinFile *binfile, RBinDexObj *bin,
|
||||
return p;
|
||||
}
|
||||
|
||||
static void set_method_flags(RBinSymbol * sym, ut64 MA) {
|
||||
static ut64 get_method_flags(ut64 MA) {
|
||||
ut64 flags = 0;
|
||||
if (MA & R_DEX_METH_PUBLIC) {
|
||||
sym->method_flags |= R_BIN_METH_PUBLIC;
|
||||
flags |= R_BIN_METH_PUBLIC;
|
||||
}
|
||||
if (MA & R_DEX_METH_PRIVATE) {
|
||||
sym->method_flags |= R_BIN_METH_PRIVATE;
|
||||
flags |= R_BIN_METH_PRIVATE;
|
||||
}
|
||||
if (MA & R_DEX_METH_PROTECTED) {
|
||||
sym->method_flags |= R_BIN_METH_PROTECTED;
|
||||
flags |= R_BIN_METH_PROTECTED;
|
||||
}
|
||||
if (MA & R_DEX_METH_STATIC) {
|
||||
sym->method_flags |= R_BIN_METH_STATIC;
|
||||
flags |= R_BIN_METH_STATIC;
|
||||
}
|
||||
if (MA & R_DEX_METH_FINAL) {
|
||||
sym->method_flags |= R_BIN_METH_FINAL;
|
||||
flags |= R_BIN_METH_FINAL;
|
||||
}
|
||||
if (MA & R_DEX_METH_SYNCHRONIZED) {
|
||||
sym->method_flags |= R_BIN_METH_SYNCHRONIZED;
|
||||
flags |= R_BIN_METH_SYNCHRONIZED;
|
||||
}
|
||||
if (MA & R_DEX_METH_BRIDGE) {
|
||||
sym->method_flags |= R_BIN_METH_BRIDGE;
|
||||
flags |= R_BIN_METH_BRIDGE;
|
||||
}
|
||||
if (MA & R_DEX_METH_VARARGS) {
|
||||
sym->method_flags |= R_BIN_METH_VARARGS;
|
||||
flags |= R_BIN_METH_VARARGS;
|
||||
}
|
||||
if (MA & R_DEX_METH_NATIVE) {
|
||||
sym->method_flags |= R_BIN_METH_NATIVE;
|
||||
flags |= R_BIN_METH_NATIVE;
|
||||
}
|
||||
if (MA & R_DEX_METH_ABSTRACT) {
|
||||
sym->method_flags |= R_BIN_METH_ABSTRACT;
|
||||
flags |= R_BIN_METH_ABSTRACT;
|
||||
}
|
||||
if (MA & R_DEX_METH_STRICT) {
|
||||
sym->method_flags |= R_BIN_METH_STRICT;
|
||||
flags |= R_BIN_METH_STRICT;
|
||||
}
|
||||
if (MA & R_DEX_METH_SYNTHETIC) {
|
||||
sym->method_flags |= R_BIN_METH_SYNTHETIC;
|
||||
flags |= R_BIN_METH_SYNTHETIC;
|
||||
}
|
||||
if (MA & R_DEX_METH_MIRANDA) {
|
||||
sym->method_flags |= R_BIN_METH_MIRANDA;
|
||||
flags |= R_BIN_METH_MIRANDA;
|
||||
}
|
||||
if (MA & R_DEX_METH_CONSTRUCTOR) {
|
||||
sym->method_flags |= R_BIN_METH_CONSTRUCTOR;
|
||||
flags |= R_BIN_METH_CONSTRUCTOR;
|
||||
}
|
||||
if (MA & R_DEX_METH_DECLARED_SYNCHRONIZED) {
|
||||
sym->method_flags |= R_BIN_METH_DECLARED_SYNCHRONIZED;
|
||||
flags |= R_BIN_METH_DECLARED_SYNCHRONIZED;
|
||||
}
|
||||
return flags;
|
||||
}
|
||||
|
||||
static void parse_class(RBinFile *binfile, RBinDexObj *bin, RBinDexClass *c,
|
||||
@ -1375,6 +1399,7 @@ static void parse_class(RBinFile *binfile, RBinDexObj *bin, RBinDexClass *c,
|
||||
cls->index = class_index;
|
||||
cls->addr = bin->header.class_offset + class_index * DEX_CLASS_SIZE;
|
||||
cls->methods = r_list_new ();
|
||||
cls->super = strdup (dex_class_super_name (bin, c));
|
||||
if (!cls->methods) {
|
||||
free (cls);
|
||||
return;
|
||||
@ -1522,9 +1547,15 @@ static int dex_loadcode(RBinFile *arch, RBinDexObj *bin) {
|
||||
r_list_free (bin->methods_list);
|
||||
return false;
|
||||
}
|
||||
bin->lines_list = r_list_newf ((RListFree)free);
|
||||
if (!bin->lines_list) {
|
||||
r_list_free (bin->lines_list);
|
||||
return false;
|
||||
}
|
||||
bin->classes_list = r_list_newf ((RListFree)r_bin_class_free);
|
||||
if (!bin->classes_list) {
|
||||
r_list_free (bin->methods_list);
|
||||
r_list_free (bin->lines_list);
|
||||
r_list_free (bin->imports_list);
|
||||
return false;
|
||||
}
|
||||
@ -1595,6 +1626,9 @@ static int dex_loadcode(RBinFile *arch, RBinDexObj *bin) {
|
||||
char *signature = dex_method_signature (bin, i);
|
||||
if (method_name && *method_name) {
|
||||
RBinImport *imp = R_NEW0 (RBinImport);
|
||||
if (!imp) {
|
||||
return false;
|
||||
}
|
||||
imp->name = r_str_newf ("%s.method.%s%s", class_name, method_name, signature);
|
||||
imp->type = r_str_const ("FUNC");
|
||||
imp->bind = r_str_const ("NONE");
|
||||
@ -1602,6 +1636,9 @@ static int dex_loadcode(RBinFile *arch, RBinDexObj *bin) {
|
||||
r_list_append (bin->imports_list, imp);
|
||||
|
||||
RBinSymbol *sym = R_NEW0 (RBinSymbol);
|
||||
if (!sym) {
|
||||
return false;
|
||||
}
|
||||
sym->name = r_str_newf ("imp.%s", imp->name);
|
||||
sym->type = r_str_const ("FUNC");
|
||||
sym->bind = r_str_const ("NONE");
|
||||
@ -1611,6 +1648,7 @@ static int dex_loadcode(RBinFile *arch, RBinDexObj *bin) {
|
||||
sym->ordinal = sym_count++;
|
||||
r_list_append (bin->methods_list, sym);
|
||||
sdb_num_set (mdb, sdb_fmt (0, "method.%d", i), sym->paddr, 0);
|
||||
|
||||
}
|
||||
free (signature);
|
||||
}
|
||||
@ -1893,6 +1931,11 @@ static ut64 size(RBinFile *arch) {
|
||||
return off + len;
|
||||
}
|
||||
|
||||
static RList *lines(RBinFile *arch) {
|
||||
struct r_bin_dex_obj_t *dex = arch->o->bin_obj;
|
||||
return r_list_clone (dex->lines_list);
|
||||
}
|
||||
|
||||
RBinPlugin r_bin_plugin_dex = {
|
||||
.name = "dex",
|
||||
.desc = "dex format bin plugin",
|
||||
@ -1914,6 +1957,7 @@ RBinPlugin r_bin_plugin_dex = {
|
||||
.get_offset = &getoffset,
|
||||
.get_name = &getname,
|
||||
.dbginfo = &r_bin_dbginfo_dex,
|
||||
.lines = &lines,
|
||||
};
|
||||
|
||||
#ifndef CORELIB
|
||||
|
@ -2264,9 +2264,10 @@ static int bin_fields(RCore *r, int mode, int va) {
|
||||
}
|
||||
|
||||
static int bin_classes(RCore *r, int mode) {
|
||||
RListIter *iter, *iter2;
|
||||
RListIter *iter, *iter2, *iter3;
|
||||
RBinSymbol *sym;
|
||||
RBinClass *c;
|
||||
RBinField *f;
|
||||
char *name;
|
||||
RList *cs = r_bin_get_classes (r->bin);
|
||||
if (!cs) {
|
||||
@ -2315,7 +2316,7 @@ static int bin_classes(RCore *r, int mode) {
|
||||
const char *classname = sdb_fmt (0, "class.%s", name);
|
||||
r_flag_set (r->flags, classname, c->addr, 1);
|
||||
r_list_foreach (c->methods, iter2, sym) {
|
||||
char *mflags = r_core_bin_method_flags_str (sym, mode);
|
||||
char *mflags = r_core_bin_method_flags_str (sym->method_flags, mode);
|
||||
char *method = sdb_fmt (1, "method%s.%s.%s",
|
||||
mflags, c->name, sym->name);
|
||||
R_FREE (mflags);
|
||||
@ -2334,7 +2335,7 @@ static int bin_classes(RCore *r, int mode) {
|
||||
c->name, c->super, c->index);
|
||||
}
|
||||
r_list_foreach (c->methods, iter2, sym) {
|
||||
char *mflags = r_core_bin_method_flags_str (sym, mode);
|
||||
char *mflags = r_core_bin_method_flags_str (sym->method_flags, mode);
|
||||
char *cmd = r_str_newf ("\"f method%s.%s.%s = 0x%"PFMT64x"\"\n", mflags, c->name, sym->name, sym->vaddr);
|
||||
r_str_replace_char (cmd, '\n', 0);
|
||||
r_cons_printf ("%s\n", cmd);
|
||||
@ -2353,7 +2354,7 @@ static int bin_classes(RCore *r, int mode) {
|
||||
}
|
||||
r_list_foreach (c->methods, iter2, sym) {
|
||||
if (sym->method_flags) {
|
||||
char *mflags = r_core_bin_method_flags_str (sym, mode);
|
||||
char *mflags = r_core_bin_method_flags_str (sym->method_flags, mode);
|
||||
r_cons_printf ("%s{\"name\":\"%s\",\"flags\":%s,\"addr\":%"PFMT64d"}",
|
||||
iter2->p? ",": "", sym->name, mflags, sym->vaddr);
|
||||
R_FREE (mflags);
|
||||
@ -2362,10 +2363,22 @@ static int bin_classes(RCore *r, int mode) {
|
||||
iter2->p? ",": "", sym->name, sym->vaddr);
|
||||
}
|
||||
}
|
||||
r_cons_printf ("], \"fields\":[");
|
||||
r_list_foreach (c->fields, iter3, f) {
|
||||
if (f->flags) {
|
||||
char *mflags = r_core_bin_method_flags_str (f->flags, mode);
|
||||
r_cons_printf ("%s{\"name\":\"%s\",\"flags\":%s,\"addr\":%"PFMT64d"}",
|
||||
iter3->p? ",": "", f->name, mflags, f->vaddr);
|
||||
R_FREE (mflags);
|
||||
} else {
|
||||
r_cons_printf ("%s{\"name\":\"%s\",\"addr\":%"PFMT64d"}",
|
||||
iter3->p? ",": "", f->name, f->vaddr);
|
||||
}
|
||||
}
|
||||
r_cons_printf ("]}");
|
||||
} else {
|
||||
int m = 0;
|
||||
r_cons_printf ("0x%08"PFMT64x" [0x%08"PFMT64x" - 0x%08"PFMT64x"] (sz %d) class %d %s",
|
||||
r_cons_printf ("0x%08"PFMT64x" [0x%08"PFMT64x" - 0x%08"PFMT64x"] (sz %"PFMT64d") class %d %s",
|
||||
c->addr, at_min, at_max, (at_max - at_min), c->index, c->name);
|
||||
if (c->super) {
|
||||
r_cons_printf (" super: %s\n", c->super);
|
||||
@ -2373,7 +2386,7 @@ static int bin_classes(RCore *r, int mode) {
|
||||
r_cons_newline ();
|
||||
}
|
||||
r_list_foreach (c->methods, iter2, sym) {
|
||||
char *mflags = r_core_bin_method_flags_str (sym, mode);
|
||||
char *mflags = r_core_bin_method_flags_str (sym->method_flags, mode);
|
||||
r_cons_printf ("0x%08"PFMT64x" method %d %s %s\n",
|
||||
sym->vaddr, m, mflags, sym->dname? sym->dname: sym->name);
|
||||
R_FREE (mflags);
|
||||
@ -3062,19 +3075,19 @@ R_API int r_core_bin_list(RCore *core, int mode) {
|
||||
return count;
|
||||
}
|
||||
|
||||
R_API char *r_core_bin_method_flags_str(RBinSymbol *sym, int mode) {
|
||||
R_API char *r_core_bin_method_flags_str(ut64 flags, int mode) {
|
||||
char *str;
|
||||
RStrBuf *buf;
|
||||
int i, len = 0;
|
||||
|
||||
buf = r_strbuf_new ("");
|
||||
if (IS_MODE_SET (mode) || IS_MODE_RAD (mode)) {
|
||||
if (!sym->method_flags) {
|
||||
if (!flags) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
for (i = 0; i != 64; i++) {
|
||||
ut64 flag = sym->method_flags & (1L << i);
|
||||
ut64 flag = flags & (1L << i);
|
||||
if (flag) {
|
||||
const char *flag_string = r_bin_get_meth_flag_string (flag, false);
|
||||
if (flag_string) {
|
||||
@ -3083,7 +3096,7 @@ R_API char *r_core_bin_method_flags_str(RBinSymbol *sym, int mode) {
|
||||
}
|
||||
}
|
||||
} else if (IS_MODE_JSON (mode)) {
|
||||
if (!sym->method_flags) {
|
||||
if (!flags) {
|
||||
r_strbuf_append (buf, "[]");
|
||||
goto out;
|
||||
}
|
||||
@ -3091,7 +3104,7 @@ R_API char *r_core_bin_method_flags_str(RBinSymbol *sym, int mode) {
|
||||
r_strbuf_append (buf, "[");
|
||||
|
||||
for (i = 0; i != 64; i++) {
|
||||
ut64 flag = sym->method_flags & (1L << i);
|
||||
ut64 flag = flags & (1L << i);
|
||||
if (flag) {
|
||||
const char *flag_string = r_bin_get_meth_flag_string (flag, false);
|
||||
|
||||
@ -3111,11 +3124,11 @@ R_API char *r_core_bin_method_flags_str(RBinSymbol *sym, int mode) {
|
||||
} else {
|
||||
int pad_len = 4; //TODO: move to a config variable
|
||||
|
||||
if (!sym->method_flags) {
|
||||
if (!flags) {
|
||||
goto padding;
|
||||
}
|
||||
for (i = 0; i != 64; i++) {
|
||||
ut64 flag = sym->method_flags & (1L << i);
|
||||
ut64 flag = flags & (1L << i);
|
||||
if (flag) {
|
||||
const char *flag_string = r_bin_get_meth_flag_string (flag, true);
|
||||
|
||||
|
@ -548,7 +548,7 @@ static int cmd_info(void *data, const char *input) {
|
||||
const char *comma = iter2->p? ",": "";
|
||||
|
||||
if (sym->method_flags) {
|
||||
char *flags = r_core_bin_method_flags_str (sym, R_CORE_BIN_JSON);
|
||||
char *flags = r_core_bin_method_flags_str (sym->method_flags, R_CORE_BIN_JSON);
|
||||
r_cons_printf ("%s{\"name\":\"%s\",\"flags\":%s,\"vaddr\":%"PFMT64d "}",
|
||||
comma, sym->name, flags, sym->vaddr);
|
||||
R_FREE (flags);
|
||||
@ -562,7 +562,7 @@ static int cmd_info(void *data, const char *input) {
|
||||
default:
|
||||
r_cons_printf ("class %s\n", cls->name);
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
char *flags = r_core_bin_method_flags_str (sym, 0);
|
||||
char *flags = r_core_bin_method_flags_str (sym->method_flags, 0);
|
||||
r_cons_printf ("0x%08"PFMT64x " method %s %s %s\n",
|
||||
sym->vaddr, cls->name, flags, sym->name);
|
||||
R_FREE (flags);
|
||||
|
@ -983,7 +983,7 @@ static void *show_class(RCore *core, int mode, int idx, RBinClass *_c, const cha
|
||||
}
|
||||
}
|
||||
|
||||
mflags = r_core_bin_method_flags_str (m, 0);
|
||||
mflags = r_core_bin_method_flags_str (m->method_flags, 0);
|
||||
|
||||
if (show_color) {
|
||||
if (i == idx) {
|
||||
|
@ -472,6 +472,7 @@ typedef struct r_bin_field_t {
|
||||
char *name;
|
||||
char *comment;
|
||||
char *format;
|
||||
ut64 flags;
|
||||
} RBinField;
|
||||
|
||||
R_API RBinField *r_bin_field_new(ut64 paddr, ut64 vaddr, int size, const char *name, const char *comment, const char *format);
|
||||
|
@ -507,7 +507,7 @@ typedef struct r_core_bin_filter_t {
|
||||
R_API int r_core_bin_info (RCore *core, int action, int mode, int va, RCoreBinFilter *filter, const char *chksum);
|
||||
R_API int r_core_bin_set_arch_bits (RCore *r, const char *name, const char * arch, ut16 bits);
|
||||
R_API int r_core_bin_update_arch_bits (RCore *r);
|
||||
R_API char *r_core_bin_method_flags_str(RBinSymbol *sym, int mode);
|
||||
R_API char *r_core_bin_method_flags_str(ut64 flags, int mode);
|
||||
|
||||
/* rtr */
|
||||
R_API int r_core_rtr_cmds (RCore *core, const char *port);
|
||||
|
Loading…
x
Reference in New Issue
Block a user