summaryrefslogtreecommitdiff
path: root/view/sharedcache
diff options
context:
space:
mode:
Diffstat (limited to 'view/sharedcache')
-rw-r--r--view/sharedcache/api/python/_sharedcachecore.py38
-rw-r--r--view/sharedcache/api/python/sharedcache.py6
-rw-r--r--view/sharedcache/api/sharedcache.cpp11
-rw-r--r--view/sharedcache/api/sharedcacheapi.h3
-rw-r--r--view/sharedcache/api/sharedcachecore.h3
-rw-r--r--view/sharedcache/core/SharedCache.cpp117
-rw-r--r--view/sharedcache/core/SharedCache.h2
7 files changed, 158 insertions, 22 deletions
diff --git a/view/sharedcache/api/python/_sharedcachecore.py b/view/sharedcache/api/python/_sharedcachecore.py
index bd9e0764..5f31697e 100644
--- a/view/sharedcache/api/python/_sharedcachecore.py
+++ b/view/sharedcache/api/python/_sharedcachecore.py
@@ -582,6 +582,44 @@ def BNDSCViewLoadSectionAtAddress(
# -------------------------------------------------------
+# _BNDSCViewProcessAllObjCSections
+
+_BNDSCViewProcessAllObjCSections = core.BNDSCViewProcessAllObjCSections
+_BNDSCViewProcessAllObjCSections.restype = None
+_BNDSCViewProcessAllObjCSections.argtypes = [
+ ctypes.POINTER(BNSharedCache),
+ ]
+
+
+# noinspection PyPep8Naming
+def BNDSCViewProcessAllObjCSections(
+ cache: ctypes.POINTER(BNSharedCache)
+ ) -> None:
+ return _BNDSCViewProcessAllObjCSections(cache)
+
+
+# -------------------------------------------------------
+# _BNDSCViewProcessObjCSectionsForImageWithInstallName
+
+_BNDSCViewProcessObjCSectionsForImageWithInstallName = core.BNDSCViewProcessObjCSectionsForImageWithInstallName
+_BNDSCViewProcessObjCSectionsForImageWithInstallName.restype = None
+_BNDSCViewProcessObjCSectionsForImageWithInstallName.argtypes = [
+ ctypes.POINTER(BNSharedCache),
+ ctypes.c_char_p,
+ ctypes.c_bool,
+ ]
+
+
+# noinspection PyPep8Naming
+def BNDSCViewProcessObjCSectionsForImageWithInstallName(
+ cache: ctypes.POINTER(BNSharedCache),
+ name: Optional[str],
+ deallocName: bool
+ ) -> None:
+ return _BNDSCViewProcessObjCSectionsForImageWithInstallName(cache, cstr(name), deallocName)
+
+
+# -------------------------------------------------------
# _BNFreeSharedCacheReference
_BNFreeSharedCacheReference = core.BNFreeSharedCacheReference
diff --git a/view/sharedcache/api/python/sharedcache.py b/view/sharedcache/api/python/sharedcache.py
index 7902c76a..e0e18bde 100644
--- a/view/sharedcache/api/python/sharedcache.py
+++ b/view/sharedcache/api/python/sharedcache.py
@@ -117,6 +117,12 @@ class SharedCache:
def load_image_containing_address(self, addr, skipObjC = False):
return sccore.BNDSCViewLoadImageContainingAddress(self.handle, addr, skipObjC)
+ def process_objc_sections_for_image_with_install_name(self, installName):
+ return sccore.BNDSCViewProcessObjCSectionsForImageWithInstallName(self.handle, installName, False)
+
+ def process_all_objc_sections(self):
+ return sccore.BNDSCViewProcessAllObjCSections(self.handle)
+
@property
def caches(self):
count = ctypes.c_ulonglong()
diff --git a/view/sharedcache/api/sharedcache.cpp b/view/sharedcache/api/sharedcache.cpp
index 6498de32..e764531c 100644
--- a/view/sharedcache/api/sharedcache.cpp
+++ b/view/sharedcache/api/sharedcache.cpp
@@ -55,6 +55,17 @@ namespace SharedCacheAPI {
return result;
}
+ void SharedCache::ProcessObjCSectionsForImageWithInstallName(std::string installName)
+ {
+ char* str = BNAllocString(installName.c_str());
+ BNDSCViewProcessObjCSectionsForImageWithInstallName(m_object, str, true);
+ }
+
+ void SharedCache::ProcessAllObjCSections()
+ {
+ BNDSCViewProcessAllObjCSections(m_object);
+ }
+
std::vector<DSCMemoryRegion> SharedCache::GetLoadedMemoryRegions()
{
size_t count;
diff --git a/view/sharedcache/api/sharedcacheapi.h b/view/sharedcache/api/sharedcacheapi.h
index f556b1a8..cfe78351 100644
--- a/view/sharedcache/api/sharedcacheapi.h
+++ b/view/sharedcache/api/sharedcacheapi.h
@@ -261,6 +261,9 @@ namespace SharedCacheAPI {
bool LoadSectionAtAddress(uint64_t addr);
bool LoadImageContainingAddress(uint64_t addr, bool skipObjC = false);
std::vector<std::string> GetAvailableImages();
+
+ void ProcessObjCSectionsForImageWithInstallName(std::string installName);
+ void ProcessAllObjCSections();
std::vector<DSCSymbol> LoadAllSymbolsAndWait();
diff --git a/view/sharedcache/api/sharedcachecore.h b/view/sharedcache/api/sharedcachecore.h
index 967a7d0b..155f39de 100644
--- a/view/sharedcache/api/sharedcachecore.h
+++ b/view/sharedcache/api/sharedcachecore.h
@@ -123,6 +123,9 @@ extern "C"
SHAREDCACHE_FFI_API bool BNDSCViewLoadImageWithInstallName(BNSharedCache* cache, char* name, bool skipObjC);
SHAREDCACHE_FFI_API bool BNDSCViewLoadSectionAtAddress(BNSharedCache* cache, uint64_t name);
SHAREDCACHE_FFI_API bool BNDSCViewLoadImageContainingAddress(BNSharedCache* cache, uint64_t address, bool skipObjC);
+
+ SHAREDCACHE_FFI_API void BNDSCViewProcessObjCSectionsForImageWithInstallName(BNSharedCache* cache, char* name, bool deallocName);
+ SHAREDCACHE_FFI_API void BNDSCViewProcessAllObjCSections(BNSharedCache* cache);
SHAREDCACHE_FFI_API char* BNDSCViewGetNameForAddress(BNSharedCache* cache, uint64_t address);
SHAREDCACHE_FFI_API char* BNDSCViewGetImageNameForAddress(BNSharedCache* cache, uint64_t address);
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp
index d4ce0921..51e95bc6 100644
--- a/view/sharedcache/core/SharedCache.cpp
+++ b/view/sharedcache/core/SharedCache.cpp
@@ -1727,6 +1727,81 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address)
return true;
}
+static void GetObjCSettings(Ref<BinaryView> view, bool* processObjCMetadata, bool* processCFStrings)
+{
+ auto settings = view->GetLoadSettings(VIEW_NAME);
+ *processCFStrings = true;
+ *processObjCMetadata = true;
+ if (settings && settings->Contains("loader.dsc.processCFStrings"))
+ *processCFStrings = settings->Get<bool>("loader.dsc.processCFStrings", view);
+ if (settings && settings->Contains("loader.dsc.processObjC"))
+ *processObjCMetadata = settings->Get<bool>("loader.dsc.processObjC", view);
+}
+
+static void ProcessObjCSectionsForImageWithName(std::string baseName, std::shared_ptr<VM> vm, std::shared_ptr<DSCObjC::DSCObjCProcessor> objc, bool processCFStrings, bool processObjCMetadata, Ref<Logger> logger)
+{
+ try
+ {
+ if (processObjCMetadata)
+ objc->ProcessObjCData(vm, baseName);
+ if (processCFStrings)
+ objc->ProcessCFStrings(vm, baseName);
+ }
+ catch (const std::exception& ex)
+ {
+ logger->LogWarn("Error processing ObjC data for image %s: %s", baseName.c_str(), ex.what());
+ }
+ catch (...)
+ {
+ logger->LogWarn("Error processing ObjC data for image %s", baseName.c_str());
+ }
+}
+
+void SharedCache::ProcessObjCSectionsForImageWithInstallName(std::string installName)
+{
+ bool processCFStrings;
+ bool processObjCMetadata;
+ GetObjCSettings(m_dscView, &processCFStrings, &processObjCMetadata);
+
+ if (!processObjCMetadata && !processCFStrings)
+ return;
+
+ auto objc = std::make_shared<DSCObjC::DSCObjCProcessor>(m_dscView, this, false);
+ auto vm = GetVMMap();
+
+ ProcessObjCSectionsForImageWithName(base_name(installName), vm, objc, processCFStrings, processObjCMetadata, m_logger);
+}
+
+void SharedCache::ProcessAllObjCSections()
+{
+ bool processCFStrings;
+ bool processObjCMetadata;
+ GetObjCSettings(m_dscView, &processCFStrings, &processObjCMetadata);
+
+ if (!processObjCMetadata && !processCFStrings)
+ return;
+
+ auto objc = std::make_shared<DSCObjC::DSCObjCProcessor>(m_dscView, this, false);
+ auto vm = GetVMMap();
+
+ std::set<uint64_t> processedImageHeaders;
+ for (auto region : GetMappedRegions())
+ {
+ if (!region.loaded)
+ continue;
+
+ // Don't repeat the same images multiple times
+ auto header = HeaderForAddress(region.start);
+ if (!header)
+ continue;
+ if (processedImageHeaders.find(header->textBase) != processedImageHeaders.end())
+ continue;
+ processedImageHeaders.insert(header->textBase);
+
+ ProcessObjCSectionsForImageWithName(header->identifierPrefix, vm, objc, processCFStrings, processObjCMetadata, m_logger);
+ }
+}
+
bool SharedCache::LoadImageWithInstallName(std::string installName, bool skipObjC)
{
auto settings = m_dscView->GetLoadSettings(VIEW_NAME);
@@ -1839,29 +1914,11 @@ bool SharedCache::LoadImageWithInstallName(std::string installName, bool skipObj
if (!skipObjC)
{
- try
- {
- auto objc = std::make_unique<DSCObjC::DSCObjCProcessor>(m_dscView, this, false);
+ bool processCFStrings;
+ bool processObjCMetadata;
+ GetObjCSettings(m_dscView, &processCFStrings, &processObjCMetadata);
- bool processCFStrings = true;
- bool processObjCMetadata = true;
- if (settings && settings->Contains("loader.dsc.processCFStrings"))
- processCFStrings = settings->Get<bool>("loader.dsc.processCFStrings", m_dscView);
- if (settings && settings->Contains("loader.dsc.processObjC"))
- processObjCMetadata = settings->Get<bool>("loader.dsc.processObjC", m_dscView);
- if (processObjCMetadata)
- objc->ProcessObjCData(vm, h->identifierPrefix);
- if (processCFStrings)
- objc->ProcessCFStrings(vm, h->identifierPrefix);
- }
- catch (const std::exception& ex)
- {
- m_logger->LogWarn("Error processing ObjC data: %s", ex.what());
- }
- catch (...)
- {
- m_logger->LogWarn("Error processing ObjC data");
- }
+ ProcessObjCSectionsForImageWithName(h->identifierPrefix, vm, std::make_shared<DSCObjC::DSCObjCProcessor>(m_dscView, this, false), processCFStrings, processObjCMetadata, m_logger);
}
m_dscView->AddAnalysisOption("linearsweep");
@@ -3067,6 +3124,22 @@ extern "C"
return false;
}
+ void BNDSCViewProcessObjCSectionsForImageWithInstallName(BNSharedCache* cache, char* name, bool deallocName)
+ {
+ std::string imageName = std::string(name);
+ if (deallocName)
+ BNFreeString(name);
+
+ if (cache->object)
+ cache->object->ProcessObjCSectionsForImageWithInstallName(imageName);
+ }
+
+ void BNDSCViewProcessAllObjCSections(BNSharedCache* cache)
+ {
+ if (cache->object)
+ cache->object->ProcessAllObjCSections();
+ }
+
char** BNDSCViewGetInstallNames(BNSharedCache* cache, size_t* count)
{
if (cache->object)
diff --git a/view/sharedcache/core/SharedCache.h b/view/sharedcache/core/SharedCache.h
index c82dea5c..8fa98c05 100644
--- a/view/sharedcache/core/SharedCache.h
+++ b/view/sharedcache/core/SharedCache.h
@@ -574,6 +574,8 @@ namespace SharedCacheCore {
bool LoadImageWithInstallName(std::string installName, bool skipObjC);
bool LoadSectionAtAddress(uint64_t address);
bool LoadImageContainingAddress(uint64_t address, bool skipObjC);
+ void ProcessObjCSectionsForImageWithInstallName(std::string installName);
+ void ProcessAllObjCSections();
std::string NameForAddress(uint64_t address);
std::string ImageNameForAddress(uint64_t address);
std::vector<std::string> GetAvailableImages();