diff --git a/libr/anal/rtti.c b/libr/anal/rtti.c index 87415e3bda..ad8b492ca9 100644 --- a/libr/anal/rtti.c +++ b/libr/anal/rtti.c @@ -2,17 +2,17 @@ #include "r_anal.h" -R_API void r_anal_rtti_print_at_vtable(RAnal *anal, ut64 addr) { +R_API void r_anal_rtti_print_at_vtable(RAnal *anal, ut64 addr, int mode) { RVTableContext context; r_anal_vtable_begin (anal, &context); if (context.abi == R_ANAL_CPP_ABI_MSVC) { - r_anal_rtti_msvc_print_at_vtable (&context, addr); + r_anal_rtti_msvc_print_at_vtable (&context, addr, mode); } else { eprint ("RTTI not supported yet for Itanium.\n"); } } -static void rtti_msvc_print_all(RVTableContext *context) { +static void rtti_msvc_print_all(RVTableContext *context, int mode) { r_cons_break_push (NULL, NULL); RList *vtables = r_anal_vtable_search (context); RListIter *vtableIter; @@ -23,7 +23,7 @@ static void rtti_msvc_print_all(RVTableContext *context) { if (r_cons_is_breaked ()) { break; } - r_anal_rtti_msvc_print_at_vtable (context, table->saddr); + r_anal_rtti_msvc_print_at_vtable (context, table->saddr, mode); r_cons_print ("\n"); } } @@ -32,11 +32,11 @@ static void rtti_msvc_print_all(RVTableContext *context) { r_cons_break_pop (); } -R_API void r_anal_rtti_print_all(RAnal *anal) { +R_API void r_anal_rtti_print_all(RAnal *anal, int mode) { RVTableContext context; r_anal_vtable_begin (anal, &context); if (context.abi == R_ANAL_CPP_ABI_MSVC) { - rtti_msvc_print_all (&context); + rtti_msvc_print_all (&context, mode); } else { eprint ("RTTI not supported yet for Itanium.\n"); } diff --git a/libr/anal/rtti_msvc.c b/libr/anal/rtti_msvc.c index a21a47f36c..59f7ebe8e5 100644 --- a/libr/anal/rtti_msvc.c +++ b/libr/anal/rtti_msvc.c @@ -44,6 +44,10 @@ static void rtti_type_descriptor_fini(rtti_type_descriptor *td) { } static bool rtti_msvc_read_complete_object_locator(RVTableContext *context, ut64 addr, rtti_complete_object_locator *col) { + if (addr == UT64_MAX) { + return false; + } + ut8 buf[3 * sizeof (ut32) + 2 * sizeof (ut64)]; int colSize = 3 * sizeof (ut32) + 2 * context->word_size; if (colSize > sizeof (buf)) { @@ -64,6 +68,10 @@ static bool rtti_msvc_read_complete_object_locator(RVTableContext *context, ut64 } static bool rtti_msvc_read_class_hierarchy_descriptor(RVTableContext *context, ut64 addr, rtti_class_hierarchy_descriptor *chd) { + if (addr == UT64_MAX) { + return false; + } + ut8 buf[3 * sizeof (ut32) + sizeof (ut64)]; int chdSize = 3 * sizeof (ut32) + context->word_size; if (chdSize > sizeof (buf)) { @@ -87,6 +95,10 @@ static ut64 rtti_msvc_base_class_descriptor_size(RVTableContext *context) { } static bool rtti_msvc_read_base_class_descriptor(RVTableContext *context, ut64 addr, rtti_base_class_descriptor *bcd) { + if (addr == UT64_MAX) { + return false; + } + ut8 buf[sizeof (ut64) + 5 * sizeof (ut32)]; int bcdSize = (int) rtti_msvc_base_class_descriptor_size (context); if (bcdSize > sizeof (buf)) { @@ -109,6 +121,10 @@ static bool rtti_msvc_read_base_class_descriptor(RVTableContext *context, ut64 a } static RList *rtti_msvc_read_base_class_array(RVTableContext *context, ut32 num_base_classes, ut64 addr) { + if (addr == UT64_MAX) { + return false; + } + RList *ret = r_list_new (); if (!ret) { return NULL; @@ -149,6 +165,10 @@ static RList *rtti_msvc_read_base_class_array(RVTableContext *context, ut32 num_ } static bool rtti_msvc_read_type_descriptor(RVTableContext *context, ut64 addr, rtti_type_descriptor *td) { + if (addr == UT64_MAX) { + return false; + } + if (!context->read_addr (context->anal, addr, &td->vtable_addr)) { return false; } @@ -201,7 +221,7 @@ static bool rtti_msvc_read_type_descriptor(RVTableContext *context, ut64 addr, r return true; } -static void rtti_msvc_print_complete_object_locator (rtti_complete_object_locator *col, ut64 addr, const char *prefix) { +static void rtti_msvc_print_complete_object_locator(rtti_complete_object_locator *col, ut64 addr, const char *prefix) { r_cons_printf ("%sComplete Object Locator at 0x%08"PFMT64x":\n" "%s\tsignature: %#x\n" "%s\tvftableOffset: %#x\n" @@ -216,7 +236,7 @@ static void rtti_msvc_print_complete_object_locator (rtti_complete_object_locato prefix, col->class_descriptor_addr); } -static void rtti_msvc_print_type_descriptor (rtti_type_descriptor *td, ut64 addr, const char *prefix) { +static void rtti_msvc_print_type_descriptor(rtti_type_descriptor *td, ut64 addr, const char *prefix) { r_cons_printf ("%sType Descriptor at 0x%08"PFMT64x":\n" "%s\tvtableAddr: 0x%08"PFMT64x"\n" "%s\tspare: 0x%08"PFMT64x"\n" @@ -227,7 +247,7 @@ static void rtti_msvc_print_type_descriptor (rtti_type_descriptor *td, ut64 addr prefix, td->name); } -static void rtti_msvc_print_class_hierarchy_descriptor (rtti_class_hierarchy_descriptor *chd, ut64 addr, const char *prefix) { +static void rtti_msvc_print_class_hierarchy_descriptor(rtti_class_hierarchy_descriptor *chd, ut64 addr, const char *prefix) { r_cons_printf ("%sClass Hierarchy Descriptor at 0x%08"PFMT64x":\n" "%s\tsignature: %#x\n" "%s\tattributes: %#x\n" @@ -240,7 +260,7 @@ static void rtti_msvc_print_class_hierarchy_descriptor (rtti_class_hierarchy_des prefix, chd->base_class_array_addr); } -static void rtti_msvc_print_base_class_descriptor (rtti_base_class_descriptor *bcd, const char *prefix) { +static void rtti_msvc_print_base_class_descriptor(rtti_base_class_descriptor *bcd, const char *prefix) { r_cons_printf ("%sBase Class Descriptor:\n" "%s\ttypeDescriptorAddr: 0x%08"PFMT64x"\n" "%s\tnumContainedBases: %#x\n" @@ -259,6 +279,43 @@ static void rtti_msvc_print_base_class_descriptor (rtti_base_class_descriptor *b prefix, bcd->attributes); } +R_API void r_anal_rtti_msvc_print_complete_object_locator(RVTableContext *context, ut64 addr, int mode) { + rtti_complete_object_locator col; + if (!rtti_msvc_read_complete_object_locator (context, addr, &col)) { + eprintf ("Failed to parse Complete Object Locator at 0x%08"PFMT64x"\n", addr); + return; + } + rtti_msvc_print_complete_object_locator (&col, addr, ""); +} + +R_API void r_anal_rtti_msvc_print_type_descriptor(RVTableContext *context, ut64 addr, int mode) { + rtti_type_descriptor td = { 0 }; + if (!rtti_msvc_read_type_descriptor (context, addr, &td)) { + eprintf ("Failed to parse Type Descriptor at 0x%08"PFMT64x"\n", addr); + return; + } + rtti_msvc_print_type_descriptor (&td, addr, ""); + rtti_type_descriptor_fini (&td); +} + +R_API void r_anal_rtti_msvc_print_class_hierarchy_descriptor(RVTableContext *context, ut64 addr, int mode) { + rtti_class_hierarchy_descriptor chd; + if (!rtti_msvc_read_class_hierarchy_descriptor (context, addr, &chd)) { + eprintf ("Failed to parse Class Hierarchy Descriptor at 0x%08"PFMT64x"\n", addr); + return; + } + rtti_msvc_print_class_hierarchy_descriptor (&chd, addr, ""); +} + +R_API void r_anal_rtti_msvc_print_base_class_descriptor(RVTableContext *context, ut64 addr, int mode) { + rtti_base_class_descriptor bcd; + if (!rtti_msvc_read_base_class_descriptor (context, addr, &bcd)) { + eprintf ("Failed to parse Base Class Descriptor at 0x%08"PFMT64x"\n", addr); + return; + } + rtti_msvc_print_base_class_descriptor (&bcd, ""); +} + static void rtti_msvc_print_complete_object_locator_recurse(RVTableContext *context, ut64 atAddress) { ut64 colRefAddr = atAddress - context->word_size; ut64 colAddr; @@ -308,6 +365,6 @@ static void rtti_msvc_print_complete_object_locator_recurse(RVTableContext *cont } } -R_API void r_anal_rtti_msvc_print_at_vtable(RVTableContext *context, ut64 addr) { +R_API void r_anal_rtti_msvc_print_at_vtable(RVTableContext *context, ut64 addr, int mode) { rtti_msvc_print_complete_object_locator_recurse (context, addr); } diff --git a/libr/core/cmd_anal.c b/libr/core/cmd_anal.c index ed612883df..777663ac78 100644 --- a/libr/core/cmd_anal.c +++ b/libr/core/cmd_anal.c @@ -6417,10 +6417,10 @@ static bool anal_fcn_data_gaps (RCore *core, const char *input) { static void cmd_anal_rtti(RCore *core, const char *input) { switch (input[0]) { case '\0': // "avr" - r_anal_rtti_print_at_vtable (core->anal, core->offset); + r_anal_rtti_print_at_vtable (core->anal, core->offset, 0); break; case 'a': // "avra" - r_anal_rtti_print_all (core->anal); + r_anal_rtti_print_all (core->anal, input[1]); break; default : r_core_cmd_help (core, help_msg_av); diff --git a/libr/include/r_anal.h b/libr/include/r_anal.h index 5f15d90b4d..3ade3a5010 100644 --- a/libr/include/r_anal.h +++ b/libr/include/r_anal.h @@ -1694,9 +1694,14 @@ R_API RList *r_anal_vtable_get_methods(RVTableContext *context, RVTableInfo *tab R_API void r_anal_list_vtables(RAnal *anal, int rad); /* rtti */ -R_API void r_anal_rtti_msvc_print_at_vtable(RVTableContext *context, ut64 addr); -R_API void r_anal_rtti_print_at_vtable(RAnal *anal, ut64 addr); -R_API void r_anal_rtti_print_all(RAnal *anal); +R_API void r_anal_rtti_msvc_print_complete_object_locator(RVTableContext *context, ut64 addr, int mode); +R_API void r_anal_rtti_msvc_print_type_descriptor(RVTableContext *context, ut64 addr, int mode); +R_API void r_anal_rtti_msvc_print_class_hierarchy_descriptor(RVTableContext *context, ut64 addr, int mode); +R_API void r_anal_rtti_msvc_print_base_class_descriptor(RVTableContext *context, ut64 addr, int mode); +R_API void r_anal_rtti_msvc_print_at_vtable(RVTableContext *context, ut64 addr, int mode); + +R_API void r_anal_rtti_print_at_vtable(RAnal *anal, ut64 addr, int mode); +R_API void r_anal_rtti_print_all(RAnal *anal, int mode); /* plugin pointers */ extern RAnalPlugin r_anal_plugin_null;