| 400 | } |
| 401 | |
| 402 | std::optional<ClassInfo> MicrosoftRTTIProcessor::ProcessRTTI(uint64_t coLocatorAddr) |
| 403 | { |
| 404 | auto coLocator = ReadCompleteObjectorLocator(m_view, coLocatorAddr); |
| 405 | if (!coLocator.has_value()) |
| 406 | return std::nullopt; |
| 407 | |
| 408 | auto startAddr = m_view->GetOriginalImageBase(); |
| 409 | auto resolveAddr = [&](const uint64_t relAddr) { |
| 410 | return coLocator->signature == COL_SIG_REV1 ? startAddr + relAddr : relAddr; |
| 411 | }; |
| 412 | |
| 413 | // Get type descriptor then check to see if the class name was demangled. |
| 414 | auto typeDescAddr = resolveAddr(coLocator->pTypeDescriptor); |
| 415 | auto typeDesc = TypeDescriptor(m_view, typeDescAddr); |
| 416 | auto className = DemangleNameMS(m_view, allowMangledClassNames, typeDesc.name); |
| 417 | if (!className.has_value()) |
| 418 | return std::nullopt; |
| 419 | |
| 420 | // If the className is empty we will change it to the address, this is to fix type clobbering. |
| 421 | if (className->empty()) |
| 422 | { |
| 423 | if (!allowAnonymousClassNames) |
| 424 | { |
| 425 | m_logger->LogDebug("Skipping CompleteObjectorLocator with anonymous name %llx", coLocatorAddr); |
| 426 | return std::nullopt; |
| 427 | } |
| 428 | className = fmt::format("anonymous_{:#x}", coLocatorAddr); |
| 429 | } |
| 430 | |
| 431 | auto classInfo = ClassInfo{RTTIProcessorType::Microsoft, className.value()}; |
| 432 | |
| 433 | auto classHierarchyDescAddr = resolveAddr(coLocator->pClassHierarchyDescriptor); |
| 434 | classInfo.baseClasses = ProcessClassHierarchyDescriptor(classHierarchyDescAddr, coLocator.value(), classInfo); |
| 435 | |
| 436 | // Locate the current base class if we are in one. |
| 437 | std::optional<BaseClassInfo> currentBaseClass; |
| 438 | if (coLocator->offset > 0) |
| 439 | { |
| 440 | for (const auto &baseClassInfo: classInfo.baseClasses) |
| 441 | { |
| 442 | if (baseClassInfo.className != classInfo.className |
| 443 | && baseClassInfo.offset == coLocator->offset) |
| 444 | { |
| 445 | currentBaseClass = baseClassInfo; |
| 446 | break; |
| 447 | } |
| 448 | } |
| 449 | } |
| 450 | |
| 451 | auto typeDescSymName = fmt::format("class {} `RTTI Type Descriptor'", classInfo.className); |
| 452 | m_view->DefineAutoSymbol(new Symbol{DataSymbol, typeDescSymName, typeDescAddr}); |
| 453 | m_view->DefineDataVariable(typeDescAddr, |
| 454 | Confidence(TypeDescriptorType(m_view, typeDesc.name.length()), RTTI_CONFIDENCE)); |
| 455 | |
| 456 | auto coLocatorName = fmt::format("{}::`RTTI Complete Object Locator'", className.value()); |
| 457 | if (currentBaseClass.has_value()) |
| 458 | coLocatorName += fmt::format("{{for `{}'}}", currentBaseClass->className); |
| 459 |
nothing calls this directly
no test coverage detected