diff options
| author | Mark Rowe <mark@vector35.com> | 2025-10-22 19:52:19 -0700 |
|---|---|---|
| committer | Mark Rowe <mark@vector35.com> | 2025-10-23 13:33:08 -0700 |
| commit | 9a8faad50f56d748fcd1498c170797c67bb53217 (patch) | |
| tree | 2b39b444d1c51c680a89d86de40af85b5f913592 /view/kernelcache/core/KernelCacheController.cpp | |
| parent | b57e208e1aa7f261cb1d0980cada3af1c05fe6d1 (diff) | |
[KernelCache] Set segment permissions based on how XNU initially maps them
XNU maps kernel cache segments in with different permissions than the
load commands indicate. For instance, `__DATA_CONST` is initially mapped
as read-write before later being re-mapped as read-only. Treating it as
read-only results in analysis falsely assuming that global variables
cannot change.
To work around this we maintain a mapping from segment name to initial
permissions (i.e., most lax permissions) and favor them over permissions
derived from the segment load command. Section semantics are also
derived from the segment's permissions when the segment is present in
the mapping.
The mapping is based on the initial permissions established by
`arm_vm_prot_init` within the XNU source.
Diffstat (limited to 'view/kernelcache/core/KernelCacheController.cpp')
| -rw-r--r-- | view/kernelcache/core/KernelCacheController.cpp | 7 |
1 files changed, 5 insertions, 2 deletions
diff --git a/view/kernelcache/core/KernelCacheController.cpp b/view/kernelcache/core/KernelCacheController.cpp index 40d4a1df..753c28ad 100644 --- a/view/kernelcache/core/KernelCacheController.cpp +++ b/view/kernelcache/core/KernelCacheController.cpp @@ -124,10 +124,13 @@ bool KernelCacheController::ApplyImage(BinaryView& view, const CacheImage& image loadedRegion = true; for (const auto& segment : image.header->segments) { - auto flags = SegmentFlagsFromMachOProtections(segment.initprot, segment.maxprot); + if (segment.vmsize == 0) + continue; + + auto flags = SegmentFlagsForSegment(segment); view.AddAutoSegment(segment.vmaddr, segment.vmsize, segment.fileoff, segment.filesize, flags); - auto relocations = m_cache.GetRelocations(); + const auto& relocations = m_cache.GetRelocations(); auto begin = std::lower_bound(relocations.begin(), relocations.end(), segment.vmaddr, [](const std::pair<uint64_t, uint64_t>& reloc, uint64_t addr) { |
