Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

WIP: Early catch some missbehaves in the class parsing and speedup ma… #23068

Merged
merged 3 commits into from
Jul 9, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 9 additions & 5 deletions libr/bin/bobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -267,10 +267,12 @@ static void filter_classes(RBinFile *bf, RList *list) {
r_list_foreach (list, iter, cls) {
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);
if (R_STR_ISEMPTY (fname)) {
R_LOG_INFO ("Corrupted class storage with nameless classes");
break;
}
r_bin_name_update (cls->name, fname);
free (fname);
r_list_foreach (cls->methods, iter2, sym) {
r_bin_filter_sym (bf, ht, sym->vaddr, sym);
}
Expand Down Expand Up @@ -325,7 +327,6 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) {
int minlen = (bf->rbin->minstrlen > 0) ? bf->rbin->minstrlen : p->minstrlen;
bf->bo = bo;

#if 0
bo->info = p->info? p->info (bf): NULL;
if (bo->info && bo->info->type) {
if (strstr (bo->info->type, "CORE")) {
Expand All @@ -337,7 +338,6 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) {
}
}
}
#endif
// XXX: no way to get info from xtr pluginz?
// Note, object size can not be set from here due to potential
// inconsistencies
Expand Down Expand Up @@ -450,6 +450,9 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) {
filter_classes (bf, bo->classes);
}
// cache addr=class+method
#if 0
// moved into libr/core/canal.c
// XXX SLOW on large binaries. only used when needed by getFunctionName from canal.c
if (bo->classes) {
RList *klasses = bo->classes;
RListIter *iter, *iter2;
Expand All @@ -465,6 +468,7 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) {
}
}
}
#endif
}
if (p->lines) {
bo->lines = p->lines (bf);
Expand Down
18 changes: 17 additions & 1 deletion libr/bin/format/objc/mach0_classes.c
Original file line number Diff line number Diff line change
Expand Up @@ -835,12 +835,16 @@ static void get_method_list(RBinFile *bf, RBinClass *klass, const char *class_na
name = malloc (name_len + 1);
len = r_buf_read_at (bf->buf, r, (ut8 *)name, name_len);
name[name_len] = 0;
// eprintf ("%d %d\n", name_len, strlen (name));
if (len < 1) {
goto error;
}
}
if (class_name) { // XXX to save memory we can just ref the RBinName instance from the class
method->classname = strdup (class_name);
} else {
R_LOG_ERROR ("Invalid class name for method. Avoid parsing invalid data");
goto error;
}
method->name = r_bin_name_new (name);
R_FREE (name);
Expand Down Expand Up @@ -1293,6 +1297,8 @@ static void get_class_ro_t(RBinFile *bf, bool *is_meta_class, RBinClass *klass,
return;
}
if (bin->has_crypto) {
R_LOG_ERROR ("Not parsing encrypted data");
return;
const char kn[] = "some_encrypted_data";
klass->name = r_bin_name_new (kn);
// klass->name = strdup ("some_encrypted_data");
Expand Down Expand Up @@ -1853,7 +1859,13 @@ 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) (bf, klass, p, false, relocs, oi);
if (!klass->name) {
if (klass->name) {
const char *klass_name = r_bin_name_tostring (klass->name);
if (strlen (klass_name) > 512) {
R_LOG_INFO ("Invalid class name, probably corrupted binary");
break;
}
} else {
char *klass_name = r_str_newf ("UnnamedClass%" PFMT64d, num_of_unnamed_class);
klass->name = r_bin_name_new (klass_name);
free (klass_name);
Expand Down Expand Up @@ -2049,6 +2061,10 @@ void MACH0_(get_category_t)(RBinFile *bf, RBinClass *klass, mach0_ut p, const RS
R_FREE (category_name);

const char *klass_name = r_bin_name_tostring (klass->name);
if (R_STR_ISEMPTY (klass_name)) {
R_LOG_ERROR ("Invalid class name");
return;
}
if (c.instanceMethods > 0) {
get_method_list (bf, klass, klass_name, false, oi, c.instanceMethods);
}
Expand Down
18 changes: 18 additions & 0 deletions libr/core/canal.c
Original file line number Diff line number Diff line change
Expand Up @@ -89,9 +89,27 @@ static int cmpaddr(const void *_a, const void *_b) {
return (a->addr > b->addr)? 1: (a->addr < b->addr)? -1: 0;
}

static void init_addr2klass(RCore *core, RBinObject *bo) {
if (bo->addr2klassmethod) {
return;
}
RList *klasses = bo->classes;
RListIter *iter, *iter2;
RBinClass *klass;
RBinSymbol *method;
// this is slow. must be optimized, but at least its cached
bo->addr2klassmethod = ht_up_new0 ();
r_list_foreach (klasses, iter, klass) {
r_list_foreach (klass->methods, iter2, method) {
ht_up_insert (bo->addr2klassmethod, method->vaddr, method);
}
}
}

static char *get_function_name(RCore *core, ut64 addr) {
RBinFile *bf = r_bin_cur (core->bin);
if (bf && bf->bo) {
init_addr2klass (core, bf->bo);
RBinSymbol *sym = ht_up_find (bf->bo->addr2klassmethod, addr, NULL);
if (sym && sym->classname && sym->name) {
const char *sym_name = r_bin_name_tostring (sym->name);
Expand Down
2 changes: 2 additions & 0 deletions test/db/formats/mach0/swift
Original file line number Diff line number Diff line change
Expand Up @@ -2044,6 +2044,7 @@ EXPECT=<<EOF
},
{
"classname": "WheresMyBrowser.LoadContentViewController",
"rawclassname": "_TtC15WheresMyBrowser25LoadContentViewController",
"addr": 4295178328,
"lang": "objc",
"index": 0,
Expand Down Expand Up @@ -2161,6 +2162,7 @@ EXPECT=<<EOF
},
{
"classname": "WheresMyBrowser.UIWebViewController",
"rawclassname": "_TtC15WheresMyBrowser19UIWebViewController",
"addr": 4295178472,
"lang": "objc",
"index": 0,
Expand Down
Loading