mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-06 03:50:02 +02:00
Merge branch 'GP-5291_ryanmkurtz_dyld' (Closes #7396)
This commit is contained in:
commit
f94a76e875
4 changed files with 595 additions and 87 deletions
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -27,7 +27,6 @@ import ghidra.program.model.data.*;
|
||||||
import ghidra.program.model.listing.*;
|
import ghidra.program.model.listing.*;
|
||||||
import ghidra.program.model.mem.MemoryBlock;
|
import ghidra.program.model.mem.MemoryBlock;
|
||||||
import ghidra.program.model.util.CodeUnitInsertionException;
|
import ghidra.program.model.util.CodeUnitInsertionException;
|
||||||
import ghidra.util.NumericUtilities;
|
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -37,7 +36,6 @@ import ghidra.util.task.TaskMonitor;
|
||||||
*
|
*
|
||||||
* @see <a href="https://github.com/apple-oss-distributions/dyld/blob/main/cache-builder/dyld_cache_format.h">dyld_cache_format.h</a>
|
* @see <a href="https://github.com/apple-oss-distributions/dyld/blob/main/cache-builder/dyld_cache_format.h">dyld_cache_format.h</a>
|
||||||
*/
|
*/
|
||||||
@SuppressWarnings("unused")
|
|
||||||
public class DyldCacheHeader implements StructConverter {
|
public class DyldCacheHeader implements StructConverter {
|
||||||
|
|
||||||
private byte[] magic;
|
private byte[] magic;
|
||||||
|
@ -69,13 +67,12 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
private long progClosuresTrieAddr;
|
private long progClosuresTrieAddr;
|
||||||
private long progClosuresTrieSize;
|
private long progClosuresTrieSize;
|
||||||
private int platform;
|
private int platform;
|
||||||
private int dyld_info;
|
private int dyldInfo;
|
||||||
private int formatVersion;
|
private int formatVersion;
|
||||||
private boolean dylibsExpectedOnDisk;
|
private boolean dylibsExpectedOnDisk;
|
||||||
private boolean simulator;
|
private boolean simulator;
|
||||||
private boolean locallyBuiltCache;
|
private boolean locallyBuiltCache;
|
||||||
private boolean builtFromChainedFixups;
|
private boolean builtFromChainedFixups;
|
||||||
private int padding;
|
|
||||||
private long sharedRegionStart;
|
private long sharedRegionStart;
|
||||||
private long sharedRegionSize;
|
private long sharedRegionSize;
|
||||||
private long maxSlide;
|
private long maxSlide;
|
||||||
|
@ -116,6 +113,8 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
private long cacheAtlasSize;
|
private long cacheAtlasSize;
|
||||||
private long dynamicDataOffset;
|
private long dynamicDataOffset;
|
||||||
private long dynamicDataMaxSize;
|
private long dynamicDataMaxSize;
|
||||||
|
private int tproMappingsOffset;
|
||||||
|
private int tproMappingsCount;
|
||||||
|
|
||||||
private int headerSize;
|
private int headerSize;
|
||||||
private BinaryReader reader;
|
private BinaryReader reader;
|
||||||
|
@ -132,6 +131,9 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
private List<DyldCacheMappingAndSlideInfo> cacheMappingAndSlideInfoList;
|
private List<DyldCacheMappingAndSlideInfo> cacheMappingAndSlideInfoList;
|
||||||
private MemoryBlock fileBlock;
|
private MemoryBlock fileBlock;
|
||||||
|
|
||||||
|
@SuppressWarnings("unused")
|
||||||
|
private int padding;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link DyldCacheHeader}.
|
* Create a new {@link DyldCacheHeader}.
|
||||||
*
|
*
|
||||||
|
@ -212,13 +214,13 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
platform = reader.readNextInt();
|
platform = reader.readNextInt();
|
||||||
}
|
}
|
||||||
if (reader.getPointerIndex() < mappingOffset) {
|
if (reader.getPointerIndex() < mappingOffset) {
|
||||||
dyld_info = reader.readNextInt();
|
dyldInfo = reader.readNextInt();
|
||||||
formatVersion = dyld_info & 0xff;
|
formatVersion = dyldInfo & 0xff;
|
||||||
dylibsExpectedOnDisk = (dyld_info >>> 8 & 1) == 1;
|
dylibsExpectedOnDisk = (dyldInfo >>> 8 & 1) == 1;
|
||||||
simulator = (dyld_info >>> 9 & 1) == 1;
|
simulator = (dyldInfo >>> 9 & 1) == 1;
|
||||||
locallyBuiltCache = (dyld_info >> 10 & 1) == 1;
|
locallyBuiltCache = (dyldInfo >> 10 & 1) == 1;
|
||||||
builtFromChainedFixups = (dyld_info >> 11 & 1) == 1;
|
builtFromChainedFixups = (dyldInfo >> 11 & 1) == 1;
|
||||||
padding = (dyld_info >> 12) & 0xfffff;
|
padding = (dyldInfo >> 12) & 0xfffff;
|
||||||
}
|
}
|
||||||
if (reader.getPointerIndex() < mappingOffset) {
|
if (reader.getPointerIndex() < mappingOffset) {
|
||||||
sharedRegionStart = reader.readNextLong();
|
sharedRegionStart = reader.readNextLong();
|
||||||
|
@ -350,6 +352,12 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
if (reader.getPointerIndex() < mappingOffset) {
|
if (reader.getPointerIndex() < mappingOffset) {
|
||||||
dynamicDataMaxSize = reader.readNextLong();
|
dynamicDataMaxSize = reader.readNextLong();
|
||||||
}
|
}
|
||||||
|
if (reader.getPointerIndex() < mappingOffset) {
|
||||||
|
tproMappingsOffset = reader.readNextInt();
|
||||||
|
}
|
||||||
|
if (reader.getPointerIndex() < mappingOffset) {
|
||||||
|
tproMappingsCount = reader.readNextInt();
|
||||||
|
}
|
||||||
|
|
||||||
headerSize = (int) (reader.getPointerIndex() - startIndex);
|
headerSize = (int) (reader.getPointerIndex() - startIndex);
|
||||||
|
|
||||||
|
@ -385,7 +393,7 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
parseSlideInfos(log, monitor);
|
parseSlideInfos(log, monitor);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void parseSlideInfos(MessageLog log, TaskMonitor monitor) throws CancelledException {
|
private void parseSlideInfos(MessageLog log, TaskMonitor monitor) {
|
||||||
if (!hasSlideInfo()) {
|
if (!hasSlideInfo()) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -476,43 +484,563 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the base address of the DYLD cache. This is where the cache should be loaded in
|
* {@return the magic bytes, which contain version information}
|
||||||
* memory.
|
|
||||||
*
|
|
||||||
* @return The base address of the DYLD cache
|
|
||||||
*/
|
|
||||||
public long getBaseAddress() {
|
|
||||||
return baseAddress;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the magic bytes, which contain version information.
|
|
||||||
*
|
|
||||||
* @return The magic bytes
|
|
||||||
*/
|
*/
|
||||||
public byte[] getMagic() {
|
public byte[] getMagic() {
|
||||||
return magic;
|
return magic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the UUID in {@link String} form
|
* {@return the mapping offset}
|
||||||
*
|
|
||||||
* @return The UUID in {@link String} form, or null if a UUID is not defined
|
|
||||||
*/
|
*/
|
||||||
public String getUUID() {
|
public int getMappingOffset() {
|
||||||
return NumericUtilities.convertBytesToString(uuid);
|
return mappingOffset;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the DYLD entry point address (if known)
|
* {@return the mapping count}
|
||||||
*
|
|
||||||
* @return The DYLD entry point address, or null if it is not known
|
|
||||||
*/
|
*/
|
||||||
public Long getEntryPoint() {
|
public int getMappingCount() {
|
||||||
if (!hasAccelerateInfo()) {
|
return mappingCount;
|
||||||
return accelerateInfoSize_dyldInCacheEntry;
|
}
|
||||||
}
|
|
||||||
return null;
|
/**
|
||||||
|
* {@return the old images offset}
|
||||||
|
*/
|
||||||
|
public int getImagesOffsetOld() {
|
||||||
|
return imagesOffsetOld;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the old images count}
|
||||||
|
*/
|
||||||
|
public int getImagesCountOld() {
|
||||||
|
return imagesCountOld;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dyld base address}
|
||||||
|
*/
|
||||||
|
public long getDyldBaseAddress() {
|
||||||
|
return dyldBaseAddress;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the code signature offset}
|
||||||
|
*/
|
||||||
|
public long getCodeSignatureOffset() {
|
||||||
|
return codeSignatureOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the code signature size}
|
||||||
|
*/
|
||||||
|
public long getCodeSignatureSize() {
|
||||||
|
return codeSignatureSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the slide info offset}
|
||||||
|
*/
|
||||||
|
public long getSlideInfoOffset() {
|
||||||
|
return slideInfoOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the slide info size}
|
||||||
|
*/
|
||||||
|
public long getSlideInfoSize() {
|
||||||
|
return slideInfoSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the local symbols offset}
|
||||||
|
*/
|
||||||
|
public long getLocalSymbolsOffset() {
|
||||||
|
return localSymbolsOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the local symbols size}
|
||||||
|
*/
|
||||||
|
public long getLocalSymbolsSize() {
|
||||||
|
return localSymbolsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the UUID, or {@code null} if it is not defined}
|
||||||
|
*/
|
||||||
|
public byte[] getUUID() {
|
||||||
|
return uuid;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the cache type}
|
||||||
|
*/
|
||||||
|
public long getCacheType() {
|
||||||
|
return cacheType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the branch pools offset}
|
||||||
|
*/
|
||||||
|
public int getBranchPoolsOffset() {
|
||||||
|
return branchPoolsOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the branch pools count}
|
||||||
|
*/
|
||||||
|
public int getBranchPoolsCount() {
|
||||||
|
return branchPoolsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the old accelerate info address or new address of mach header in dyld cache, or
|
||||||
|
* {@code null} if it is not defined}
|
||||||
|
*/
|
||||||
|
public long getAccelerateInfoAddrOrDyldInCacheMH() {
|
||||||
|
return accelerateInfoAddr_dyldInCacheMH;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the old accelerate info size or new address of entry point in dyld cache, or
|
||||||
|
* {@code null} if it is not defined}
|
||||||
|
*/
|
||||||
|
public long getAccelerateInfoSizeOrDyldInCacheEntry() {
|
||||||
|
return accelerateInfoSize_dyldInCacheEntry;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the images text offset}
|
||||||
|
*/
|
||||||
|
public long getImagesTextOffset() {
|
||||||
|
return imagesTextOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the images text count}
|
||||||
|
*/
|
||||||
|
public long getImagesTextCount() {
|
||||||
|
return imagesTextCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the patch info address}
|
||||||
|
*/
|
||||||
|
public long getPatchInfoAddr() {
|
||||||
|
return patchInfoAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the patch info size}
|
||||||
|
*/
|
||||||
|
public long getPatchInfoSize() {
|
||||||
|
return patchInfoSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the other image group address (unused)}
|
||||||
|
*/
|
||||||
|
public long getOtherImageGroupAddrUnused() {
|
||||||
|
return otherImageGroupAddrUnused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the other image group size (unused)}
|
||||||
|
*/
|
||||||
|
public long getOtherImageGroupSizeUnused() {
|
||||||
|
return otherImageGroupSizeUnused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the program launch closures address}
|
||||||
|
*/
|
||||||
|
public long getProgClosuresAddr() {
|
||||||
|
return progClosuresAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the program launch closures size}
|
||||||
|
*/
|
||||||
|
public long getProgClosuresSize() {
|
||||||
|
return progClosuresSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the program launch closures trie address}
|
||||||
|
*/
|
||||||
|
public long getProgClosuresTrieAddr() {
|
||||||
|
return progClosuresTrieAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the program launch closures trie size}
|
||||||
|
*/
|
||||||
|
public long getProgClosuresTrieSize() {
|
||||||
|
return progClosuresTrieSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the platform}
|
||||||
|
*/
|
||||||
|
public int getPlatform() {
|
||||||
|
return platform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dyld info}
|
||||||
|
*/
|
||||||
|
public int getDyldInfo() {
|
||||||
|
return dyldInfo;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the format version}
|
||||||
|
*/
|
||||||
|
public int getFormatVersion() {
|
||||||
|
return formatVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dylibs expected on disk value}
|
||||||
|
*/
|
||||||
|
public boolean getDylibsExpectedOnDisk() {
|
||||||
|
return dylibsExpectedOnDisk;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the simulator value}
|
||||||
|
*/
|
||||||
|
public boolean getSimulator() {
|
||||||
|
return simulator;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the locally built cache value}
|
||||||
|
*/
|
||||||
|
public boolean getLocallyBuildCache() {
|
||||||
|
return locallyBuiltCache;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the built from chained fixups value}
|
||||||
|
*/
|
||||||
|
public boolean getBuiltFromChainedFixups() {
|
||||||
|
return builtFromChainedFixups;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the shared region start}
|
||||||
|
*/
|
||||||
|
public long getSharedRegionStart() {
|
||||||
|
return sharedRegionStart;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the shared region size}
|
||||||
|
*/
|
||||||
|
public long getSharedRegionSize() {
|
||||||
|
return sharedRegionSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the max slide}
|
||||||
|
*/
|
||||||
|
public long getMaxSlide() {
|
||||||
|
return maxSlide;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dylibs image array address}
|
||||||
|
*/
|
||||||
|
public long getDylibsImageArrayAddr() {
|
||||||
|
return dylibsImageArrayAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dylibs image array size}
|
||||||
|
*/
|
||||||
|
public long getDylibsImageArraySize() {
|
||||||
|
return dylibsImageArraySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dylibs trie address}
|
||||||
|
*/
|
||||||
|
public long getDylibsTriAddr() {
|
||||||
|
return dylibsTrieAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dylibs trie size}
|
||||||
|
*/
|
||||||
|
public long getDylibsTrieSize() {
|
||||||
|
return dylibsTrieSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the other image array address}
|
||||||
|
*/
|
||||||
|
public long getOtherImageArrayAddr() {
|
||||||
|
return otherImageArrayAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the other image array size}
|
||||||
|
*/
|
||||||
|
public long getOtherImageArraySize() {
|
||||||
|
return otherImageArraySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the other trie address}
|
||||||
|
*/
|
||||||
|
public long getOtherTriAddr() {
|
||||||
|
return otherTrieAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the other trie size}
|
||||||
|
*/
|
||||||
|
public long getOtherTrieSize() {
|
||||||
|
return otherTrieSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the mapping with slide offset}
|
||||||
|
*/
|
||||||
|
public int getMappingWithSlideOffset() {
|
||||||
|
return mappingWithSlideOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the mapping with slide count}
|
||||||
|
*/
|
||||||
|
public int getMappingWithSlideCount() {
|
||||||
|
return mappingWithSlideCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dylibs PrebuildLoaderSet state array address (unused), or {@code null} if it is
|
||||||
|
* not defined}
|
||||||
|
*/
|
||||||
|
public long getDylibsPBLStateArrayAddrUnused() {
|
||||||
|
return dylibsPBLStateArrayAddrUnused;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dylibs PrebuildLoaderSet set address}
|
||||||
|
*/
|
||||||
|
public long getDylibsPBLSetAddr() {
|
||||||
|
return dylibsPBLSetAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the programs PrebuildLoaderSet set pool address, or {@code null} if it is not
|
||||||
|
* defined}
|
||||||
|
*/
|
||||||
|
public long getProgramsPBLSetPoolAddr() {
|
||||||
|
return programsPBLSetPoolAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the programs PrebuildLoaderSet set pool size}
|
||||||
|
*/
|
||||||
|
public long getProgramsPBLSetPoolSize() {
|
||||||
|
return programsPBLSetPoolSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the program trie address}
|
||||||
|
*/
|
||||||
|
public long getProgramTrieAddr() {
|
||||||
|
return programTrieAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the program trie size}
|
||||||
|
*/
|
||||||
|
public int getProgramTrieSize() {
|
||||||
|
return programTrieSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the OS version}
|
||||||
|
*/
|
||||||
|
public int getOsVersion() {
|
||||||
|
return osVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the alt platform}
|
||||||
|
*/
|
||||||
|
public int getAltPlatform() {
|
||||||
|
return altPlatform;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the alt OS version}
|
||||||
|
*/
|
||||||
|
public int getAltOsVersion() {
|
||||||
|
return altOsVersion;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the swift opts offset}
|
||||||
|
*/
|
||||||
|
public long getSwiftOptsOffset() {
|
||||||
|
return swiftOptsOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the swift opts size}
|
||||||
|
*/
|
||||||
|
public long getSwiftOptsSize() {
|
||||||
|
return swiftOptsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the subcache array offset}
|
||||||
|
*/
|
||||||
|
public int getSubCacheArrayOffset() {
|
||||||
|
return subCacheArrayOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the subcache array count, or {@code null} if it is not defined}
|
||||||
|
*/
|
||||||
|
public Integer getSubCacheArrayCount() {
|
||||||
|
return subCacheArrayCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the symbol file UUID, or {@code null} if it is not defined}
|
||||||
|
*/
|
||||||
|
public byte[] getSymbolFileUUID() {
|
||||||
|
return symbolFileUUID;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the rosetta read-only address}
|
||||||
|
*/
|
||||||
|
public long getRosettaReadOnlyAddr() {
|
||||||
|
return rosettaReadOnlyAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the rosetta read-only size}
|
||||||
|
*/
|
||||||
|
public long getRosettaReadOnlySize() {
|
||||||
|
return rosettaReadOnlySize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the rosetta read-write address}
|
||||||
|
*/
|
||||||
|
public long getRosettaReadWriteAddr() {
|
||||||
|
return rosettaReadWriteAddr;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the rosetta read-write size}
|
||||||
|
*/
|
||||||
|
public long getRosettaReadWriteSize() {
|
||||||
|
return rosettaReadWriteSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the images offset}
|
||||||
|
*/
|
||||||
|
public int getImagesOffset() {
|
||||||
|
return imagesOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the images count}
|
||||||
|
*/
|
||||||
|
public int getImagesCount() {
|
||||||
|
return imagesCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the cache subtype, or {@code null} if it is not defined}
|
||||||
|
*/
|
||||||
|
public Integer getCacheSubType() {
|
||||||
|
return cacheSubType;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the ObjC opts offset}
|
||||||
|
*/
|
||||||
|
public long getObjcOptsOffset() {
|
||||||
|
return objcOptsOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the ObjC opts size}
|
||||||
|
*/
|
||||||
|
public long getObjcOptsSize() {
|
||||||
|
return objcOptsSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the cache atlas offset}
|
||||||
|
*/
|
||||||
|
public long getCacheAtlasOffset() {
|
||||||
|
return cacheAtlasOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the cache atlas size}
|
||||||
|
*/
|
||||||
|
public long getCacheAtlasSize() {
|
||||||
|
return cacheAtlasSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dynamic data offset}
|
||||||
|
*/
|
||||||
|
public long getDynamicDataOffset() {
|
||||||
|
return dynamicDataOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the dynamic data max size}
|
||||||
|
*/
|
||||||
|
public long getDynamicDataMaxSize() {
|
||||||
|
return dynamicDataMaxSize;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the tpro mappings offset}
|
||||||
|
*/
|
||||||
|
public int getTproMappingsOffset() {
|
||||||
|
return tproMappingsOffset;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the tpro mappings count}
|
||||||
|
*/
|
||||||
|
public int getTproMappingsCount() {
|
||||||
|
return tproMappingsCount;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the reader associated with the header}
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
public BinaryReader getReader() {
|
||||||
|
return reader;
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return the base address of the DYLD cache}
|
||||||
|
* <p>
|
||||||
|
* This is where the cache should be loaded in memory.
|
||||||
|
*/
|
||||||
|
public long getBaseAddress() {
|
||||||
|
return baseAddress;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -524,30 +1052,6 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
return mappingInfoList;
|
return mappingInfoList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the file offset to first {@link DyldCacheImageInfo}.
|
|
||||||
*
|
|
||||||
* @return The file offset to first {@link DyldCacheImageInfo}
|
|
||||||
*/
|
|
||||||
public int getImagesOffset() {
|
|
||||||
if (imagesOffset != 0) {
|
|
||||||
return imagesOffset;
|
|
||||||
}
|
|
||||||
return imagesOffsetOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the number of {@link DyldCacheImageInfo}s.
|
|
||||||
*
|
|
||||||
* @return The number of {@link DyldCacheImageInfo}s
|
|
||||||
*/
|
|
||||||
public int getImagesCount() {
|
|
||||||
if (imagesOffset != 0) {
|
|
||||||
return imagesCount;
|
|
||||||
}
|
|
||||||
return imagesCountOld;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Generates a {@link List} of {@link DyldCacheImage}s that are mapped in by this
|
* Generates a {@link List} of {@link DyldCacheImage}s that are mapped in by this
|
||||||
* {@link DyldCacheHeader}. Requires header to have been parsed.
|
* {@link DyldCacheHeader}. Requires header to have been parsed.
|
||||||
|
@ -581,16 +1085,6 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
return subcacheEntryList;
|
return subcacheEntryList;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* Gets the symbol file UUID in {@link String} form
|
|
||||||
*
|
|
||||||
* @return The symbol file UUID in {@link String} form, or null if a symbol file UUID is not
|
|
||||||
* defined or is all zeros
|
|
||||||
*/
|
|
||||||
public String getSymbolFileUUID() {
|
|
||||||
return NumericUtilities.convertBytesToString(symbolFileUUID);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Gets the {@link List} of {@link DyldCacheMappingAndSlideInfo}s. Requires header to have been parsed.
|
* Gets the {@link List} of {@link DyldCacheMappingAndSlideInfo}s. Requires header to have been parsed.
|
||||||
*
|
*
|
||||||
|
@ -718,6 +1212,8 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
addHeaderField(struct, QWORD, "cacheAtlasSize", "size of embedded cache atlas");
|
addHeaderField(struct, QWORD, "cacheAtlasSize", "size of embedded cache atlas");
|
||||||
addHeaderField(struct, QWORD, "dynamicDataOffset", "VM offset from cache_header* to the location of dyld_cache_dynamic_data_header");
|
addHeaderField(struct, QWORD, "dynamicDataOffset", "VM offset from cache_header* to the location of dyld_cache_dynamic_data_header");
|
||||||
addHeaderField(struct, QWORD, "dynamicDataMaxSize", "maximum size of space reserved from dynamic data");
|
addHeaderField(struct, QWORD, "dynamicDataMaxSize", "maximum size of space reserved from dynamic data");
|
||||||
|
addHeaderField(struct, DWORD, "tproMappingsOffset", "file offset to first dyld_cache_tpro_mapping_info");
|
||||||
|
addHeaderField(struct, DWORD, "tproMappingsCount", "number of dyld_cache_tpro_mapping_info entries");
|
||||||
// @formatter:on
|
// @formatter:on
|
||||||
|
|
||||||
struct.setCategoryPath(new CategoryPath(MachConstants.DATA_TYPE_CATEGORY));
|
struct.setCategoryPath(new CategoryPath(MachConstants.DATA_TYPE_CATEGORY));
|
||||||
|
@ -871,7 +1367,7 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markupHeader(Program program, AddressSpace space, TaskMonitor monitor,
|
private void markupHeader(Program program, AddressSpace space, TaskMonitor monitor,
|
||||||
MessageLog log) throws CancelledException {
|
MessageLog log) {
|
||||||
monitor.setMessage("Marking up DYLD header...");
|
monitor.setMessage("Marking up DYLD header...");
|
||||||
monitor.initialize(1);
|
monitor.initialize(1);
|
||||||
try {
|
try {
|
||||||
|
@ -948,7 +1444,7 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markupCodeSignature(Program program, AddressSpace space, TaskMonitor monitor,
|
private void markupCodeSignature(Program program, AddressSpace space, TaskMonitor monitor,
|
||||||
MessageLog log) throws CancelledException {
|
MessageLog log) {
|
||||||
monitor.setMessage("Marking up DYLD code signature...");
|
monitor.setMessage("Marking up DYLD code signature...");
|
||||||
monitor.initialize(1);
|
monitor.initialize(1);
|
||||||
try {
|
try {
|
||||||
|
@ -965,7 +1461,7 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void markupSlideInfo(Program program, AddressSpace space, TaskMonitor monitor,
|
private void markupSlideInfo(Program program, AddressSpace space, TaskMonitor monitor,
|
||||||
MessageLog log) throws CancelledException {
|
MessageLog log) {
|
||||||
monitor.setMessage("Marking up DYLD slide info...");
|
monitor.setMessage("Marking up DYLD slide info...");
|
||||||
monitor.initialize(1);
|
monitor.initialize(1);
|
||||||
try {
|
try {
|
||||||
|
@ -1012,7 +1508,7 @@ public class DyldCacheHeader implements StructConverter {
|
||||||
monitor.initialize(branchPoolList.size());
|
monitor.initialize(branchPoolList.size());
|
||||||
try {
|
try {
|
||||||
Address addr = fileOffsetToAddr(branchPoolsOffset, program, space);
|
Address addr = fileOffsetToAddr(branchPoolsOffset, program, space);
|
||||||
for (Long element : branchPoolList) {
|
for (int i = 0; i < branchPoolList.size(); i++) {
|
||||||
Data d = DataUtilities.createData(program, addr, Pointer64DataType.dataType,
|
Data d = DataUtilities.createData(program, addr, Pointer64DataType.dataType,
|
||||||
Pointer64DataType.dataType.getLength(),
|
Pointer64DataType.dataType.getLength(),
|
||||||
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
|
DataUtilities.ClearDataMode.CHECK_FOR_SPACE);
|
||||||
|
|
|
@ -4,9 +4,9 @@
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
@ -35,6 +35,7 @@ import ghidra.program.model.mem.MemoryAccessException;
|
||||||
import ghidra.program.model.mem.MemoryBlock;
|
import ghidra.program.model.mem.MemoryBlock;
|
||||||
import ghidra.program.model.symbol.SourceType;
|
import ghidra.program.model.symbol.SourceType;
|
||||||
import ghidra.program.model.symbol.SymbolUtilities;
|
import ghidra.program.model.symbol.SymbolUtilities;
|
||||||
|
import ghidra.util.NumericUtilities;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
@ -143,7 +144,9 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
|
||||||
*/
|
*/
|
||||||
private void setDyldCacheEntryPoint(SplitDyldCache splitDyldCache) throws Exception {
|
private void setDyldCacheEntryPoint(SplitDyldCache splitDyldCache) throws Exception {
|
||||||
monitor.initialize(1, "Setting entry pointer base...");
|
monitor.initialize(1, "Setting entry pointer base...");
|
||||||
Long entryPoint = splitDyldCache.getDyldCacheHeader(0).getEntryPoint();
|
Long entryPoint = !splitDyldCache.getDyldCacheHeader(0).hasAccelerateInfo()
|
||||||
|
? splitDyldCache.getDyldCacheHeader(0).getAccelerateInfoSizeOrDyldInCacheEntry()
|
||||||
|
: null;
|
||||||
if (entryPoint != null) {
|
if (entryPoint != null) {
|
||||||
Address entryPointAddr = space.getAddress(entryPoint);
|
Address entryPointAddr = space.getAddress(entryPoint);
|
||||||
program.getSymbolTable().addExternalEntryPoint(entryPointAddr);
|
program.getSymbolTable().addExternalEntryPoint(entryPointAddr);
|
||||||
|
@ -186,7 +189,8 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
|
||||||
if (!bookmarkSet) {
|
if (!bookmarkSet) {
|
||||||
program.getBookmarkManager()
|
program.getBookmarkManager()
|
||||||
.setBookmark(block.getStart(), BookmarkType.INFO, "Dyld Cache Header",
|
.setBookmark(block.getStart(), BookmarkType.INFO, "Dyld Cache Header",
|
||||||
name + " - " + dyldCacheHeader.getUUID());
|
name + " - " +
|
||||||
|
NumericUtilities.convertBytesToString(dyldCacheHeader.getUUID()));
|
||||||
bookmarkSet = true;
|
bookmarkSet = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -27,6 +27,7 @@ import ghidra.formats.gfilesystem.*;
|
||||||
import ghidra.program.model.address.Address;
|
import ghidra.program.model.address.Address;
|
||||||
import ghidra.program.model.listing.Program;
|
import ghidra.program.model.listing.Program;
|
||||||
import ghidra.program.model.mem.MemoryAccessException;
|
import ghidra.program.model.mem.MemoryAccessException;
|
||||||
|
import ghidra.util.NumericUtilities;
|
||||||
import ghidra.util.exception.CancelledException;
|
import ghidra.util.exception.CancelledException;
|
||||||
import ghidra.util.task.TaskMonitor;
|
import ghidra.util.task.TaskMonitor;
|
||||||
|
|
||||||
|
@ -149,7 +150,8 @@ public class DyldCacheUtils {
|
||||||
splitHeader.parseFromFile(shouldProcessLocalSymbols, log, monitor);
|
splitHeader.parseFromFile(shouldProcessLocalSymbols, log, monitor);
|
||||||
headers.add(splitHeader);
|
headers.add(splitHeader);
|
||||||
names.add(splitFSRL.getName());
|
names.add(splitFSRL.getName());
|
||||||
uuidToFileMap.put(splitHeader.getUUID(), splitFSRL);
|
uuidToFileMap.put(NumericUtilities.convertBytesToString(splitHeader.getUUID()),
|
||||||
|
splitFSRL);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Validate the subcaches
|
// Validate the subcaches
|
||||||
|
@ -164,7 +166,8 @@ public class DyldCacheUtils {
|
||||||
}
|
}
|
||||||
log.appendMsg("Including subcache: " + fsrl.getName() + " - " + uuid);
|
log.appendMsg("Including subcache: " + fsrl.getName() + " - " + uuid);
|
||||||
}
|
}
|
||||||
String symbolUUID = baseHeader.getSymbolFileUUID();
|
String symbolUUID =
|
||||||
|
NumericUtilities.convertBytesToString(baseHeader.getSymbolFileUUID());
|
||||||
if (symbolUUID != null) {
|
if (symbolUUID != null) {
|
||||||
FSRL symbolFSRL = uuidToFileMap.get(symbolUUID);
|
FSRL symbolFSRL = uuidToFileMap.get(symbolUUID);
|
||||||
if (symbolFSRL == null) {
|
if (symbolFSRL == null) {
|
||||||
|
|
|
@ -55,10 +55,15 @@ public class DyldCacheAnalyzer extends FileFormatAnalyzer {
|
||||||
createFragment(program, headerDataType.getName(), headerData.getMinAddress(),
|
createFragment(program, headerDataType.getName(), headerData.getMinAddress(),
|
||||||
headerData.getMaxAddress().add(1));
|
headerData.getMaxAddress().add(1));
|
||||||
|
|
||||||
reader.setPointerIndex(header.getImagesOffset());
|
int imagesOffset = header.getImagesOffset() != 0 ? header.getImagesOffset()
|
||||||
Address address = toAddr(program, header.getImagesOffset());
|
: header.getImagesOffsetOld();
|
||||||
|
int imagesCount = header.getImagesOffset() != 0 ? header.getImagesCount()
|
||||||
|
: header.getImagesCountOld();
|
||||||
|
|
||||||
for (int i = 0; i < header.getImagesCount(); ++i) {
|
reader.setPointerIndex(imagesOffset);
|
||||||
|
Address address = toAddr(program, imagesOffset);
|
||||||
|
|
||||||
|
for (int i = 0; i < imagesCount; ++i) {
|
||||||
|
|
||||||
if (monitor.isCancelled()) {
|
if (monitor.isCancelled()) {
|
||||||
break;
|
break;
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue