mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-06-02 06:50:52 +08:00
Merge branch 'GP-3526_ryanmkurtz_macho-indirect' into patch
This commit is contained in:
@@ -133,6 +133,7 @@ public class MachoProgramBuilder {
|
|||||||
processUnsupportedLoadCommands();
|
processUnsupportedLoadCommands();
|
||||||
boolean exportsFound = processExports(machoHeader);
|
boolean exportsFound = processExports(machoHeader);
|
||||||
processSymbolTables(machoHeader, !exportsFound);
|
processSymbolTables(machoHeader, !exportsFound);
|
||||||
|
processIndirectSymbols();
|
||||||
setRelocatableProperty();
|
setRelocatableProperty();
|
||||||
processLibraries();
|
processLibraries();
|
||||||
processProgramDescription();
|
processProgramDescription();
|
||||||
@@ -593,6 +594,84 @@ public class MachoProgramBuilder {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void processIndirectSymbols() throws Exception {
|
||||||
|
// We only want to directly handle indirect symbols on incomplete dylibs that were extracted
|
||||||
|
// from a dyld_shared_cache. If the Mach-O is fully-formed and contains binding information
|
||||||
|
// (found in the DyldChainedFixupsCommand or DyldInfoCommand), thunk analysis properly
|
||||||
|
// associates indirect symbols with their "real" symbol and we shouldn't do anything here.
|
||||||
|
if (machoHeader.getFirstLoadCommand(DyldChainedFixupsCommand.class) != null ||
|
||||||
|
machoHeader.getFirstLoadCommand(DyldInfoCommand.class) != null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
monitor.setMessage("Processing indirect symbols...");
|
||||||
|
|
||||||
|
SymbolTableCommand symbolTableCommand =
|
||||||
|
machoHeader.getFirstLoadCommand(SymbolTableCommand.class);
|
||||||
|
|
||||||
|
DynamicSymbolTableCommand dynamicCommand =
|
||||||
|
machoHeader.getFirstLoadCommand(DynamicSymbolTableCommand.class);
|
||||||
|
|
||||||
|
if (dynamicCommand == null) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
int[] indirectSymbols = dynamicCommand.getIndirectSymbols();
|
||||||
|
if (indirectSymbols.length == 0) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
List<Integer> sectionTypes = List.of(SectionTypes.S_NON_LAZY_SYMBOL_POINTERS,
|
||||||
|
SectionTypes.S_LAZY_SYMBOL_POINTERS, SectionTypes.S_SYMBOL_STUBS);
|
||||||
|
|
||||||
|
List<Section> sections = machoHeader.getAllSections()
|
||||||
|
.stream()
|
||||||
|
.filter(s -> sectionTypes.contains(s.getType()))
|
||||||
|
.toList();
|
||||||
|
|
||||||
|
for (Section section : sections) {
|
||||||
|
if (monitor.isCancelled()) {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
if (section.getSize() == 0) {
|
||||||
|
continue;
|
||||||
|
}
|
||||||
|
|
||||||
|
Namespace namespace = createNamespace(section.getSectionName());
|
||||||
|
|
||||||
|
int indirectSymbolTableIndex = section.getReserved1();
|
||||||
|
|
||||||
|
int symbolSize = machoHeader.getAddressSize();
|
||||||
|
if (section.getType() == SectionTypes.S_SYMBOL_STUBS) {
|
||||||
|
symbolSize = section.getReserved2();
|
||||||
|
}
|
||||||
|
|
||||||
|
int nSymbols = (int) section.getSize() / symbolSize;
|
||||||
|
|
||||||
|
Address startAddr = space.getAddress(section.getAddress());
|
||||||
|
for (int i = indirectSymbolTableIndex; i < indirectSymbolTableIndex + nSymbols; ++i) {
|
||||||
|
if (monitor.isCancelled()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
int symbolIndex = indirectSymbols[i];
|
||||||
|
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
|
||||||
|
if (symbol != null) {
|
||||||
|
String name = generateValidName(symbol.getString());
|
||||||
|
if (name != null && name.length() > 0) {
|
||||||
|
try {
|
||||||
|
program.getSymbolTable()
|
||||||
|
.createLabel(startAddr, name, namespace, SourceType.IMPORTED);
|
||||||
|
}
|
||||||
|
catch (Exception e) {
|
||||||
|
log.appendMsg("Unable to create indirect symbol " + name);
|
||||||
|
log.appendException(e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
startAddr = startAddr.add(symbolSize);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected void setRelocatableProperty() {
|
protected void setRelocatableProperty() {
|
||||||
Options props = program.getOptions(Program.PROGRAM_INFO);
|
Options props = program.getOptions(Program.PROGRAM_INFO);
|
||||||
switch (machoHeader.getFileType()) {
|
switch (machoHeader.getFileType()) {
|
||||||
|
|||||||
Reference in New Issue
Block a user