| 330 | |
| 331 | |
| 332 | std::vector<BaseClassInfo> MicrosoftRTTIProcessor::ProcessClassHierarchyDescriptor(uint64_t address, CompleteObjectLocator &coLocator, const ClassInfo &classInfo) |
| 333 | { |
| 334 | auto startAddr = m_view->GetOriginalImageBase(); |
| 335 | auto resolveAddr = [&](const uint64_t relAddr) { |
| 336 | return coLocator.signature == COL_SIG_REV1 ? startAddr + relAddr : relAddr; |
| 337 | }; |
| 338 | |
| 339 | auto ptrBaseTy = coLocator.signature ? RelativeToBinaryStartPointerBaseType : AbsolutePointerBaseType; |
| 340 | |
| 341 | auto classHierarchyDesc = ClassHierarchyDescriptor(m_view, address); |
| 342 | auto classHierarchyDescName = fmt::format("{}::`RTTI Class Hierarchy Descriptor'", classInfo.className); |
| 343 | m_view->DefineAutoSymbol(new Symbol{DataSymbol, classHierarchyDescName, address}); |
| 344 | m_view->DefineDataVariable(address, |
| 345 | Confidence(ClassHierarchyDescriptorType(m_view, ptrBaseTy), RTTI_CONFIDENCE)); |
| 346 | |
| 347 | auto baseClassArrayAddr = resolveAddr(classHierarchyDesc.pBaseClassArray); |
| 348 | auto baseClassArray = BaseClassArray(m_view, baseClassArrayAddr, classHierarchyDesc.numBaseClasses); |
| 349 | auto baseClassArrayName = fmt::format("{}::`RTTI Base Class Array'", classInfo.className); |
| 350 | m_view->DefineAutoSymbol(new Symbol{DataSymbol, baseClassArrayName, baseClassArrayAddr}); |
| 351 | m_view->DefineDataVariable(baseClassArrayAddr, |
| 352 | Confidence(BaseClassArrayType(m_view, baseClassArray.length, ptrBaseTy), |
| 353 | RTTI_CONFIDENCE)); |
| 354 | |
| 355 | std::vector<BaseClassInfo> baseClasses = {}; |
| 356 | for (auto pBaseClassDescAddr: baseClassArray.descriptors) |
| 357 | { |
| 358 | auto baseClassDescAddr = resolveAddr(pBaseClassDescAddr); |
| 359 | auto baseClassDesc = BaseClassDescriptor(m_view, baseClassDescAddr); |
| 360 | |
| 361 | auto baseClassTypeDescAddr = resolveAddr(baseClassDesc.pTypeDescriptor); |
| 362 | if (baseClassTypeDescAddr == 0) |
| 363 | { |
| 364 | // Fixes issue https://github.com/Vector35/binaryninja-api/issues/6837 |
| 365 | m_logger->LogWarn("Skipping BaseClassDescriptor with null pTypeDescriptor %llx", baseClassDescAddr); |
| 366 | continue; |
| 367 | } |
| 368 | auto baseClassTypeDesc = TypeDescriptor(m_view, baseClassTypeDescAddr); |
| 369 | auto baseClassName = DemangleNameMS(m_view, allowMangledClassNames, baseClassTypeDesc.name); |
| 370 | if (!baseClassName.has_value()) |
| 371 | { |
| 372 | m_logger->LogWarn("Skipping BaseClassDescriptor with mangled name %llx", baseClassTypeDescAddr); |
| 373 | continue; |
| 374 | } |
| 375 | |
| 376 | BaseClassInfo baseClassInfo = {baseClassName.value(), (uint64_t)baseClassDesc.where_mdisp}; |
| 377 | |
| 378 | auto baseClassDescName = fmt::format("{}::`RTTI Base Class Descriptor at ({},{},{},{})", baseClassInfo.className, |
| 379 | baseClassDesc.where_mdisp, baseClassDesc.where_pdisp, |
| 380 | baseClassDesc.where_vdisp, baseClassDesc.attributes); |
| 381 | m_view->DefineAutoSymbol(new Symbol{DataSymbol, baseClassDescName, baseClassDescAddr}); |
| 382 | m_view->DefineDataVariable(baseClassDescAddr, |
| 383 | Confidence(BaseClassDescriptorType(m_view, ptrBaseTy), RTTI_CONFIDENCE)); |
| 384 | |
| 385 | auto baseClassTypeDescSymName = fmt::format("class {} `RTTI Type Descriptor'", baseClassInfo.className); |
| 386 | m_view->DefineAutoSymbol(new Symbol{DataSymbol, baseClassTypeDescSymName, baseClassTypeDescAddr}); |
| 387 | m_view->DefineDataVariable(baseClassTypeDescAddr, |
| 388 | Confidence(TypeDescriptorType(m_view, baseClassTypeDesc.name.length()), RTTI_CONFIDENCE)); |
| 389 |
nothing calls this directly
no test coverage detected