mirror of
https://github.com/radareorg/radare2.git
synced 2024-11-23 13:19:54 +00:00
Use RBinName for RBinClass too ##bin
This commit is contained in:
parent
b7cd5aa6f1
commit
98acbb3c1b
@ -1057,10 +1057,10 @@ R_API RBinClass *r_bin_class_new(const char *name, const char *super, ut64 attr)
|
||||
r_return_val_if_fail (name, NULL);
|
||||
RBinClass *c = R_NEW0 (RBinClass);
|
||||
if (c) {
|
||||
c->name = strdup (name);
|
||||
c->name = r_bin_name_new (name);
|
||||
if (R_STR_ISNOTEMPTY (super)) {
|
||||
c->super = r_list_newf (free);
|
||||
r_list_append (c->super, strdup (super));
|
||||
r_list_append (c->super, r_bin_name_new (super));
|
||||
}
|
||||
// TODO: use vectors!
|
||||
c->methods = r_list_newf (r_bin_symbol_free);
|
||||
|
@ -1488,6 +1488,26 @@ R_API RBinName *r_bin_name_new(const char *name) {
|
||||
return bn;
|
||||
}
|
||||
|
||||
R_API void r_bin_name_update(RBinName *bn, const char *name) {
|
||||
r_return_if_fail (bn && name);
|
||||
free (bn->oname);
|
||||
bn->oname = strdup (name);
|
||||
}
|
||||
|
||||
R_API RBinName *r_bin_name_clone(RBinName *bn) {
|
||||
RBinName *nn = R_NEW0 (RBinName);
|
||||
if (bn->name) {
|
||||
nn->name = strdup (bn->name);
|
||||
}
|
||||
if (bn->oname) {
|
||||
nn->oname = strdup (bn->oname);
|
||||
}
|
||||
if (bn->fname) {
|
||||
nn->oname = strdup (bn->fname);
|
||||
}
|
||||
return nn;
|
||||
}
|
||||
|
||||
R_API void r_bin_name_filtered(RBinName *bn, const char *fname) {
|
||||
r_return_if_fail (bn && fname);
|
||||
free (bn->fname);
|
||||
|
@ -214,26 +214,14 @@ static void filter_classes(RBinFile *bf, RList *list) {
|
||||
RBinClass *cls;
|
||||
RBinSymbol *sym;
|
||||
r_list_foreach (list, iter, cls) {
|
||||
if (!cls->name) {
|
||||
continue;
|
||||
const char *kname = r_bin_name_tostring (cls->name);
|
||||
char *fname = r_bin_filter_name (bf, db, cls->index, kname);
|
||||
if (fname) {
|
||||
r_bin_name_update (cls->name, fname);
|
||||
free (fname);
|
||||
}
|
||||
int namepad_len = strlen (cls->name) + 32;
|
||||
char *namepad = malloc (namepad_len + 1);
|
||||
if (namepad) {
|
||||
char *p;
|
||||
strcpy (namepad, cls->name);
|
||||
p = r_bin_filter_name (bf, db, cls->index, namepad);
|
||||
if (p) {
|
||||
free (namepad);
|
||||
namepad = p;
|
||||
}
|
||||
free (cls->name);
|
||||
cls->name = namepad;
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
if (sym->name) {
|
||||
r_bin_filter_sym (bf, ht, sym->vaddr, sym);
|
||||
}
|
||||
}
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
r_bin_filter_sym (bf, ht, sym->vaddr, sym);
|
||||
}
|
||||
}
|
||||
ht_su_free (db);
|
||||
@ -265,9 +253,9 @@ static void r_bin_object_rebuild_classes_ht(RBinObject *bo) {
|
||||
r_list_foreach (bo->classes, it, klass) {
|
||||
if (klass->name) {
|
||||
ht_pp_insert (bo->classes_ht, klass->name, klass);
|
||||
|
||||
r_list_foreach (klass->methods, it2, method) {
|
||||
char *name = r_str_newf ("%s::%s", klass->name, method->name);
|
||||
const char *klass_name = r_bin_name_tostring (klass->name);
|
||||
char *name = r_str_newf ("%s::%s", klass_name, method->name);
|
||||
ht_pp_insert (bo->methods_ht, name, method);
|
||||
free (name);
|
||||
}
|
||||
|
@ -200,20 +200,17 @@ struct MACH0_(SCategory) {
|
||||
|
||||
static char *readstr(RBinFile *bf, ut64 addr);
|
||||
static mach0_ut va2pa(mach0_ut p, ut32 *offset, ut32 *left, RBinFile *bf);
|
||||
static void copy_sym_name_with_namespace(const char *class_name, char *read_name, RBinSymbol *sym);
|
||||
static void get_ivar_list(RBinFile *bf, RBinClass *klass, mach0_ut p);
|
||||
static void get_objc_property_list(RBinFile *bf, RBinClass *klass, mach0_ut p);
|
||||
static void get_method_list(RBinFile *bf, const char *class_name, RBinClass *klass, bool is_static, objc_cache_opt_info *oi, mach0_ut p);
|
||||
static void get_protocol_list(RBinFile *bf, RBinClass *klass, objc_cache_opt_info *oi, mach0_ut p);
|
||||
static void get_method_list(RBinFile *bf, RBinClass *klass, const char *class_name, bool is_static, objc_cache_opt_info *oi, mach0_ut p);
|
||||
static void get_objc_property_list_of_lists(RBinFile *bf, RBinClass *klass, mach0_ut p);
|
||||
static void get_method_list_of_lists(RBinFile *bf, const char *class_name, RBinClass *klass, bool is_static, objc_cache_opt_info *oi, mach0_ut p);
|
||||
static void get_method_list_of_lists(RBinFile *bf, RBinClass *klass, const char *class_name, bool is_static, objc_cache_opt_info *oi, mach0_ut p);
|
||||
static void get_protocol_list_of_lists(RBinFile *bf, RBinClass *klass, objc_cache_opt_info *oi, mach0_ut p);
|
||||
static void get_class_ro_t(RBinFile *bf, bool *is_meta_class, RBinClass *klass, objc_cache_opt_info *oi, mach0_ut p);
|
||||
static RList *MACH0_(parse_categories)(RBinFile *bf, MetaSections *ms, const RSkipList *relocs, objc_cache_opt_info *oi);
|
||||
static bool read_ptr_pa(RBinFile *bf, ut64 paddr, mach0_ut *out);
|
||||
static bool read_ptr_va(RBinFile *bf, ut64 vaddr, mach0_ut *out);
|
||||
static char *read_str(RBinFile *bf, mach0_ut p, ut32 *offset, ut32 *left);
|
||||
static char *get_class_name(mach0_ut p, RBinFile *bf);
|
||||
|
||||
static inline bool is_thumb(RBinFile *bf) {
|
||||
struct MACH0_(obj_t) *bin = (struct MACH0_(obj_t) *)bf->bo->bin_obj;
|
||||
@ -237,8 +234,8 @@ static mach0_ut va2pa(mach0_ut p, ut32 *offset, ut32 *left, RBinFile *bf) {
|
||||
return bin->va2pa (p, offset, left, bf);
|
||||
}
|
||||
mach0_ut addr = p;
|
||||
RVecSegment *sections = MACH0_(get_segments_vec) (bf, bin); // don't free, cached by bin
|
||||
RBinSection *s;
|
||||
RVecSegment *sections = MACH0_(get_segments_vec) (bf, bin); // don't free, cached by bin
|
||||
R_VEC_FOREACH (sections, s) {
|
||||
if (addr >= s->vaddr && addr < s->vaddr + s->vsize) {
|
||||
if (offset) {
|
||||
@ -254,7 +251,7 @@ static mach0_ut va2pa(mach0_ut p, ut32 *offset, ut32 *left, RBinFile *bf) {
|
||||
return r;
|
||||
}
|
||||
|
||||
static void copy_sym_name_with_namespace(const char *class_name, char *read_name, RBinSymbol *sym) {
|
||||
static inline void copy_sym_name_with_namespace(RBinSymbol *sym, const char *class_name, char *read_name) {
|
||||
sym->classname = strdup (class_name? class_name: "");
|
||||
sym->name = strdup (read_name);
|
||||
}
|
||||
@ -697,23 +694,22 @@ static void iterate_list_of_lists(RBinFile *bf, OnList cb, void * ctx, mach0_ut
|
||||
}
|
||||
|
||||
// TODO: remove class_name, because it's already in klass->name
|
||||
static void get_method_list(RBinFile *bf, const char *class_name, RBinClass *klass, bool is_static, objc_cache_opt_info *oi, mach0_ut p) {
|
||||
static void get_method_list(RBinFile *bf, RBinClass *klass, const char *class_name, bool is_static, objc_cache_opt_info *oi, mach0_ut p) {
|
||||
struct MACH0_(SMethodList) ml;
|
||||
mach0_ut r;
|
||||
ut32 offset, left, i;
|
||||
char *name = NULL;
|
||||
char *rtype = NULL;
|
||||
int len;
|
||||
bool bigendian;
|
||||
ut8 sml[sizeof (struct MACH0_(SMethodList))] = {0};
|
||||
ut8 sm[sizeof (struct MACH0_(SMethod))] = {0};
|
||||
|
||||
RBinSymbol *method = NULL;
|
||||
if (!bf || !bf->bo || !bf->bo->bin_obj || !bf->bo->info) {
|
||||
R_LOG_WARN ("incorrect RBinFile pointer");
|
||||
R_LOG_WARN ("Incorrect RBinFile pointer");
|
||||
return;
|
||||
}
|
||||
bigendian = bf->bo->info->big_endian;
|
||||
const bool bigendian = bf->bo->info->big_endian;
|
||||
r = va2pa (p, &offset, &left, bf);
|
||||
if (!r) {
|
||||
return;
|
||||
@ -840,7 +836,7 @@ static void get_method_list(RBinFile *bf, const char *class_name, RBinClass *kla
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
copy_sym_name_with_namespace (class_name, name, method);
|
||||
copy_sym_name_with_namespace (method, class_name, name); // XXX r_bin_name_tostring (klass->name), name);
|
||||
R_FREE (name);
|
||||
}
|
||||
|
||||
@ -901,15 +897,14 @@ error:
|
||||
return;
|
||||
}
|
||||
|
||||
///////////////////////////////////////////////////////////////////////////////
|
||||
static void get_protocol_list(RBinFile *bf, RBinClass *klass, objc_cache_opt_info *oi, mach0_ut p) {
|
||||
struct MACH0_(SProtocolList) pl = {0};
|
||||
struct MACH0_(SProtocol) pc;
|
||||
char *class_name = NULL;
|
||||
ut32 offset, left, i, j;
|
||||
mach0_ut q, r;
|
||||
int len;
|
||||
bool bigendian;
|
||||
char *class_name = NULL;
|
||||
ut8 spl[sizeof (struct MACH0_(SProtocolList))] = {0};
|
||||
ut8 spc[sizeof (struct MACH0_(SProtocol))] = {0};
|
||||
ut8 sptr[sizeof (mach0_ut)] = {0};
|
||||
@ -1034,15 +1029,16 @@ static void get_protocol_list(RBinFile *bf, RBinClass *klass, objc_cache_opt_inf
|
||||
}
|
||||
name[name_len] = 0;
|
||||
}
|
||||
class_name = r_str_newf ("%s::%s%s", klass->name, "(protocol)", name);
|
||||
const char *cname = r_bin_name_tostring2 (klass->name, 'd');
|
||||
class_name = r_str_newf ("%s::(protocol)%s", cname, name);
|
||||
R_FREE (name);
|
||||
}
|
||||
|
||||
if (pc.instanceMethods > 0) {
|
||||
get_method_list (bf, class_name, klass, false, oi, pc.instanceMethods);
|
||||
get_method_list (bf, klass, class_name, false, oi, pc.instanceMethods);
|
||||
}
|
||||
if (pc.classMethods > 0) {
|
||||
get_method_list (bf, class_name, klass, true, oi, pc.classMethods);
|
||||
get_method_list (bf, klass, class_name, true, oi, pc.classMethods);
|
||||
}
|
||||
R_FREE (class_name);
|
||||
p += sizeof (ut32);
|
||||
@ -1067,11 +1063,10 @@ static void get_objc_property_list_of_lists(RBinFile *bf, RBinClass *klass, mach
|
||||
|
||||
static void on_method_list(mach0_ut p, void * _ctx) {
|
||||
MethodListOfListsCtx * ctx = _ctx;
|
||||
|
||||
get_method_list (ctx->bf, ctx->class_name, ctx->klass, ctx->is_static, ctx->oi, p);
|
||||
get_method_list (ctx->bf, ctx->klass, ctx->class_name, ctx->is_static, ctx->oi, p);
|
||||
}
|
||||
|
||||
static void get_method_list_of_lists(RBinFile *bf, const char *class_name, RBinClass *klass, bool is_static, objc_cache_opt_info *oi, mach0_ut p) {
|
||||
static void get_method_list_of_lists(RBinFile *bf, RBinClass *klass, const char *class_name, bool is_static, objc_cache_opt_info *oi, mach0_ut p) {
|
||||
MethodListOfListsCtx ctx;
|
||||
|
||||
ctx.bf = bf;
|
||||
@ -1307,23 +1302,26 @@ static void get_class_ro_t(RBinFile *bf, bool *is_meta_class, RBinClass *klass,
|
||||
return;
|
||||
}
|
||||
if (bin->has_crypto) {
|
||||
klass->name = strdup ("some_encrypted_data");
|
||||
left = strlen (klass->name) + 1;
|
||||
const char *kn = "some_encrypted_data";
|
||||
klass->name = r_bin_name_new (kn);
|
||||
// klass->name = strdup ("some_encrypted_data");
|
||||
left = strlen (kn) + 1;
|
||||
} else {
|
||||
int name_len = R_MIN (MAX_CLASS_NAME_LEN, left);
|
||||
char *name = malloc (name_len + 1);
|
||||
if (name) {
|
||||
int rc = r_buf_read_at (bf->buf, r, (ut8 *)name, name_len);
|
||||
if (rc != name_len) {
|
||||
rc = 0;
|
||||
}
|
||||
name[rc] = 0;
|
||||
klass->name = demangle_classname (name);
|
||||
free (name);
|
||||
char name[MAX_CLASS_NAME_LEN];
|
||||
int name_len = R_MIN (MAX_CLASS_NAME_LEN - 1, left);
|
||||
int rc = r_buf_read_at (bf->buf, r, (ut8 *)name, name_len);
|
||||
if (rc != name_len) {
|
||||
rc = 0;
|
||||
}
|
||||
name[rc] = 0;
|
||||
klass->name = r_bin_name_new (name);
|
||||
char *dn = demangle_classname (name);
|
||||
r_bin_name_demangled (klass->name, dn);
|
||||
free (dn);
|
||||
}
|
||||
//eprintf ("0x%x %s\n", s, klass->name);
|
||||
char *k = r_str_newf ("objc_class_%s.offset", klass->name);
|
||||
const char *klass_name = r_bin_name_tostring2 (klass->name, 'd');
|
||||
char *k = r_str_newf ("objc_class_%s.offset", klass_name);
|
||||
sdb_num_set (bin->kv, k, s, 0);
|
||||
free (k);
|
||||
}
|
||||
@ -1334,10 +1332,11 @@ static void get_class_ro_t(RBinFile *bf, bool *is_meta_class, RBinClass *klass,
|
||||
#endif
|
||||
|
||||
if (cro.baseMethods > 0) {
|
||||
const char *klass_name = r_bin_name_tostring2 (klass->name, 'd');
|
||||
if (cro.baseMethods & 1) {
|
||||
get_method_list_of_lists (bf, klass->name, klass, (cro.flags & RO_META) ? true : false, oi, cro.baseMethods & ~1);
|
||||
get_method_list_of_lists (bf, klass, klass_name, (cro.flags & RO_META) ? true : false, oi, cro.baseMethods & ~1);
|
||||
} else {
|
||||
get_method_list (bf, klass->name, klass, (cro.flags & RO_META) ? true : false, oi, cro.baseMethods);
|
||||
get_method_list (bf, klass, klass_name, (cro.flags & RO_META) ? true : false, oi, cro.baseMethods);
|
||||
}
|
||||
}
|
||||
if (cro.baseProtocols > 0) {
|
||||
@ -1825,10 +1824,9 @@ RList *MACH0_(parse_classes)(RBinFile *bf, objc_cache_opt_info *oi) {
|
||||
p = r_read_ble (&pp[0], bigendian, 8 * sizeof (mach0_ut));
|
||||
MACH0_(get_class_t) (p, bf, klass, false, relocs, oi);
|
||||
if (!klass->name) {
|
||||
klass->name = r_str_newf ("UnnamedClass%" PFMT64d, num_of_unnamed_class);
|
||||
if (!klass->name) {
|
||||
goto get_classes_error;
|
||||
}
|
||||
char *klass_name = r_str_newf ("UnnamedClass%" PFMT64d, num_of_unnamed_class);
|
||||
klass->name = r_bin_name_new (klass_name);
|
||||
free (klass_name);
|
||||
num_of_unnamed_class++;
|
||||
}
|
||||
r_list_append (ret, klass);
|
||||
@ -1877,10 +1875,11 @@ static RList *MACH0_(parse_categories)(RBinFile *bf, MetaSections *ms, const RSk
|
||||
continue;
|
||||
}
|
||||
klass->lang = R_BIN_LANG_OBJC;
|
||||
char *par = strchr (klass->name, '(');
|
||||
const char *klass_name = r_bin_name_tostring (klass->name);
|
||||
char *par = strchr (klass_name, '(');
|
||||
if (par) {
|
||||
size_t idx = par - klass->name;
|
||||
char *super = strdup (klass->name);
|
||||
size_t idx = par - klass_name;
|
||||
char *super = strdup (klass_name);
|
||||
super[idx++] = 0;
|
||||
char *cpar = strchr (super + idx, ')');
|
||||
if (cpar) {
|
||||
@ -1981,7 +1980,9 @@ void MACH0_(get_category_t)(mach0_ut p, RBinFile *bf, RBinClass *klass, const RS
|
||||
return;
|
||||
}
|
||||
target_class_name += _objc_class_len;
|
||||
klass->name = r_str_newf ("%s(%s)", target_class_name, category_name);
|
||||
char *kname = r_str_newf ("%s(%s)", target_class_name, category_name);
|
||||
klass->name = r_bin_name_new (kname);
|
||||
free (kname);
|
||||
} else {
|
||||
mach0_ut ro_data_field = c.targetClass + 4 * ptr_size;
|
||||
mach0_ut ro_data;
|
||||
@ -2000,24 +2001,30 @@ void MACH0_(get_category_t)(mach0_ut p, RBinFile *bf, RBinClass *klass, const RS
|
||||
}
|
||||
|
||||
target_class_name = read_str (bf, name_at, &offset, &left);
|
||||
char *demangled = NULL;
|
||||
if (target_class_name) {
|
||||
demangled = demangle_classname (target_class_name);
|
||||
char *kname = r_str_newf ("%s(%s)", target_class_name, category_name);
|
||||
klass->name = r_bin_name_new (kname);
|
||||
char *demangled = demangle_classname (target_class_name);
|
||||
if (demangled) {
|
||||
char *dname = r_str_newf ("%s(%s)", demangled, category_name);
|
||||
r_bin_name_demangled (klass->name, dname);
|
||||
free (dname);
|
||||
free (demangled);
|
||||
}
|
||||
free (kname);
|
||||
}
|
||||
klass->name = r_str_newf ("%s(%s)", r_str_getf (demangled), category_name);
|
||||
R_FREE (target_class_name);
|
||||
R_FREE (demangled);
|
||||
}
|
||||
|
||||
klass->addr = p;
|
||||
|
||||
R_FREE (category_name);
|
||||
|
||||
const char *klass_name = r_bin_name_tostring (klass->name);
|
||||
if (c.instanceMethods > 0) {
|
||||
get_method_list (bf, klass->name, klass, false, oi, c.instanceMethods);
|
||||
get_method_list (bf, klass, klass_name, false, oi, c.instanceMethods);
|
||||
}
|
||||
if (c.classMethods > 0) {
|
||||
get_method_list (bf, klass->name, klass, true, oi, c.classMethods);
|
||||
get_method_list (bf, klass, klass_name, true, oi, c.classMethods);
|
||||
}
|
||||
if (c.protocols > 0) {
|
||||
get_protocol_list (bf, klass, oi, c.protocols);
|
||||
|
@ -345,7 +345,7 @@ out_error:
|
||||
// XXX. this is using binfile->buf directly :(
|
||||
// https://github.com/android/platform_dalvik/blob/0641c2b4836fae3ee8daf6c0af45c316c84d5aeb/libdex/DexDebugInfo.cpp#L312
|
||||
// https://github.com/android/platform_dalvik/blob/0641c2b4836fae3ee8daf6c0af45c316c84d5aeb/libdex/DexDebugInfo.cpp#L141
|
||||
static void dex_parse_debug_item(RBinFile *bf, RBinDexClass *c, int MI, int MA, int paddr, int ins_size, int insns_size, char *class_name, int regsz, int debug_info_off) {
|
||||
static void dex_parse_debug_item(RBinFile *bf, RBinDexClass *c, int MI, int MA, int paddr, int ins_size, int insns_size, const char *class_name, int regsz, int debug_info_off) {
|
||||
RBin *rbin = bf->rbin;
|
||||
RBinDexObj *dex = bf->bo->bin_obj; // bin .. unnecessary arg
|
||||
// runtime error: pointer index expression with base 0x000000004402 overflowed to 0xffffffffff0043fc
|
||||
@ -1062,11 +1062,12 @@ static void parse_dex_class_fields(RBinFile *bf, RBinDexClass *c, RBinClass *cls
|
||||
if (!sym) {
|
||||
break;
|
||||
}
|
||||
const char *cls_name = r_bin_name_tostring (cls->name);
|
||||
if (is_sfield) {
|
||||
sym->name = r_str_newf ("%s.sfield_%s:%s", cls->name, fieldName, type_str);
|
||||
sym->name = r_str_newf ("%s.sfield_%s:%s", cls_name, fieldName, type_str);
|
||||
sym->type = "STATIC";
|
||||
} else {
|
||||
sym->name = r_str_newf ("%s.ifield_%s:%s", cls->name, fieldName, type_str);
|
||||
sym->name = r_str_newf ("%s.ifield_%s:%s", cls_name, fieldName, type_str);
|
||||
sym->type = "FIELD";
|
||||
}
|
||||
sym->name = r_str_replace (sym->name, "method.", "", 0);
|
||||
@ -1078,7 +1079,7 @@ static void parse_dex_class_fields(RBinFile *bf, RBinDexClass *c, RBinClass *cls
|
||||
|
||||
if (dex->dexdump) {
|
||||
char *accessStr = createAccessFlagStr (accessFlags, kAccessForField);
|
||||
bin->cb_printf (" #%u : (in %s;)\n", (unsigned int)i, cls->name);
|
||||
bin->cb_printf (" #%u : (in %s;)\n", (unsigned int)i, cls_name);
|
||||
bin->cb_printf (" name : '%s'\n", fieldName);
|
||||
bin->cb_printf (" type : '%s'\n", type_str);
|
||||
bin->cb_printf (" access : 0x%04x (%s)\n",
|
||||
@ -1119,6 +1120,7 @@ static void parse_dex_class_method(RBinFile *bf, RBinDexClass *c, RBinClass *cls
|
||||
ut64 encoded_method_addr;
|
||||
bool err = false;
|
||||
ut64 MI, MA, MC;
|
||||
const char *cls_name = r_bin_name_tostring (cls->name);
|
||||
ut64 i;
|
||||
for (i = 0; i < DM; i++) {
|
||||
err = false;
|
||||
@ -1154,7 +1156,7 @@ static void parse_dex_class_method(RBinFile *bf, RBinDexClass *c, RBinClass *cls
|
||||
continue;
|
||||
}
|
||||
char *signature = dex_method_signature (dex, MI);
|
||||
char *flag_name = r_str_newf ("%s.method.%s%s", cls->name, method_name, signature);
|
||||
char *flag_name = r_str_newf ("%s.method.%s%s", cls_name, method_name, signature);
|
||||
if (!flag_name || !*flag_name) {
|
||||
R_FREE (flag_name);
|
||||
R_FREE (signature);
|
||||
@ -1206,7 +1208,7 @@ static void parse_dex_class_method(RBinFile *bf, RBinDexClass *c, RBinClass *cls
|
||||
}
|
||||
if (dex->dexdump) {
|
||||
char* accessStr = createAccessFlagStr (MA, kAccessForMethod);
|
||||
cb_printf (" #%" PFMT64d " : (in %s;)\n", i, cls->name);
|
||||
cb_printf (" #%" PFMT64d " : (in %s;)\n", i, cls_name);
|
||||
cb_printf (" name : '%s'\n", method_name);
|
||||
cb_printf (" type : '%s'\n", signature);
|
||||
cb_printf (" access : 0x%04x (%s)\n", (ut32)MA, accessStr);
|
||||
@ -1419,7 +1421,7 @@ static void parse_dex_class_method(RBinFile *bf, RBinDexClass *c, RBinClass *cls
|
||||
if (bin_dbginfo) {
|
||||
ut64 addr = r_buf_tell (bf->buf);
|
||||
dex_parse_debug_item (bf, c, MI, MA, sym->paddr, ins_size,
|
||||
insns_size, cls->name, regsz, debug_info_off);
|
||||
insns_size, cls_name, regsz, debug_info_off);
|
||||
r_buf_seek (bf->buf, addr, R_BUF_SET);
|
||||
}
|
||||
} else if (MC > 0) {
|
||||
@ -1442,15 +1444,13 @@ static void parse_class(RBinFile *bf, RBinDexClass *c, int class_index, int *met
|
||||
RBin *rbin = bf->rbin;
|
||||
int z;
|
||||
RBinClass *cls = R_NEW0 (RBinClass);
|
||||
if (!cls) {
|
||||
goto beach;
|
||||
}
|
||||
cls->name = dex_class_name (dex, c);
|
||||
cls->lang = R_BIN_LANG_JAVA;
|
||||
if (!cls->name) {
|
||||
char *cls_name = dex_class_name (dex, c);
|
||||
if (!cls_name) {
|
||||
goto beach;
|
||||
}
|
||||
r_str_replace_char (cls->name, ';', 0);
|
||||
r_str_replace_char (cls_name, ';', 0);
|
||||
cls->name = r_bin_name_new (cls_name);
|
||||
cls->index = class_index;
|
||||
cls->addr = dex->header.class_offset + (class_index * DEX_CLASS_SIZE);
|
||||
cls->methods = r_list_newf ((RListFree)r_bin_symbol_free);
|
||||
@ -1472,7 +1472,7 @@ static void parse_class(RBinFile *bf, RBinDexClass *c, int class_index, int *met
|
||||
cls->visibility_str = createAccessFlagStr (c->access_flags, kAccessForClass);
|
||||
r_list_append (dex->classes_list, cls);
|
||||
if (dex->dexdump) {
|
||||
rbin->cb_printf (" Class descriptor : '%s;'\n", cls->name);
|
||||
rbin->cb_printf (" Class descriptor : '%s;'\n", cls_name);
|
||||
rbin->cb_printf (" Access flags : 0x%04x (%s)\n", c->access_flags,
|
||||
r_str_get (cls->visibility_str));
|
||||
if (cls->super) {
|
||||
@ -1562,18 +1562,17 @@ static void parse_class(RBinFile *bf, RBinDexClass *c, int class_index, int *met
|
||||
|
||||
if (dex->dexdump) {
|
||||
const char *source_file = getstr (dex, c->source_file);
|
||||
if (!source_file) {
|
||||
rbin->cb_printf (
|
||||
" source_file_idx : %d (unknown)\n\n",
|
||||
c->source_file);
|
||||
} else {
|
||||
if (source_file) {
|
||||
rbin->cb_printf (" source_file_idx : %d (%s)\n\n",
|
||||
c->source_file, source_file);
|
||||
c->source_file, source_file);
|
||||
} else {
|
||||
rbin->cb_printf (" source_file_idx : %d (unknown)\n\n",
|
||||
c->source_file);
|
||||
}
|
||||
}
|
||||
cls = NULL;
|
||||
beach:
|
||||
return;
|
||||
R_FREE (cls_name);
|
||||
}
|
||||
|
||||
static bool is_class_idx_in_code_classes(RBinDexObj *dex, int class_idx) {
|
||||
|
@ -1443,13 +1443,9 @@ static RList *classes(RBinFile *bf) {
|
||||
if (bf->rbin->verbose) {
|
||||
R_LOG_ERROR ("KLASS failed at 0x%"PFMT64x", is_classlist %d", pointer_to_class, is_classlist);
|
||||
}
|
||||
klass->name = r_str_newf ("UnnamedClass%u", num_of_unnamed_class);
|
||||
if (!klass->name) {
|
||||
R_FREE (klass);
|
||||
R_FREE (pointers);
|
||||
MACH0_(mach0_free) (mach0);
|
||||
goto beach;
|
||||
}
|
||||
char *kname = r_str_newf ("UnnamedClass%u", num_of_unnamed_class);
|
||||
klass->name = r_bin_name_new (kname);
|
||||
free (kname);
|
||||
num_of_unnamed_class++;
|
||||
}
|
||||
r_list_append (ret, klass);
|
||||
|
@ -3535,7 +3535,7 @@ static void classdump_c(RCore *r, RBinClass *c) {
|
||||
free (n);
|
||||
}
|
||||
}
|
||||
const char *klass_name = c->name; // r_bin_name_tostring2 (c->name, pref);
|
||||
const char *klass_name = r_bin_name_tostring2 (c->name, pref);
|
||||
if (is_objc) {
|
||||
r_cons_printf ("} objc_class_%s;\n", klass_name);
|
||||
} else {
|
||||
@ -3545,7 +3545,7 @@ static void classdump_c(RCore *r, RBinClass *c) {
|
||||
|
||||
static void classdump_cxx(RCore *r, RBinClass *c) {
|
||||
const int pref = r_config_get_b (r->config, "asm.demangle")? 'd': 0;
|
||||
const char *klass_name = c->name; // r_bin_name_tostring2 (c->name, pref);
|
||||
const char *klass_name = r_bin_name_tostring2 (c->name, pref);
|
||||
r_cons_printf ("class %s {\n", klass_name);
|
||||
RListIter *iter2;
|
||||
RBinField *f;
|
||||
@ -3576,10 +3576,11 @@ static void classdump_cxx(RCore *r, RBinClass *c) {
|
||||
}
|
||||
|
||||
static void classdump_objc(RCore *r, RBinClass *c) {
|
||||
const int pref = 0; // r_config_get_b (r->config, "asm.demangle")? 'd': 0;
|
||||
const int pref = r_config_get_b (r->config, "asm.demangle")? 'd': 0;
|
||||
const char *cname = r_bin_name_tostring2 (c->name, pref);
|
||||
if (c->super) {
|
||||
int n = 0;
|
||||
r_cons_printf ("@interface %s :", c->name);
|
||||
r_cons_printf ("@interface %s :", cname);
|
||||
RBinName *bn;
|
||||
RListIter *iter;
|
||||
r_list_foreach (c->super, iter, bn) {
|
||||
@ -3596,7 +3597,7 @@ static void classdump_objc(RCore *r, RBinClass *c) {
|
||||
r_cons_printf ("\n{\n");
|
||||
}
|
||||
} else {
|
||||
r_cons_printf ("@interface %s\n{\n", c->name);
|
||||
r_cons_printf ("@interface %s\n{\n", cname);
|
||||
}
|
||||
RListIter *iter2, *iter3;
|
||||
RBinField *f;
|
||||
@ -3607,9 +3608,9 @@ static void classdump_objc(RCore *r, RBinClass *c) {
|
||||
const char *fn = r_bin_name_tostring2 (f->name, pref);
|
||||
if (f->type) {
|
||||
const char *ft = r_bin_name_tostring2 (f->type, pref);
|
||||
r_cons_printf (" %s %s::(%s)%s\n", ft, c->name, ks, fn);
|
||||
r_cons_printf (" %s %s::(%s)%s\n", ft, cname, ks, fn);
|
||||
} else {
|
||||
r_cons_printf (" isa %s::(%s)%s\n", c->name, ks, fn);
|
||||
r_cons_printf (" isa %s::(%s)%s\n", cname, ks, fn);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -3635,7 +3636,8 @@ static void classdump_swift(RCore *r, RBinClass *c) {
|
||||
RBinField *f;
|
||||
RListIter *iter;
|
||||
RBinSymbol *sym;
|
||||
char *pn = strdup (c->name);
|
||||
const char *cname = r_bin_name_tostring2 (c->name, pref);
|
||||
char *pn = strdup (cname);
|
||||
char *cn = (char *)r_str_rchr (pn, NULL, '/');
|
||||
if (cn) {
|
||||
*cn = 0;
|
||||
@ -3688,11 +3690,12 @@ static void classdump_swift(RCore *r, RBinClass *c) {
|
||||
}
|
||||
|
||||
static void classdump_java(RCore *r, RBinClass *c) {
|
||||
const int pref = r_config_get_b (r->config, "asm.demangle")? 'd': 0;
|
||||
RBinField *f;
|
||||
RListIter *iter;
|
||||
RBinSymbol *sym;
|
||||
char *pn = strdup (c->name);
|
||||
const int pref = r_config_get_b (r->config, "asm.demangle")? 'd': 0;
|
||||
const char *cname = r_bin_name_tostring2 (c->name, pref);
|
||||
char *pn = strdup (cname);
|
||||
char *cn = (char *)r_str_rchr (pn, NULL, '/');
|
||||
if (cn) {
|
||||
*cn = 0;
|
||||
@ -3765,10 +3768,11 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
}
|
||||
const bool bin_filter = r_config_get_b (r->config, "bin.filter");
|
||||
r_list_foreach (cs, iter, c) {
|
||||
if (!c || R_STR_ISEMPTY (c->name)) {
|
||||
const char *cname = r_bin_name_tostring2 (c->name, pref);
|
||||
if (!c || R_STR_ISEMPTY (cname)) {
|
||||
continue;
|
||||
}
|
||||
char *name = strdup (c->name);
|
||||
char *name = strdup (cname);
|
||||
r_name_filter (name, -1);
|
||||
ut64 at_min = UT64_MAX;
|
||||
ut64 at_max = 0LL;
|
||||
@ -3796,7 +3800,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
char *mflags = r_bin_attr_tostring (sym->attr, false);
|
||||
r_str_replace_char (mflags, ' ', '.');
|
||||
// XXX probably access flags should not be part of the flag name
|
||||
r_strf_var (method, 256, "method%s%s.%s.%s", R_STR_ISEMPTY (mflags)? "":".", mflags, c->name, sym->name);
|
||||
r_strf_var (method, 256, "method%s%s.%s.%s", R_STR_ISEMPTY (mflags)? "":".", mflags, cname, sym->name);
|
||||
R_FREE (mflags);
|
||||
r_name_filter (method, -1);
|
||||
r_flag_set (r->flags, method, sym->vaddr, 1);
|
||||
@ -3811,11 +3815,11 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
free (fn);
|
||||
}
|
||||
} else if (IS_MODE_SIMPLEST (mode)) {
|
||||
r_cons_printf ("%s\n", c->name);
|
||||
r_cons_printf ("%s\n", cname);
|
||||
} else if (IS_MODE_SIMPLE (mode)) {
|
||||
char *supers = csv_supers (c->super);
|
||||
r_cons_printf ("0x%08"PFMT64x" [0x%08"PFMT64x" - 0x%08"PFMT64x"] %s %s%s%s\n",
|
||||
c->addr, at_min, at_max, r_bin_lang_tostring (c->lang), c->name, *supers ? " " : "", supers);
|
||||
c->addr, at_min, at_max, r_bin_lang_tostring (c->lang), cname, *supers ? " " : "", supers);
|
||||
free (supers);
|
||||
} else if (IS_MODE_CLASSDUMP (mode)) {
|
||||
if (c) {
|
||||
@ -3858,7 +3862,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
char *n = r_name_filter_shell (name);
|
||||
r_cons_printf ("\"f class.%s = 0x%"PFMT64x"\"\n", n, at_min);
|
||||
if (c->super) {
|
||||
char *cn = c->name;
|
||||
const char *cn = cname;
|
||||
RListIter *iter;
|
||||
RBinName *bn;
|
||||
r_list_foreach (c->super, iter, bn) {
|
||||
@ -3871,7 +3875,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
r_list_foreach (c->methods, iter2, sym) {
|
||||
char *mflags = r_bin_attr_tostring (sym->attr, false);
|
||||
r_str_replace_char (mflags, ' ', '.');
|
||||
char *n = c->name; // r_name_filter_shell (c->name);
|
||||
const char *n = cname; // r_name_filter_shell (cname);
|
||||
char *sn = sym->name; //r_name_filter_shell (sym->name); // symbol contains classname
|
||||
const char *predot = R_STR_ISNOTEMPTY (mflags)? ".": "";
|
||||
// char *cmd = r_str_newf ("\"f method%s.%s.%s = 0x%"PFMT64x"\"\n", mflags, n, sn, sym->vaddr);
|
||||
@ -3897,7 +3901,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
r_list_foreach (c->fields, iter2, f) {
|
||||
const char *kind = r_bin_field_kindstr (f);
|
||||
const char *fname = r_bin_name_tostring2 (f->name, pref);
|
||||
char *fn = r_str_newf ("field.%s.%s.%s", c->name, kind, fname);
|
||||
char *fn = r_str_newf ("field.%s.%s.%s", cname, kind, fname);
|
||||
r_name_filter (fn, -1);
|
||||
ut64 at = f->vaddr; // sym->vaddr + (f->vaddr & 0xffff);
|
||||
r_cons_printf ("\"f %s = 0x%08"PFMT64x"\"\n", fn, at);
|
||||
@ -3905,7 +3909,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
}
|
||||
|
||||
// C struct
|
||||
r_cons_printf ("\"\"td struct %s {", c->name);
|
||||
r_cons_printf ("\"\"td struct %s {", cname);
|
||||
if (r_list_empty (c->fields)) {
|
||||
// XXX workaround because we cant register empty structs yet
|
||||
// XXX https://github.com/radareorg/radare2/issues/16342
|
||||
@ -3928,7 +3932,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
free (n);
|
||||
} else if (IS_MODE_JSON (mode)) {
|
||||
pj_o (pj);
|
||||
pj_ks (pj, "classname", c->name);
|
||||
pj_ks (pj, "classname", cname);
|
||||
pj_kN (pj, "addr", c->addr);
|
||||
const char *lang = r_bin_lang_tostring (c->lang);
|
||||
if (lang && *lang != '?') {
|
||||
@ -4013,7 +4017,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
|
||||
int m = 0;
|
||||
const char *cl = r_bin_lang_tostring (c->lang);
|
||||
r_cons_printf ("0x%08"PFMT64x" [0x%08"PFMT64x" - 0x%08"PFMT64x"] %6"PFMT64d" %s class %d %s",
|
||||
c->addr, at_min, at_max, (at_max - at_min), cl, c->index, c->name);
|
||||
c->addr, at_min, at_max, (at_max - at_min), cl, c->index, cname);
|
||||
if (r_list_empty (c->super)) {
|
||||
r_cons_newline ();
|
||||
} else {
|
||||
|
@ -98,22 +98,24 @@ static void pair(const char *a, const char *b) {
|
||||
}
|
||||
|
||||
static void classdump_keys(RCore *core, RBinObject *bo) {
|
||||
const int pref = r_config_get_b (core->config, "asm.demangle")? 'd': 0;
|
||||
const bool iova = r_config_get_b (core->config, "io.va");
|
||||
RBinClass *k;
|
||||
RBinField *f;
|
||||
RBinSymbol *m;
|
||||
RListIter *iter, *iter2;
|
||||
r_list_foreach (bo->classes, iter, k) {
|
||||
const char *kname = r_bin_name_tostring2 (k->name, pref);
|
||||
r_list_foreach (k->fields, iter2, f) {
|
||||
const char *kind = r_bin_field_kindstr (f);
|
||||
r_cons_printf ("klass.%s.field.%s.%s=0x%"PFMT64x"\n",
|
||||
k->name, kind, r_bin_name_tostring2 (f->name, 'f'),
|
||||
kname, kind, r_bin_name_tostring2 (f->name, 'f'),
|
||||
iova? f->vaddr: f->paddr);
|
||||
}
|
||||
r_list_foreach (k->methods, iter2, m) {
|
||||
char *attr = r_bin_attr_tostring (m->attr, true);
|
||||
r_cons_printf ("klass.%s.method.%s.%s=0x%"PFMT64x"\n",
|
||||
k->name, r_str_get (attr), m->name,
|
||||
kname, r_str_get (attr), m->name,
|
||||
iova? m->vaddr: m->paddr);
|
||||
free (attr);
|
||||
}
|
||||
@ -533,8 +535,8 @@ static bool isKnownPackage(const char *cn) {
|
||||
}
|
||||
|
||||
static void cmd_ic_comma(RCore *core, const char *input) {
|
||||
r_return_if_fail (core && input[0] == 'c' && input[1] == ',');
|
||||
const char *q = input + 2;
|
||||
r_return_if_fail (core && input[0] == ',');
|
||||
const char *q = input + 1;
|
||||
RList *bfiles = r_core_bin_files (core);
|
||||
RListIter *objs_iter;
|
||||
RBinFile *bf;
|
||||
@ -553,19 +555,17 @@ static void cmd_ic_comma(RCore *core, const char *input) {
|
||||
RListIter *iter, *iter2;
|
||||
core->bin->cur = bf;
|
||||
r_list_foreach (obj->classes, iter, klass) {
|
||||
if (!klass->name) {
|
||||
continue;
|
||||
}
|
||||
const char *kname = r_bin_name_tostring (klass->name);
|
||||
RBinSymbol *method;
|
||||
r_list_foreach (klass->methods, iter2, method) {
|
||||
char *addr = r_str_newf ("0x%08"PFMT64x, iova? method->vaddr: method->paddr);
|
||||
r_table_add_row (t, addr, "method", klass->name, method->name, NULL);
|
||||
r_table_add_row (t, addr, "method", kname, method->name, NULL);
|
||||
free (addr);
|
||||
}
|
||||
RBinField *field;
|
||||
r_list_foreach (klass->fields, iter2, field) {
|
||||
char *addr = r_str_newf ("0x%08"PFMT64x, iova? field->vaddr: field->paddr);
|
||||
r_table_add_row (t, addr, "field", klass->name, field->name, NULL);
|
||||
r_table_add_row (t, addr, "field", kname, field->name, NULL);
|
||||
free (addr);
|
||||
}
|
||||
}
|
||||
@ -581,6 +581,7 @@ static void cmd_ic_comma(RCore *core, const char *input) {
|
||||
}
|
||||
|
||||
static void cmd_ic_sub(RCore *core, const char *input) {
|
||||
const int pref = r_config_get_b (core->config, "asm.demangle")? 0: 'o';
|
||||
RListIter *iter;
|
||||
RBinClass *k;
|
||||
RBinSymbol *m;
|
||||
@ -601,7 +602,8 @@ static void cmd_ic_sub(RCore *core, const char *input) {
|
||||
RBinClass *klass = NULL;
|
||||
RList *klasses = r_bin_get_classes (core->bin);
|
||||
r_list_foreach (klasses, iter, k) {
|
||||
if (!strcmp (k->name, klass_name)) {
|
||||
const char *kname = r_bin_name_tostring2 (k->name, pref);
|
||||
if (!strcmp (kname, klass_name)) {
|
||||
if (method_name) {
|
||||
klass = k;
|
||||
} else {
|
||||
@ -636,14 +638,15 @@ void cmd_ic_add(RCore *core, const char *input) {
|
||||
char *method_name = r_str_after (klass_name, '.');
|
||||
RBinClass *klass = NULL;
|
||||
r_list_foreach (klasses, iter, k) {
|
||||
if (!strcmp (k->name, klass_name)) {
|
||||
const char *kname = r_bin_name_tostring (k->name);
|
||||
if (!strcmp (kname, klass_name)) {
|
||||
klass = k;
|
||||
break;
|
||||
}
|
||||
}
|
||||
if (!klass) {
|
||||
klass = R_NEW0 (RBinClass);
|
||||
klass->name = strdup (klass_name);
|
||||
klass->name = r_bin_name_new (klass_name);
|
||||
r_list_append (klasses, klass);
|
||||
}
|
||||
if (method_name == NULL) {
|
||||
@ -680,33 +683,36 @@ static void cmd_icg(RCore *core, RBinObject *obj, const char *arg) { // "icg"
|
||||
const char *match = r_str_trim_head_ro (arg);
|
||||
if (R_STR_ISNOTEMPTY (match)) {
|
||||
r_list_foreach (obj->classes, iter, cls) {
|
||||
if (!match || !strstr (cls->name, match)) {
|
||||
const char *kname = r_bin_name_tostring2 (cls->name, pref);
|
||||
if (!match || !strstr (kname, match)) {
|
||||
continue;
|
||||
}
|
||||
r_cons_printf ("agn %s\n", cls->name);
|
||||
r_cons_printf ("agn %s\n", kname);
|
||||
if (cls->super) {
|
||||
RBinName *bn;
|
||||
r_list_foreach (cls->super, iter2, bn) {
|
||||
const char *sk = r_bin_name_tostring2 (bn, pref);
|
||||
if (match && strstr (sk, match)) {
|
||||
r_cons_printf ("agn %s\n", sk);
|
||||
r_cons_printf ("age %s %s\n", sk, cls->name);
|
||||
r_cons_printf ("age %s %s\n", sk, kname);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
} else if (fullGraph) {
|
||||
r_list_foreach (obj->classes, iter, cls) {
|
||||
const char *kname = r_bin_name_tostring2 (cls->name, pref);
|
||||
RBinName *bn;
|
||||
r_cons_printf ("agn %s\n", cls->name);
|
||||
r_cons_printf ("agn %s\n", kname);
|
||||
r_list_foreach (cls->super, iter2, bn) {
|
||||
const char *sk = r_bin_name_tostring2 (bn, pref);
|
||||
r_cons_printf ("agn %s\n", sk);
|
||||
r_cons_printf ("age %s %s\n", sk, cls->name);
|
||||
r_cons_printf ("age %s %s\n", sk, kname);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
r_list_foreach (obj->classes, iter, cls) {
|
||||
const char *kname = r_bin_name_tostring2 (cls->name, pref);
|
||||
char *sk;
|
||||
RListIter *iter;
|
||||
r_list_foreach (cls->super, iter, sk) {
|
||||
@ -714,8 +720,8 @@ static void cmd_icg(RCore *core, RBinObject *obj, const char *arg) { // "icg"
|
||||
continue;
|
||||
}
|
||||
r_cons_printf ("agn %s\n", sk);
|
||||
r_cons_printf ("agn %s\n", cls->name);
|
||||
r_cons_printf ("age %s %s\n", sk, cls->name);
|
||||
r_cons_printf ("agn %s\n", kname);
|
||||
r_cons_printf ("age %s %s\n", sk, kname);
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -729,6 +735,7 @@ static void cmd_icg(RCore *core, RBinObject *obj, const char *arg) { // "icg"
|
||||
r_core_bin_info (core, x, pj, mode, va, NULL, y);
|
||||
|
||||
static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va) {
|
||||
const int pref = r_config_get_b (core->config, "asm.demangle")? 'd': 0;
|
||||
int cmd = input[0];
|
||||
int mode = 0;
|
||||
const char *arg = input + 2;
|
||||
@ -740,6 +747,11 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
arg = "";
|
||||
lastchar = input + strlen (input) - 1;
|
||||
}
|
||||
bool show_help = false;
|
||||
if (*lastchar == '?') {
|
||||
show_help = true;
|
||||
lastchar--;
|
||||
}
|
||||
switch (*lastchar) {
|
||||
case 'j':
|
||||
case 'k':
|
||||
@ -756,9 +768,6 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
mode = 0;
|
||||
break;
|
||||
}
|
||||
if (mode == ',') {
|
||||
cmd_ic_comma (core, input);
|
||||
}
|
||||
bool is_superquiet = strstr (input, "qq");
|
||||
bool is_doublerad = strstr (input, "**");
|
||||
///
|
||||
@ -784,14 +793,19 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
case 'c': // "icc"
|
||||
case '*': // "ic*"
|
||||
case 0: // "ic" "icq"
|
||||
{
|
||||
if (mode == ',') {
|
||||
cmd_ic_comma (core, input);
|
||||
} else {
|
||||
if (show_help) {
|
||||
r_core_cmd_help_contains (core, help_msg_i, "ic");
|
||||
break;
|
||||
}
|
||||
const bool iova = r_config_get_b (core->config, "io.va");
|
||||
RListIter *objs_iter;
|
||||
RBinFile *bf;
|
||||
RBinFile *cur = core->bin->cur;
|
||||
RList *objs = r_core_bin_files (core);
|
||||
int count = 0;
|
||||
bool filtered = false;
|
||||
int idx = -1;
|
||||
const char *cls_name = NULL;
|
||||
if (r_num_is_valid_input (core->num, arg)) {
|
||||
@ -808,15 +822,12 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
RBinObject *obj = bf->bo;
|
||||
if (!obj || !obj->classes || r_list_empty (obj->classes)) {
|
||||
if (mode == 'j') {
|
||||
r_cons_printf ("%s{}", first? "": ",");
|
||||
r_cons_printf ("%s[]", first? "": ",");
|
||||
}
|
||||
first = false;
|
||||
continue;
|
||||
}
|
||||
first = false;
|
||||
if (filtered) {
|
||||
break;
|
||||
}
|
||||
RBinClass *cls;
|
||||
RBinSymbol *sym;
|
||||
RListIter *iter, *iter2;
|
||||
@ -824,8 +835,9 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
|
||||
if (is_superquiet) {
|
||||
r_list_foreach (obj->classes, iter, cls) {
|
||||
if (!isKnownPackage (cls->name)) {
|
||||
r_cons_printf ("%s\n", cls->name);
|
||||
const char *kname = r_bin_name_tostring (cls->name);
|
||||
if (!isKnownPackage (kname)) {
|
||||
r_cons_printf ("%s\n", kname);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -837,13 +849,14 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
break;
|
||||
case 's': // "ics"
|
||||
r_list_foreach (obj->classes, iter, cls) {
|
||||
const char *kname = r_bin_name_tostring (cls->name);
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
ut64 addr = iova? sym->vaddr: sym->paddr;
|
||||
if (addr == 0 || addr == UT64_MAX) {
|
||||
continue;
|
||||
}
|
||||
r_cons_printf ("0x%"PFMT64x" [%s] %s\n",
|
||||
addr, cls->name, sym->name);
|
||||
addr, kname, sym->name);
|
||||
}
|
||||
}
|
||||
break;
|
||||
@ -883,10 +896,11 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
}
|
||||
}
|
||||
if (addr >= min && addr < max) {
|
||||
const char *kname = r_bin_name_tostring (cls->name);
|
||||
if (method) {
|
||||
r_cons_printf ("%s::%s\n", cls->name, method);
|
||||
r_cons_printf ("%s::%s\n", kname, method);
|
||||
} else {
|
||||
r_cons_printf ("%s\n", cls->name);
|
||||
r_cons_printf ("%s\n", kname);
|
||||
}
|
||||
}
|
||||
min = UT64_MAX;
|
||||
@ -920,6 +934,7 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
if (mode == 'j') {
|
||||
mode = R_MODE_JSON;
|
||||
}
|
||||
// TODO add the ability to filter by name
|
||||
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes));
|
||||
break;
|
||||
case ' ': // "ic"
|
||||
@ -927,31 +942,19 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
default:
|
||||
{
|
||||
r_list_foreach (obj->classes, iter, cls) {
|
||||
if ((idx >= 0 && idx != count++) || (R_STR_ISNOTEMPTY (cls_name) && strcmp (cls_name, cls->name))) {
|
||||
const char *kname = r_bin_name_tostring2 (cls->name, pref);
|
||||
if ((idx >= 0 && idx != count++) || (R_STR_ISNOTEMPTY (cls_name) && strcmp (cls_name, kname))) {
|
||||
continue;
|
||||
}
|
||||
if (is_doublerad) {
|
||||
r_cons_printf ("ac %s\n", cls->name);
|
||||
r_cons_printf ("ac %s\n", kname);
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
r_cons_printf ("ac %s %s 0x%08"PFMT64x"\n", cls->name,
|
||||
r_cons_printf ("ac %s %s 0x%08"PFMT64x"\n", kname,
|
||||
sym->name, iova? sym->vaddr: sym->paddr);
|
||||
}
|
||||
eprintf ("doble rad quit\n");
|
||||
continue;
|
||||
}
|
||||
bool listed_classes = false;
|
||||
if (idx != -1 || R_STR_ISNOTEMPTY (cls_name)) {
|
||||
filtered = true;
|
||||
r_cons_printf ("class %s\n", cls->name);
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
char *flags = r_core_bin_attr_tostring (sym->attr, true);
|
||||
r_cons_printf ("0x%08"PFMT64x " method %s %-4s %s\n",
|
||||
iova? sym->vaddr: sym->paddr,
|
||||
cls->name, flags, sym->name);
|
||||
free (flags);
|
||||
}
|
||||
continue;
|
||||
}
|
||||
|
||||
switch (mode) {
|
||||
case '*':
|
||||
@ -974,7 +977,6 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
iova? sym->vaddr: sym->paddr);
|
||||
}
|
||||
r_cons_newline ();
|
||||
input++;
|
||||
break;
|
||||
case 'j':
|
||||
{
|
||||
@ -983,28 +985,24 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
listed_classes = true;
|
||||
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len);
|
||||
}
|
||||
#if 0
|
||||
input++;
|
||||
pj_ks (pj, "class", cls->name);
|
||||
pj_ka (pj, "methods");
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
pj_o (pj);
|
||||
pj_ks (pj, "name", sym->name);
|
||||
if (sym->attr) {
|
||||
// TODO: must be an array of strings
|
||||
char *flags = r_core_bin_attr_tostring (sym->attr, false);
|
||||
pj_k (pj, "flags");
|
||||
pj_j (pj, flags);
|
||||
free (flags);
|
||||
}
|
||||
pj_kN (pj, "vaddr", sym->vaddr);
|
||||
pj_kN (pj, "paddr", sym->paddr);
|
||||
pj_end (pj);
|
||||
}
|
||||
pj_end (pj);
|
||||
#endif
|
||||
break;
|
||||
case 0:
|
||||
if (idx == -1 && R_STR_ISEMPTY (cls_name)) {
|
||||
size_t len = r_list_length (obj->classes);
|
||||
int mode = 0;
|
||||
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, len);
|
||||
listed_classes = true;
|
||||
} else {
|
||||
r_cons_printf ("class %s\n", kname);
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
char *flags = r_core_bin_attr_tostring (sym->attr, true);
|
||||
r_cons_printf ("0x%08"PFMT64x " method %s %-4s %s\n",
|
||||
iova? sym->vaddr: sym->paddr,
|
||||
kname, flags, sym->name);
|
||||
free (flags);
|
||||
}
|
||||
}
|
||||
break;
|
||||
case 'q':
|
||||
{
|
||||
size_t len = r_list_length (obj->classes);
|
||||
@ -1015,12 +1013,12 @@ static void cmd_ic(RCore *core, const char *input, PJ *pj, int is_array, bool va
|
||||
}
|
||||
break;
|
||||
default:
|
||||
r_cons_printf ("class %s\n", cls->name);
|
||||
r_cons_printf ("class %s\n", kname);
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
char *flags = r_core_bin_attr_tostring (sym->attr, true);
|
||||
r_cons_printf ("0x%08"PFMT64x " method %s %-4s %s\n",
|
||||
iova? sym->vaddr: sym->paddr,
|
||||
cls->name, flags, sym->name);
|
||||
kname, flags, sym->name);
|
||||
free (flags);
|
||||
}
|
||||
break;
|
||||
@ -1108,26 +1106,6 @@ static int cmd_info(void *data, const char *input) {
|
||||
if (!space && question) {
|
||||
space = question + 1;
|
||||
}
|
||||
if (question < space && question > input) {
|
||||
question--;
|
||||
char *prefix = strdup (input);
|
||||
char *tmp = strchr (prefix, '?');
|
||||
if (tmp) {
|
||||
*tmp = 0;
|
||||
}
|
||||
if (*prefix == 'd') {
|
||||
r_core_cmd_help (core, help_msg_id);
|
||||
} else {
|
||||
r_core_cmdf (core, "i?~& i%s", prefix);
|
||||
}
|
||||
free (prefix);
|
||||
goto done;
|
||||
}
|
||||
R_FREE (core->table_query);
|
||||
if (space && (*space == ' ' || *space == ',')) {
|
||||
core->table_query = r_str_trim_dup (space + 1);
|
||||
}
|
||||
|
||||
switch (input[0]) {
|
||||
case 'i': // "ii"
|
||||
if (input[1] == 'c') { // "iic"
|
||||
@ -1203,6 +1181,26 @@ static int cmd_info(void *data, const char *input) {
|
||||
goto done;
|
||||
break;
|
||||
}
|
||||
if (question < space && question > input) {
|
||||
question--;
|
||||
char *prefix = strdup (input);
|
||||
char *tmp = strchr (prefix, '?');
|
||||
if (tmp) {
|
||||
*tmp = 0;
|
||||
}
|
||||
if (*prefix == 'd') {
|
||||
r_core_cmd_help (core, help_msg_id);
|
||||
} else {
|
||||
r_core_cmdf (core, "i?~& i%s", prefix);
|
||||
}
|
||||
free (prefix);
|
||||
goto done;
|
||||
}
|
||||
R_FREE (core->table_query);
|
||||
if (space && (*space == ' ' || *space == ',')) {
|
||||
core->table_query = r_str_trim_dup (space + 1);
|
||||
}
|
||||
|
||||
// TODO: slowly deprecate the loopy subcommands in here
|
||||
while (*input) {
|
||||
const char ch = *input;
|
||||
|
@ -1150,6 +1150,7 @@ static int cmd_meta_others(RCore *core, const char *input) {
|
||||
// r_meta_cleanup (core->anal->meta, 0LL, UT64_MAX);
|
||||
break;
|
||||
default:
|
||||
eprintf ("((((%s))))\n", input);
|
||||
R_LOG_ERROR ("Missing space after CC");
|
||||
break;
|
||||
}
|
||||
|
@ -931,7 +931,7 @@ static void findMethodBounds(RList *methods, ut64 *min, ut64 *max) {
|
||||
ut64 at_max = 0LL;
|
||||
|
||||
r_list_foreach (methods, iter, sym) {
|
||||
if (sym->vaddr) {
|
||||
if (sym->vaddr && sym->vaddr != UT64_MAX) {
|
||||
if (sym->vaddr < at_min) {
|
||||
at_min = sym->vaddr;
|
||||
}
|
||||
@ -950,9 +950,6 @@ static ut64 findClassBounds(RCore *core, const char *input, int *len) {
|
||||
RBinClass *c;
|
||||
RList *cs = r_bin_get_classes (core->bin);
|
||||
r_list_foreach (cs, iter, c) {
|
||||
if (!c || !c->name || !c->name[0]) {
|
||||
continue;
|
||||
}
|
||||
findMethodBounds (c->methods, &min, &max);
|
||||
if (len) {
|
||||
*len = (max - min);
|
||||
@ -963,8 +960,7 @@ static ut64 findClassBounds(RCore *core, const char *input, int *len) {
|
||||
}
|
||||
|
||||
static void cmd_pCD(RCore *core, const char *input) {
|
||||
int h, w = r_cons_get_size (&h);
|
||||
int i;
|
||||
int i, h, w = r_cons_get_size (&h);
|
||||
int rows = h - 2;
|
||||
int obsz = core->blocksize;
|
||||
int user_rows = r_num_math (core->num, input);
|
||||
|
@ -638,7 +638,7 @@ R_API bool r_core_visual_bit_editor(RCore *core) {
|
||||
case 'k':
|
||||
case 10:
|
||||
case ' ':
|
||||
//togglebit();
|
||||
// togglebit();
|
||||
{
|
||||
const int nbyte = x / 8;
|
||||
const int nbit = 7 - (x - (nbyte * 8));
|
||||
@ -1064,15 +1064,16 @@ R_API bool r_core_visual_hudclasses(RCore *core) {
|
||||
list->free = free;
|
||||
RList *classes = r_bin_get_classes (core->bin);
|
||||
r_list_foreach (classes, iter, c) {
|
||||
const char *cname = r_bin_name_tostring2 (c->name, pref);
|
||||
r_list_foreach (c->fields, iter2, f) {
|
||||
const char *fname = r_bin_name_tostring2 (f->name, pref);
|
||||
r_list_append (list, r_str_newf ("0x%08"PFMT64x" %s %s",
|
||||
f->vaddr, c->name, fname));
|
||||
f->vaddr, cname, fname));
|
||||
}
|
||||
r_list_foreach (c->methods, iter2, m) {
|
||||
const char *name = m->dname? m->dname: m->name;
|
||||
r_list_append (list, r_str_newf ("0x%08"PFMT64x" %s %s",
|
||||
m->vaddr, c->name, name));
|
||||
m->vaddr, cname, name));
|
||||
}
|
||||
}
|
||||
res = r_cons_hud (list, NULL);
|
||||
@ -1182,12 +1183,14 @@ static void *show_class(RCore *core, int mode, int *idx, RBinClass *_c, const ch
|
||||
int skip = *idx - 10;
|
||||
bool found = false;
|
||||
|
||||
const char *_cname = r_bin_name_tostring (_c->name);
|
||||
switch (mode) {
|
||||
case 'c':
|
||||
r_cons_printf ("[hjkl_/Cfm]> classes:\n\n");
|
||||
r_list_foreach (list, iter, c) {
|
||||
const char *cname = r_bin_name_tostring (c->name);
|
||||
if (grep) {
|
||||
if (!r_str_casestr (c->name, grep)) {
|
||||
if (!r_str_casestr (cname, grep)) {
|
||||
i++;
|
||||
continue;
|
||||
}
|
||||
@ -1205,14 +1208,14 @@ static void *show_class(RCore *core, int mode, int *idx, RBinClass *_c, const ch
|
||||
const char *clr = Color_BLUE;
|
||||
r_cons_printf (Color_GREEN ">>" Color_RESET " %02d %s0x%08"
|
||||
PFMT64x Color_YELLOW " %s\n" Color_RESET,
|
||||
i, clr, c->addr, c->name);
|
||||
i, clr, c->addr, cname);
|
||||
} else {
|
||||
r_cons_printf ("- %02d %s0x%08"PFMT64x Color_RESET" %s\n",
|
||||
i, core->cons->context->pal.offset, c->addr, c->name);
|
||||
i, core->cons->context->pal.offset, c->addr, cname);
|
||||
}
|
||||
} else {
|
||||
r_cons_printf ("%s %02d 0x%08"PFMT64x" %s\n",
|
||||
(i==*idx)?">>":"- ", i, c->addr, c->name);
|
||||
(i==*idx)?">>":"- ", i, c->addr, cname);
|
||||
}
|
||||
if (i++ == *idx) {
|
||||
cur = c;
|
||||
@ -1230,7 +1233,7 @@ static void *show_class(RCore *core, int mode, int *idx, RBinClass *_c, const ch
|
||||
return cur;
|
||||
case 'f':
|
||||
// show fields
|
||||
r_cons_printf ("[hjkl_/cFm]> fields of %s:\n\n", _c->name);
|
||||
r_cons_printf ("[hjkl_/cFm]> fields of %s:\n\n", _cname);
|
||||
r_list_foreach (_c->fields, iter, f) {
|
||||
const char *name = r_bin_name_tostring2 (f->name, 'f');
|
||||
if (grep) {
|
||||
@ -1250,8 +1253,8 @@ static void *show_class(RCore *core, int mode, int *idx, RBinClass *_c, const ch
|
||||
|
||||
char *mflags = strdup ("");
|
||||
|
||||
if (r_str_startswith (name, _c->name)) {
|
||||
name += strlen (_c->name);
|
||||
if (r_str_startswith (name, _cname)) {
|
||||
name += strlen (_cname);
|
||||
}
|
||||
if (show_color) {
|
||||
if (i == *idx) {
|
||||
@ -1290,7 +1293,7 @@ static void *show_class(RCore *core, int mode, int *idx, RBinClass *_c, const ch
|
||||
R_LOG_WARN ("No class selected");
|
||||
return mur;
|
||||
}
|
||||
r_cons_printf ("[hjkl_/cfM]> methods of %s\n\n", _c->name);
|
||||
r_cons_printf ("[hjkl_/cfM]> methods of %s\n\n", _cname);
|
||||
r_list_foreach (_c->methods, iter, m) {
|
||||
const char *name = m->dname? m->dname: m->name;
|
||||
if (grep) {
|
||||
@ -1310,8 +1313,8 @@ static void *show_class(RCore *core, int mode, int *idx, RBinClass *_c, const ch
|
||||
|
||||
char *mflags = r_core_bin_attr_tostring (m->attr, false);
|
||||
if (show_color) {
|
||||
if (r_str_startswith (name, _c->name)) {
|
||||
name += strlen (_c->name);
|
||||
if (r_str_startswith (name, _cname)) {
|
||||
name += strlen (_cname);
|
||||
}
|
||||
if (i == *idx) {
|
||||
const char *clr = Color_BLUE;
|
||||
|
@ -273,10 +273,9 @@ typedef struct r_bin_info_t {
|
||||
} RBinInfo;
|
||||
|
||||
typedef struct r_bin_symbol_t {
|
||||
/* heap-allocated */
|
||||
#if R2_590
|
||||
RBinName *name; // R2_590
|
||||
RBinName *classname; // R2_590
|
||||
RBinName *name;
|
||||
RBinName *classname;
|
||||
#else
|
||||
char *name; // deprecate and use bname
|
||||
char *dname; // deprecate and use bname
|
||||
@ -287,6 +286,7 @@ typedef struct r_bin_symbol_t {
|
||||
const char *forwarder;
|
||||
const char *bind; // tied to attr already
|
||||
const char *type; // typed to attr already
|
||||
// RBinName *type;
|
||||
const char *rtype;
|
||||
bool is_imported;
|
||||
/* only used by java */
|
||||
@ -593,10 +593,7 @@ typedef struct r_bin_plugin_t {
|
||||
typedef void (*RBinSymbollCallback)(RBinObject *obj, void *symbol);
|
||||
|
||||
typedef struct r_bin_class_t {
|
||||
char *name; // must be deprecated and use bname only
|
||||
#if R2_590
|
||||
RBinName *name;
|
||||
#endif
|
||||
RList *super; // list of RBinName
|
||||
char *visibility_str; // XXX R2_590 - only used by dex+java should be ut32 or bitfield.. should be usable for swift too
|
||||
int index; // should be unsigned?
|
||||
@ -893,6 +890,8 @@ R_API const char *r_bin_lang_tostring(int type);
|
||||
R_API RList *r_bin_get_mem(RBin *bin);
|
||||
|
||||
R_API RBinName *r_bin_name_new(const char *name);
|
||||
R_API RBinName *r_bin_name_clone(RBinName *bn);
|
||||
R_API void r_bin_name_update(RBinName *bn, const char *name);
|
||||
R_API char *r_bin_name_tostring(RBinName *bn);
|
||||
R_API char *r_bin_name_tostring2(RBinName *bn, int type);
|
||||
R_API void r_bin_name_demangled(RBinName *bn, const char *dname);
|
||||
|
@ -766,7 +766,8 @@ static ut8 *get_classes(RCore *c, int *len) {
|
||||
const RList *list = r_bin_get_classes (c->bin);
|
||||
RList *reslist = r_list_newf (free);
|
||||
r_list_foreach (list, iter, klass) {
|
||||
r_list_append (reslist, strdup (klass->name));
|
||||
const char *kname = r_bin_name_tostring (klass->name);
|
||||
r_list_append (reslist, strdup (kname));
|
||||
}
|
||||
r_list_sort (reslist, (RListComparator)strcmp);
|
||||
char *buf = r_str_list_join (reslist, "\n");
|
||||
@ -789,10 +790,11 @@ static ut8 *get_fields(RCore *c, int *len) {
|
||||
RList *reslist = r_list_newf (free);
|
||||
RListIter *iter, *iter2;
|
||||
r_list_foreach (list, iter, klass) {
|
||||
const char *kname = r_bin_name_tostring (klass->name);
|
||||
RBinField *field;
|
||||
r_list_foreach (klass->fields, iter2, field) {
|
||||
const char *fname = r_bin_name_tostring2 (field->name, pref);
|
||||
r_list_append (reslist, r_str_newf ("%s.%s", klass->name, fname));
|
||||
r_list_append (reslist, r_str_newf ("%s.%s", kname, fname));
|
||||
}
|
||||
}
|
||||
r_list_sort (reslist, (RListComparator)strcmp);
|
||||
@ -814,8 +816,9 @@ static ut8 *get_methods(RCore *c, int *len) {
|
||||
const RList *list = r_bin_get_classes (c->bin);
|
||||
RList *reslist = r_list_newf (free);
|
||||
r_list_foreach (list, iter, klass) {
|
||||
const char *kname = r_bin_name_tostring (klass->name);
|
||||
r_list_foreach (klass->methods, iter2, sym) {
|
||||
r_list_append (reslist, r_str_newf ("%s.%s", klass->name, sym->name));
|
||||
r_list_append (reslist, r_str_newf ("%s.%s", kname, sym->name));
|
||||
}
|
||||
}
|
||||
r_list_sort (reslist, (RListComparator)strcmp);
|
||||
|
@ -4,6 +4,7 @@
|
||||
|
||||
#include <math.h>
|
||||
#include "class.h"
|
||||
#define R_BIN_CLASSNAME(x) (x)->name? (x)->name: (x)->oname
|
||||
|
||||
static inline RBinName *__bin_name_new(const char *name) {
|
||||
r_return_val_if_fail (name, NULL);
|
||||
@ -708,7 +709,7 @@ R_API void r_bin_java_get_class_info_json(RBinJavaObj *bin, PJ *pj) {
|
||||
pj_ki (pj, "is_synthetic", ((klass->attr & R_BIN_JAVA_CLASS_ACC_SYNTHETIC) != 0));
|
||||
pj_ki (pj, "is_annotation", ((klass->attr & R_BIN_JAVA_CLASS_ACC_ANNOTATION) != 0));
|
||||
pj_ki (pj, "is_enum", ((klass->attr & R_BIN_JAVA_CLASS_ACC_ENUM) != 0));
|
||||
pj_ks (pj, "name", klass->name);
|
||||
pj_ks (pj, "name", R_BIN_CLASSNAME (klass->name));
|
||||
if (klass->super) {
|
||||
RBinName *bn;
|
||||
RListIter *iter;
|
||||
@ -731,7 +732,7 @@ R_API void r_bin_java_get_class_info_json(RBinJavaObj *bin, PJ *pj) {
|
||||
}
|
||||
// enumerate all interface classes and append them to the interfaces
|
||||
if ((klassv->attr & R_BIN_ATTR_INTERFACE) != 0) {
|
||||
pj_s (pj, klassv->name);
|
||||
pj_s (pj, R_BIN_CLASSNAME (klassv->name));
|
||||
}
|
||||
}
|
||||
pj_end (pj);
|
||||
@ -2792,7 +2793,9 @@ R_API RList *r_bin_java_get_classes(RBinJavaObj *bin) {
|
||||
#endif
|
||||
k->methods = r_bin_java_enum_class_methods (bin, bin->cf2.this_class);
|
||||
k->fields = r_bin_java_enum_class_fields (bin, bin->cf2.this_class);
|
||||
k->name = r_bin_java_get_this_class_name (bin);
|
||||
char *kname = r_bin_java_get_this_class_name (bin);
|
||||
k->name = __bin_name_new (kname);
|
||||
free (kname);
|
||||
char *n = r_bin_java_get_name_from_bin_cp_list (bin, bin->cf2.super_class);
|
||||
if (R_STR_ISNOTEMPTY (n)) {
|
||||
k->super = r_list_newf ((void*)__bin_name_free);
|
||||
@ -2809,7 +2812,9 @@ R_API RList *r_bin_java_get_classes(RBinJavaObj *bin) {
|
||||
k->methods = r_bin_java_enum_class_methods (bin, cp_obj->info.cp_class.name_idx);
|
||||
k->fields = r_bin_java_enum_class_fields (bin, cp_obj->info.cp_class.name_idx);
|
||||
k->index = idx;
|
||||
k->name = r_bin_java_get_item_name_from_bin_cp_list (bin, cp_obj);
|
||||
char *name = r_bin_java_get_item_name_from_bin_cp_list (bin, cp_obj);
|
||||
k->name = __bin_name_new (name);
|
||||
free (name);
|
||||
r_list_append (classes, k);
|
||||
idx++;
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user