diff options
| author | Glenn Smith <glenn@vector35.com> | 2025-02-18 18:03:06 -0500 |
|---|---|---|
| committer | Glenn Smith <glenn@vector35.com> | 2025-02-26 14:17:52 -0500 |
| commit | b3cfd46356af3416d72bd6593bb2a397e72554b6 (patch) | |
| tree | 0c1a5120a2764c7b64746da902b17d04409043d7 /view/sharedcache | |
| parent | 4bda0ac97e4961cbb0c5d050fc66989135519aac (diff) | |
[SharedCache] Fix loading DSC BNDB from a local project crashing
Also fixes a BinaryViewRef leak
Diffstat (limited to 'view/sharedcache')
| -rw-r--r-- | view/sharedcache/core/SharedCache.cpp | 15 | ||||
| -rw-r--r-- | view/sharedcache/core/VM.cpp | 44 | ||||
| -rw-r--r-- | view/sharedcache/core/VM.h | 8 |
3 files changed, 41 insertions, 26 deletions
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp index 2980c0e2..e3c115cd 100644 --- a/view/sharedcache/core/SharedCache.cpp +++ b/view/sharedcache/core/SharedCache.cpp @@ -317,19 +317,16 @@ uint64_t SharedCache::FastGetBackingCacheCount(BinaryNinja::Ref<BinaryNinja::Bin } case LargeCacheFormat: { - auto mainFileName = baseFile->Path(); auto subCacheCount = header.subCacheArrayCount; return subCacheCount + 1; } case SplitCacheFormat: { - auto mainFileName = baseFile->Path(); auto subCacheCount = header.subCacheArrayCount; return subCacheCount + 2; } case iOS16CacheFormat: { - auto mainFileName = baseFile->Path(); auto subCacheCount = header.subCacheArrayCount; return subCacheCount + 2; } @@ -640,7 +637,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock) subCachePath = path + "." + entry.fileExtension; subCacheFilename = mainFileName + "." + entry.fileExtension; } - auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath); + auto subCacheFile = MapFileWithoutApplyingSlide(ResolveFilePath(m_dscView, subCachePath)); dyld_cache_header subCacheHeader {}; uint64_t headerSize = subCacheFile->ReadUInt32(16); @@ -727,7 +724,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock) { auto subCachePath = path + "." + std::to_string(i); auto subCacheFilename = mainFileName + "." + std::to_string(i); - auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath); + auto subCacheFile = MapFileWithoutApplyingSlide(ResolveFilePath(m_dscView, subCachePath)); dyld_cache_header subCacheHeader {}; uint64_t headerSize = subCacheFile->ReadUInt32(16); @@ -773,7 +770,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock) // Load .symbols subcache try { auto subCachePath = path + ".symbols"; - auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath); + auto subCacheFile = MapFileWithoutApplyingSlide(ResolveFilePath(m_dscView, subCachePath)); dyld_cache_header subCacheHeader {}; uint64_t headerSize = subCacheFile->ReadUInt32(16); @@ -870,7 +867,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock) subCacheFilename = mainFileName + "." + entry.fileExtension; } - auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath); + auto subCacheFile = MapFileWithoutApplyingSlide(ResolveFilePath(m_dscView, subCachePath)); dyld_cache_header subCacheHeader {}; uint64_t headerSize = subCacheFile->ReadUInt32(16); @@ -931,7 +928,7 @@ void SharedCache::PerformInitialLoad(std::lock_guard<std::mutex>& lock) try { auto subCachePath = path + ".symbols"; - auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath); + auto subCacheFile = MapFileWithoutApplyingSlide(ResolveFilePath(m_dscView, subCachePath)); dyld_cache_header subCacheHeader {}; uint64_t headerSize = subCacheFile->ReadUInt32(16); if (subCacheFile->ReadUInt32(16) > sizeof(dyld_cache_header)) @@ -3564,7 +3561,7 @@ uint64_t SharedCache::GetObjCRelativeMethodBaseAddress(const VMReader& reader) c std::shared_ptr<MMappedFileAccessor> SharedCache::MapFile(const std::string& path) { uint64_t baseAddress = m_cacheInfo->BaseAddress(); - return MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), path, + return MMappedFileAccessor::Open(m_dscView->GetFile()->GetSessionId(), path, [baseAddress, logger = m_logger](std::shared_ptr<MMappedFileAccessor> mmap) { ParseAndApplySlideInfoForFile(mmap, baseAddress, logger); }) diff --git a/view/sharedcache/core/VM.cpp b/view/sharedcache/core/VM.cpp index dcc87723..711c2a88 100644 --- a/view/sharedcache/core/VM.cpp +++ b/view/sharedcache/core/VM.cpp @@ -63,6 +63,13 @@ void VMShutdown() {} std::string ResolveFilePath(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const std::string& path) { auto dscProjectFile = dscView->GetFile()->GetProjectFile(); + BinaryNinja::LogDebugF( + "ResolveFilePath:\n of: {}\n path: {}\n pfn: {}\n pfp: {}", + dscView->GetFile()->GetOriginalFilename(), + path, + dscProjectFile ? dscProjectFile->GetName() : "", + dscProjectFile ? dscProjectFile->GetPathOnDisk() : "" + ); // If we're not in a project, just return the path we were given if (!dscProjectFile) @@ -73,8 +80,22 @@ std::string ResolveFilePath(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, c // TODO: do we need to support looking in subfolders? // Replace project file path on disk with project file name for resolution std::string projectFilePathOnDisk = dscProjectFile->GetPathOnDisk(); + std::string originalFilePathOnDisk = dscView->GetFile()->GetOriginalFilename(); std::string cleanPath = path; - cleanPath.replace(cleanPath.find(projectFilePathOnDisk), projectFilePathOnDisk.size(), dscProjectFile->GetName()); + if (auto pindex = cleanPath.find(projectFilePathOnDisk); pindex != std::string::npos) + { + cleanPath.replace(pindex, projectFilePathOnDisk.size(), dscProjectFile->GetName()); + } + else if (auto oindex = cleanPath.find(originalFilePathOnDisk); oindex != std::string::npos) + { + BinaryNinja::Ref<BinaryNinja::ProjectFile> originalProjectFile = dscProjectFile->GetProject()->GetFileByPathOnDisk(originalFilePathOnDisk); + if (!originalProjectFile) + { + BinaryNinja::LogErrorF("Failed to resolve file path for {}: original file {} not found", path, originalFilePathOnDisk); + return path; + } + cleanPath.replace(oindex, originalFilePathOnDisk.size(), originalProjectFile->GetName()); + } size_t lastSlashPos = cleanPath.find_last_of("/\\"); std::string fileName; @@ -108,10 +129,7 @@ std::string ResolveFilePath(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, c } } - if (dscView->GetFile()->GetProjectFile()) - { - BinaryNinja::LogError("Failed to resolve file path for %s", path.c_str()); - } + BinaryNinja::LogErrorF("Failed to resolve file path for {}", path); // If we couldn't find a sibling filename, just return the path we were given return path; @@ -235,7 +253,7 @@ void FileAccessorCache::EvictFromCacheIfNeeded() } } -std::shared_ptr<LazyMappedFileAccessor> FileAccessorCache::OpenLazily(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, +std::shared_ptr<LazyMappedFileAccessor> FileAccessorCache::OpenLazily( const uint64_t sessionID, const std::string& path, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine) { @@ -247,9 +265,9 @@ std::shared_ptr<LazyMappedFileAccessor> FileAccessorCache::OpenLazily(BinaryNinj } auto accessor = std::make_shared<LazyMappedFileAccessor>(path, - [=, dscView = std::move(dscView), postAllocationRoutine = std::move(postAllocationRoutine)]( + [=, postAllocationRoutine = std::move(postAllocationRoutine)]( const std::string& path) { - auto accessor = Open(dscView, sessionID, path); + auto accessor = Open(sessionID, path); if (postAllocationRoutine) { postAllocationRoutine(accessor); @@ -262,12 +280,12 @@ std::shared_ptr<LazyMappedFileAccessor> FileAccessorCache::OpenLazily(BinaryNinj } std::shared_ptr<MMappedFileAccessor> FileAccessorCache::Open( - BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const uint64_t sessionID, const std::string& path) + const uint64_t sessionID, const std::string& path) { EvictFromCacheIfNeeded(); mmapCount++; - auto accessor = std::shared_ptr<MMappedFileAccessor>(new MMappedFileAccessor(ResolveFilePath(dscView, path)), + auto accessor = std::shared_ptr<MMappedFileAccessor>(new MMappedFileAccessor(path), [this](MMappedFileAccessor* accessor) { Close(accessor); }); std::lock_guard lock(m_mutex); @@ -291,11 +309,11 @@ void FileAccessorCache::Close(MMappedFileAccessor* accessor) delete accessor; } -std::shared_ptr<LazyMappedFileAccessor> MMappedFileAccessor::Open(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, +std::shared_ptr<LazyMappedFileAccessor> MMappedFileAccessor::Open( const uint64_t sessionID, const std::string& path, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine) { - return FileAccessorCache::Shared().OpenLazily(dscView, sessionID, path, std::move(postAllocationRoutine)); + return FileAccessorCache::Shared().OpenLazily(sessionID, path, std::move(postAllocationRoutine)); } void MMappedFileAccessor::InitialVMSetup() @@ -537,7 +555,7 @@ void VM::MapPages(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, uint64_t se } auto accessor = - MMappedFileAccessor::Open(std::move(dscView), sessionID, filePath, std::move(postAllocationRoutine)); + MMappedFileAccessor::Open(sessionID, ResolveFilePath(dscView, filePath), std::move(postAllocationRoutine)); auto [it, inserted] = m_map.insert_or_assign({vm_address, vm_address + size}, PageMapping(std::move(accessor), fileoff)); if (m_safe && !inserted) { diff --git a/view/sharedcache/core/VM.h b/view/sharedcache/core/VM.h index 44bd5e63..e245751a 100644 --- a/view/sharedcache/core/VM.h +++ b/view/sharedcache/core/VM.h @@ -79,7 +79,7 @@ public: std::string_view filePath() const { return m_filePath; } private: - std::string m_filePath; + std::string m_filePath; }; uint64_t MMapCount(); @@ -93,7 +93,7 @@ public: MMappedFileAccessor(const std::string &path); ~MMappedFileAccessor(); - static std::shared_ptr<LazyMappedFileAccessor> Open(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const uint64_t sessionID, const std::string &path, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine = nullptr); + static std::shared_ptr<LazyMappedFileAccessor> Open(const uint64_t sessionID, const std::string &path, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine = nullptr); static void CloseAll(const uint64_t sessionID); @@ -163,7 +163,7 @@ class FileAccessorCache public: static FileAccessorCache& Shared(); - std::shared_ptr<LazyMappedFileAccessor> OpenLazily(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, + std::shared_ptr<LazyMappedFileAccessor> OpenLazily( const uint64_t sessionID, const std::string& path, std::function<void(std::shared_ptr<MMappedFileAccessor>)> postAllocationRoutine); @@ -173,7 +173,7 @@ private: FileAccessorCache(); std::shared_ptr<MMappedFileAccessor> Open( - BinaryNinja::Ref<BinaryNinja::BinaryView> dscView, const uint64_t sessionID, const std::string& path); + const uint64_t sessionID, const std::string& path); void Close(MMappedFileAccessor* accessor); |
