diff options
| author | Mason Reed <mason@vector35.com> | 2026-01-12 10:58:59 -0800 |
|---|---|---|
| committer | Mason Reed <35282038+emesare@users.noreply.github.com> | 2026-01-13 19:37:46 -0800 |
| commit | e299a6c1bf74f0ca6d2c3d79135e8c23e6b9fbba (patch) | |
| tree | 132683a047f4a97c0dc18a1f01df8f46b79105b1 /plugins/rtti/microsoft.cpp | |
| parent | 0893694568345908163262785097878460604855 (diff) | |
[RTTI] Improve virtual function discovery
- Allow extern functions to show up in a MSVC vtable
- Fix https://github.com/Vector35/binaryninja-api/issues/7871
- Share code between itanium and msvc vft analysis, it is the same logic basically
Diffstat (limited to 'plugins/rtti/microsoft.cpp')
| -rw-r--r-- | plugins/rtti/microsoft.cpp | 34 |
1 files changed, 8 insertions, 26 deletions
diff --git a/plugins/rtti/microsoft.cpp b/plugins/rtti/microsoft.cpp index 684a68cd..b57b15f6 100644 --- a/plugins/rtti/microsoft.cpp +++ b/plugins/rtti/microsoft.cpp @@ -482,37 +482,19 @@ std::optional<ClassInfo> MicrosoftRTTIProcessor::ProcessRTTI(uint64_t coLocatorA std::optional<VirtualFunctionTableInfo> MicrosoftRTTIProcessor::ProcessVFT(uint64_t vftAddr, ClassInfo &classInfo, std::optional<BaseClassInfo> baseClassInfo) { VirtualFunctionTableInfo vftInfo = {vftAddr}; - // Gather all virtual functions - BinaryReader reader = BinaryReader(m_view); - reader.Seek(vftAddr); // Virtual functions and the analysis object of it, if it exists. std::vector<std::pair<uint64_t, std::optional<Ref<Function>>>> virtualFunctions = {}; + uint64_t currentVftEntry = vftAddr; while (true) { - uint64_t readOffset = reader.GetOffset(); - if (!m_view->IsValidOffset(readOffset)) + uint64_t vFuncAddr = 0; + const FunctionDiscoverState state = DiscoverVirtualFunction(currentVftEntry, vFuncAddr); + if (state == FunctionDiscoverState::Failed) break; - uint64_t vFuncAddr = reader.ReadPointer(); - auto funcs = m_view->GetAnalysisFunctionsForAddress(vFuncAddr); - if (funcs.empty()) - { - Ref<Segment> segment = m_view->GetSegmentAt(vFuncAddr); - if (segment == nullptr || !(segment->GetFlags() & (SegmentExecutable | SegmentDenyWrite))) - { - // Last CompleteObjectLocator or hit the next CompleteObjectLocator - break; - } - // TODO: Is likely a function check here? - m_logger->LogDebugF("Discovered function from virtual function table... {:#x}", vFuncAddr); - auto vftPlatform = m_view->GetDefaultPlatform()->GetAssociatedPlatformByAddress(vFuncAddr); - auto vFunc = m_view->AddFunctionForAnalysis(vftPlatform, vFuncAddr, true); - virtualFunctions.emplace_back(vFuncAddr, vFunc ? std::optional(vFunc) : std::nullopt); - } - else - { - // Only ever add one function. - virtualFunctions.emplace_back(vFuncAddr, funcs.front()); - } + currentVftEntry += m_view->GetAddressSize(); + Ref<Platform> vftPlatform = m_view->GetDefaultPlatform()->GetAssociatedPlatformByAddress(vFuncAddr); + Ref<Function> vFunc = m_view->GetAnalysisFunction(vftPlatform, vFuncAddr); + virtualFunctions.emplace_back(vFuncAddr, vFunc ? std::optional(vFunc) : std::nullopt); } if (virtualFunctions.empty()) |
