From eb805879dfc297045200c95789095f3bfe48773c Mon Sep 17 00:00:00 2001 From: Adubbz <Adubbz@users.noreply.github.com> Date: Sat, 30 Mar 2019 16:49:59 +1100 Subject: [PATCH] Automatically set the entry point for kip1s --- .../common/SwitchProgramBuilder.java | 35 ++++++++++++++++++- .../switchloader/kip1/KIP1ProgramBuilder.java | 10 ++++++ 2 files changed, 44 insertions(+), 1 deletion(-) diff --git a/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java b/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java index 1c7cedf..049a5b3 100644 --- a/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java +++ b/src/main/java/adubbz/switchloader/common/SwitchProgramBuilder.java @@ -81,7 +81,7 @@ public abstract class SwitchProgramBuilder protected Program program; protected MemoryBlockUtil mbu; - long baseAddress; + protected long baseAddress; protected AddressSpace aSpace; protected MemoryBlockHelper memBlockHelper; @@ -515,9 +515,42 @@ private String[] getDynamicLibraryNames() return dynamicLibraryNames; } + protected Address createEntryFunction(String name, long entryAddr, TaskMonitor monitor) + { + Address entryAddress = this.aSpace.getAddress(entryAddr); + + // TODO: Entry may refer to a pointer - make sure we have execute permission + MemoryBlock block = this.program.getMemory().getBlock(entryAddress); + + if (block == null || !block.isExecute()) + { + return entryAddress; + } + + Function function = program.getFunctionManager().getFunctionAt(entryAddress); + + if (function != null) + { + program.getSymbolTable().addExternalEntryPoint(entryAddress); + return entryAddress; // symbol-based function already created + } + + try + { + createOneByteFunction(name, entryAddress, true); + } + catch (Exception e) + { + Msg.error(this, "Could not create symbol at entry point: " + e); + } + + return entryAddress; + } + private Set<Long> processRelocations(Program program, BinaryReader provider, List<Relocation> relocs, ElfSymbolTable symtab, long rel, long relsz) throws IOException { Set<Long> locations = new HashSet<Long>(); + for (long i = 0; i < relsz / 0x18; i++) { long offset = provider.readLong(rel + i * 0x18); diff --git a/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java b/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java index 1d14d65..f4e5e31 100644 --- a/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java +++ b/src/main/java/adubbz/switchloader/kip1/KIP1ProgramBuilder.java @@ -15,6 +15,7 @@ import ghidra.app.util.bin.ByteArrayProvider; import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.importer.MemoryConflictHandler; +import ghidra.program.model.address.Address; import ghidra.program.model.address.AddressOutOfBoundsException; import ghidra.program.model.address.AddressOverflowException; import ghidra.program.model.address.AddressSpace; @@ -38,6 +39,15 @@ public static void loadKIP1(KIP1Header header, ByteProvider provider, Program pr builder.load(monitor); } + @Override + protected void load(TaskMonitor monitor) + { + super.load(monitor); + + // KIP1s always start with a branch instruction at the start of their text + this.createEntryFunction("entry", this.baseAddress, monitor); + } + @Override protected void loadDefaultSegments(TaskMonitor monitor) throws IOException, AddressOverflowException, AddressOutOfBoundsException {