summaryrefslogtreecommitdiff
path: root/view/sharedcache/core/SharedCache.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'view/sharedcache/core/SharedCache.cpp')
-rw-r--r--view/sharedcache/core/SharedCache.cpp152
1 files changed, 80 insertions, 72 deletions
diff --git a/view/sharedcache/core/SharedCache.cpp b/view/sharedcache/core/SharedCache.cpp
index b734a6b1..0f61da63 100644
--- a/view/sharedcache/core/SharedCache.cpp
+++ b/view/sharedcache/core/SharedCache.cpp
@@ -133,6 +133,24 @@ std::string base_name(std::string const& path)
return path.substr(path.find_last_of("/\\") + 1);
}
+BNSegmentFlag SegmentFlagsFromMachOProtections(int initProt, int maxProt) {
+
+ uint32_t flags = 0;
+ if (initProt & MACHO_VM_PROT_READ)
+ flags |= SegmentReadable;
+ if (initProt & MACHO_VM_PROT_WRITE)
+ flags |= SegmentWritable;
+ if (initProt & MACHO_VM_PROT_EXECUTE)
+ flags |= SegmentExecutable;
+ if (((initProt & MACHO_VM_PROT_WRITE) == 0) &&
+ ((maxProt & MACHO_VM_PROT_WRITE) == 0))
+ flags |= SegmentDenyWrite;
+ if (((initProt & MACHO_VM_PROT_EXECUTE) == 0) &&
+ ((maxProt & MACHO_VM_PROT_EXECUTE) == 0))
+ flags |= SegmentDenyExecute;
+ return (BNSegmentFlag)flags;
+}
+
#pragma clang diagnostic push
#pragma clang diagnostic ignored "-Wunused-function"
@@ -305,11 +323,7 @@ void SharedCache::PerformInitialLoad()
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
{
baseFile->Read(&mapping, primaryCacheHeader.mappingOffset + (i * sizeof(mapping)), sizeof(mapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = mapping.fileOffset;
- mapRawToAddrAndSize.second.first = mapping.address;
- mapRawToAddrAndSize.second.second = mapping.size;
- cache.mappings.push_back(mapRawToAddrAndSize);
+ cache.mappings.push_back(mapping);
}
MutableState().backingCaches.push_back(std::move(cache));
@@ -373,11 +387,7 @@ void SharedCache::PerformInitialLoad()
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
{
baseFile->Read(&mapping, primaryCacheHeader.mappingOffset + (i * sizeof(mapping)), sizeof(mapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = mapping.fileOffset;
- mapRawToAddrAndSize.second.first = mapping.address;
- mapRawToAddrAndSize.second.second = mapping.size;
- cache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ cache.mappings.push_back(mapping);
}
MutableState().backingCaches.push_back(std::move(cache));
@@ -449,11 +459,7 @@ void SharedCache::PerformInitialLoad()
{
subCacheFile->Read(&subCacheMapping, subCacheHeader.mappingOffset + (j * sizeof(subCacheMapping)),
sizeof(subCacheMapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = subCacheMapping.fileOffset;
- mapRawToAddrAndSize.second.first = subCacheMapping.address;
- mapRawToAddrAndSize.second.second = subCacheMapping.size;
- subCache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ subCache.mappings.push_back(subCacheMapping);
}
if (subCacheHeader.mappingCount == 1 && subCacheHeader.imagesCountOld == 0 && subCacheHeader.imagesCount == 0
@@ -485,11 +491,7 @@ void SharedCache::PerformInitialLoad()
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
{
baseFile->Read(&mapping, primaryCacheHeader.mappingOffset + (i * sizeof(mapping)), sizeof(mapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = mapping.fileOffset;
- mapRawToAddrAndSize.second.first = mapping.address;
- mapRawToAddrAndSize.second.second = mapping.size;
- cache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ cache.mappings.push_back(mapping);
}
MutableState().backingCaches.push_back(std::move(cache));
@@ -545,11 +547,7 @@ void SharedCache::PerformInitialLoad()
{
subCacheFile->Read(&subCacheMapping, subCacheHeader.mappingOffset + (j * sizeof(subCacheMapping)),
sizeof(subCacheMapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = subCacheMapping.fileOffset;
- mapRawToAddrAndSize.second.first = subCacheMapping.address;
- mapRawToAddrAndSize.second.second = subCacheMapping.size;
- subCache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ subCache.mappings.push_back(subCacheMapping);
}
MutableState().backingCaches.push_back(std::move(subCache));
@@ -591,11 +589,7 @@ void SharedCache::PerformInitialLoad()
{
subCacheFile->Read(&subCacheMapping, subCacheHeader.mappingOffset + (j * sizeof(subCacheMapping)),
sizeof(subCacheMapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = subCacheMapping.fileOffset;
- mapRawToAddrAndSize.second.first = subCacheMapping.address;
- mapRawToAddrAndSize.second.second = subCacheMapping.size;
- subCache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ subCache.mappings.push_back(subCacheMapping);
}
MutableState().backingCaches.push_back(std::move(subCache));
@@ -612,11 +606,7 @@ void SharedCache::PerformInitialLoad()
for (size_t i = 0; i < primaryCacheHeader.mappingCount; i++)
{
baseFile->Read(&mapping, primaryCacheHeader.mappingOffset + (i * sizeof(mapping)), sizeof(mapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = mapping.fileOffset;
- mapRawToAddrAndSize.second.first = mapping.address;
- mapRawToAddrAndSize.second.second = mapping.size;
- cache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ cache.mappings.push_back(mapping);
}
MutableState().backingCaches.push_back(std::move(cache));
@@ -694,12 +684,7 @@ void SharedCache::PerformInitialLoad()
{
subCacheFile->Read(&subCacheMapping, subCacheHeader.mappingOffset + (j * sizeof(subCacheMapping)),
sizeof(subCacheMapping));
-
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = subCacheMapping.fileOffset;
- mapRawToAddrAndSize.second.first = subCacheMapping.address;
- mapRawToAddrAndSize.second.second = subCacheMapping.size;
- subCache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ subCache.mappings.push_back(subCacheMapping);
if (subCachePath.find(".dylddata") != std::string::npos)
{
@@ -756,11 +741,7 @@ void SharedCache::PerformInitialLoad()
{
subCacheFile->Read(&subCacheMapping, subCacheHeader.mappingOffset + (j * sizeof(subCacheMapping)),
sizeof(subCacheMapping));
- std::pair<uint64_t, std::pair<uint64_t, uint64_t>> mapRawToAddrAndSize;
- mapRawToAddrAndSize.first = subCacheMapping.fileOffset;
- mapRawToAddrAndSize.second.first = subCacheMapping.address;
- mapRawToAddrAndSize.second.second = subCacheMapping.size;
- subCache.mappings.push_back(std::move(mapRawToAddrAndSize));
+ subCache.mappings.push_back(subCacheMapping);
}
MutableState().backingCaches.push_back(std::move(subCache));
@@ -806,19 +787,7 @@ void SharedCache::PerformInitialLoad()
sectionRegion.prettyName = imageHeader.value().identifierPrefix + "::" + std::string(segName);
sectionRegion.start = segment.vmaddr;
sectionRegion.size = segment.vmsize;
- uint32_t flags = 0;
- if (segment.initprot & MACHO_VM_PROT_READ)
- flags |= SegmentReadable;
- if (segment.initprot & MACHO_VM_PROT_WRITE)
- flags |= SegmentWritable;
- if (segment.initprot & MACHO_VM_PROT_EXECUTE)
- flags |= SegmentExecutable;
- if (((segment.initprot & MACHO_VM_PROT_WRITE) == 0) &&
- ((segment.maxprot & MACHO_VM_PROT_WRITE) == 0))
- flags |= SegmentDenyWrite;
- if (((segment.initprot & MACHO_VM_PROT_EXECUTE) == 0) &&
- ((segment.maxprot & MACHO_VM_PROT_EXECUTE) == 0))
- flags |= SegmentDenyExecute;
+ uint32_t flags = SegmentFlagsFromMachOProtections(segment.initprot, segment.maxprot);
// if we're positive we have an entry point for some reason, force the segment
// executable. this helps with kernel images.
@@ -850,11 +819,10 @@ void SharedCache::PerformInitialLoad()
for (const auto& mapping : cache.mappings)
{
MemoryRegion region;
- region.start = mapping.second.first;
- region.size = mapping.second.second;
+ region.start = mapping.address;
+ region.size = mapping.size;
region.prettyName = base_name(cache.path) + "::" + std::to_string(i);
- // FIXME flags!!! BackingCache.mapping needs refactored to store this information!
- region.flags = (BNSegmentFlag)(BNSegmentFlag::SegmentReadable | BNSegmentFlag::SegmentExecutable);
+ region.flags = SegmentFlagsFromMachOProtections(mapping.initProt, mapping.maxProt);
MutableState().nonImageRegions.push_back(std::move(region));
i++;
}
@@ -998,7 +966,7 @@ std::shared_ptr<VM> SharedCache::GetVMMap(bool mapPages)
{
for (const auto& mapping : cache.mappings)
{
- vm->MapPages(m_dscView, m_dscView->GetFile()->GetSessionId(), mapping.second.first, mapping.first, mapping.second.second, cache.path,
+ 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);
});
@@ -1065,9 +1033,9 @@ void SharedCache::ParseAndApplySlideInfoForFile(std::shared_ptr<MMappedFileAcces
{
for (const auto& mapping : backingCache.mappings)
{
- if (mapping.second.first < base)
+ if (mapping.address < base)
{
- base = mapping.second.first;
+ base = mapping.address;
break;
}
}
@@ -1696,7 +1664,7 @@ bool SharedCache::LoadSectionAtAddress(uint64_t address)
m_dscView->GetParentView()->WriteBuffer(rawViewEnd, buff);
m_dscView->GetParentView()->AddAutoSegment(rawViewEnd, region.size, rawViewEnd, region.size, region.flags);
m_dscView->AddUserSegment(region.start, region.size, rawViewEnd, region.size, region.flags);
- m_dscView->AddUserSection(name, region.start, region.size, ReadOnlyCodeSectionSemantics);
+ m_dscView->AddUserSection(name, region.start, region.size, region.flags & SegmentDenyExecute ? ReadOnlyDataSectionSemantics : ReadOnlyCodeSectionSemantics);
m_dscView->WriteBuffer(region.start, buff);
region.loaded = true;
@@ -3298,11 +3266,11 @@ extern "C"
mappings = (BNDSCBackingCacheMapping*)malloc(sizeof(BNDSCBackingCacheMapping) * viewCaches[i].mappings.size());
size_t j = 0;
- for (const auto& [fileOffset, mapping] : viewCaches[i].mappings)
+ for (const auto& mapping : viewCaches[i].mappings)
{
- mappings[j].vmAddress = mapping.first;
- mappings[j].size = mapping.second;
- mappings[j].fileOffset = fileOffset;
+ mappings[j].vmAddress = mapping.address;
+ mappings[j].size = mapping.size;
+ mappings[j].fileOffset = mapping.fileOffset;
j++;
}
caches[i].mappings = mappings;
@@ -3445,6 +3413,34 @@ void InitDSCViewType()
namespace SharedCacheCore {
+void Serialize(SerializationContext& context, const dyld_cache_mapping_info& value)
+{
+ context.writer.StartArray();
+ Serialize(context, value.address);
+ Serialize(context, value.size);
+ Serialize(context, value.fileOffset);
+ Serialize(context, value.maxProt);
+ Serialize(context, value.initProt);
+ context.writer.EndArray();
+}
+
+void Deserialize(DeserializationContext& context, std::string_view name, std::vector<dyld_cache_mapping_info>& b)
+{
+
+ auto bArr = context.doc[name.data()].GetArray();
+ for (auto& s : bArr)
+ {
+ dyld_cache_mapping_info mapping;
+ auto s2 = s.GetArray();
+ mapping.address = s2[0].GetUint64();
+ mapping.size = s2[1].GetUint64();
+ mapping.fileOffset = s2[2].GetUint64();
+ mapping.maxProt = s2[3].GetUint();
+ mapping.initProt = s2[4].GetUint();
+ b.push_back(mapping);
+ }
+}
+
void SharedCache::Store(SerializationContext& context) const
{
Serialize(context, "metadataVersion", METADATA_VERSION);
@@ -3616,6 +3612,19 @@ void SharedCache::Load(DeserializationContext& context)
m_metadataValid = true;
}
+void BackingCache::Store(SerializationContext& context) const
+{
+ MSS(path);
+ MSS(isPrimary);
+ MSS(mappings);
+}
+void BackingCache::Load(DeserializationContext& context)
+{
+ MSL(path);
+ MSL(isPrimary);
+ MSL(mappings);
+}
+
#if defined(__GNUC__) || defined(__clang__)
__attribute__((always_inline)) void SharedCache::AssertMutable() const
#elif defined(_MSC_VER)
@@ -3664,5 +3673,4 @@ const std::unordered_map<uint64_t, SharedCacheMachOHeader>& SharedCache::AllImag
{
return State().headers;
}
-
} // namespace SharedCacheCore