Merge remote-tracking branch 'origin/GP-3912_ryanmkurtz_macholibs'

This commit is contained in:
Ryan Kurtz 2023-10-05 06:54:55 -04:00
commit c24d25f3ab
2 changed files with 66 additions and 19 deletions

View File

@ -29,19 +29,22 @@ import ghidra.app.util.bin.format.macho.dyld.DyldChainedPtr.DyldChainType;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressSpace;
import ghidra.program.model.listing.Library;
import ghidra.program.model.listing.Program;
import ghidra.program.model.mem.Memory;
import ghidra.program.model.mem.MemoryAccessException;
import ghidra.program.model.reloc.Relocation.Status;
import ghidra.program.model.reloc.RelocationResult;
import ghidra.program.model.symbol.Symbol;
import ghidra.program.model.symbol.*;
import ghidra.util.exception.CancelledException;
import ghidra.util.exception.InvalidInputException;
import ghidra.util.task.TaskMonitor;
public class DyldChainedFixups {
private MachHeader machoHeader;
private Program program;
private List<String> libraryPaths;
private MessageLog log;
private TaskMonitor monitor;
private Memory memory;
@ -52,13 +55,15 @@ public class DyldChainedFixups {
*
* @param program The {@link Program}
* @param header The Mach-O header
* @param libraryPaths A {@link List} of the library paths
* @param log The log
* @param monitor A cancelable task monitor.
*/
public DyldChainedFixups(Program program, MachHeader header, MessageLog log,
TaskMonitor monitor) {
public DyldChainedFixups(Program program, MachHeader header, List<String> libraryPaths,
MessageLog log, TaskMonitor monitor) {
this.program = program;
this.machoHeader = header;
this.libraryPaths = libraryPaths;
this.log = log;
this.monitor = monitor;
this.memory = program.getMemory();
@ -265,12 +270,13 @@ public class DyldChainedFixups {
int chainOrdinal = (int) DyldChainedPtr.getOrdinal(pointerFormat, chainValue);
long addend = DyldChainedPtr.getAddend(pointerFormat, chainValue);
DyldChainedImport chainedImport = chainedImports.getChainedImport(chainOrdinal);
//int libOrdinal = chainedImport.getLibOrdinal();
symName = chainedImport.getName();
// lookup the symbol, and then add addend
List<Symbol> globalSymbols = program.getSymbolTable().getGlobalSymbols(symName);
if (globalSymbols.size() == 1) {
newChainValue = globalSymbols.get(0).getAddress().getOffset();
Symbol symbol = globalSymbols.get(0);
newChainValue = symbol.getAddress().getOffset();
fixupExternalLibrary(chainedImport.getLibOrdinal(), symbol);
}
newChainValue += addend;
}
@ -288,7 +294,9 @@ public class DyldChainedFixups {
// lookup the symbol, and then add addend
List<Symbol> globalSymbols = program.getSymbolTable().getGlobalSymbols(symName);
if (globalSymbols.size() == 1) {
newChainValue = globalSymbols.get(0).getAddress().getOffset();
Symbol symbol = globalSymbols.get(0);
newChainValue = symbol.getAddress().getOffset();
fixupExternalLibrary(chainedImport.getLibOrdinal(), symbol);
}
newChainValue = newChainValue + auth_value_add;
}
@ -326,6 +334,24 @@ public class DyldChainedFixups {
}
}
private void fixupExternalLibrary(int libraryOrdinal, Symbol symbol) {
ExternalManager extManager = program.getExternalManager();
int libraryIndex = libraryOrdinal - 1;
if (libraryIndex >= 0 && libraryIndex < libraryPaths.size()) {
Library library = extManager.getExternalLibrary(libraryPaths.get(libraryIndex));
ExternalLocation loc =
extManager.getUniqueExternalLocation(Library.UNKNOWN, symbol.getName());
if (loc != null) {
try {
loc.setName(library, symbol.getName(), SourceType.IMPORTED);
}
catch (InvalidInputException e) {
log.appendException(e);
}
}
}
}
/**
* Fixes up any chained pointers, starting at the given address.
*

View File

@ -127,12 +127,12 @@ public class MachoProgramBuilder {
processStubs();
processUndefinedSymbols();
processAbsoluteSymbols();
List<Address> chainedFixups = processChainedFixups(machoHeader);
processBindings(false);
List<String> libraryPaths = processLibraries();
List<Address> chainedFixups = processChainedFixups(libraryPaths);
processBindings(false, libraryPaths);
processSectionRelocations();
processExternalRelocations();
processLocalRelocations();
processLibraries();
processEncryption();
processUnsupportedLoadCommands();
@ -742,18 +742,19 @@ public class MachoProgramBuilder {
}
}
public List<Address> processChainedFixups(MachHeader header) throws Exception {
DyldChainedFixups dyldChainedFixups = new DyldChainedFixups(program, header, log, monitor);
public List<Address> processChainedFixups(List<String> libraryPaths) throws Exception {
DyldChainedFixups dyldChainedFixups =
new DyldChainedFixups(program, machoHeader, libraryPaths, log, monitor);
return dyldChainedFixups.processChainedFixups();
}
protected void processBindings(boolean doClassic) throws Exception {
protected void processBindings(boolean doClassic, List<String> libraryPaths) throws Exception {
List<DyldInfoCommand> commands = machoHeader.getLoadCommands(DyldInfoCommand.class);
for (DyldInfoCommand command : commands) {
processBindings(command.getBindingTable());
processBindings(command.getLazyBindingTable());
processBindings(command.getWeakBindingTable());
processBindings(command.getBindingTable(), libraryPaths);
processBindings(command.getLazyBindingTable(), libraryPaths);
processBindings(command.getWeakBindingTable(), libraryPaths);
}
if (commands.size() == 0 && doClassic) {
@ -777,7 +778,7 @@ public class MachoProgramBuilder {
}
}
private void processBindings(BindingTable bindingTable) throws Exception {
private void processBindings(BindingTable bindingTable, List<String> libraryPaths) throws Exception {
DataConverter converter = DataConverter.getInstance(program.getLanguage().isBigEndian());
SymbolTable symbolTable = program.getSymbolTable();
@ -787,7 +788,7 @@ public class MachoProgramBuilder {
if (threadedBindings != null) {
DyldChainedFixups dyldChainedFixups =
new DyldChainedFixups(program, machoHeader, log, monitor);
new DyldChainedFixups(program, machoHeader, libraryPaths, log, monitor);
DyldChainedImports chainedImports = new DyldChainedImports(bindings);
for (Binding threadedBinding : threadedBindings) {
List<Address> fixedAddresses = new ArrayList<>();
@ -819,6 +820,8 @@ public class MachoProgramBuilder {
Address addr =
space.getAddress(segments.get(binding.getSegmentIndex()).getVMaddress() +
binding.getSegmentOffset());
fixupExternalLibrary(binding.getLibraryOrdinal(), symbol, libraryPaths);
boolean success = false;
try {
@ -838,6 +841,20 @@ public class MachoProgramBuilder {
}
}
private void fixupExternalLibrary(int libraryOrdinal, Symbol symbol, List<String> libraryPaths)
throws InvalidInputException {
ExternalManager extManager = program.getExternalManager();
int libraryIndex = libraryOrdinal - 1;
if (libraryIndex >= 0 && libraryIndex < libraryPaths.size()) {
Library library = extManager.getExternalLibrary(libraryPaths.get(libraryIndex));
ExternalLocation loc =
extManager.getUniqueExternalLocation(Library.UNKNOWN, symbol.getName());
if (loc != null) {
loc.setName(library, symbol.getName(), SourceType.IMPORTED);
}
}
}
protected void markupHeaders(MachHeader header, Address headerAddr) throws Exception {
monitor.setMessage("Processing header markup...");
@ -1143,15 +1160,16 @@ public class MachoProgramBuilder {
performRelocations(relocationMap);
}
protected void processLibraries() throws Exception {
protected List<String> processLibraries() throws Exception {
monitor.setMessage("Processing libraries...");
Options props = program.getOptions(Program.PROGRAM_INFO);
int libraryIndex = 0;
List<String> libraryPaths = new ArrayList<>();
for (LoadCommand command : machoHeader.getLoadCommands()) {
if (monitor.isCancelled()) {
return;
return libraryPaths;
}
String libraryPath = null;
@ -1168,6 +1186,7 @@ public class MachoProgramBuilder {
}
if (libraryPath != null) {
libraryPaths.add(libraryPath);
int index = libraryPath.lastIndexOf("/");
String libraryName = index != -1 ? libraryPath.substring(index + 1) : libraryPath;
if (!libraryName.equals(program.getName())) {
@ -1182,6 +1201,8 @@ public class MachoProgramBuilder {
if (program.getSymbolTable().getLibrarySymbol(Library.UNKNOWN) == null) {
program.getSymbolTable().createExternalLibrary(Library.UNKNOWN, SourceType.IMPORTED);
}
return libraryPaths;
}
/**