From 9cc51c4dd9b321479d1959cbbc6d2bc781290cb1 Mon Sep 17 00:00:00 2001 From: Mark Rowe Date: Tue, 24 Mar 2026 13:46:57 -0700 Subject: [PATCH] [DSC] Process Objective-C metadata when loading view from .bndb The processed Objective-C metadata is not saved to the .bdnb. It must be recomputed when the view is loaded. Fixes https://github.com/Vector35/binaryninja-api/issues/8030. --- .../core/SharedCacheController.cpp | 24 +++++++++++++++++++ view/sharedcache/core/SharedCacheController.h | 3 +++ view/sharedcache/core/SharedCacheView.cpp | 8 +++++++ view/sharedcache/core/SharedCacheView.h | 1 + 4 files changed, 36 insertions(+) diff --git a/view/sharedcache/core/SharedCacheController.cpp b/view/sharedcache/core/SharedCacheController.cpp index 8886748f0..8ed011bd3 100644 --- a/view/sharedcache/core/SharedCacheController.cpp +++ b/view/sharedcache/core/SharedCacheController.cpp @@ -292,3 +292,27 @@ void SharedCacheController::LoadMetadata(const Metadata& metadata) m_loadedImages.insert(region); } } + + +void SharedCacheController::ProcessObjCForLoadedImages(BinaryView& view) +{ + if (!m_processObjC || m_loadedImages.empty()) + return; + + for (const auto& headerAddress : m_loadedImages) + { + auto image = m_cache.GetImageAt(headerAddress); + if (!image) + continue; + + auto objcProcessor = DSCObjC::SharedCacheObjCProcessor(&view, image->headerAddress); + try + { + objcProcessor.ProcessObjCData(); + } + catch (std::exception& e) + { + m_logger->LogErrorForExceptionF(e, "Failed to restore ObjC metadata for image at {:#x}: {}", headerAddress, e.what()); + } + } +} diff --git a/view/sharedcache/core/SharedCacheController.h b/view/sharedcache/core/SharedCacheController.h index ff8593210..c468bee5e 100644 --- a/view/sharedcache/core/SharedCacheController.h +++ b/view/sharedcache/core/SharedCacheController.h @@ -63,5 +63,8 @@ namespace BinaryNinja::DSC { Ref GetMetadata() const; void LoadMetadata(const Metadata& metadata); + + // Re-run the ObjC processor for loaded images to restore Objective-C metadata. + void ProcessObjCForLoadedImages(BinaryView& view); }; } // namespace BinaryNinja::DSC diff --git a/view/sharedcache/core/SharedCacheView.cpp b/view/sharedcache/core/SharedCacheView.cpp index 746bd7eb7..6893922de 100644 --- a/view/sharedcache/core/SharedCacheView.cpp +++ b/view/sharedcache/core/SharedCacheView.cpp @@ -981,6 +981,14 @@ bool SharedCacheView::InitController() return true; } + +void SharedCacheView::DidApplySnapshotData() +{ + if (auto controller = SharedCacheController::FromView(*this)) + controller->ProcessObjCForLoadedImages(*this); +} + + void SharedCacheView::SetPrimaryFileName(std::string primaryFileName) { m_primaryFileName = std::move(primaryFileName); diff --git a/view/sharedcache/core/SharedCacheView.h b/view/sharedcache/core/SharedCacheView.h index 5f916b30e..70ed8338c 100644 --- a/view/sharedcache/core/SharedCacheView.h +++ b/view/sharedcache/core/SharedCacheView.h @@ -25,6 +25,7 @@ class SharedCacheView : public BinaryNinja::BinaryView ~SharedCacheView() override = default; bool Init() override; + void DidApplySnapshotData() override; // Initialized the shared cache controller for this view. This is what allows us to load images and regions. bool InitController();