mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2024-11-30 08:04:38 +00:00
Merge remote-tracking branch 'origin/GP-3912_ryanmkurtz_macholibs'
This commit is contained in:
commit
c24d25f3ab
@ -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.
|
||||
*
|
||||
|
@ -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;
|
||||
}
|
||||
|
||||
/**
|
||||
|
Loading…
Reference in New Issue
Block a user