mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-03 09:49:23 +02:00
Merge remote-tracking branch 'origin/GP-5681_ryanmkurtz_macho' into
Ghidra_11.4 (Closes #8124)
This commit is contained in:
commit
c594e41f60
6 changed files with 70 additions and 29 deletions
|
@ -25,8 +25,9 @@ import ghidra.app.util.bin.format.macho.dyld.DyldChainedPtr.DyldChainType;
|
|||
import ghidra.app.util.bin.format.macho.dyld.DyldFixup;
|
||||
import ghidra.app.util.importer.MessageLog;
|
||||
import ghidra.app.util.opinion.MachoProgramBuilder;
|
||||
import ghidra.app.util.opinion.MachoProgramUtils;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.listing.Program;
|
||||
import ghidra.program.model.listing.*;
|
||||
import ghidra.program.model.mem.Memory;
|
||||
import ghidra.program.model.reloc.Relocation.Status;
|
||||
import ghidra.program.model.symbol.*;
|
||||
|
@ -136,41 +137,79 @@ public class DyldChainedFixups {
|
|||
public static List<Address> fixupChainedPointers(List<DyldFixup> fixups, Program program,
|
||||
Address imagebase, List<String> libraryPaths, MessageLog log, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
List<Address> fixedAddrs = new ArrayList<>();
|
||||
if (fixups.isEmpty()) {
|
||||
return fixedAddrs;
|
||||
return List.of();
|
||||
}
|
||||
|
||||
Memory memory = program.getMemory();
|
||||
SymbolTable symbolTable = program.getSymbolTable();
|
||||
ExternalManager extMgr = program.getExternalManager();
|
||||
|
||||
// Figure out how much space in the EXTERNAL block we need, and make it
|
||||
Address extAddr = null;
|
||||
try {
|
||||
long externalSize = fixups.stream()
|
||||
.filter(e -> e.value() == null && e.symbol() != null && e.libOrdinal() != null)
|
||||
.mapToLong(DyldFixup::size)
|
||||
.sum();
|
||||
if (externalSize > 0) {
|
||||
extAddr = MachoProgramUtils.addExternalBlock(program, externalSize, log);
|
||||
}
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.appendMsg(
|
||||
"Failed to create space in EXTERNAL block for chained fixups: " + e.getMessage());
|
||||
}
|
||||
|
||||
List<Address> fixedAddrs = new ArrayList<>();
|
||||
monitor.initialize(fixups.size(), "Fixing up chained pointers...");
|
||||
for (DyldFixup fixup : fixups) {
|
||||
monitor.increment();
|
||||
Status status = Status.UNSUPPORTED;
|
||||
Address addr = imagebase.add(fixup.offset());
|
||||
String symbol = fixup.symbol();
|
||||
Address fixupAddr = imagebase.add(fixup.offset());
|
||||
Long fixupValue = fixup.value();
|
||||
String fixupSymbol = fixup.symbol();
|
||||
long[] value = new long[] {};
|
||||
try {
|
||||
if (fixup.value() != null) {
|
||||
if (fixupValue == null && fixupSymbol != null && fixup.libOrdinal() != null &&
|
||||
extAddr != null) {
|
||||
try {
|
||||
symbolTable.createLabel(extAddr, fixupSymbol, SourceType.IMPORTED);
|
||||
fixupValue = extAddr.getOffset();
|
||||
Function stubFunc = MachoProgramBuilder.createOneByteFunction(program,
|
||||
fixupSymbol, extAddr);
|
||||
if (stubFunc != null) {
|
||||
ExternalLocation loc = extMgr.addExtLocation(Library.UNKNOWN,
|
||||
fixupSymbol, null, SourceType.IMPORTED);
|
||||
stubFunc.setThunkedFunction(loc.createFunction());
|
||||
}
|
||||
}
|
||||
finally {
|
||||
extAddr = extAddr.add(fixup.size());
|
||||
}
|
||||
}
|
||||
if (fixupValue != null) {
|
||||
if (fixup.size() == 8 || fixup.size() == 4) {
|
||||
if (fixup.size() == 8) {
|
||||
memory.setLong(addr, fixup.value());
|
||||
memory.setLong(fixupAddr, fixupValue);
|
||||
}
|
||||
else {
|
||||
memory.setInt(addr, fixup.value().intValue());
|
||||
memory.setInt(fixupAddr, fixupValue.intValue());
|
||||
}
|
||||
fixedAddrs.add(addr);
|
||||
status = Status.APPLIED_OTHER;
|
||||
fixedAddrs.add(fixupAddr);
|
||||
status = Status.APPLIED;
|
||||
}
|
||||
value = new long[] { fixup.value() };
|
||||
value = new long[] { fixupValue };
|
||||
}
|
||||
if (symbol != null && fixup.libOrdinal() != null) {
|
||||
if (fixupSymbol != null && fixup.libOrdinal() != null) {
|
||||
value = new long[] { fixup.libOrdinal() };
|
||||
try {
|
||||
MachoProgramBuilder.fixupExternalLibrary(program, libraryPaths,
|
||||
fixup.libOrdinal(), symbol);
|
||||
fixup.libOrdinal(), fixupSymbol);
|
||||
}
|
||||
catch (Exception e) {
|
||||
log.appendMsg("WARNING: Problem fixing up symbol '%s' - %s"
|
||||
.formatted(symbol, e.getMessage()));
|
||||
.formatted(fixupSymbol, e.getMessage()));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -179,7 +218,7 @@ public class DyldChainedFixups {
|
|||
}
|
||||
finally {
|
||||
program.getRelocationTable()
|
||||
.add(addr, status, RELOCATION_TYPE, value, fixup.size(), symbol);
|
||||
.add(fixupAddr, status, RELOCATION_TYPE, value, fixup.size(), fixupSymbol);
|
||||
}
|
||||
}
|
||||
log.appendMsg("Fixed up " + fixedAddrs.size() + " chained pointers.");
|
||||
|
|
|
@ -146,7 +146,7 @@ public abstract class AbstractClassicProcessor {
|
|||
status = Status.UNSUPPORTED;
|
||||
}
|
||||
else {
|
||||
status = Status.APPLIED_OTHER;
|
||||
status = Status.APPLIED;
|
||||
}
|
||||
|
||||
// put an entry in the relocation table, handled or not
|
||||
|
|
|
@ -150,7 +150,7 @@ public class DyldCacheProgramBuilder extends MachoProgramBuilder {
|
|||
if (entryPoint != null) {
|
||||
Address entryPointAddr = space.getAddress(entryPoint);
|
||||
program.getSymbolTable().addExternalEntryPoint(entryPointAddr);
|
||||
createOneByteFunction("entry", entryPointAddr);
|
||||
createOneByteFunction(program, "entry", entryPointAddr);
|
||||
}
|
||||
else {
|
||||
log.appendMsg("Unable to determine entry point.");
|
||||
|
|
|
@ -514,7 +514,7 @@ public class MachoProgramBuilder {
|
|||
if (!realEntryFound) {
|
||||
program.getSymbolTable().createLabel(addr, "entry", SourceType.IMPORTED);
|
||||
program.getSymbolTable().addExternalEntryPoint(addr);
|
||||
createOneByteFunction("entry", addr);
|
||||
createOneByteFunction(program, "entry", addr);
|
||||
realEntryFound = true;
|
||||
}
|
||||
else {
|
||||
|
@ -684,10 +684,11 @@ public class MachoProgramBuilder {
|
|||
monitor.increment();
|
||||
int symbolIndex = indirectSymbols.get(i);
|
||||
NList symbol = symbolTableCommand.getSymbolAt(symbolIndex);
|
||||
String name =
|
||||
symbol != null ? SymbolUtilities.replaceInvalidChars(symbol.getString(), true)
|
||||
: "STUB_" + startAddr;
|
||||
Function stubFunc = createOneByteFunction(name, startAddr);
|
||||
String name = null;
|
||||
if (symbol != null) {
|
||||
name = SymbolUtilities.replaceInvalidChars(symbol.getString(), true);
|
||||
}
|
||||
Function stubFunc = createOneByteFunction(program, name, startAddr);
|
||||
if (stubFunc != null && symbol != null) {
|
||||
ExternalLocation loc = program.getExternalManager()
|
||||
.addExtLocation(Library.UNKNOWN, name, null, SourceType.IMPORTED);
|
||||
|
@ -965,8 +966,8 @@ public class MachoProgramBuilder {
|
|||
}
|
||||
finally {
|
||||
program.getRelocationTable()
|
||||
.add(addr, success ? Status.APPLIED_OTHER : Status.FAILURE,
|
||||
binding.getType(), null, bytes.length, binding.getSymbolName());
|
||||
.add(addr, success ? Status.APPLIED : Status.FAILURE, binding.getType(),
|
||||
null, bytes.length, binding.getSymbolName());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -1584,7 +1585,7 @@ public class MachoProgramBuilder {
|
|||
}
|
||||
Register tModeRegister = program.getLanguage().getRegister("TMode");
|
||||
program.getProgramContext().setValue(tModeRegister, address, address, BigInteger.ONE);
|
||||
createOneByteFunction(null, address);
|
||||
createOneByteFunction(program, null, address);
|
||||
}
|
||||
|
||||
private void processLazyPointerSection(AddressSetView set) {
|
||||
|
@ -1638,13 +1639,14 @@ public class MachoProgramBuilder {
|
|||
* create a one-byte function, so that when the code is analyzed,
|
||||
* it will be disassembled, and the function created with the correct body.
|
||||
*
|
||||
* @param program The {@link Program}
|
||||
* @param name the name of the function
|
||||
* @param address location to create the function
|
||||
* @return If a function already existed at the given address, that function will be returned.
|
||||
* Otherwise, the newly created function will be returned. If there was a problem creating
|
||||
* the function, null will be returned.
|
||||
*/
|
||||
Function createOneByteFunction(String name, Address address) {
|
||||
public static Function createOneByteFunction(Program program, String name, Address address) {
|
||||
FunctionManager functionMgr = program.getFunctionManager();
|
||||
Function function = functionMgr.getFunctionAt(address);
|
||||
if (function != null) {
|
||||
|
|
|
@ -64,9 +64,9 @@ public class MachoProgramUtils {
|
|||
Address ret;
|
||||
if (externalBlock != null) {
|
||||
ret = externalBlock.getEnd().add(1);
|
||||
MemoryBlock newBlock = mem.createBlock(externalBlock, "REEXPORTS", ret, size);
|
||||
MemoryBlock newBlock =
|
||||
mem.createBlock(externalBlock, MemoryBlock.EXTERNAL_BLOCK_NAME, ret, size);
|
||||
mem.join(externalBlock, newBlock);
|
||||
//joinedBlock.setName(MemoryBlock.EXTERNAL_BLOCK_NAME);
|
||||
}
|
||||
else {
|
||||
ret = MachoProgramUtils.getNextAvailableAddress(program);
|
||||
|
|
|
@ -113,7 +113,7 @@ public class MachoExtractProgramBuilder extends MachoProgramBuilder {
|
|||
// location to the newly exported function
|
||||
Function func = funcManager.getFunctionAt(sym.getAddress());
|
||||
if (func != null && func.getThunkedFunction(false) != null) {
|
||||
func.setThunkedFunction(createOneByteFunction(name, exportAddr));
|
||||
func.setThunkedFunction(createOneByteFunction(program, name, exportAddr));
|
||||
|
||||
// Remove the external location associated with the thunk function.
|
||||
// After the first delete, the external location becomes an external label, which
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue