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

bicto #22847

Open
wants to merge 4 commits into
base: master
Choose a base branch
from
Open

bicto #22847

Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
62 changes: 59 additions & 3 deletions libr/bin/bfile.c
Original file line number Diff line number Diff line change
Expand Up @@ -8,9 +8,15 @@
#define R_STRING_SCAN_BUFFER_SIZE 4096
#define R_STRING_MAX_UNI_BLOCKS 4

static RBinClass *__getClass(RBinFile *bf, const char *name) {
static RBinClass *get_class(RBinFile *bf, const char *name) {
R_RETURN_VAL_IF_FAIL (bf && bf->bo && bf->bo->classes_ht && name, NULL);
#if R2_USE_NEW_ABI
void *htidxptr = ht_pp_find (bf->bo->classes_ht, name, NULL);
int htidx = (int)(size_t)htidxptr;
return RVecRBinClass_at (&bf->bo->classes, htidx - 1);
#else
return ht_pp_find (bf->bo->classes_ht, name, NULL);
#endif
}

static RBinSymbol *__getMethod(RBinFile *bf, const char *klass, const char *method) {
Expand Down Expand Up @@ -1092,20 +1098,49 @@ R_API RBinClass *r_bin_class_new(const char *name, const char *super, ut64 attr)
return c;
}

R_API void r_bin_class_free(RBinClass *k) {
#if R2_USE_NEW_ABI
R_API void r_bin_class_init(RBinClass *c, const char *name, const char *super, ut64 attr) {
R_RETURN_IF_FAIL (c && name);
c->name = r_bin_name_new (name);
if (R_STR_ISNOTEMPTY (super)) {
c->super = r_list_newf (free);
r_list_append (c->super, r_bin_name_new (super));
}
// TODO: use vectors!
c->methods = r_list_newf (r_bin_symbol_free);
c->fields = r_list_newf (r_bin_field_free);
c->attr = attr;
}

R_API void r_bin_class_fini(RBinClass *k) {
if (k) {
free (k->name);
r_list_free (k->super);
free (k->visibility_str);
r_list_free (k->methods);
r_list_free (k->fields);
}
}
#else
static inline void r_bin_class_fini(RBinClass *k) {
free (k->name);
r_list_free (k->super);
free (k->visibility_str);
r_list_free (k->methods);
r_list_free (k->fields);
}
#endif

R_API void r_bin_class_free(RBinClass *k) {
if (k) {
r_bin_class_fini (k),
free (k);
}
}

R_API RBinClass *r_bin_file_add_class(RBinFile *bf, const char *name, const char *super, ut64 attr) {
R_RETURN_VAL_IF_FAIL (name && bf && bf->bo, NULL);
RBinClass *c = __getClass (bf, name);
RBinClass *c = get_class (bf, name);
if (c) {
if (R_STR_ISNOTEMPTY (super)) {
r_list_free (c->super);
Expand All @@ -1114,13 +1149,30 @@ R_API RBinClass *r_bin_file_add_class(RBinFile *bf, const char *name, const char
}
return c;
}
#if R2_USE_NEW_ABI
RBinClass bc = {0};
r_bin_class_init (&bc, name, super, attr);
bc.index = RVecRBinClass_length (&bf->bo->classes);
RVecRBinClass_push_back (&bf->bo->classes, &bc);
// free (c);
// const int htidx = bc.index + 1;
const int htidx = RVecRBinClass_length (&bf->bo->classes); // bc.index + 1;
ht_pp_update (bf->bo->classes_ht, name, (void*)(size_t)htidx);
// eprintf ("0-> %s (%s)\n", r_bin_name_tostring (c->name), name);
c = RVecRBinClass_last (&bf->bo->classes);
// eprintf ("1-> %s (%s)\n", r_bin_name_tostring (c->name), name);
// free (c);
// c = RVecRBinClass_at (&bf->bo->classes, 0);
// return c;
#else
c = r_bin_class_new (name, super, attr);
if (c) {
// XXX. no need for a list, the ht is iterable too
c->index = r_list_length (bf->bo->classes);
r_list_append (bf->bo->classes, c);
ht_pp_insert (bf->bo->classes_ht, name, c);
}
#endif
return c;
}

Expand All @@ -1142,8 +1194,11 @@ R_API RBinSymbol *r_bin_file_add_method(RBinFile *bf, const char *klass, const c
sym->lang = lang;
char *name = r_str_newf ("%s::%s", klass, method);
ht_pp_insert (bf->bo->methods_ht, name, sym);
#if R2_USE_NEW_ABI
#else
// RBinSymbol *dsym = r_bin_symbol_clone (sym);
r_list_append (c->methods, sym);
#endif
free (name);
}
}
Expand Down Expand Up @@ -1220,6 +1275,7 @@ R_API RBinFile *r_bin_file_open(RBin *bin, const char *file, RBinFileOptions *op

// TODO Improve this API
R_API void r_bin_file_merge(RBinFile *dst, RBinFile *src) {
R_RETURN_IF_FAIL (dst && src);
// merge imports
// merge dbginfo
sdb_merge (dst->bo->kv, src->bo->kv);
Expand Down
8 changes: 8 additions & 0 deletions libr/bin/bin.c
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ R_API void r_bin_string_free(void *_str) {
}
}

// R2_600 - return RBinFile instead of bool. avoid toctou
R_API bool r_bin_open(RBin *bin, const char *file, RBinFileOptions *opt) {
R_RETURN_VAL_IF_FAIL (bin && bin->iob.io && opt, false);

Expand Down Expand Up @@ -270,6 +271,7 @@ R_API bool r_bin_reload(RBin *bin, ut32 bf_id, ut64 baseaddr) {
return res;
}

// R2_600 - return RBinFile instead of bool. avoid toctou
R_API bool r_bin_open_buf(RBin *bin, RBuffer *buf, RBinFileOptions *opt) {
R_RETURN_VAL_IF_FAIL (bin && opt, false);

Expand Down Expand Up @@ -318,10 +320,12 @@ R_API bool r_bin_open_buf(RBin *bin, RBuffer *buf, RBinFileOptions *opt) {
return false;
}
// r_ref (bf);
// return bf instead of bool!
bin->cur = bf;
return res;
}

// R2_600 - return RBinFile instead of bool. avoid toctou
R_API bool r_bin_open_io(RBin *bin, RBinFileOptions *opt) {
R_RETURN_VAL_IF_FAIL (bin && opt && bin->iob.io, false);
R_RETURN_VAL_IF_FAIL (opt->fd >= 0 && (st64)opt->sz >= 0, false);
Expand Down Expand Up @@ -1303,11 +1307,15 @@ R_API RBuffer *r_bin_package(RBin *bin, const char *type, const char *file, RLis
return NULL;
}

#if R2_USE_NEW_ABI
// this api is deprecated. just access the binobject instead
#else
R_API RList* /*<RBinClass>*/ r_bin_get_classes(RBin *bin) {
R_RETURN_VAL_IF_FAIL (bin, NULL);
RBinObject *bo = r_bin_cur_object (bin);
return bo ? bo->classes : NULL;
}
#endif

/* returns vaddr, rebased with the baseaddr of bin, if va is enabled for bin, * paddr otherwise */
R_API ut64 r_bin_get_vaddr(RBin *bin, ut64 paddr, ut64 vaddr) {
Expand Down
79 changes: 64 additions & 15 deletions libr/bin/bobj.c
Original file line number Diff line number Diff line change
Expand Up @@ -51,7 +51,11 @@ static void object_delete_items(RBinObject *o) {
}
r_list_free (o->symbols);

#if R2_USE_NEW_ABI
RVecRBinClass_fini (&o->classes);
#else
r_list_free (o->classes);
#endif
ht_pp_free (o->classes_ht);
ht_pp_free (o->methods_ht);
r_list_free (o->lines);
Expand Down Expand Up @@ -168,7 +172,7 @@ static void classes_from_symbols2(RBinFile *bf, RBinSymbol *sym) {
}
}

static RList *classes_from_symbols(RBinFile *bf) {
static void classes_from_symbols(RBinFile *bf) {
RBinSymbol *sym;
RListIter *iter;
// TODO: Use rvec here
Expand All @@ -181,7 +185,6 @@ static RList *classes_from_symbols(RBinFile *bf) {
classes_from_symbols2 (bf, sym);
}
}
return bf->bo->classes;
}

// TODO: kill offset and sz, because those should be inferred from binfile->buf
Expand All @@ -198,7 +201,11 @@ R_IPI RBinObject *r_bin_object_new(RBinFile *bf, RBinPlugin *plugin, ut64 basead
bo->regstate = NULL;
bo->kv = sdb_new0 (); // XXX bf->sdb bf->bo->sdb wtf
bo->baddr = baseaddr;
#if R2_USE_NEW_ABI
RVecRBinClass_init (&bo->classes);
#else
bo->classes = r_list_newf ((RListFree)r_bin_class_free);
#endif
bo->classes_ht = ht_pp_new0 ();
bo->methods_ht = ht_pp_new0 ();
bo->baddr_shift = 0;
Expand Down Expand Up @@ -258,13 +265,19 @@ R_IPI RBinObject *r_bin_object_new(RBinFile *bf, RBinPlugin *plugin, ut64 basead
return bo;
}

static void filter_classes(RBinFile *bf, RList *list) {
static void filter_classes(RBinFile *bf) {
HtSU *db = ht_su_new0 ();
HtPP *ht = ht_pp_new0 ();
RListIter *iter, *iter2;
RBinClass *cls;
RBinSymbol *sym;
r_list_foreach (list, iter, cls) {
#if R2_USE_NEW_ABI
RListIter *iter2;
R_VEC_FOREACH (&bf->bo->classes, cls)
#else
RListIter *iter, *iter2;
r_list_foreach (bf->bo->classes, iter, cls)
#endif
{
const char *kname = r_bin_name_tostring (cls->name);
char *fname = r_bin_filter_name (bf, db, cls->index, kname);
if (fname) {
Expand Down Expand Up @@ -298,14 +311,32 @@ static void r_bin_object_rebuild_classes_ht(RBinObject *bo) {
ht_pp_free (bo->methods_ht);
bo->methods_ht = ht_pp_new0 ();

#if R2_USE_NEW_ABI
RListIter *it2;
#else
RListIter *it, *it2;
#endif
RBinClass *klass;
RBinSymbol *method;
r_list_foreach (bo->classes, it, klass) {
#if R2_USE_NEW_ABI
int klass_idx = 0;
R_VEC_FOREACH (&bo->classes, klass)
#else
r_list_foreach (bo->classes, it, klass)
#endif
{
if (klass->name) {
ht_pp_insert (bo->classes_ht, klass->name, klass);
const char *klass_name = r_bin_name_tostring (klass->name);
#if R2_USE_NEW_ABI
void *htidxptr = (void*)(size_t)klass_idx;
ht_pp_insert (bo->classes_ht, klass_name, htidxptr);
klass_idx++;
/// TODO
#else
ht_pp_insert (bo->classes_ht, klass_name, klass);
#endif
r_list_foreach (klass->methods, it2, method) {
const char *klass_name = r_bin_name_tostring (klass->name);
// const char *klass_name = r_bin_name_tostring (klass->name);
const char *method_name = r_bin_name_tostring (method->name);
char *name = r_str_newf ("%s::%s", klass_name, method_name);
ht_pp_insert (bo->methods_ht, name, method);
Expand Down Expand Up @@ -429,26 +460,43 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) {
}
if (bin->filter_rules & R_BIN_REQ_CLASSES) {
if (p->classes) {
#if R2_USE_NEW_ABI
p->classes (bf);
#else
RList *classes = p->classes (bf);
if (classes) {
// XXX we should probably merge them instead
r_list_free (bo->classes);
bo->classes = classes;
r_bin_object_rebuild_classes_ht (bo);
}
#endif
r_bin_object_rebuild_classes_ht (bo);
isSwift = r_bin_lang_swift (bf);
if (isSwift) {
bo->classes = classes_from_symbols (bf);
classes_from_symbols (bf);
bo->classes = bf->bo->classes; // XXX unnecessary i think
}
} else {
RList *classes = classes_from_symbols (bf);
if (classes) {
bo->classes = classes;
}
classes_from_symbols (bf);
bo->classes = bf->bo->classes;
}
if (bin->filter) {
filter_classes (bf, bo->classes);
filter_classes (bf);
}
#if R2_USE_NEW_ABI
if (RVecRBinClass_length (&bo->classes) > 0 && !bo->addr2klassmethod) {
RListIter *iter;
RBinClass *klass;
RBinSymbol *method;
bo->addr2klassmethod = ht_up_new0 ();
R_VEC_FOREACH (&bo->classes, klass) {
// this is slow. must be optimized, but at least its cached
r_list_foreach (klass->methods, iter, method) {
ht_up_insert (bo->addr2klassmethod, method->vaddr, method);
}
}
}
#else
// cache addr=class+method
if (bo->classes) {
RList *klasses = bo->classes;
Expand All @@ -465,6 +513,7 @@ R_API int r_bin_object_set_items(RBinFile *bf, RBinObject *bo) {
}
}
}
#endif
}
if (p->lines) {
bo->lines = p->lines (bf);
Expand Down
4 changes: 4 additions & 0 deletions libr/bin/format/dex/dex.h
Original file line number Diff line number Diff line change
Expand Up @@ -142,7 +142,11 @@ typedef struct r_bin_dex_obj_t {
RList *methods_list;
RList *trycatch_list;
RList *imports_list;
#if R2_USE_NEW_ABI
// it's stored in RBinObject
#else
RList *classes_list;
#endif
RList *lines_list;
ut64 code_from;
ut64 code_to;
Expand Down