Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SharedCache] Rework how file accessors are handled #6392

Closed
wants to merge 1 commit into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 0 additions & 2 deletions view/sharedcache/core/DSCView.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -28,8 +28,6 @@ DSCView::DSCView(const std::string& typeName, BinaryView* data, bool parseOnly)

DSCView::~DSCView()
{
if (!m_parseOnly)
MMappedFileAccessor::CloseAll(GetFile()->GetSessionId());
}

enum DSCPlatform {
Expand Down
63 changes: 32 additions & 31 deletions view/sharedcache/core/SharedCache.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -211,7 +211,7 @@ uint64_t SharedCache::FastGetBackingCacheCount(BinaryNinja::Ref<BinaryNinja::Bin
{
std::shared_ptr<MMappedFileAccessor> baseFile;
try {
baseFile = MMappedFileAccessor::Open(dscView, dscView->GetFile()->GetSessionId(), dscView->GetFile()->GetOriginalFilename())->lock();
baseFile = MapFileWithoutApplyingSlide(dscView->GetFile()->GetOriginalFilename());
}
catch (...){
LogError("Shared Cache preload: Failed to open file %s", dscView->GetFile()->GetOriginalFilename().c_str());
Expand Down Expand Up @@ -274,7 +274,7 @@ void SharedCache::PerformInitialLoad()
{
m_logger->LogInfo("Performing initial load of Shared Cache");
auto path = m_dscView->GetFile()->GetOriginalFilename();
auto baseFile = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), path)->lock();
auto baseFile = MapFileWithoutApplyingSlide(path);

m_viewSpecificState->progress = LoadProgressLoadingCaches;

Expand Down Expand Up @@ -358,7 +358,7 @@ void SharedCache::PerformInitialLoad()
for (auto address : addresses)
{
i++;
auto vm = GetVMMap(true);
auto vm = GetVMMap();
auto machoHeader = SharedCache::LoadHeaderForAddress(vm, address, "dyld_shared_cache_branch_islands_" + std::to_string(i));
if (machoHeader)
{
Expand Down Expand Up @@ -446,7 +446,7 @@ void SharedCache::PerformInitialLoad()
subCachePath = path + "." + entry.fileExtension;
subCacheFilename = mainFileName + "." + entry.fileExtension;
}
auto subCacheFile = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), subCachePath)->lock();
auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath);

dyld_cache_header subCacheHeader {};
uint64_t headerSize = subCacheFile->ReadUInt32(16);
Expand Down Expand Up @@ -533,7 +533,7 @@ void SharedCache::PerformInitialLoad()
{
auto subCachePath = path + "." + std::to_string(i);
auto subCacheFilename = mainFileName + "." + std::to_string(i);
auto subCacheFile = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), subCachePath)->lock();
auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath);

dyld_cache_header subCacheHeader {};
uint64_t headerSize = subCacheFile->ReadUInt32(16);
Expand Down Expand Up @@ -578,7 +578,7 @@ void SharedCache::PerformInitialLoad()
// Load .symbols subcache
try {
auto subCachePath = path + ".symbols";
auto subCacheFile = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), subCachePath)->lock();
auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath);

dyld_cache_header subCacheHeader {};
uint64_t headerSize = subCacheFile->ReadUInt32(16);
Expand Down Expand Up @@ -675,7 +675,7 @@ void SharedCache::PerformInitialLoad()
subCacheFilename = mainFileName + "." + entry.fileExtension;
}

auto subCacheFile = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), subCachePath)->lock();
auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath);

dyld_cache_header subCacheHeader {};
uint64_t headerSize = subCacheFile->ReadUInt32(16);
Expand Down Expand Up @@ -734,7 +734,7 @@ void SharedCache::PerformInitialLoad()
try
{
auto subCachePath = path + ".symbols";
auto subCacheFile = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), subCachePath)->lock();
auto subCacheFile = MapFileWithoutApplyingSlide(subCachePath);
dyld_cache_header subCacheHeader {};
uint64_t headerSize = subCacheFile->ReadUInt32(16);
if (subCacheFile->ReadUInt32(16) > sizeof(dyld_cache_header))
Expand Down Expand Up @@ -770,7 +770,7 @@ void SharedCache::PerformInitialLoad()

// We have set up enough metadata to map VM now.

auto vm = GetVMMap(true);
auto vm = GetVMMap();
if (!vm)
{
m_logger->LogError("Failed to map VM pages for Shared Cache on initial load, this is fatal.");
Expand Down Expand Up @@ -969,21 +969,16 @@ void SharedCache::PerformInitialLoad()
m_viewSpecificState->progress = LoadProgressFinished;
}

std::shared_ptr<VM> SharedCache::GetVMMap(bool mapPages)
std::shared_ptr<VM> SharedCache::GetVMMap()
{
std::shared_ptr<VM> vm = std::make_shared<VM>(0x1000);

if (mapPages)
{
for (const auto& cache : State().backingCaches)
{
for (const auto& mapping : cache.mappings)
{
vm->MapPages(m_dscView, m_dscView->GetFile()->GetSessionId(), mapping.address, mapping.fileOffset, mapping.size, cache.path,
[this, vm=vm](std::shared_ptr<MMappedFileAccessor> mmap){
ParseAndApplySlideInfoForFile(mmap);
});
}
for (const auto& cache : State().backingCaches) {
for (const auto& mapping : cache.mappings) {
vm->MapPages(m_dscView, m_dscView->GetFile()->GetSessionId(), mapping.address, mapping.fileOffset, mapping.size, cache.path,
[this, vm=vm](std::shared_ptr<MMappedFileAccessor> mmap){
ParseAndApplySlideInfoForFile(mmap);
});
}
}

Expand Down Expand Up @@ -1587,7 +1582,6 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address)
}
m_logger->LogInfo("Loading stub island %s @ 0x%llx", stubIsland.prettyName.c_str(), stubIsland.start);
auto targetFile = vm->MappingAtAddress(stubIsland.start).first.fileAccessor->lock();
ParseAndApplySlideInfoForFile(targetFile);
auto reader = VMReader(vm);
auto buff = reader.ReadBuffer(stubIsland.start, stubIsland.size);
m_dscView->GetMemoryMap()->AddDataMemoryRegion(stubIsland.prettyName, stubIsland.start, buff, SegmentReadable | SegmentExecutable);
Expand Down Expand Up @@ -1616,7 +1610,6 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address)
}
m_logger->LogInfo("Loading dyld data %s", dyldData.prettyName.c_str());
auto targetFile = vm->MappingAtAddress(dyldData.start).first.fileAccessor->lock();
ParseAndApplySlideInfoForFile(targetFile);
auto reader = VMReader(vm);
auto buff = reader.ReadBuffer(dyldData.start, dyldData.size);
m_dscView->GetMemoryMap()->AddDataMemoryRegion(dyldData.prettyName, dyldData.start, buff, SegmentReadable);
Expand Down Expand Up @@ -1645,7 +1638,6 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address)
}
m_logger->LogInfo("Loading non-image region %s", region.prettyName.c_str());
auto targetFile = vm->MappingAtAddress(region.start).first.fileAccessor->lock();
ParseAndApplySlideInfoForFile(targetFile);
auto reader = VMReader(vm);
auto buff = reader.ReadBuffer(region.start, region.size);
m_dscView->GetMemoryMap()->AddDataMemoryRegion(region.prettyName, region.start, buff, region.flags);
Expand Down Expand Up @@ -1674,7 +1666,6 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address)
m_logger->LogDebug("Partial loading image %s", targetHeader.installName.c_str());

auto targetFile = vm->MappingAtAddress(targetSegment->start).first.fileAccessor->lock();
ParseAndApplySlideInfoForFile(targetFile);
auto buff = reader.ReadBuffer(targetSegment->start, targetSegment->size);
m_dscView->GetMemoryMap()->AddDataMemoryRegion(targetSegment->prettyName, targetSegment->start, buff, targetSegment->flags);

Expand Down Expand Up @@ -1824,8 +1815,6 @@ bool SharedCache::LoadImageWithInstallName(std::string installName, bool skipObj
}

auto targetFile = vm->MappingAtAddress(region.start).first.fileAccessor->lock();
ParseAndApplySlideInfoForFile(targetFile);

auto buff = reader.ReadBuffer(region.start, region.size);

region.loaded = true;
Expand Down Expand Up @@ -2829,7 +2818,7 @@ std::vector<std::pair<std::string, Ref<Symbol>>> SharedCache::LoadAllSymbolsAndW
auto header = HeaderForAddress(img.headerLocation);
std::shared_ptr<MMappedFileAccessor> mapping;
try {
mapping = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), header->exportTriePath)->lock();
mapping = MapFile(header->exportTriePath);
}
catch (...)
{
Expand Down Expand Up @@ -2928,7 +2917,7 @@ void SharedCache::FindSymbolAtAddrAndApplyToAddr(
{
std::shared_ptr<MMappedFileAccessor> mapping;
try {
mapping = MMappedFileAccessor::Open(m_dscView, m_dscView->GetFile()->GetSessionId(), header->exportTriePath)->lock();
mapping = MapFile(header->exportTriePath);
}
catch (...)
{
Expand Down Expand Up @@ -3268,7 +3257,7 @@ extern "C"
if (cache->object)
{
try {
auto vm = cache->object->GetVMMap(true);
auto vm = cache->object->GetVMMap();
auto viewImageHeaders = cache->object->AllImageHeaders();
*count = viewImageHeaders.size();
BNDSCImage* images = (BNDSCImage*)malloc(sizeof(BNDSCImage) * viewImageHeaders.size());
Expand Down Expand Up @@ -3347,7 +3336,7 @@ extern "C"
BNDSCMemoryUsageInfo BNDSCViewGetMemoryUsageInfo()
{
BNDSCMemoryUsageInfo info;
info.mmapRefs = mmapCount.load();
info.mmapRefs = MMapCount();
info.sharedCacheRefs = sharedCacheReferences.load();
return info;
}
Expand Down Expand Up @@ -3680,4 +3669,16 @@ size_t SharedCache::GetObjCRelativeMethodBaseAddress(const VMReader& reader) con
return 0;
}

std::shared_ptr<MMappedFileAccessor> SharedCache::MapFile(const std::string& path)
{
return MMappedFileAccessor::
Open(m_dscView, m_dscView->GetFile()->GetSessionId(), path, [this](std::shared_ptr<MMappedFileAccessor> mmap) {
ParseAndApplySlideInfoForFile(mmap);
})->lock();
}

std::shared_ptr<MMappedFileAccessor> SharedCache::MapFileWithoutApplyingSlide(const std::string& path) {
return std::make_shared<MMappedFileAccessor>(path);
}

} // namespace SharedCacheCore
6 changes: 5 additions & 1 deletion view/sharedcache/core/SharedCache.h
Original file line number Diff line number Diff line change
Expand Up @@ -592,13 +592,14 @@ namespace SharedCacheCore {
void DeserializeFromRawView();

public:
std::shared_ptr<VM> GetVMMap(bool mapPages = true);
std::shared_ptr<VM> GetVMMap();

static SharedCache* GetFromDSCView(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView);
static uint64_t FastGetBackingCacheCount(BinaryNinja::Ref<BinaryNinja::BinaryView> dscView);
bool SaveToDSCView();

void ParseAndApplySlideInfoForFile(std::shared_ptr<MMappedFileAccessor> file);

std::optional<uint64_t> GetImageStart(std::string installName);
std::optional<SharedCacheMachOHeader> HeaderForAddress(uint64_t);
bool LoadImageWithInstallName(std::string installName, bool skipObjC);
Expand Down Expand Up @@ -656,6 +657,9 @@ namespace SharedCacheCore {
// Must be called before first access to `MutableState()` after the state
// is loaded from the cache. Can safely be called multiple times.
void WillMutateState();

std::shared_ptr<MMappedFileAccessor> MapFile(const std::string& path);
static std::shared_ptr<MMappedFileAccessor> MapFileWithoutApplyingSlide(const std::string& path);
};

}
Expand Down
Loading