mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -09:00
GP-0: Small Mach-O refactorings
This commit is contained in:
@@ -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);
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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()) {
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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.
|
||||
|
||||
@@ -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
|
||||
*
|
||||
@@ -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) {
|
||||
|
||||
Reference in New Issue
Block a user