8 #define NAME_BUF_SIZE 64
9 #define BASE_CLASSES_MAX 32
53 return addr + (col_addr - col_base);
62 int colSize = 5 *
sizeof(
ut32);
64 colSize +=
sizeof(
ut32);
66 if (colSize >
sizeof(
buf)) {
102 if (chdSize >
sizeof(
buf)) {
136 if (bcdSize >
sizeof(
buf)) {
175 while (num_base_classes > 0) {
200 bcdAddr = base + bcdOffset;
217 if (num_base_classes > 0) {
242 bool endFound =
false;
243 bool endInvalid =
false;
245 context->analysis->iob.read_at(
context->analysis->iob.io, nameAddr + bufOffset,
buf,
sizeof(
buf));
247 for (
i = 0;
i <
sizeof(
buf);
i++) {
248 if (
buf[
i] ==
'\0') {
252 if (
buf[
i] == 0xff) {
258 if (endFound || endInvalid) {
261 bufOffset +=
sizeof(
buf);
273 if (bufOffset == 0) {
276 context->analysis->iob.read_at(
context->analysis->iob.io, nameAddr,
277 (
ut8 *)td->
name, (
int)(nameLen + 1));
285 "%s\tsignature: %#x\n"
286 "%s\tvftableOffset: %#x\n"
287 "%s\tcdOffset: %#x\n"
288 "%s\ttypeDescriptorAddr: 0x%08" PFMT32x "\n"
289 "%s\tclassDescriptorAddr: 0x%08" PFMT32x "\n",
313 "%s\tvtableAddr: 0x%08" PFMT64x "\n"
314 "%s\tspare: 0x%08" PFMT64x "\n"
332 "%s\tsignature: %#x\n"
333 "%s\tattributes: %#x\n"
334 "%s\tnumBaseClasses: %#x\n"
335 "%s\tbaseClassArrayAddr: 0x%08" PFMT32x "\n\n",
354 "%s\ttypeDescriptorAddr: 0x%08" PFMT32x "\n"
355 "%s\tnumContainedBases: %#x\n"
360 "%s\tattributes: %#x\n\n",
397 size_t original_len = strlen(
name);
398 if (original_len < 7 || (strncmp(
name,
".?AV", 4) != 0 && strncmp(
name,
".?AU", 4) != 0) || strncmp(
name + original_len - 2,
"@@", 2) != 0) {
401 char *ret =
context->analysis->binb.demangle(
NULL,
"msvc",
name, 0,
false);
403 char *
n = strchr(ret,
' ');
502 if (!
context->read_addr(
context->analysis, colRefAddr, &colAddr)) {
510 RZ_LOG_ERROR(
"Failed to parse complete object locator at 0x%08" PFMT64x " (referenced from 0x%08" PFMT64x ")\n", colAddr, colRefAddr);
530 RZ_LOG_ERROR(
"Failed to parse class hierarchy descriptor at 0x%08" PFMT64x "\n", classHierarchyDescriptorAddr);
537 ut32 baseClassArrayOffset = 0;
544 if (!baseClassArray) {
546 RZ_LOG_ERROR(
"Failed to parse base class array starting at 0x%08" PFMT64x "\n", base + baseClassArrayOffset);
561 pj_k(pj,
"complete_object_locator");
563 pj_k(pj,
"type_desc");
565 pj_k(pj,
"class_hierarchy_desc");
567 pj_ka(pj,
"base_classes");
577 rz_list_foreach (baseClassArray, bcdIter, bcd) {
590 pj_k(pj,
"type_desc");
598 RZ_LOG_ERROR(
"Failed to parse type descriptor at 0x%08" PFMT64x "\n", baseTypeDescriptorAddr);
732 ut32 baseClassArrayOffset = 0;
733 if (
context->vt_context->word_size == 8) {
747 rz_list_foreach (col->
bcd, bcdIter, bcd) {
758 base_desc->
bcd = bcd;
793 return strdup(original_name);
797 RZ_LOG_DEBUG(
"Class name '%s' was already taken!\n", original_name);
817 RzAnalysisVTable vtable;
821 vtable.addr = vtable_info->saddr;
825 RVTableMethodInfo *vmeth;
827 RzAnalysisMethod meth;
829 meth.addr = vmeth->addr;
830 meth.vtable_offset = vmeth->vtable_offset;
835 meth.method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL;
837 RzAnalysisMethod exist_meth;
839 meth.addr = vmeth->addr;
841 meth.real_name =
rz_str_new(exist_meth.real_name);
842 meth.vtable_offset = vmeth->vtable_offset;
843 meth.method_type = RZ_ANALYSIS_CLASS_METHOD_VIRTUAL;
859 if (!base_td->
valid) {
864 const char *base_class_name;
866 RZ_LOG_DEBUG(
"Base td %s has no col. Falling back to recovery from td only.\n", base_td->
td.
name);
872 if (!base_class_name) {
873 RZ_LOG_DEBUG(
"Failed to convert !base td->col or td to a class\n");
877 RzAnalysisBaseClass base;
880 base.class_name =
strdup(base_class_name);
898 const char *existing = ht_up_find(
context->col_td_classes, col->
addr,
NULL);
899 if (existing !=
NULL) {
935 const char *existing = ht_up_find(
context->col_td_classes, td->
addr,
NULL);
936 if (existing !=
NULL) {
968 context.vt_context = vt_context;
972 context.addr_col = ht_up_new0();
974 context.addr_td = ht_up_new0();
980 rz_list_foreach (vtables, vtableIter, table) {
981 ut64 colRefAddr = table->saddr - vt_context->word_size;
983 if (!vt_context->read_addr(vt_context->analysis, colRefAddr, &colAddr)) {
1013 ht_up_free(
context.col_td_classes);
RZ_API RzAnalysisFunction * rz_analysis_get_function_at(RzAnalysis *analysis, ut64 addr)
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 void rz_analysis_class_base_fini(RzAnalysisBaseClass *base)
RZ_API bool rz_analysis_class_exists(RzAnalysis *analysis, const char *name)
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 void rz_cons_break_pop(void)
RZ_API void rz_cons_break_push(RzConsBreak cb, void *user)
RZ_API int rz_cons_printf(const char *format,...)
RZ_API bool rz_cons_is_breaked(void)
unsigned short prefix[65536]
RZ_API void Ht_() free(HtName_(Ht) *ht)
return memset(p, 0, total)
memcpy(mem, inblock.get(), min(CONTAINING_RECORD(inblock.get(), MEMBLOCK, data) ->size, size))
RZ_API RZ_OWN RzList * rz_list_newf(RzListFree f)
Returns a new initialized RzList pointer and sets the free method.
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 * malloc(size_t size)
return strdup("=SP r13\n" "=LR r14\n" "=PC r15\n" "=A0 r0\n" "=A1 r1\n" "=A2 r2\n" "=A3 r3\n" "=ZF zf\n" "=SF nf\n" "=OF vf\n" "=CF cf\n" "=SN or0\n" "gpr lr .32 56 0\n" "gpr pc .32 60 0\n" "gpr cpsr .32 64 0 ____tfiae_________________qvczn\n" "gpr or0 .32 68 0\n" "gpr tf .1 64.5 0 thumb\n" "gpr ef .1 64.9 0 endian\n" "gpr jf .1 64.24 0 java\n" "gpr qf .1 64.27 0 sticky_overflow\n" "gpr vf .1 64.28 0 overflow\n" "gpr cf .1 64.29 0 carry\n" "gpr zf .1 64.30 0 zero\n" "gpr nf .1 64.31 0 negative\n" "gpr itc .4 64.10 0 if_then_count\n" "gpr gef .4 64.16 0 great_or_equal\n" "gpr r0 .32 0 0\n" "gpr r1 .32 4 0\n" "gpr r2 .32 8 0\n" "gpr r3 .32 12 0\n" "gpr r4 .32 16 0\n" "gpr r5 .32 20 0\n" "gpr r6 .32 24 0\n" "gpr r7 .32 28 0\n" "gpr r8 .32 32 0\n" "gpr r9 .32 36 0\n" "gpr r10 .32 40 0\n" "gpr r11 .32 44 0\n" "gpr r12 .32 48 0\n" "gpr r13 .32 52 0\n" "gpr r14 .32 56 0\n" "gpr r15 .32 60 0\n" "gpr r16 .32 64 0\n" "gpr r17 .32 68 0\n")
static void rtti_msvc_print_base_class_descriptor_json(PJ *pj, rtti_base_class_descriptor *bcd)
static ut64 rtti_msvc_base_class_descriptor_size(RVTableContext *context)
struct recovery_complete_object_locator_t RecoveryCompleteObjectLocator
RZ_API void rz_analysis_rtti_msvc_print_base_class_descriptor(RVTableContext *context, ut64 addr, int mode)
static void rtti_msvc_print_class_hierarchy_descriptor_json(PJ *pj, rtti_class_hierarchy_descriptor *chd)
RZ_API void rz_analysis_rtti_msvc_print_type_descriptor(RVTableContext *context, ut64 addr, int mode)
void recovery_complete_object_locator_free(RecoveryCompleteObjectLocator *col)
RZ_API void rz_analysis_rtti_msvc_recover_all(RVTableContext *vt_context, RzList *vtables)
RZ_API void rz_analysis_rtti_msvc_print_complete_object_locator(RVTableContext *context, ut64 addr, int mode)
static void rtti_msvc_print_type_descriptor_json(PJ *pj, rtti_type_descriptor *td)
RZ_API char * rz_analysis_rtti_msvc_demangle_class_name(RVTableContext *context, const char *name)
RZ_API void rz_analysis_rtti_msvc_print_class_hierarchy_descriptor(RVTableContext *context, ut64 addr, int mode)
static const char * recovery_apply_complete_object_locator(RRTTIMSVCAnalContext *context, RecoveryCompleteObjectLocator *col)
static RzList * rtti_msvc_read_base_class_array(RVTableContext *context, ut32 num_base_classes, ut64 base, ut32 offset)
static bool rtti_msvc_print_complete_object_locator_recurse(RVTableContext *context, ut64 atAddress, RzOutputMode mode, bool strict)
static void rtti_msvc_print_complete_object_locator_json(PJ *pj, rtti_complete_object_locator *col)
struct rtti_class_hierarchy_descriptor_t rtti_class_hierarchy_descriptor
static bool rtti_msvc_read_class_hierarchy_descriptor(RVTableContext *context, ut64 addr, rtti_class_hierarchy_descriptor *chd)
RecoveryTypeDescriptor * recovery_analysis_type_descriptor(RRTTIMSVCAnalContext *context, ut64 addr, RecoveryCompleteObjectLocator *col)
static const char * recovery_apply_type_descriptor(RRTTIMSVCAnalContext *context, RecoveryTypeDescriptor *td)
void str_value_free(HtUPKv *kv)
RecoveryCompleteObjectLocator * recovery_complete_object_locator_new()
static ut64 rtti_msvc_addr(RVTableContext *context, ut64 col_addr, ut64 col_base, ut32 addr)
static void rtti_type_descriptor_fini(rtti_type_descriptor *td)
RecoveryCompleteObjectLocator * recovery_analysis_complete_object_locator(RRTTIMSVCAnalContext *context, ut64 addr, RVTableInfo *vtable)
static void rtti_msvc_print_base_class_descriptor(rtti_base_class_descriptor *bcd, const char *prefix)
static void rtti_msvc_print_class_hierarchy_descriptor(rtti_class_hierarchy_descriptor *chd, ut64 addr, const char *prefix)
static bool rtti_msvc_read_base_class_descriptor(RVTableContext *context, ut64 addr, rtti_base_class_descriptor *bcd)
RecoveryTypeDescriptor * recovery_type_descriptor_new()
static bool rtti_msvc_read_complete_object_locator(RVTableContext *context, ut64 addr, rtti_complete_object_locator *col)
struct rtti_base_class_descriptor_t rtti_base_class_descriptor
static void rtti_msvc_print_complete_object_locator(rtti_complete_object_locator *col, ut64 addr, const char *prefix)
static void rtti_msvc_print_type_descriptor(rtti_type_descriptor *td, ut64 addr, const char *prefix)
static void recovery_apply_bases(RRTTIMSVCAnalContext *context, const char *class_name, RzVector *base_descs)
RZ_API bool rz_analysis_rtti_msvc_print_at_vtable(RVTableContext *context, ut64 addr, RzOutputMode mode, bool strict)
struct rtti_msvc_analysis_context_t RRTTIMSVCAnalContext
struct recovery_base_descriptor_t RecoveryBaseDescriptor
static bool rtti_msvc_read_type_descriptor(RVTableContext *context, ut64 addr, rtti_type_descriptor *td)
struct rtti_complete_object_locator_t rtti_complete_object_locator
void recovery_type_descriptor_free(RecoveryTypeDescriptor *td)
struct rtti_type_descriptor_t rtti_type_descriptor
static void recovery_apply_vtable(RVTableContext *context, const char *class_name, RVTableInfo *vtable_info)
static char * unique_class_name(RzAnalysis *analysis, const char *original_name)
static ut32 rz_read_at_le32(const void *src, size_t offset)
static ut32 rz_read_le32(const void *src)
static ut64 rz_read_ble(const void *src, bool big_endian, int size)
static ut32 rz_read_at_be32(const void *src, size_t offset)
static ut32 rz_read_be32(const void *src)
#define RZ_LOG_WARN(fmtstr,...)
#define RZ_LOG_DEBUG(fmtstr,...)
#define RZ_LOG_ERROR(fmtstr,...)
RZ_API PJ * pj_ko(PJ *j, const char *k)
RZ_API PJ * pj_ka(PJ *j, const char *k)
RZ_API PJ * pj_ki(PJ *j, const char *k, int d)
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 char * rz_str_newf(const char *fmt,...) RZ_PRINTF_CHECK(1
RZ_API char * rz_str_new(const char *str)
RzOutputMode
Enum to describe the way data are printed.
RZ_API void rz_pvector_init(RzPVector *vec, RzPVectorFree free)
RZ_API void * rz_vector_reserve(RzVector *vec, size_t capacity)
RZ_API void * rz_vector_push(RzVector *vec, void *x)
void(* RzPVectorFree)(void *e)
#define rz_vector_foreach(vec, it)
static void ** rz_pvector_push(RzPVector *vec, void *x)
RZ_API void rz_vector_clear(RzVector *vec)
RZ_API void rz_vector_init(RzVector *vec, size_t elem_size, RzVectorFree free, void *free_user)
RZ_API void rz_pvector_clear(RzPVector *vec)
#define rz_pvector_foreach(vec, it)
rtti_base_class_descriptor * bcd
RecoveryTypeDescriptor * td
RecoveryTypeDescriptor * td
rtti_class_hierarchy_descriptor chd
rtti_complete_object_locator col
RecoveryCompleteObjectLocator * col
ut32 type_descriptor_addr
struct rtti_base_class_descriptor_t::@22 where
ut32 base_class_array_addr
ut32 type_descriptor_addr
ut32 class_descriptor_addr
RVTableContext * vt_context
RzPVector complete_object_locators
RzPVector type_descriptors
RZ_API ut64 rz_analysis_vtable_info_get_size(RVTableContext *context, RVTableInfo *vtable)
RZ_API void rz_analysis_vtable_info_free(RVTableInfo *vtable)
ut64(WINAPI *w32_GetEnabledXStateFeatures)()