GP-0: Small Mach-O refactorings

This commit is contained in:
Ryan Kurtz
2023-08-16 12:34:15 -04:00
parent 1d16c0c8b2
commit 3f130fc4e1
7 changed files with 76 additions and 33 deletions

View File

@@ -146,6 +146,8 @@ public class Section implements StructConverter {
/**
* Returns an input stream to underlying bytes of this section.
*
* @param header The Mach-O header
* @return an input stream to underlying bytes of this section
* @throws IOException if an i/o error occurs.
*/
@@ -220,6 +222,17 @@ public class Section implements StructConverter {
return reserved3;
}
/**
* Returns true if the section contains the given address
*
* @param address The address to check
* @return True if the section contains the given address; otherwise, false
*/
public boolean contains(long address) {
return Long.compareUnsigned(address, addr) >= 0 &&
Long.compareUnsigned(address, addr + size) < 0;
}
@Override
public DataType toDataType() throws DuplicateNameException, IOException {
StructureDataType struct = new StructureDataType("section", 0);

View File

@@ -200,6 +200,17 @@ public class SegmentCommand extends LoadCommand {
return (flags & SegmentConstants.FLAG_APPLE_PROTECTED) != 0;
}
/**
* Returns true if the segment contains the given address
*
* @param addr The address to check
* @return True if the segment contains the given address; otherwise, false
*/
public boolean contains(long addr) {
return Long.compareUnsigned(addr, vmaddr) >= 0 &&
Long.compareUnsigned(addr, vmaddr + vmsize) < 0;
}
@Override
public DataType toDataType() throws DuplicateNameException, IOException {
StructureDataType struct = new StructureDataType(getCommandName(), 0);

View File

@@ -652,7 +652,7 @@ public class DyldCacheHeader implements StructConverter {
addHeaderField(struct, QWORD, "localSymbolsOffset","file offset of where local symbols are stored");
addHeaderField(struct, QWORD, "localSymbolsSize", "size of local symbols information");
addHeaderField(struct, new ArrayDataType(BYTE, 16, 1), "uuid","unique value for each shared cache file");
addHeaderField(struct, QWORD, "cacheType", "0 for development, 1 for production");
addHeaderField(struct, QWORD, "cacheType", "0 for development, 1 for production, 2 for multi-cache");
addHeaderField(struct, DWORD, "branchPoolsOffset","file offset to table of uint64_t pool addresses");
addHeaderField(struct, DWORD, "branchPoolsCount", "number of uint64_t entries");
if (hasAccelerateInfo()) {

View File

@@ -32,9 +32,11 @@ import ghidra.util.exception.DuplicateNameException;
@SuppressWarnings("unused")
public class DyldCacheMappingAndSlideInfo implements StructConverter {
public static long DYLD_CACHE_MAPPING_AUTH_DATA = 1 << 3L;
public static long DYLD_CACHE_MAPPING_DIRTY_DATA = 1 << 1L;
public static long DYLD_CACHE_MAPPING_CONST_DATA = 1 << 2L;
public static long DYLD_CACHE_MAPPING_AUTH_DATA = 0x1;
public static long DYLD_CACHE_MAPPING_DIRTY_DATA = 0x2;
public static long DYLD_CACHE_MAPPING_CONST_DATA = 0x4;
public static long DYLD_CACHE_MAPPING_TEXT_STUBS = 0x8;
public static long DYLD_CACHE_DYNAMIC_CONFIG_DATA = 0x10;
private long address;
private long size;
@@ -128,6 +130,14 @@ public class DyldCacheMappingAndSlideInfo implements StructConverter {
return (flags & DYLD_CACHE_MAPPING_CONST_DATA) != 0;
}
public boolean isTextStubs() {
return (flags & DYLD_CACHE_MAPPING_TEXT_STUBS) != 0;
}
public boolean isConfigData() {
return (flags & DYLD_CACHE_DYNAMIC_CONFIG_DATA) != 0;
}
/**
* Returns true if the initial protections include READ.
*
@@ -155,6 +165,17 @@ public class DyldCacheMappingAndSlideInfo implements StructConverter {
return (initProt & SegmentConstants.PROTECTION_X) != 0;
}
/**
* Returns true if the mapping contains the given address
*
* @param addr The address to check
* @return True if the mapping contains the given address; otherwise, false
*/
public boolean contains(long addr) {
return Long.compareUnsigned(addr, address) >= 0 &&
Long.compareUnsigned(addr, address + size) < 0;
}
@Override
public DataType toDataType() throws DuplicateNameException, IOException {
StructureDataType struct = new StructureDataType("dyld_cache_mapping_and_slide_info", 0);

View File

@@ -633,7 +633,7 @@ public class MachoProgramBuilder {
int symbolIndex = indirectSymbols[i];
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
if (symbol != null) {
String name = generateValidName(symbol.getString());
String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
if (name != null && name.length() > 0) {
try {
program.getSymbolTable()
@@ -701,7 +701,7 @@ public class MachoProgramBuilder {
return;
}
try {
String name = generateValidName(symbol.getString());
String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
if (name != null && name.length() > 0) {
program.getSymbolTable().createLabel(start, name, SourceType.IMPORTED);
}
@@ -751,7 +751,7 @@ public class MachoProgramBuilder {
}
for (NList symbol : absoluteSymbols) {
try {
String name = generateValidName(symbol.getString());
String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
if (name != null && name.length() > 0) {
program.getSymbolTable().createLabel(start, name, SourceType.IMPORTED);
}
@@ -1200,7 +1200,9 @@ public class MachoProgramBuilder {
}
}
program.getSymbolTable().createExternalLibrary(Library.UNKNOWN, SourceType.IMPORTED);
if (program.getSymbolTable().getLibrarySymbol(Library.UNKNOWN) == null) {
program.getSymbolTable().createExternalLibrary(Library.UNKNOWN, SourceType.IMPORTED);
}
}
/**
@@ -1485,7 +1487,7 @@ public class MachoProgramBuilder {
}
}
private Namespace createNamespace(String namespaceName) {
protected Namespace createNamespace(String namespaceName) {
try {
return program.getSymbolTable()
.createNameSpace(program.getGlobalNamespace(), namespaceName,
@@ -1503,10 +1505,6 @@ public class MachoProgramBuilder {
return program.getGlobalNamespace();
}
private String generateValidName(String name) {
return SymbolUtilities.replaceInvalidChars(name, true);
}
/**
* create a one-byte function, so that when the code is analyzed,
* it will be disassembled, and the function created with the correct body.

View File

@@ -32,9 +32,9 @@ import ghidra.util.exception.NotFoundException;
import ghidra.util.task.TaskMonitor;
/**
* A class for extracting DYLIB files from a {@link DyldCacheFileSystem}
* A class for extracting components from a {@link DyldCacheFileSystem}
*/
public class DyldCacheDylibExtractor {
public class DyldCacheExtractor {
/**
* Gets an {@link ByteProvider} that reads a DYLIB from a {@link DyldCacheFileSystem}. The
@@ -61,6 +61,22 @@ public class DyldCacheDylibExtractor {
return packedSegments.getByteProvider(fsrl);
}
/**
* Converts the given value to a byte array
*
* @param value The value to convert to a byte array
* @param size The number of bytes to convert (must be 4 or 8)
* @return The value as a byte array of the given size
* @throws IllegalArgumentException if size is an unsupported value
*/
private static byte[] toBytes(long value, int size) throws IllegalArgumentException {
if (size != 4 && size != 8) {
throw new IllegalArgumentException("Size must be 4 or 8 (got " + size + ")");
}
DataConverter converter = LittleEndianDataConverter.INSTANCE;
return size == 8 ? converter.getBytes(value) : converter.getBytes((int) value);
}
/**
* Gets a {@link Map} of {DyldCacheSlideInfoCommon}s to their corresponding
* {@link DyldCacheSlideFixup}s
@@ -619,22 +635,6 @@ public class DyldCacheDylibExtractor {
"Failed to find provider for segment: " + segment.getSegmentName());
}
/**
* Converts the given value to a byte array
*
* @param value The value to convert to a byte array
* @param size The number of bytes to convert (must be 4 or 8)
* @return The value as a byte array of the given size
* @throws IllegalArgumentException if size is an unsupported value
*/
private byte[] toBytes(long value, int size) throws IllegalArgumentException {
if (size != 4 && size != 8) {
throw new IllegalArgumentException("Size must be 4 or 8 (got " + size + ")");
}
DataConverter converter = LittleEndianDataConverter.INSTANCE;
return size == 8 ? converter.getBytes(value) : converter.getBytes((int) value);
}
/**
* Fixes-up the slide pointers
*

View File

@@ -70,7 +70,7 @@ public class DyldCacheFileSystem extends GFileSystemBase {
addr - splitDyldCache.getDyldCacheHeader(index).getBaseAddress();
if (slideFixupMap == null) {
slideFixupMap = DyldCacheDylibExtractor.getSlideFixups(splitDyldCache, monitor);
slideFixupMap = DyldCacheExtractor.getSlideFixups(splitDyldCache, monitor);
}
if (!parsedLocalSymbols) {
@@ -82,7 +82,7 @@ public class DyldCacheFileSystem extends GFileSystemBase {
}
try {
return DyldCacheDylibExtractor.extractDylib(machHeaderStartIndexInProvider,
return DyldCacheExtractor.extractDylib(machHeaderStartIndexInProvider,
splitDyldCache, index, slideFixupMap, file.getFSRL(), monitor);
}
catch (MachException e) {