MCPcopy Create free account
hub / github.com/Vector35/binaryninja-api / ProcessRTTI

Method ProcessRTTI

plugins/rtti/itanium.cpp:443–552  ·  view source on GitHub ↗

Source from the content-addressed store, hash-verified

441
442
443std::optional<ClassInfo> ItaniumRTTIProcessor::ProcessRTTI(uint64_t objectAddr)
444{
445 // TODO: You cant get sub-object offsets from rtti, its stored above this ptr in vtable.
446 // Get object as type info then check to see if it's valid.
447 auto typeInfoVariant = ReadTypeInfoVariant(m_view, objectAddr);
448 if (!typeInfoVariant.has_value())
449 return std::nullopt;
450
451 auto typeInfo = TypeInfo(m_view, objectAddr);
452 auto className = DemangleNameItanium(m_view, allowMangledClassNames, typeInfo.type_name);
453 if (!className.has_value() || className->empty())
454 return std::nullopt;
455 auto classInfo = ClassInfo{RTTIProcessorType::Itanium, className.value()};
456
457 auto nameFromTypeInfoSymbol = [&](uint64_t addr) -> std::optional<std::string> {
458 auto sym = m_view->GetSymbolByAddress(addr);
459 if (sym == nullptr || sym->GetType() != ExternalSymbol)
460 return std::nullopt;
461 auto symName = sym->GetShortName();
462 // Remove type info prefix.
463 if (symName.rfind("_typeinfo_for_", 0) != 0)
464 return std::nullopt;
465 return symName.substr(14);
466 };
467
468 if (typeInfoVariant == TIVSIClass)
469 {
470 // Read the base class.
471 auto siClassTypeInfo = SIClassTypeInfo(m_view, objectAddr);
472 auto subTypeInfoVariant = ReadTypeInfoVariant(m_view, siClassTypeInfo.base_type);
473 std::string subTypeName;
474 if (!subTypeInfoVariant.has_value())
475 {
476 // Allow externals to be used in place of a backed subtype.
477 // TODO: We should probably warn that vtables will likely be inaccurate.
478 // TODO: Because we wont know what offsets are valid.
479 auto externTypeName = nameFromTypeInfoSymbol(siClassTypeInfo.base_type);
480 if (!externTypeName.has_value())
481 return std::nullopt;
482 m_logger->LogDebug("Non-backed external subtype for %llx", objectAddr);
483 subTypeName = externTypeName.value();
484 }
485 else
486 {
487 auto subTypeInfo = TypeInfo(m_view, siClassTypeInfo.base_type);
488 subTypeName = subTypeInfo.type_name;
489 }
490 // Demangle base class name and set
491 auto baseClassName = DemangleNameItanium(m_view, allowMangledClassNames, subTypeName);
492 if (!baseClassName.has_value())
493 {
494 m_logger->LogWarn("Skipping base class with mangled name %llx", siClassTypeInfo.base_type);
495 return std::nullopt;
496 }
497 // NOTE: The base class offset is not able to be resolved here.
498 // NOTE: To resolve the base class offset you must go to the vtable.
499 uint64_t baseClassOffset = 0;
500 auto subBaseClassInfo = BaseClassInfo {baseClassName.value(), baseClassOffset};

Callers 1

RTTIAnalysisFunction · 0.45

Calls 15

ReadTypeInfoVariantFunction · 0.85
TypeInfoClass · 0.85
SIClassTypeInfoClass · 0.85
ConfidenceClass · 0.85
SIClassTypeInfoTypeFunction · 0.85
VMIClassTypeInfoClass · 0.85
VMIClassTypeInfoTypeFunction · 0.85
ClassTypeInfoTypeFunction · 0.85
TypeInfoSizeFunction · 0.85
GetSymbolByAddressMethod · 0.80
GetShortNameMethod · 0.80
LogDebugMethod · 0.80

Tested by

no test coverage detected