diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java index 2eeb4af452..12ce63c7bf 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/macho/commands/chained/DyldChainedFixups.java @@ -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 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 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 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 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. * diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java index cdb6eb2a06..94a6278820 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/opinion/MachoProgramBuilder.java @@ -127,12 +127,12 @@ public class MachoProgramBuilder { processStubs(); processUndefinedSymbols(); processAbsoluteSymbols(); - List
chainedFixups = processChainedFixups(machoHeader); - processBindings(false); + List libraryPaths = processLibraries(); + List
chainedFixups = processChainedFixups(libraryPaths); + processBindings(false, libraryPaths); processSectionRelocations(); processExternalRelocations(); processLocalRelocations(); - processLibraries(); processEncryption(); processUnsupportedLoadCommands(); @@ -742,18 +742,19 @@ public class MachoProgramBuilder { } } - public List
processChainedFixups(MachHeader header) throws Exception { - DyldChainedFixups dyldChainedFixups = new DyldChainedFixups(program, header, log, monitor); + public List
processChainedFixups(List 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 libraryPaths) throws Exception { List 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 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
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 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 processLibraries() throws Exception { monitor.setMessage("Processing libraries..."); Options props = program.getOptions(Program.PROGRAM_INFO); int libraryIndex = 0; + List 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; } /**