Skip to content

Commit

Permalink
- Fix references to imports in big binaries
Browse files Browse the repository at this point in the history
- Revert relocating symbols to 0x01XXXXXX
- Keep imports/exports sections
  • Loading branch information
Maschell committed Mar 10, 2019
1 parent b37a5e6 commit a4de06b
Show file tree
Hide file tree
Showing 2 changed files with 21 additions and 16 deletions.
19 changes: 4 additions & 15 deletions src/main/java/de/mas/ghidra/wiiu/RPXUtils.java
Original file line number Diff line number Diff line change
Expand Up @@ -60,8 +60,6 @@ public static byte[] convertRPX(ByteProvider bProvider, TaskMonitor monitor)
}
}

long curSymbolAddress = 0x01000000;

for (ElfSectionHeader h : elfFile.getSections()) {
monitor.checkCanceled();
long curSize = h.getSize();
Expand All @@ -72,8 +70,7 @@ public static byte[] convertRPX(ByteProvider bProvider, TaskMonitor monitor)
if (offset != 0) {
if ((flags & SHT_NOBITS) != SHT_NOBITS) {
byte[] data = h.getData();
if (h.getType() == SHT_RPL_CRCS || h.getType() == SHT_RPL_EXPORTS || h.getType() == SHT_RPL_IMPORTS
|| h.getType() == SHT_RPL_FILEINFO) {
if (h.getType() == SHT_RPL_CRCS || h.getType() == SHT_RPL_FILEINFO) {
data = new byte[0];
curSize = 0;
} else {
Expand Down Expand Up @@ -125,17 +122,15 @@ public static byte[] convertRPX(ByteProvider bProvider, TaskMonitor monitor)
String symbolSectionName = Utils.stringFromStringTable(sh_str_sh_data, curSection.getName());
buffer.position((int) (entry_offset + 4));
// Set Value to a custom symbol address
curSymbolAddress += 4;
buffer.putInt((int) curSymbolAddress);
buffer.position((int) (entry_offset + 12));

// Change type to LOCAL so it won't be in the export list.
// Force FUNC type so the name will be used in the decompiler.
byte symbolType = ElfSymbol.STT_FUNC;
// But change to OBJECT for data imports
if (symbolSectionName.startsWith(".d")) {
symbolType = ElfSymbol.STT_OBJECT;
}

// Change type to LOCAL so it won't be in the export list.
buffer.put((byte) ((ElfSymbol.STB_LOCAL << 4) | symbolType)); // 12
}
entryPos += h.getEntrySize();
Expand All @@ -155,13 +150,7 @@ public static byte[] convertRPX(ByteProvider bProvider, TaskMonitor monitor)
}
buffer.putInt((int) flags);

// Hacky way to fix import relocations
if (h.getType() == SHT_RPL_IMPORTS) {
buffer.putInt(0);
} else {
buffer.putInt((int) h.getAddress());
}

buffer.putInt((int) h.getAddress());
buffer.putInt((int) offset);
buffer.putInt((int) curSize);
buffer.putInt(h.getLink());
Expand Down
18 changes: 17 additions & 1 deletion src/main/java/ghidra/app/util/opinion/RPXLoader.java
Original file line number Diff line number Diff line change
Expand Up @@ -69,6 +69,8 @@ public int getTierPriority() {
return 0;
}

// public static final int R_PPC_REL24 = 10;

@Override
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options, Program program,
MemoryConflictHandler handler, TaskMonitor monitor, MessageLog log) throws IOException {
Expand Down Expand Up @@ -108,20 +110,34 @@ public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options,

ExternalManagerDB em = (ExternalManagerDB) program.getExternalManager();
ExternalLocation location;
RefType type = RefType.UNCONDITIONAL_CALL;
if (!isData) {
location = em.addExtFunction(rplName, symbol.getNameAsString(), null, SourceType.IMPORTED);
} else {
type = RefType.DATA;
location = em.addExtLocation(rplName, symbol.getNameAsString(), null, SourceType.IMPORTED);
}

// Attempt to remove to auto analyzed memory reference that's created due to the
// relocation.
// if (reloc.getType() == R_PPC_REL24) {
// Relocation r = program.getRelocationTable().getRelocation(addr);
// program.getRelocationTable().remove(r);
// }

// We need this to have working references. (=> clicking on Imports, Show
// Referenences to.. is working)
// Setting the RefType.INVALID works for some reason!
// If the set it to DATA, everything is treated like DATA, and if we use
// something like "UNCONDITIONAL_CALL" for functions
// then decompiler doesn't get the right function names anymore.
program.getReferenceManager().addExternalReference(addr, 1, location, SourceType.USER_DEFINED,

program.getReferenceManager().addExternalReference(addr, 1, location, SourceType.IMPORTED,
RefType.INVALID);
// force the memory reference to the target address, even if the referenced
// address is too far away!
program.getReferenceManager().addMemoryReference(addr, aspace.getAddress(symbol.getValue()),
type, SourceType.IMPORTED, 0);

// Add a comment to easily see from which rpl the function is coming.
program.getListing().setComment(addr, 0, rplName + "::" + symbol.getNameAsString());
Expand Down

0 comments on commit a4de06b

Please sign in to comment.