Skip to content

Commit 62fa275

Browse files
committed
Merge branch 'GP-0_ryanmkurtz_macho-prepwork'
2 parents 08a2571 + 3f130fc commit 62fa275

File tree

7 files changed

+76
-33
lines changed

7 files changed

+76
-33
lines changed

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/Section.java

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -146,6 +146,8 @@ public boolean isExecute() {
146146

147147
/**
148148
* Returns an input stream to underlying bytes of this section.
149+
*
150+
* @param header The Mach-O header
149151
* @return an input stream to underlying bytes of this section
150152
* @throws IOException if an i/o error occurs.
151153
*/
@@ -220,6 +222,17 @@ public int getReserved3() {
220222
return reserved3;
221223
}
222224

225+
/**
226+
* Returns true if the section contains the given address
227+
*
228+
* @param address The address to check
229+
* @return True if the section contains the given address; otherwise, false
230+
*/
231+
public boolean contains(long address) {
232+
return Long.compareUnsigned(address, addr) >= 0 &&
233+
Long.compareUnsigned(address, addr + size) < 0;
234+
}
235+
223236
@Override
224237
public DataType toDataType() throws DuplicateNameException, IOException {
225238
StructureDataType struct = new StructureDataType("section", 0);

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/SegmentCommand.java

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -200,6 +200,17 @@ public boolean isAppleProtected() {
200200
return (flags & SegmentConstants.FLAG_APPLE_PROTECTED) != 0;
201201
}
202202

203+
/**
204+
* Returns true if the segment contains the given address
205+
*
206+
* @param addr The address to check
207+
* @return True if the segment contains the given address; otherwise, false
208+
*/
209+
public boolean contains(long addr) {
210+
return Long.compareUnsigned(addr, vmaddr) >= 0 &&
211+
Long.compareUnsigned(addr, vmaddr + vmsize) < 0;
212+
}
213+
203214
@Override
204215
public DataType toDataType() throws DuplicateNameException, IOException {
205216
StructureDataType struct = new StructureDataType(getCommandName(), 0);

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheHeader.java

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -652,7 +652,7 @@ public DataType toDataType() throws DuplicateNameException, IOException {
652652
addHeaderField(struct, QWORD, "localSymbolsOffset","file offset of where local symbols are stored");
653653
addHeaderField(struct, QWORD, "localSymbolsSize", "size of local symbols information");
654654
addHeaderField(struct, new ArrayDataType(BYTE, 16, 1), "uuid","unique value for each shared cache file");
655-
addHeaderField(struct, QWORD, "cacheType", "0 for development, 1 for production");
655+
addHeaderField(struct, QWORD, "cacheType", "0 for development, 1 for production, 2 for multi-cache");
656656
addHeaderField(struct, DWORD, "branchPoolsOffset","file offset to table of uint64_t pool addresses");
657657
addHeaderField(struct, DWORD, "branchPoolsCount", "number of uint64_t entries");
658658
if (hasAccelerateInfo()) {

Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/dyld/DyldCacheMappingAndSlideInfo.java

Lines changed: 24 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,11 @@
3232
@SuppressWarnings("unused")
3333
public class DyldCacheMappingAndSlideInfo implements StructConverter {
3434

35-
public static long DYLD_CACHE_MAPPING_AUTH_DATA = 1 << 3L;
36-
public static long DYLD_CACHE_MAPPING_DIRTY_DATA = 1 << 1L;
37-
public static long DYLD_CACHE_MAPPING_CONST_DATA = 1 << 2L;
35+
public static long DYLD_CACHE_MAPPING_AUTH_DATA = 0x1;
36+
public static long DYLD_CACHE_MAPPING_DIRTY_DATA = 0x2;
37+
public static long DYLD_CACHE_MAPPING_CONST_DATA = 0x4;
38+
public static long DYLD_CACHE_MAPPING_TEXT_STUBS = 0x8;
39+
public static long DYLD_CACHE_DYNAMIC_CONFIG_DATA = 0x10;
3840

3941
private long address;
4042
private long size;
@@ -128,6 +130,14 @@ public boolean isConstData() {
128130
return (flags & DYLD_CACHE_MAPPING_CONST_DATA) != 0;
129131
}
130132

133+
public boolean isTextStubs() {
134+
return (flags & DYLD_CACHE_MAPPING_TEXT_STUBS) != 0;
135+
}
136+
137+
public boolean isConfigData() {
138+
return (flags & DYLD_CACHE_DYNAMIC_CONFIG_DATA) != 0;
139+
}
140+
131141
/**
132142
* Returns true if the initial protections include READ.
133143
*
@@ -155,6 +165,17 @@ public boolean isExecute() {
155165
return (initProt & SegmentConstants.PROTECTION_X) != 0;
156166
}
157167

168+
/**
169+
* Returns true if the mapping contains the given address
170+
*
171+
* @param addr The address to check
172+
* @return True if the mapping contains the given address; otherwise, false
173+
*/
174+
public boolean contains(long addr) {
175+
return Long.compareUnsigned(addr, address) >= 0 &&
176+
Long.compareUnsigned(addr, address + size) < 0;
177+
}
178+
158179
@Override
159180
public DataType toDataType() throws DuplicateNameException, IOException {
160181
StructureDataType struct = new StructureDataType("dyld_cache_mapping_and_slide_info", 0);

Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java

Lines changed: 7 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -633,7 +633,7 @@ protected void processIndirectSymbols() throws Exception {
633633
int symbolIndex = indirectSymbols[i];
634634
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
635635
if (symbol != null) {
636-
String name = generateValidName(symbol.getString());
636+
String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
637637
if (name != null && name.length() > 0) {
638638
try {
639639
program.getSymbolTable()
@@ -701,7 +701,7 @@ protected void processUndefinedSymbols() throws Exception {
701701
return;
702702
}
703703
try {
704-
String name = generateValidName(symbol.getString());
704+
String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
705705
if (name != null && name.length() > 0) {
706706
program.getSymbolTable().createLabel(start, name, SourceType.IMPORTED);
707707
}
@@ -751,7 +751,7 @@ protected void processAbsoluteSymbols() throws Exception {
751751
}
752752
for (NList symbol : absoluteSymbols) {
753753
try {
754-
String name = generateValidName(symbol.getString());
754+
String name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
755755
if (name != null && name.length() > 0) {
756756
program.getSymbolTable().createLabel(start, name, SourceType.IMPORTED);
757757
}
@@ -1200,7 +1200,9 @@ else if (command instanceof PreboundDynamicLibraryCommand pbdlCommand) {
12001200
}
12011201
}
12021202

1203-
program.getSymbolTable().createExternalLibrary(Library.UNKNOWN, SourceType.IMPORTED);
1203+
if (program.getSymbolTable().getLibrarySymbol(Library.UNKNOWN) == null) {
1204+
program.getSymbolTable().createExternalLibrary(Library.UNKNOWN, SourceType.IMPORTED);
1205+
}
12041206
}
12051207

12061208
/**
@@ -1485,7 +1487,7 @@ private void processLazyPointerSection(AddressSetView set) {
14851487
}
14861488
}
14871489

1488-
private Namespace createNamespace(String namespaceName) {
1490+
protected Namespace createNamespace(String namespaceName) {
14891491
try {
14901492
return program.getSymbolTable()
14911493
.createNameSpace(program.getGlobalNamespace(), namespaceName,
@@ -1503,10 +1505,6 @@ private Namespace createNamespace(String namespaceName) {
15031505
return program.getGlobalNamespace();
15041506
}
15051507

1506-
private String generateValidName(String name) {
1507-
return SymbolUtilities.replaceInvalidChars(name, true);
1508-
}
1509-
15101508
/**
15111509
* create a one-byte function, so that when the code is analyzed,
15121510
* it will be disassembled, and the function created with the correct body.
Lines changed: 18 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -32,9 +32,9 @@
3232
import ghidra.util.task.TaskMonitor;
3333

3434
/**
35-
* A class for extracting DYLIB files from a {@link DyldCacheFileSystem}
35+
* A class for extracting components from a {@link DyldCacheFileSystem}
3636
*/
37-
public class DyldCacheDylibExtractor {
37+
public class DyldCacheExtractor {
3838

3939
/**
4040
* Gets an {@link ByteProvider} that reads a DYLIB from a {@link DyldCacheFileSystem}. The
@@ -61,6 +61,22 @@ public static ByteProvider extractDylib(long dylibOffset, SplitDyldCache splitDy
6161
return packedSegments.getByteProvider(fsrl);
6262
}
6363

64+
/**
65+
* Converts the given value to a byte array
66+
*
67+
* @param value The value to convert to a byte array
68+
* @param size The number of bytes to convert (must be 4 or 8)
69+
* @return The value as a byte array of the given size
70+
* @throws IllegalArgumentException if size is an unsupported value
71+
*/
72+
private static byte[] toBytes(long value, int size) throws IllegalArgumentException {
73+
if (size != 4 && size != 8) {
74+
throw new IllegalArgumentException("Size must be 4 or 8 (got " + size + ")");
75+
}
76+
DataConverter converter = LittleEndianDataConverter.INSTANCE;
77+
return size == 8 ? converter.getBytes(value) : converter.getBytes((int) value);
78+
}
79+
6480
/**
6581
* Gets a {@link Map} of {DyldCacheSlideInfoCommon}s to their corresponding
6682
* {@link DyldCacheSlideFixup}s
@@ -619,22 +635,6 @@ private ByteProvider getSegmentProvider(SegmentCommand segment,
619635
"Failed to find provider for segment: " + segment.getSegmentName());
620636
}
621637

622-
/**
623-
* Converts the given value to a byte array
624-
*
625-
* @param value The value to convert to a byte array
626-
* @param size The number of bytes to convert (must be 4 or 8)
627-
* @return The value as a byte array of the given size
628-
* @throws IllegalArgumentException if size is an unsupported value
629-
*/
630-
private byte[] toBytes(long value, int size) throws IllegalArgumentException {
631-
if (size != 4 && size != 8) {
632-
throw new IllegalArgumentException("Size must be 4 or 8 (got " + size + ")");
633-
}
634-
DataConverter converter = LittleEndianDataConverter.INSTANCE;
635-
return size == 8 ? converter.getBytes(value) : converter.getBytes((int) value);
636-
}
637-
638638
/**
639639
* Fixes-up the slide pointers
640640
*

Ghidra/Features/FileFormats/src/main/java/ghidra/file/formats/ios/dyldcache/DyldCacheFileSystem.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ public ByteProvider getByteProvider(GFile file, TaskMonitor monitor)
7070
addr - splitDyldCache.getDyldCacheHeader(index).getBaseAddress();
7171

7272
if (slideFixupMap == null) {
73-
slideFixupMap = DyldCacheDylibExtractor.getSlideFixups(splitDyldCache, monitor);
73+
slideFixupMap = DyldCacheExtractor.getSlideFixups(splitDyldCache, monitor);
7474
}
7575

7676
if (!parsedLocalSymbols) {
@@ -82,7 +82,7 @@ public ByteProvider getByteProvider(GFile file, TaskMonitor monitor)
8282
}
8383

8484
try {
85-
return DyldCacheDylibExtractor.extractDylib(machHeaderStartIndexInProvider,
85+
return DyldCacheExtractor.extractDylib(machHeaderStartIndexInProvider,
8686
splitDyldCache, index, slideFixupMap, file.getFSRL(), monitor);
8787
}
8888
catch (MachException e) {

0 commit comments

Comments
 (0)