11 #define VMI_CLASS_TYPE_INFO_NAME "__vmi_class_type_info"
12 #define SI_CLASS_TYPE_INFO_NAME "__si_class_type_info"
13 #define CLASS_TYPE_INFO_NAME "__class_type_info"
14 #define NAME_BUF_SIZE 256
16 #define VT_WORD_SIZE(ctx) \
103 *unique_name = (at & unique_mask) == 0;
200 at = at & 0xffffffff;
201 if (at < 1 || at > 0xfffff) {
311 "%s Type Info type: %s\n"
312 "%s Belongs to class vtable: 0x%08" PFMT64x "\n"
313 "%s Reference to RTTI's type class: 0x%08" PFMT64x "\n"
314 "%s Reference to type's name: 0x%08" PFMT64x "\n"
316 "%s Name unique: %s\n",
348 "%s Type Info type: %s\n"
349 "%s Belongs to class vtable: 0x%08" PFMT64x "\n"
350 "%s Reference to RTTI's type class: 0x%08" PFMT64x "\n"
351 "%s Reference to type's name: 0x%08" PFMT64x "\n"
353 "%s Name unique: %s\n"
355 "%s Count of base classes: 0x%x"
370 "%s Base class flags: 0x%" PFMT64x
392 pj_k(pj,
"base_classes");
410 "%s Type Info type: %s\n"
411 "%s Belongs to class vtable: 0x%08" PFMT64x "\n"
412 "%s Reference to RTTI's type class: 0x%08" PFMT64x "\n"
413 "%s Reference to type's name: 0x%08" PFMT64x "\n"
415 "%s Name unique: %s\n"
416 "%s Reference to parent's type info: 0x%08" PFMT64x "\n",
481 return !strcmp(
section->name,
".data.rel.ro") ||
482 !strcmp(
section->name,
".data.rel.ro.local") ||
576 bool name_unique =
false;
586 ut64 base_type_rtti = 0;
588 return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
600 return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
602 ut32 vmi_flags = integers & 0xffffffff;
605 return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
607 integers = integers & 0xffffffff;
608 if (integers < 1 || integers > 0xfffff) {
609 return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
611 ut32 vmi_base_count = integers;
615 return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
620 for (
i = 0;
i < vmi_base_count;
i++) {
621 if (!
context->read_addr(
context->analysis, tmp_addr, &integers)) {
623 return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
627 if (!
context->read_addr(
context->analysis, tmp_addr, &integers)) {
629 return create_class_type(rtti_vptr, type_name, name_addr, name_unique, rtti_addr, vtable_addr);
631 vmi_bases[
i].
flags = integers;
648 if (!
context->read_addr(
context->analysis, rtti_ptr, &rtti_addr)) {
660 follow -= 2 *
context->word_size;
750 if (
name[0] !=
'_') {
752 result =
context->analysis->binb.demangle(
NULL,
"cxx", to_demangle, 0,
false);
755 result =
context->analysis->binb.demangle(
NULL,
"cxx",
name, 0,
false);
768 RzAnalysisVTable vtable = { .id =
NULL, .offset = 0, .size =
size, .addr = vtable_info->saddr };
772 RVTableMethodInfo *vmeth;
774 RzAnalysisMethod meth;
776 meth.addr = vmeth->addr;
777 meth.vtable_offset = vmeth->vtable_offset;
782 meth.method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL;
784 RzAnalysisMethod exist_meth;
786 meth.addr = vmeth->addr;
788 meth.real_name =
rz_str_new(exist_meth.real_name);
789 meth.vtable_offset = vmeth->vtable_offset;
790 meth.method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL;
816 RzAnalysisBaseClass base = { .class_name = base_info.
name, .offset = 0 };
828 RzAnalysisBaseClass base = { .class_name = base_info.
name, .offset = 0 };
841 RzAnalysisMethod *meth;
844 meth->method_type = RZ_ANALYSIS_CLASS_METHOD_CONSTRUCTOR;
848 if (meth->method_type == RZ_ANALYSIS_CLASS_METHOD_VIRTUAL) {
849 meth->method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL_DESTRUCTOR;
851 meth->method_type = RZ_ANALYSIS_CLASS_METHOD_DESTRUCTOR;
868 rz_list_foreach (vtables,
iter, vtable) {
890 rz_list_foreach (rtti_list,
iter, cti) {
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
RzBinInfo * info(RzBinFile *bf)
RZ_API bool rz_analysis_class_method_exists_by_addr(RzAnalysis *analysis, const char *class_name, ut64 addr)
RZ_API RzAnalysisClassErr rz_analysis_class_base_set(RzAnalysis *analysis, const char *class_name, RzAnalysisBaseClass *base)
RZ_API RzVector * rz_analysis_class_method_get_all(RzAnalysis *analysis, const char *class_name)
RZ_API void rz_analysis_class_base_fini(RzAnalysisBaseClass *base)
RZ_API void rz_analysis_class_vtable_fini(RzAnalysisVTable *vtable)
RZ_API RzAnalysisClassErr rz_analysis_class_vtable_set(RzAnalysis *analysis, const char *class_name, RzAnalysisVTable *vtable)
RZ_API RzAnalysisClassErr rz_analysis_class_method_set(RzAnalysis *analysis, const char *class_name, RzAnalysisMethod *meth)
RZ_API void rz_analysis_class_method_fini(RzAnalysisMethod *meth)
RZ_API RzAnalysisClassErr rz_analysis_class_create(RzAnalysis *analysis, const char *name)
RZ_API RzAnalysisClassErr rz_analysis_class_method_get_by_addr(RzAnalysis *analysis, const char *class_name, ut64 addr, RzAnalysisMethod *method)
RZ_API int rz_cons_printf(const char *format,...)
unsigned short prefix[65536]
RZ_API void Ht_() free(HtName_(Ht) *ht)
RZ_API RZ_OWN RzList * rz_list_new(void)
Returns a new initialized RzList pointer (free method is not initialized)
RZ_API RZ_BORROW RzListIter * rz_list_append(RZ_NONNULL RzList *list, void *data)
Appends at the end of the list a new element.
RZ_API void rz_list_free(RZ_NONNULL RzList *list)
Empties the list and frees the list pointer.
void * calloc(size_t number, size_t size)
static void rtti_itanium_print_si_class_type_info(si_class_type_info *si_cti, const char *prefix)
static vmi_class_type_info * rtti_itanium_vmi_class_type_info_new(RVTableContext *context, ut64 addr, ut64 source_vtable)
RZ_API void rz_analysis_rtti_itanium_recover_all(RVTableContext *context, RzList *vtables)
RZ_API char * rz_analysis_rtti_itanium_demangle_class_name(RVTableContext *context, const char *name)
static class_type_info * raw_rtti_parse(RVTableContext *context, ut64 vtable_addr, ut64 rtti_addr)
Try to parse as much valid looking RTTI as you can.
static void rtti_itanium_vmi_class_type_info_free(vmi_class_type_info *cti)
static RTypeInfoType rtti_itanium_type_info_type_from_flag(RVTableContext *context, ut64 atAddress)
struct vmi_class_type_info_t vmi_class_type_info
static void rtti_itanium_vmi_class_type_info_fini(vmi_class_type_info *vmi_cti)
static const char * type_to_string(RTypeInfoType type)
static bool rtti_itanium_vmi_class_type_info_init(RVTableContext *context, ut64 addr, vmi_class_type_info *vmi_cti)
@ RZ_TYPEINFO_TYPE_SI_CLASS
@ RZ_TYPEINFO_TYPE_VMI_CLASS
@ RZ_TYPEINFO_TYPE_UNKNOWN
static void rtti_itanium_print_si_class_type_info_json(si_class_type_info *si_cti)
#define VMI_CLASS_TYPE_INFO_NAME
static void rtti_itanium_print_class_type_info(class_type_info *cti, const char *prefix)
static void rtti_itanium_print_class_type_info_json(class_type_info *cti)
RZ_API bool rz_analysis_rtti_itanium_print_at_vtable(RVTableContext *context, ut64 addr, RzOutputMode mode)
struct base_class_type_info_t base_class_type_info
static si_class_type_info * create_si_class_type(ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut64 basetype_addr, ut64 typeinfo_addr, ut64 source_vtable)
static void rtti_itanium_class_type_info_fini(class_type_info *cti)
static void rtti_itanium_print_vmi_class_type_info_json(vmi_class_type_info *vmi_cti)
static si_class_type_info * rtti_itanium_si_class_type_info_new(RVTableContext *context, ut64 addr, ut64 source_vtable)
static bool rtti_itanium_read_type_name(RVTableContext *context, ut64 addr, class_type_info *cti)
static void rtti_itanium_si_class_type_info_free(si_class_type_info *cti)
static class_type_info * rtti_itanium_class_type_info_new(RVTableContext *context, ut64 addr, ut64 source_vtable)
static bool rtti_itanium_si_class_type_info_init(RVTableContext *context, ut64 addr, si_class_type_info *si_cti)
static void rtti_itanium_print_vmi_class_type_info(vmi_class_type_info *vmi_cti, const char *prefix)
#define SI_CLASS_TYPE_INFO_NAME
static class_type_info * create_class_type(ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut64 typeinfo_addr, ut64 source_vtable)
#define VT_WORD_SIZE(ctx)
static char * rtti_itanium_read_type_name_custom(RVTableContext *context, ut64 addr, ut64 *str_addr, bool *unique_name)
static void add_class_bases(RVTableContext *context, const class_type_info *cti)
Add any base class information about the type into analysis/classes.
#define CLASS_TYPE_INFO_NAME
static bool rtti_itanium_class_type_info_init(RVTableContext *context, ut64 addr, class_type_info *cti)
static void detect_constructor_destructor(RzAnalysis *analysis, class_type_info *cti)
static void rtti_itanium_si_class_type_info_fini(si_class_type_info *si_cti)
struct class_type_info_t class_type_info
static class_type_info * rtti_itanium_type_info_new(RVTableContext *context, ut64 vtable_addr)
static void rtti_itanium_class_type_info_free(class_type_info *cti)
static vmi_class_type_info * create_vmi_class_type(ut64 vtable_addr, char *name, ut64 name_addr, bool unique_name, ut32 flags, ut32 base_count, base_class_type_info *bases, ut64 typeinfo_addr, ut64 source_vtable)
struct si_class_type_info_t si_class_type_info
static bool can_section_contain_rtti_vpointer(RzBinSection *section)
static void recovery_apply_vtable(RVTableContext *context, const char *class_name, RVTableInfo *vtable_info)
static void rtti_itanium_type_info_free(void *info)
#define rz_return_val_if_fail(expr, val)
#define rz_return_val_if_reached(val)
#define rz_return_if_reached()
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API PJ * pj_kb(PJ *j, const char *k, bool v)
RZ_API PJ * pj_k(PJ *j, const char *k)
RZ_API PJ * pj_end(PJ *j)
RZ_API const char * pj_string(PJ *pj)
RZ_API void pj_free(PJ *j)
RZ_API PJ * pj_ks(PJ *j, const char *k, const char *v)
RZ_API PJ * pj_kn(PJ *j, const char *k, ut64 n)
RZ_API PJ * pj_kN(PJ *j, const char *k, st64 n)
RZ_API char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_new(const char *str)
RZ_API bool rz_str_startswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string starts with a specifc sequence of characters (case sensitive)
RZ_API int rz_str_cmp(const char *dst, const char *orig, int len)
RZ_API bool rz_str_endswith(RZ_NONNULL const char *str, RZ_NONNULL const char *needle)
Checks if a string ends with a specifc sequence of characters (case sensitive)
RzOutputMode
Enum to describe the way data are printed.
#define rz_vector_foreach(vec, it)
RZ_API void rz_vector_free(RzVector *vec)
RZ_API SetU * set_u_new(void)
RZ_API void set_u_free(SetU *s)
RZ_API void set_u_add(SetU *s, ut64 u)
RZ_API bool set_u_contains(SetU *s, ut64 u)
static struct sockaddr static addrlen static backlog const void static flags void flags
enum base_class_type_info_t::flags_masks_e flags_masks
enum vmi_class_type_info_t::vmi_flags_masks_e vmi_flags_masks
@ non_diamond_repeat_mask
base_class_type_info * vmi_bases
RZ_API ut64 rz_analysis_vtable_info_get_size(RVTableContext *context, RVTableInfo *vtable)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()