mirror of
https://github.com/radareorg/radare2.git
synced 2025-02-10 00:02:39 +00:00
Implement icc*, in sync with ic* to get C strcuts from mach0 classes into r2 ##bin
This commit is contained in:
parent
2b0962af31
commit
5881fcd2e1
125
libr/core/cbin.c
125
libr/core/cbin.c
@ -3060,6 +3060,84 @@ static int bin_trycatch(RCore *core, int mode) {
|
||||
return true;
|
||||
}
|
||||
|
||||
// https://nshipster.com/type-encodings/
|
||||
static char *objc_type_toc(const char *objc_type) {
|
||||
if (!objc_type) {
|
||||
return strdup ("void*");
|
||||
}
|
||||
if (*objc_type == '^' && objc_type[1] == '{') {
|
||||
char *a = strdup (objc_type + 2);
|
||||
char *b = strchr (a, '>');
|
||||
if (b) {
|
||||
*b = 0;
|
||||
}
|
||||
a[strlen (a) - 1] = 0;
|
||||
return a;
|
||||
}
|
||||
if (*objc_type == '<') {
|
||||
char *a = strdup (objc_type + 1);
|
||||
char *b = strchr (a, '>');
|
||||
if (b) {
|
||||
*b = 0;
|
||||
}
|
||||
return a;
|
||||
}
|
||||
if (!strcmp (objc_type, "f")) { return strdup ("float"); }
|
||||
if (!strcmp (objc_type, "d")) { return strdup ("double"); }
|
||||
if (!strcmp (objc_type, "i")) { return strdup ("int"); }
|
||||
if (!strcmp (objc_type, "s")) { return strdup ("short"); }
|
||||
if (!strcmp (objc_type, "l")) { return strdup ("long"); }
|
||||
if (!strcmp (objc_type, "L")) { return strdup ("unsigned long"); }
|
||||
if (!strcmp (objc_type, "*")) { return strdup ("char*"); }
|
||||
if (!strcmp (objc_type, "c")) { return strdup ("bool"); }
|
||||
if (!strcmp (objc_type, "v")) { return strdup ("void"); }
|
||||
if (!strcmp (objc_type, "#")) { return strdup ("class"); }
|
||||
if (!strcmp (objc_type, "B")) { return strdup ("cxxbool"); }
|
||||
if (!strcmp (objc_type, "Q")) { return strdup ("uint64_t"); }
|
||||
if (!strcmp (objc_type, "q")) { return strdup ("long long"); }
|
||||
if (!strcmp (objc_type, "C")) { return strdup ("uint8_t"); }
|
||||
if (strlen (objc_type) == 1) {
|
||||
eprintf ("Unknown objc type '%s'\n", objc_type);
|
||||
}
|
||||
if (r_str_startswith (objc_type, "@\"")) {
|
||||
char *s = r_str_newf ("struct %s", objc_type + 2);
|
||||
s[strlen (s) - 1] = '*';
|
||||
return s;
|
||||
}
|
||||
return strdup (objc_type);
|
||||
}
|
||||
|
||||
static char *objc_name_toc(const char *objc_name) {
|
||||
const char *n = r_str_lchr (objc_name, ')');
|
||||
char *s = strdup (n? n + 1: objc_name);
|
||||
char *p = strchr (s, '(');
|
||||
if (p) {
|
||||
*p = 0;
|
||||
}
|
||||
return s;
|
||||
}
|
||||
|
||||
static void classdump_c(RCore *r, RBinClass *c) {
|
||||
r_cons_printf ("typedef struct class_%s {\n", c->name);
|
||||
RListIter *iter2;
|
||||
RBinField *f;
|
||||
// XXX this is a hack because r2 doesnt supports empty structs yet
|
||||
// XXX https://github.com/radareorg/radare2/issues/16342
|
||||
if (r_list_empty (c->fields)) {
|
||||
r_cons_printf ("void *padding;\n");
|
||||
}
|
||||
r_list_foreach (c->fields, iter2, f) {
|
||||
if (f->type && f->name) {
|
||||
char *n = objc_name_toc (f->name);
|
||||
char *t = objc_type_toc (f->type);
|
||||
r_cons_printf (" %s %s; // %d\n", t, n, f->offset);
|
||||
free (t);
|
||||
free (n);
|
||||
}
|
||||
}
|
||||
r_cons_printf ("} %s;\n\n", c->name);
|
||||
}
|
||||
|
||||
static void classdump_objc(RCore *r, RBinClass *c) {
|
||||
if (c->super) {
|
||||
r_cons_printf ("@interface %s : %s\n{\n", c->name, c->super);
|
||||
@ -3143,7 +3221,7 @@ static int bin_classes(RCore *r, int mode) {
|
||||
return false;
|
||||
}
|
||||
r_flag_space_set (r->flags, R_FLAGS_FS_CLASSES);
|
||||
} else if (IS_MODE_RAD (mode)) {
|
||||
} else if (IS_MODE_RAD (mode) && !IS_MODE_CLASSDUMP (mode)) {
|
||||
r_cons_println ("fs classes");
|
||||
}
|
||||
|
||||
@ -3194,6 +3272,21 @@ static int bin_classes(RCore *r, int mode) {
|
||||
r_cons_printf ("0x%08"PFMT64x" [0x%08"PFMT64x" - 0x%08"PFMT64x"] %s%s%s\n",
|
||||
c->addr, at_min, at_max, c->name, c->super ? " " : "",
|
||||
c->super ? c->super : "");
|
||||
} else if (IS_MODE_CLASSDUMP (mode)) {
|
||||
if (c) {
|
||||
RBinFile *bf = r_bin_cur (r->bin);
|
||||
if (bf && bf->o) {
|
||||
if (IS_MODE_RAD (mode)) {
|
||||
classdump_c (r, c);
|
||||
} else if (bf->o->lang == R_BIN_NM_JAVA || (bf->o->info && bf->o->info->lang && strstr (bf->o->info->lang, "dalvik"))) {
|
||||
classdump_java (r, c);
|
||||
} else {
|
||||
classdump_objc (r, c);
|
||||
}
|
||||
} else {
|
||||
classdump_objc (r, c);
|
||||
}
|
||||
}
|
||||
} else if (IS_MODE_RAD (mode)) {
|
||||
char *n = __filterShell (name);
|
||||
r_cons_printf ("\"f class.%s = 0x%"PFMT64x"\"\n", n, at_min);
|
||||
@ -3228,6 +3321,23 @@ static int bin_classes(RCore *r, int mode) {
|
||||
}
|
||||
R_FREE (mflags);
|
||||
}
|
||||
r_list_foreach (c->fields, iter2, f) {
|
||||
char *fn = r_str_newf ("field.%s.%s", c->name, f->name);
|
||||
ut64 at = f->vaddr; // sym->vaddr + (f->vaddr & 0xffff);
|
||||
r_cons_printf ("\"f %s = 0x%08"PFMT64x"\"\n", fn, at);
|
||||
free (fn);
|
||||
}
|
||||
|
||||
// C struct
|
||||
r_cons_printf ("\"td struct %s {", c->name);
|
||||
r_list_foreach (c->fields, iter2, f) {
|
||||
char *n = objc_name_toc (f->name);
|
||||
char *t = objc_type_toc (f->type);
|
||||
r_cons_printf (" %s %s;", t, n);
|
||||
free (t);
|
||||
free (n);
|
||||
}
|
||||
r_cons_printf ("};\"\n");
|
||||
} else if (IS_MODE_JSON (mode)) {
|
||||
if (c->super) {
|
||||
r_cons_printf ("%s{\"classname\":\"%s\",\"addr\":%"PFMT64d",\"index\":%d,\"visibility\":\"%s\",\"super\":\"%s\",\"methods\":[",
|
||||
@ -3262,19 +3372,6 @@ static int bin_classes(RCore *r, int mode) {
|
||||
}
|
||||
}
|
||||
r_cons_printf ("]}");
|
||||
} else if (IS_MODE_CLASSDUMP (mode)) {
|
||||
if (c) {
|
||||
RBinFile *bf = r_bin_cur (r->bin);
|
||||
if (bf && bf->o) {
|
||||
if (bf->o->lang == R_BIN_NM_JAVA || (bf->o->info && bf->o->info->lang && strstr (bf->o->info->lang, "dalvik"))) {
|
||||
classdump_java (r, c);
|
||||
} else {
|
||||
classdump_objc (r, c);
|
||||
}
|
||||
} else {
|
||||
classdump_objc (r, c);
|
||||
}
|
||||
}
|
||||
} else {
|
||||
int m = 0;
|
||||
r_cons_printf ("0x%08"PFMT64x" [0x%08"PFMT64x" - 0x%08"PFMT64x"] %6"PFMT64d" class %d %s",
|
||||
|
@ -1045,7 +1045,7 @@ static int cmd_info(void *data, const char *input) {
|
||||
if (!obj) {
|
||||
break;
|
||||
}
|
||||
if (input[2] && input[2] != 'j' && !strstr (input, "qq")) {
|
||||
if (input[2] && input[2] != '*' && input[2] != 'j' && !strstr (input, "qq")) {
|
||||
bool radare2 = strstr (input, "**") != NULL;
|
||||
int idx = -1;
|
||||
const char * cls_name = NULL;
|
||||
@ -1134,7 +1134,7 @@ static int cmd_info(void *data, const char *input) {
|
||||
r_cons_printf ("%s\n", cls->name);
|
||||
}
|
||||
}
|
||||
} else if (input[1] == 'l' && obj) { // "icl"
|
||||
} else if (input[1] == 'l') { // "icl"
|
||||
r_list_foreach (obj->classes, iter, cls) {
|
||||
r_list_foreach (cls->methods, iter2, sym) {
|
||||
const char *comma = iter2->p? " ": "";
|
||||
@ -1144,8 +1144,11 @@ static int cmd_info(void *data, const char *input) {
|
||||
r_cons_newline ();
|
||||
}
|
||||
}
|
||||
} else if (input[1] == 'c' && obj) { // "icc"
|
||||
} else if (input[1] == 'c') { // "icc"
|
||||
mode = R_MODE_CLASSDUMP;
|
||||
if (input[2] == '*') {
|
||||
mode |= R_MODE_RADARE;
|
||||
}
|
||||
RBININFO ("classes", R_CORE_BIN_ACC_CLASSES, NULL, r_list_length (obj->classes));
|
||||
input = " ";
|
||||
} else { // "icq"
|
||||
|
Loading…
x
Reference in New Issue
Block a user