Initial implementation of RBinName and RBinAttr ##bin

This commit is contained in:
pancake 2023-10-28 11:14:00 +02:00 committed by pancake
parent 94a6c058ea
commit c1a17af587
14 changed files with 339 additions and 219 deletions

View File

@ -1521,6 +1521,7 @@ R_API void r_bin_trycatch_free(RBinTrycatch *tc) {
}
R_API const char *r_bin_field_kindstr(RBinField *f) {
r_return_val_if_fail (f, NULL);
switch (f->kind) {
case R_BIN_FIELD_KIND_PROPERTY:
return "property";
@ -1530,3 +1531,66 @@ R_API const char *r_bin_field_kindstr(RBinField *f) {
return "var"; // maybe ivar for objc?
}
}
R_API RBinName *r_bin_name_new(const char *name) {
r_return_val_if_fail (name, NULL);
RBinName *bn = R_NEW0 (RBinName);
bn->oname = strdup (name);
// oname and dname
return bn;
}
R_API void r_bin_name_demangled(RBinName *bn, const char *dname) {
r_return_if_fail (bn && dname);
if (bn->name && !bn->oname) {
bn->oname = bn->name;
} else {
free (bn->name);
}
bn->name = strdup (dname);
}
R_API char *r_bin_name_tostring(RBinName *bn) {
r_return_val_if_fail (bn, NULL);
if (bn->name) {
return bn->name;
}
if (bn->oname) {
return bn->oname;
}
return bn->fname;
}
// prefered type
R_API char *r_bin_name_tostring2(RBinName *bn, int type) {
r_return_val_if_fail (bn, NULL);
if (type == 'd' && bn->name) {
return bn->name;
}
if (type == 'f' && bn->fname) {
return bn->fname;
}
if (type == 'o' && bn->oname) {
return bn->oname;
}
return r_bin_name_tostring (bn);
}
R_API void r_bin_name_free(RBinName *bn) {
if (bn) {
free (bn->name);
free (bn->oname);
free (bn->fname);
free (bn);
}
}
// TODO : not implemented yet
R_API char *r_bin_attr_tostring(ut64 attr) {
return NULL;
}
// TODO : not implemented yet
R_API ut64 r_bin_attr_fromstring(const char *s) {
return 0ULL;
}

View File

@ -1249,9 +1249,9 @@ void MACH0_(get_class_t)(mach0_ut p, RBinFile *bf, RBinClass *klass, bool dupe,
const char *klass_name = get_class_name (c.superclass, bf);
if (klass_name) {
if (klass->super == NULL) {
klass->super = r_list_newf (free);
klass->super = r_list_newf ((void *)r_bin_name_free);
}
r_list_append (klass->super, (void *)klass_name);
r_list_append (klass->super, (void *)r_bin_name_new (klass_name));
}
} else if (relocs) {
struct reloc_t reloc_at_class_addr;
@ -1263,20 +1263,18 @@ void MACH0_(get_class_t)(mach0_ut p, RBinFile *bf, RBinClass *klass, bool dupe,
char *target_class_name = (char*) ((struct reloc_t*) found->data)->name;
if (r_str_startswith (target_class_name, _objc_class)) {
target_class_name += _objc_class_len;
if (klass->super == NULL) {
klass->super = r_list_newf (free);
}
RBinName *sup = r_bin_name_new (target_class_name);
if (r_str_startswith (target_class_name, "_T")) {
char *dsuper = r_bin_demangle_swift (target_class_name, true, true);
if (!dsuper || !strcmp (dsuper, target_class_name)) {
R_LOG_DEBUG ("Failed to demangle");
r_list_append (klass->super, strdup (target_class_name));
} else {
r_list_append (klass->super, dsuper);
if (dsuper && strcmp (dsuper, target_class_name)) {
r_bin_name_demangled (sup, dsuper);
}
} else {
r_list_append (klass->super, strdup (target_class_name));
free (dsuper);
}
if (klass->super == NULL) {
klass->super = r_list_newf ((void *)r_bin_name_free);
}
r_list_append (klass->super, sup);
}
}
}
@ -1399,21 +1397,15 @@ static void parse_type(RList *list, RBinFile *bf, SwiftType st, HtUP *symbols_ht
char *super_name = readstr (bf, st.super_addr);
if (super_name) {
if (*super_name > 5) {
klass->super = r_list_newf (free);
#if 1
klass->super = r_list_newf ((void *)r_bin_name_free);
RBinName *bn = r_bin_name_new (super_name);
char *sname = r_bin_demangle_swift (super_name, 0, false);
if (R_STR_ISNOTEMPTY (sname)) {
r_list_append (klass->super, sname);
free (super_name);
} else {
r_list_append (klass->super, super_name);
r_bin_name_demangled (bn, sname);
}
#else
r_list_append (klass->super, super_name);
#endif
} else {
free (super_name);
r_list_append (klass->super, bn);
}
free (super_name);
}
klass->addr = st.addr;
klass->lang = R_BIN_LANG_SWIFT;
@ -1637,7 +1629,7 @@ RList *MACH0_(parse_classes)(RBinFile *bf, objc_cache_opt_info *oi) {
R_LOG_ERROR ("Chopped classlist data");
break;
}
klass = r_bin_class_new ("", "", R_BIN_CLASS_PUBLIC);
klass = r_bin_class_new ("", "", R_BIN_ATTR_PUBLIC);
R_FREE (klass->name); // allow NULL name in rbinclass?
klass->lang = R_BIN_LANG_OBJC;
size = sizeof (mach0_ut);
@ -1710,15 +1702,17 @@ static RList *MACH0_(parse_categories)(RBinFile *bf, MetaSections *ms, const RSk
if (par) {
size_t idx = par - klass->name;
char *super = strdup (klass->name);
// TODO: demangle name!!
super[idx++] = 0;
char *cpar = strchr (super + idx, ')');
if (cpar) {
*cpar = 0;
}
r_list_free (klass->super);
klass->super = r_list_newf (free);
r_list_append (klass->super, super);
if (klass->super == NULL) {
klass->super = r_list_newf ((void *)r_bin_name_free);
}
RBinName *bn = r_bin_name_new (super);
// TODO: demangle name!!
r_list_append (klass->super, bn);
// char *name = strdup (super + idx);
// free (klass->name);
// klass->name = name;

View File

@ -5,7 +5,7 @@
#include <r_lib.h>
// set this to true for debugging purposes
#define USE_THIS_CODE 0
#define USE_THIS_CODE 1
static R_TH_LOCAL int have_swift_demangle = -1;
#if R2__UNIX__

View File

@ -183,35 +183,22 @@ static char *createAccessFlagStr(ut32 flags, AccessFor forWhat) {
},
};
size_t i, count = r_num_bit_count (flags);
const int kLongest = 21;
const int maxSize = (count + 1) * (kLongest + 1);
char* str, *cp;
// produces a huge number????
if (count < 1 || (count * (kLongest+1)) < 1) {
return NULL;
}
cp = str = (char*) calloc (count + 1, (kLongest + 1));
if (!str) {
if (count < 1) {
return NULL;
}
RStrBuf *sb = r_strbuf_new ("");
for (i = 0; i < NUM_FLAGS; i++) {
if (flags & 0x01) {
if (flags & 1) {
const char *accessStr = kAccessStrings[forWhat][i];
int len = strlen (accessStr);
if (cp != str) {
*cp++ = ' ';
if (!r_strbuf_is_empty (sb)) {
r_strbuf_append (sb, " ");
}
if (((cp - str) + len) >= maxSize) {
free (str);
return NULL;
}
memcpy (cp, accessStr, len);
cp += len;
r_strbuf_append (sb, accessStr);
}
flags >>= 1;
}
*cp = '\0';
return str;
return r_strbuf_drain (sb);
}
static const char *dex_type_descriptor(RBinDexObj *dex, int type_idx) {
@ -1017,7 +1004,6 @@ static ut64 dex_get_type_offset(RBinFile *bf, int type_idx) {
static const char *dex_class_super_name(RBinDexObj *bin, RBinDexClass *c) {
r_return_val_if_fail (bin && bin->types && c, NULL);
int cid = c->super_class;
if (cid < 0 || cid >= bin->header.types_size) {
return NULL;
@ -1470,8 +1456,8 @@ static void parse_class(RBinFile *bf, RBinDexClass *c, int class_index, int *met
cls->methods = r_list_newf ((RListFree)r_bin_symbol_free);
const char *super = dex_class_super_name (dex, c);
if (super) {
cls->super = r_list_newf (free);
r_list_append (cls->super, strdup (super));
cls->super = r_list_newf ((void*)r_bin_name_free);
r_list_append (cls->super, r_bin_name_new (super));
}
if (!cls->methods) {
free (cls);
@ -1490,11 +1476,11 @@ static void parse_class(RBinFile *bf, RBinDexClass *c, int class_index, int *met
rbin->cb_printf (" Access flags : 0x%04x (%s)\n", c->access_flags,
r_str_get (cls->visibility_str));
if (cls->super) {
char *sk;
RBinName *bn;
RListIter *iter;
rbin->cb_printf (" Superclass : '");
r_list_foreach (cls->super, iter, sk) {
rbin->cb_printf ("%s%s", iter->n? ",": "", sk);
r_list_foreach (cls->super, iter, bn) {
rbin->cb_printf ("%s%s", iter->n? ",": "", r_bin_name_tostring (bn));
}
rbin->cb_printf ("'\n");
}

View File

@ -6,21 +6,15 @@
#include "../../shlr/java/class.h"
#include "../../shlr/java/code.h"
static void add_bin_obj_to_sdb(RBinJavaObj *bin);
static int add_sdb_bin_obj(const char *key, RBinJavaObj *bin_obj);
static int add_sdb_bin_obj(const char *key, RBinJavaObj *bin_obj) {
int result = false;
char *addr, value[SDB_NUM_BUFSZ] = {
0
};
addr = sdb_itoa ((ut64) (size_t) bin_obj, 16, value, sizeof (value));
static bool add_sdb_bin_obj(const char *key, RBinJavaObj *bin_obj) {
char value[SDB_NUM_BUFSZ] = {0};
char *addr = sdb_itoa ((ut64) (size_t) bin_obj, 16, value, sizeof (value));
if (key && bin_obj && bin_obj->kv) {
R_LOG_DEBUG ("Adding %s:%s to the bin_objs db", key, addr);
sdb_set (bin_obj->kv, key, addr, 0);
result = true;
return true;
}
return result;
return false;
}
static void add_bin_obj_to_sdb(RBinJavaObj *bj) {

View File

@ -40,6 +40,19 @@ static void pair_bool(PJ *pj, const char *key, bool val) {
}
}
static char *csv_supers(RList *supers) {
RBinName *bn;
RListIter *iter;
RStrBuf *sb = r_strbuf_new ("");
r_list_foreach (supers, iter, bn) {
if (!r_strbuf_is_empty (sb)) {
r_strbuf_append (sb, ", ");
}
r_strbuf_append (sb, r_bin_name_tostring (bn));
}
return r_strbuf_drain (sb);
}
static void pair_int(PJ *pj, const char *key, int val) {
if (pj) {
pj_ki (pj, key, val);
@ -3558,22 +3571,19 @@ static void classdump_cxx(RCore *r, RBinClass *c) {
}
static void classdump_objc(RCore *r, RBinClass *c) {
const bool asm_demangle = r_config_get_b (r->config, "asm.demangle");
const int pref = asm_demangle? 0: 'o';
if (c->super) {
int n = 0;
r_cons_printf ("@interface %s :", c->name);
const char *sk;
RBinName *bn;
RListIter *iter;
r_list_foreach (c->super, iter, sk) {
r_list_foreach (c->super, iter, bn) {
const char *sk = r_bin_name_tostring2 (bn, pref);
switch (n) {
case 0:
r_cons_printf (" %s", sk);
break;
case 1:
r_cons_printf ("< %s", sk);
break;
default:
r_cons_printf (", %s", sk);
break;
case 0: r_cons_printf (" %s", sk); break;
case 1: r_cons_printf ("< %s", sk); break;
default: r_cons_printf (", %s", sk); break;
}
}
if (r_list_length (c->super) > 1) {
@ -3611,6 +3621,8 @@ static void classdump_objc(RCore *r, RBinClass *c) {
}
static void classdump_swift(RCore *r, RBinClass *c) {
const bool asm_demangle = r_config_get_b (r->config, "asm.demangle");
const int pref = asm_demangle? 0: 'o';
RBinField *f;
RListIter *iter;
RBinSymbol *sym;
@ -3629,13 +3641,14 @@ static void classdump_swift(RCore *r, RBinClass *c) {
r_cons_printf ("@objc\n");
}
r_cons_printf ("class %s ", klassname);
if (c->super) {
char *sc;
r_list_foreach (c->super, iter, sc) {
r_cons_printf (": %s", sc);
if (!r_list_empty (c->super)) {
RBinName *bn;
r_list_foreach (c->super, iter, bn) {
r_cons_printf (": %s", r_bin_name_tostring2 (bn, pref));
}
r_cons_printf (" ");
}
r_cons_printf (" {\n");
r_cons_printf ("{\n");
free (klassname);
r_list_foreach (c->fields, iter, f) {
if (!f->name) {
@ -3709,6 +3722,8 @@ static bool is_javaish(RBinFile *bf) {
}
static bool bin_classes(RCore *r, PJ *pj, int mode) {
const bool asm_demangle = r_config_get_b (r->config, "asm.demangle");
const int pref = asm_demangle? 0: 'o';
RListIter *iter, *iter2, *iter3;
RBinSymbol *sym;
RBinClass *c;
@ -3780,12 +3795,9 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
} else if (IS_MODE_SIMPLEST (mode)) {
r_cons_printf ("%s\n", c->name);
} else if (IS_MODE_SIMPLE (mode)) {
char *supers = c->super
? r_str_list_join (c->super, ", ")
: strdup ("");
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, c->super ? " " : "",
r_str_get (supers));
c->addr, at_min, at_max, r_bin_lang_tostring (c->lang), c->name, *supers ? " " : "", supers);
free (supers);
} else if (IS_MODE_CLASSDUMP (mode)) {
if (c) {
@ -3830,12 +3842,11 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
if (c->super) {
char *cn = c->name;
RListIter *iter;
const char *sk;
r_list_foreach (c->super, iter, sk) {
char *fsk = strdup (sk);
RBinName *bn;
r_list_foreach (c->super, iter, bn) {
char *fsk = strdup (r_bin_name_tostring2 (bn, pref));
r_name_filter (fsk, -1);
r_cons_printf ("\"f super.%s.%s = %d\"\n",
cn, fsk, c->index);
r_cons_printf ("\"f super.%s.%s = %d\"\n", cn, fsk, c->index);
free (fsk);
}
}
@ -3866,7 +3877,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
char *fn = r_str_newf ("field.%s.%s.%s", c->name, kind, f->name);
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);
r_cons_printf ("\"f %s = 0x%08"PFMT64x"\"\n", fn, at);
free (fn);
}
@ -3904,10 +3915,10 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
pj_ks (pj, "visibility", c->visibility_str);
}
RListIter *iter;
const char *sk;
pj_ka (pj, "super");
r_list_foreach (c->super, iter, sk) {
pj_s (pj, sk);
RBinName *bn;
r_list_foreach (c->super, iter, bn) {
pj_s (pj, r_bin_name_tostring (bn));
}
pj_end (pj);
}
@ -3969,7 +3980,7 @@ static bool bin_classes(RCore *r, PJ *pj, int mode) {
if (r_list_empty (c->super)) {
r_cons_newline ();
} else {
char *csv = r_str_list_join (c->super, ", ");
char *csv = csv_supers (c->super);
if (r_str_startswith (csv, "_T")) {
R_LOG_WARN ("undemangled symbol, maybe good to fix in rbin instead of core");
char *dsuper = r_bin_demangle (r->bin->cur, csv, csv, 0, false);

View File

@ -1442,6 +1442,8 @@ static int cmd_info(void *data, const char *input) {
} else if (input[1] == '+') { // "ic+"
cmd_ic_add (core, input + 2);
} else if (input[1] == 'g') { // "icg"
const bool asm_demangle = r_config_get_b (core->config, "asm.demangle");
const int pref = asm_demangle? 0: 'o';
RBinClass *cls;
RListIter *iter, *iter2;
RBinObject *obj = r_bin_cur_object (core->bin);
@ -1452,13 +1454,14 @@ static int cmd_info(void *data, const char *input) {
const char *match = r_str_trim_head_ro (input + 2);
if (R_STR_ISNOTEMPTY (match)) {
r_list_foreach (obj->classes, iter, cls) {
char *sk;
if (!match || !strstr (cls->name, match)) {
continue;
}
r_cons_printf ("agn %s\n", cls->name);
if (cls->super) {
r_list_foreach (cls->super, iter2, sk) {
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);
@ -1468,9 +1471,10 @@ static int cmd_info(void *data, const char *input) {
}
} else if (fullGraph) {
r_list_foreach (obj->classes, iter, cls) {
const char *sk;
RBinName *bn;
r_cons_printf ("agn %s\n", cls->name);
r_list_foreach (cls->super, iter2, sk) {
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);
}

View File

@ -27,12 +27,12 @@ static const char *r_cmd_java_strtok(const char *str1, const char b, size_t len)
static const char *r_cmd_java_consumetok(const char *str1, const char b, size_t len);
static int r_cmd_java_reload_bin_from_buf(RCore *core, RBinJavaObj *obj, ut8* buffer, ut64 len);
static int r_cmd_java_print_json_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_all_definitions( RAnal *anal );
static int r_cmd_java_print_class_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_field_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_method_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_import_definitions( RBinJavaObj *obj );
static int r_cmd_java_print_json_definitions(RBinJavaObj *obj);
static int r_cmd_java_print_all_definitions(RAnal *anal);
static int r_cmd_java_print_class_definitions(RBinJavaObj *obj);
static int r_cmd_java_print_field_definitions(RBinJavaObj *obj);
static int r_cmd_java_print_method_definitions(RBinJavaObj *obj);
static int r_cmd_java_print_import_definitions(RBinJavaObj *obj);
static int r_cmd_java_resolve_cp_idx(RBinJavaObj *obj, ut16 idx);
static int r_cmd_java_resolve_cp_type(RBinJavaObj *obj, ut16 idx);

View File

@ -71,7 +71,11 @@ R_LIB_VERSION_HEADER (r_bin);
#define R_BIN_REQ_TRYCATCH 0x100000000
#define R_BIN_REQ_SECTIONS_MAPPING 0x200000000
// R2_590 - deprecate
#define R_BIN_CLASS_PUBLIC 0x0000000000000004L
/* RBinSymbol->method_flags : */
// XXX unify with RBinAttribute instead! R2_590
#define R_BIN_METH_CLASS 0x0000000000000001L
#define R_BIN_METH_STATIC 0x0000000000000002L
#define R_BIN_METH_PUBLIC 0x0000000000000004L
@ -161,15 +165,47 @@ typedef enum {
R_STRING_TYPE_BASE64 = 'b',
} RStringType;
// used for symbols, classes, methods... generic for elf, dex, pe, swift, ...
typedef enum {
// R2_590 rename to R_BIN_VISIBILITY // R_BIN_SCOPE_(PRIVATE|PUBLIC|..) ?
R_BIN_CLASS_PRIVATE,
R_BIN_CLASS_PUBLIC,
R_BIN_CLASS_FRIENDLY,
R_BIN_CLASS_PROTECTED,
// ?? R_BIN_CLASS_HIDDEN,
// ?? R_BIN_CLASS_INTERNAL,
} RBinClassVisibility; // R2_590 - RBinScope
// see binclass.visibility_str
R_BIN_ATTR_PRIVATE,
R_BIN_ATTR_FILEPRIVATE,
R_BIN_ATTR_PUBLIC,
R_BIN_ATTR_HIDDEN,
R_BIN_ATTR_INTERNAL, // same as fileprivate?
R_BIN_ATTR_FRIENDLY,
R_BIN_ATTR_PROTECTED,
R_BIN_ATTR_SEALED,
R_BIN_ATTR_UNSAFE,
R_BIN_ATTR_ASYNC,
R_BIN_ATTR_EXTERN,
R_BIN_ATTR_READONLY,
R_BIN_ATTR_STATIC,
R_BIN_ATTR_CONST,
R_BIN_ATTR_VIRTUAL,
R_BIN_ATTR_MUTATING,
R_BIN_ATTR_FINAL,
R_BIN_ATTR_ABSTRACT,
R_BIN_ATTR_INTERFACE,
R_BIN_ATTR_SYNTHETIC, // synthesized methods
R_BIN_ATTR_SYMBOLIC,
R_BIN_ATTR_VERIFIED,
R_BIN_ATTR_MIRANDA,
R_BIN_ATTR_CONSTRUCTOR,
R_BIN_ATTR_ACCESSOR, // getter / setter
// R_BIN_ATTR_GETTER, // getter / setter
// R_BIN_ATTR_SETTER, // getter / setter
R_BIN_ATTR_OPTIMIZED,
R_BIN_ATTR_ANNOTATED,
R_BIN_ATTR_BRIDGE,
R_BIN_ATTR_STRICT,
R_BIN_ATTR_SYNCHRONIZED,
R_BIN_ATTR_VOLATILE,
R_BIN_ATTR_TRANSIENT,
R_BIN_ATTR_ENUM,
R_BIN_ATTR_NATIVE,
} RBinAttribute;
typedef enum {
R_BIN_RELOC_1 = 1,
@ -192,6 +228,13 @@ typedef struct r_bin_addr_t {
int bits;
} RBinAddr;
typedef struct r_bin_name_t {
// char *name; // user-defined custom name TODO
char *name; // demangled name
char *oname; // original (mangled) name
char *fname; // flag name
} RBinName;
typedef struct r_bin_hash_t {
const char *type;
ut64 addr;
@ -251,10 +294,12 @@ typedef struct r_bin_info_t {
typedef struct r_bin_symbol_t {
/* heap-allocated */
char *name;
char *dname;
char *name; // deprecate and use bname
char *dname; // deprecate and use bname
char *libname;
char *classname;
RBinName *bname; // R2_590
RBinName *cname; // R2_590
/* const-unique-strings */
const char *forwarder;
const char *bind;
@ -568,15 +613,14 @@ typedef struct r_bin_plugin_t {
typedef void (*RBinSymbollCallback)(RBinObject *obj, void *symbol);
typedef struct r_bin_class_t {
char *name;
// TODO: char *module; // namespace
RList *super; // list of char*
char *visibility_str; // XXX only used by java
int index;
char *name; // must be deprecated and use bname only
RBinName *bname; // R2_590
RList *super; // list of RBinName
char *visibility_str; // XXX only used by dex+java should be ut32 or bitfield.. should be usable for swift too
int index; // should be unsigned?
ut64 addr;
char *ns; // namespace
char *ns; // namespace // maybe RBinName?
RList *methods; // <RBinSymbol>
RList *fields; // <RBinField>
// RList *interfaces; // <char *>
@ -616,8 +660,7 @@ typedef struct r_bin_reloc_t {
} RBinReloc;
typedef struct r_bin_string_t {
// TODO: rename string->name (avoid colisions)
char *string;
char *string; // TODO: rename to text or so
ut64 vaddr;
ut64 paddr;
ut32 ordinal;
@ -638,14 +681,19 @@ typedef struct r_bin_field_t {
int size;
int offset;
ut32 visibility;
#if 0
RBinName *type;
RBinName *name;
#else
char *name;
char *type;
#endif
// char *realname;
RBinFieldKind kind;
char *type;
char *comment;
char *format;
bool format_named; // whether format is the name of a format or a raw pf format string
ut64 flags;
ut64 flags; // rename to attr and use R_BIN_ATTR_
} RBinField;
R_API const char *r_bin_field_kindstr(RBinField *f);
@ -862,6 +910,15 @@ 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 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);
R_API void r_bin_name_free(RBinName *bn);
R_API char *r_bin_attr_tostring(ut64 attr);
R_API ut64 r_bin_attr_fromstring(const char *s);
/* filter.c */
typedef struct HtSU_t HtSU;

View File

@ -7,6 +7,22 @@
#include <math.h>
#include "class.h"
static inline RBinName *__bin_name_new(const char *name) {
r_return_val_if_fail (name, NULL);
RBinName *bn = R_NEW0 (RBinName);
bn->oname = strdup (name);
// oname and dname
return bn;
}
static inline void __bin_name_free(RBinName *bn) {
if (bn) {
free (bn->name);
free (bn->oname);
free (bn->fname);
free (bn);
}
}
#ifdef IFDBG
#undef IFDBG
#endif
@ -713,10 +729,10 @@ R_API void r_bin_java_get_class_info_json(RBinJavaObj *bin, PJ *pj) {
pj_ki (pj, "is_enum", is_enum);
pj_ks (pj, "name", klass->name);
if (klass->super) {
const char *sk;
RBinName *bn;
pj_ka (pj, "super");
r_list_foreach (klass->super, iter, sk) {
pj_ks (pj, "super", sk);
r_list_foreach (klass->super, iter, bn) {
pj_ks (pj, "super", bn->name? bn->name: bn->oname);
}
pj_end (pj);
}
@ -2837,21 +2853,17 @@ R_API RList *r_bin_java_get_classes(RBinJavaObj *bin) {
k->name = r_bin_java_get_this_class_name (bin);
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 (free);
r_list_append (k->super, n);
} else {
free (n);
k->super = r_list_newf ((void*)__bin_name_free);
r_list_append (k->super, __bin_name_new (n));
}
free (n);
k->index = (idx++);
k->lang = R_BIN_LANG_JAVA;
r_list_append (classes, k);
r_list_foreach (bin->cp_list, iter, cp_obj) {
if (cp_obj && cp_obj->tag == R_BIN_JAVA_CP_CLASS
&& (this_class_cp_obj != cp_obj && is_class_interface (bin, cp_obj))) {
k = R_NEW0 (RBinClass);
if (!k) {
break;
}
RBinClass *k = R_NEW0 (RBinClass);
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;
@ -2872,8 +2884,7 @@ R_API RBinSymbol *r_bin_java_create_new_symbol_from_invoke_dynamic(RBinJavaCPTyp
R_API RBinSymbol *r_bin_java_create_new_symbol_from_cp_idx(ut32 cp_idx, ut64 baddr) {
RBinSymbol *sym = NULL;
RBinJavaCPTypeObj *obj = r_bin_java_get_item_from_bin_cp_list (
R_BIN_JAVA_GLOBAL_BIN, cp_idx);
RBinJavaCPTypeObj *obj = r_bin_java_get_item_from_bin_cp_list (R_BIN_JAVA_GLOBAL_BIN, cp_idx);
if (obj) {
switch (obj->tag) {
case R_BIN_JAVA_CP_METHODREF:
@ -2895,9 +2906,8 @@ R_API RList *U(r_bin_java_get_fields)(RBinJavaObj * bin) {
RListIter *iter = NULL, *iter_tmp = NULL;
RList *fields = r_list_new ();
RBinJavaField *fm_type;
RBinField *field;
r_list_foreach_safe (bin->fields_list, iter, iter_tmp, fm_type) {
field = r_bin_java_create_new_rbinfield_from_field (fm_type, bin->loadaddr);
RBinField *field = r_bin_java_create_new_rbinfield_from_field (fm_type, bin->loadaddr);
if (field) {
r_list_append (fields, field);
}
@ -2985,20 +2995,21 @@ R_API RList *r_bin_java_get_symbols(RBinJavaObj *bin) {
}
bin->lang = "java";
if (bin->cf.major[1] >= 46) {
static R_TH_LOCAL char lang[32];
int langid;
switch (bin->cf.major[1]) {
static R_TH_LOCAL char lang[32];
int langid;
case 46:
case 47:
case 48:
langid = 2 + (bin->cf.major[1] - 46);
snprintf (lang, sizeof (lang) - 1, "java 1.%d", langid);
bin->lang = lang;
break;
default:
langid = 5 + (bin->cf.major[1] - 49);
snprintf (lang, sizeof (lang) - 1, "java %d", langid);
bin->lang = lang;
case 46:
case 47:
case 48:
langid = 2 + (bin->cf.major[1] - 46);
snprintf (lang, sizeof (lang) - 1, "java 1.%d", langid);
bin->lang = lang;
break;
default:
langid = 5 + (bin->cf.major[1] - 49);
snprintf (lang, sizeof (lang) - 1, "java %d", langid);
bin->lang = lang;
break;
}
}
imports = r_bin_java_get_imports (bin);
@ -3055,12 +3066,11 @@ R_API RList *r_bin_java_get_strings(RBinJavaObj *bin) {
}
R_API void *r_bin_java_free(RBinJavaObj *bin) {
char *bin_obj_key = NULL;
if (!bin) {
return NULL;
}
// Delete the bin object from the data base.
bin_obj_key = r_bin_java_build_obj_key (bin);
char *bin_obj_key = r_bin_java_build_obj_key (bin);
// if (bin->AllJavaBinObjs && sdb_exists (bin->AllJavaBinObjs, bin_obj_key)) {
// sdb_unset (bin->AllJavaBinObjs, bin_obj_key, 0);
// }
@ -3093,6 +3103,7 @@ R_API void *r_bin_java_free(RBinJavaObj *bin) {
}
R_API RBinJavaObj *r_bin_java_new_buf(RBuffer *buf, ut64 loadaddr, Sdb *kv) {
r_return_val_if_fail (buf, NULL);
RBinJavaObj *bin = R_NEW0 (RBinJavaObj);
if (!bin) {
return NULL;
@ -3128,17 +3139,16 @@ R_API void r_bin_java_constant_pool(void /*RBinJavaCPTypeObj*/ *o) {
}
R_API void r_bin_java_fmtype_free(void /*RBinJavaField*/ *f) {
RBinJavaField *fm_type = f;
if (!fm_type) {
return;
if (R_LIKELY (f)) {
RBinJavaField *fm_type = f;
free (fm_type->descriptor);
free (fm_type->name);
free (fm_type->flags_str);
free (fm_type->class_name);
free (fm_type->metas);
r_list_free (fm_type->attributes);
free (fm_type);
}
free (fm_type->descriptor);
free (fm_type->name);
free (fm_type->flags_str);
free (fm_type->class_name);
free (fm_type->metas);
r_list_free (fm_type->attributes);
free (fm_type);
}
// Start Free the various attribute types
R_API void r_bin_java_unknown_attr_free(void /*RBinJavaAttrInfo*/ *a) {

View File

@ -35,10 +35,10 @@ EXPECT=<<EOF
0x100003e30 objc var 1 name
0x100008200 [0x100008200 - 0x100008200] 0 objc class 0 main.Employer :: main.Employee
---
class Employee {
class Employee {
property name : Swift.String;
}
class Employer {
class Employer {
}
@objc
class main.Employee : Swift._SwiftObject {

View File

@ -63,15 +63,15 @@ fs classes
"f method.Employee.shortWord = 0x100001cf0"
"f method.Employee.wideWord = 0x100001d10"
"f method.class.Employee.sayHello = 0x100001be0"
'f field.Employee.var.isa = 0x00000000
'f field.Employee.var._shortWord = 0x100003328
'f field.Employee.var._username = 0x100003330
'f field.Employee.var._firstName = 0x100003338
'f field.Employee.var._wideWord = 0x100003340
'f field.Employee.property.username = 0x00000000
'f field.Employee.property.firstName = 0x00000000
'f field.Employee.property.shortWord = 0x00000000
'f field.Employee.property.wideWord = 0x00000000
"f field.Employee.var.isa = 0x00000000"
"f field.Employee.var._shortWord = 0x100003328"
"f field.Employee.var._username = 0x100003330"
"f field.Employee.var._firstName = 0x100003338"
"f field.Employee.var._wideWord = 0x100003340"
"f field.Employee.property.username = 0x00000000"
"f field.Employee.property.firstName = 0x00000000"
"f field.Employee.property.shortWord = 0x00000000"
"f field.Employee.property.wideWord = 0x00000000"
""td struct Employee { struct objc_class * isa; short _shortWord; struct NSString* _username; struct NSString* _firstName; uint64_t _wideWord; void* username; void* firstName; void* shortWord; void* wideWord;};
EOF
RUN
@ -313,15 +313,15 @@ fs classes
"f method.Employee.wideWord = 0x100007b44"
"f method.Employee..cxx_destruct = 0x100007b60"
"f method.class.Employee.sayHello = 0x100007958"
'f field.Employee.var.isa = 0x00000000
'f field.Employee.var._shortWord = 0x10000c228
'f field.Employee.var._username = 0x10000c22c
'f field.Employee.var._firstName = 0x10000c230
'f field.Employee.var._wideWord = 0x10000c234
'f field.Employee.property.username = 0x00000000
'f field.Employee.property.firstName = 0x00000000
'f field.Employee.property.shortWord = 0x00000000
'f field.Employee.property.wideWord = 0x00000000
"f field.Employee.var.isa = 0x00000000"
"f field.Employee.var._shortWord = 0x10000c228"
"f field.Employee.var._username = 0x10000c22c"
"f field.Employee.var._firstName = 0x10000c230"
"f field.Employee.var._wideWord = 0x10000c234"
"f field.Employee.property.username = 0x00000000"
"f field.Employee.property.firstName = 0x00000000"
"f field.Employee.property.shortWord = 0x00000000"
"f field.Employee.property.wideWord = 0x00000000"
""td struct Employee { struct objc_class * isa; short _shortWord; struct NSString* _username; struct NSString* _firstName; uint64_t _wideWord; void* username; void* firstName; void* shortWord; void* wideWord;};
EOF
RUN
@ -565,15 +565,15 @@ fs classes
"f method.Employee.wideWord = 0x100007ba8"
"f method.Employee..cxx_destruct = 0x100007bc4"
"f method.class.Employee.sayHello = 0x1000079a8"
'f field.Employee.var.isa = 0x00000000
'f field.Employee.var._shortWord = 0x10000c1d8
'f field.Employee.var._username = 0x10000c1dc
'f field.Employee.var._firstName = 0x10000c1e0
'f field.Employee.var._wideWord = 0x10000c1e4
'f field.Employee.property.username = 0x00000000
'f field.Employee.property.firstName = 0x00000000
'f field.Employee.property.shortWord = 0x00000000
'f field.Employee.property.wideWord = 0x00000000
"f field.Employee.var.isa = 0x00000000"
"f field.Employee.var._shortWord = 0x10000c1d8"
"f field.Employee.var._username = 0x10000c1dc"
"f field.Employee.var._firstName = 0x10000c1e0"
"f field.Employee.var._wideWord = 0x10000c1e4"
"f field.Employee.property.username = 0x00000000"
"f field.Employee.property.firstName = 0x00000000"
"f field.Employee.property.shortWord = 0x00000000"
"f field.Employee.property.wideWord = 0x00000000"
""td struct Employee { struct objc_class * isa; short _shortWord; struct NSString* _username; struct NSString* _firstName; uint64_t _wideWord; void* username; void* firstName; void* shortWord; void* wideWord;};
EOF
RUN

View File

@ -721,26 +721,26 @@ colu: 12
addr: 0x00001149
EOF
EXPECT_ERR=<<EOF
DEBUG: [cbin.c:3255] (section .dynstr) Css 141 @ 0x480
DEBUG: [cbin.c:3255] (section .rela.dyn) Cd 8[24] @ 0x550
DEBUG: [cbin.c:3255] (section .rela.plt) Cd 8[3] @ 0x610
DEBUG: [cbin.c:3255] (section .init_array) Cd 8[1] @ 0x3db8
DEBUG: [cbin.c:3255] (section .fini_array) Cd 8[1] @ 0x3dc0
DEBUG: [cbin.c:3255] (section .dynamic) Cd 8[62] @ 0x3dc8
DEBUG: [cbin.c:3255] (section .got) Cd 8[9] @ 0x3fb8
DEBUG: [cbin.c:3255] (section .dynstr) Css 141 @ 0x480
DEBUG: [cbin.c:3255] (section .rela.dyn) Cd 8[24] @ 0x550
DEBUG: [cbin.c:3255] (section .rela.plt) Cd 8[3] @ 0x610
DEBUG: [cbin.c:3255] (section .init_array) Cd 8[1] @ 0x3db8
DEBUG: [cbin.c:3255] (section .fini_array) Cd 8[1] @ 0x3dc0
DEBUG: [cbin.c:3255] (section .dynamic) Cd 8[62] @ 0x3dc8
DEBUG: [cbin.c:3255] (section .got) Cd 8[9] @ 0x3fb8
WARN: [cbin.c:1832] Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
DEBUG: [cbin.c:2520] Cannot resolve symbol address __libc_start_main
DEBUG: [cbin.c:2520] Cannot resolve symbol address _ITM_deregisterTMCloneTable
DEBUG: [cbin.c:2520] Cannot resolve symbol address __gmon_start__
DEBUG: [cbin.c:2520] Cannot resolve symbol address _ITM_registerTMCloneTable
DEBUG: [cbin.c:2520] Cannot resolve symbol address __cxa_finalize
DEBUG: [cbin.c:3268] (section .dynstr) Css 141 @ 0x480
DEBUG: [cbin.c:3268] (section .rela.dyn) Cd 8[24] @ 0x550
DEBUG: [cbin.c:3268] (section .rela.plt) Cd 8[3] @ 0x610
DEBUG: [cbin.c:3268] (section .init_array) Cd 8[1] @ 0x3db8
DEBUG: [cbin.c:3268] (section .fini_array) Cd 8[1] @ 0x3dc0
DEBUG: [cbin.c:3268] (section .dynamic) Cd 8[62] @ 0x3dc8
DEBUG: [cbin.c:3268] (section .got) Cd 8[9] @ 0x3fb8
DEBUG: [cbin.c:3268] (section .dynstr) Css 141 @ 0x480
DEBUG: [cbin.c:3268] (section .rela.dyn) Cd 8[24] @ 0x550
DEBUG: [cbin.c:3268] (section .rela.plt) Cd 8[3] @ 0x610
DEBUG: [cbin.c:3268] (section .init_array) Cd 8[1] @ 0x3db8
DEBUG: [cbin.c:3268] (section .fini_array) Cd 8[1] @ 0x3dc0
DEBUG: [cbin.c:3268] (section .dynamic) Cd 8[62] @ 0x3dc8
DEBUG: [cbin.c:3268] (section .got) Cd 8[9] @ 0x3fb8
WARN: [cbin.c:1845] Relocs has not been applied. Please use `-e bin.relocs.apply=true` or `-e bin.cache=true` next time
DEBUG: [cbin.c:2533] Cannot resolve symbol address __libc_start_main
DEBUG: [cbin.c:2533] Cannot resolve symbol address _ITM_deregisterTMCloneTable
DEBUG: [cbin.c:2533] Cannot resolve symbol address __gmon_start__
DEBUG: [cbin.c:2533] Cannot resolve symbol address _ITM_registerTMCloneTable
DEBUG: [cbin.c:2533] Cannot resolve symbol address __cxa_finalize
EOF
RUN

View File

@ -4,7 +4,7 @@ CMDS=<<EOF
icc
EOF
EXPECT=<<EOF
class SomeClass {
class SomeClass {
property meh : Swift.Int;
property cow : Swift.Int;
func 0() {} // 0x100003cff
@ -18,7 +18,7 @@ class SomeClass {
func 8() {} // 0x100003d2c
func 9() {} // 0x100003d34
}
class SuperKlass {
class SuperKlass {
property superfield : Swift.Int;
func superfield.allocator__Swift.Int() {} // 0x1000028f0
func superfield.allocator__Swift.Int() {} // 0x100002950
@ -37,7 +37,7 @@ class klass.SuperKlass : Swift._SwiftObject {
var isa : struct objc_class *;
var superfield;
}
class swift {
class swift {
func getRootSuperclass() {} // 0x100002b70
func swift51override_conformsToSwiftProtocol(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*, llvm::StringRef, swift::TargetProtocolConformanceDescriptor<swift::InProcess> const* (*)(swift::TargetMetadata<swift::InProcess> const*, swift::TargetProtocolDescriptor<swift::InProcess> const*, llvm::StringRef)) {} // 0x100002bb0
func Lazy<(anonymous namespace)::ConformanceState>::defaultInitCallback(void*) {} // 0x1000031f0