summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/VM.cpp
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/core/VM.cpp
parent4bda0ac97e4961cbb0c5d050fc66989135519aac (diff)
[SharedCache] Fix loading DSC BNDB from a local project crashing
Also fixes a BinaryViewRef leak
Diffstat (limited to 'view/sharedcache/core/VM.cpp')
-rw-r--r--view/sharedcache/core/VM.cpp44
1 files changed, 31 insertions, 13 deletions
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)
{