summaryrefslogtreecommitdiff
path: root/view/sharedcache
diff options
context:
space:
mode:
authorGlenn Smith <glenn@vector35.com>2025-02-18 18:03:06 -0500
committerGlenn Smith <glenn@vector35.com>2025-02-26 14:17:52 -0500
commitb3cfd46356af3416d72bd6593bb2a397e72554b6 (patch)
tree0c1a5120a2764c7b64746da902b17d04409043d7 /view/sharedcache
parent4bda0ac97e4961cbb0c5d050fc66989135519aac (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.cpp15
-rw-r--r--view/sharedcache/core/VM.cpp44
-rw-r--r--view/sharedcache/core/VM.h8
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);