diff options
Diffstat (limited to 'view/sharedcache')
| -rw-r--r-- | view/sharedcache/api/python/_sharedcachecore.py | 38 | ||||
| -rw-r--r-- | view/sharedcache/api/python/sharedcache.py | 6 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcache.cpp | 11 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcacheapi.h | 3 | ||||
| -rw-r--r-- | view/sharedcache/api/sharedcachecore.h | 3 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.cpp | 117 | ||||
| -rw-r--r-- | view/sharedcache/core/SharedCache.h | 2 |
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(); |
