From e7b1fae4ac7b4994982424c5ad32177d6cea9589 Mon Sep 17 00:00:00 2001 From: Mason Reed Date: Sun, 30 Nov 2025 16:06:21 -0500 Subject: [RTTI] Add more error checking for malformed PE binaries Fixes https://github.com/Vector35/binaryninja-api/issues/7705 RTTI processing with malformed sections can still cause prolonged analysis, in extreme cases like the binary in the issue needing the user to stop the RTTI processing once it gets to the Itanium RTTI pass. More work to be done, I would like to solve this with some section heuristics using the sections/segments entropy. --- plugins/rtti/microsoft.cpp | 42 ++++++++++++++++++++++++++++++++++++++---- 1 file changed, 38 insertions(+), 4 deletions(-) (limited to 'plugins/rtti/microsoft.cpp') diff --git a/plugins/rtti/microsoft.cpp b/plugins/rtti/microsoft.cpp index 86875b25..ad9eb2e4 100644 --- a/plugins/rtti/microsoft.cpp +++ b/plugins/rtti/microsoft.cpp @@ -694,14 +694,34 @@ void MicrosoftRTTIProcessor::ProcessRTTI() { if (segment->GetFlags() == (SegmentReadable | SegmentContainsData)) { + // If a malformed binary makes the binary view set up unbacked segments we should not attempt to read in them. + if (m_view->ReadBuffer(segment->GetStart(), 4).GetLength() != 4) + { + m_logger->LogInfo("Unbacked start for segment %llx... skipping", segment->GetStart()); + continue; + } m_logger->LogDebug("Attempting to find RTTI in segment %llx", segment->GetStart()); - scan(segment); + try + { + scan(segment); + } + catch (std::exception &e) + { + m_logger->LogWarn("Unhandled exception in segment scan %llx %s", segment->GetStart(), e.what()); + } } else if (checkWritableRData && rdataSection && rdataSection->GetStart() == segment->GetStart()) { m_logger->LogDebug("Attempting to find RTTI in writable rdata segment %llx", segment->GetStart()); - scan(segment); + try + { + scan(segment); + } + catch (std::exception &e) + { + m_logger->LogWarn("Unhandled exception in writable segment scan %llx %s", segment->GetStart(), e.what()); + } } } @@ -757,13 +777,27 @@ void MicrosoftRTTIProcessor::ProcessVFT() if (segment->GetFlags() == (SegmentReadable | SegmentContainsData)) { m_logger->LogDebug("Attempting to find VirtualFunctionTables in segment %llx", segment->GetStart()); - scan(segment); + try + { + scan(segment); + } + catch (std::exception &e) + { + m_logger->LogWarn("Unhandled exception in vtable segment scan %llx %s", segment->GetStart(), e.what()); + } } else if (checkWritableRData && rdataSection && rdataSection->GetStart() == segment->GetStart()) { m_logger->LogDebug("Attempting to find VirtualFunctionTables in writable rdata segment %llx", segment->GetStart()); - scan(segment); + try + { + scan(segment); + } + catch (std::exception &e) + { + m_logger->LogWarn("Unhandled exception in vtable writable segment scan %llx %s", segment->GetStart(), e.what()); + } } } } -- cgit v1.3.1