- Fix references to imports in big binaries

- Revert relocating symbols to 0x01XXXXXX
- Keep imports/exports sections
This commit is contained in:
Maschell 2019-03-11 00:24:24 +01:00
parent b37a5e6b5c
commit a4de06bfac
2 changed files with 21 additions and 16 deletions

View File

@ -60,8 +60,6 @@ public class RPXUtils {
} }
} }
long curSymbolAddress = 0x01000000;
for (ElfSectionHeader h : elfFile.getSections()) { for (ElfSectionHeader h : elfFile.getSections()) {
monitor.checkCanceled(); monitor.checkCanceled();
long curSize = h.getSize(); long curSize = h.getSize();
@ -72,8 +70,7 @@ public class RPXUtils {
if (offset != 0) { if (offset != 0) {
if ((flags & SHT_NOBITS) != SHT_NOBITS) { if ((flags & SHT_NOBITS) != SHT_NOBITS) {
byte[] data = h.getData(); byte[] data = h.getData();
if (h.getType() == SHT_RPL_CRCS || h.getType() == SHT_RPL_EXPORTS || h.getType() == SHT_RPL_IMPORTS if (h.getType() == SHT_RPL_CRCS || h.getType() == SHT_RPL_FILEINFO) {
|| h.getType() == SHT_RPL_FILEINFO) {
data = new byte[0]; data = new byte[0];
curSize = 0; curSize = 0;
} else { } else {
@ -125,17 +122,15 @@ public class RPXUtils {
String symbolSectionName = Utils.stringFromStringTable(sh_str_sh_data, curSection.getName()); String symbolSectionName = Utils.stringFromStringTable(sh_str_sh_data, curSection.getName());
buffer.position((int) (entry_offset + 4)); buffer.position((int) (entry_offset + 4));
// Set Value to a custom symbol address // Set Value to a custom symbol address
curSymbolAddress += 4;
buffer.putInt((int) curSymbolAddress);
buffer.position((int) (entry_offset + 12)); 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. // Force FUNC type so the name will be used in the decompiler.
byte symbolType = ElfSymbol.STT_FUNC; byte symbolType = ElfSymbol.STT_FUNC;
// But change to OBJECT for data imports
if (symbolSectionName.startsWith(".d")) { if (symbolSectionName.startsWith(".d")) {
symbolType = ElfSymbol.STT_OBJECT; 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 buffer.put((byte) ((ElfSymbol.STB_LOCAL << 4) | symbolType)); // 12
} }
entryPos += h.getEntrySize(); entryPos += h.getEntrySize();
@ -155,13 +150,7 @@ public class RPXUtils {
} }
buffer.putInt((int) flags); 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) offset);
buffer.putInt((int) curSize); buffer.putInt((int) curSize);
buffer.putInt(h.getLink()); buffer.putInt(h.getLink());

View File

@ -69,6 +69,8 @@ public class RPXLoader extends ElfLoader {
return 0; return 0;
} }
// public static final int R_PPC_REL24 = 10;
@Override @Override
public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options, Program program, public void load(ByteProvider provider, LoadSpec loadSpec, List<Option> options, Program program,
MemoryConflictHandler handler, TaskMonitor monitor, MessageLog log) throws IOException { MemoryConflictHandler handler, TaskMonitor monitor, MessageLog log) throws IOException {
@ -108,20 +110,34 @@ public class RPXLoader extends ElfLoader {
ExternalManagerDB em = (ExternalManagerDB) program.getExternalManager(); ExternalManagerDB em = (ExternalManagerDB) program.getExternalManager();
ExternalLocation location; ExternalLocation location;
RefType type = RefType.UNCONDITIONAL_CALL;
if (!isData) { if (!isData) {
location = em.addExtFunction(rplName, symbol.getNameAsString(), null, SourceType.IMPORTED); location = em.addExtFunction(rplName, symbol.getNameAsString(), null, SourceType.IMPORTED);
} else { } else {
type = RefType.DATA;
location = em.addExtLocation(rplName, symbol.getNameAsString(), null, SourceType.IMPORTED); 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 // We need this to have working references. (=> clicking on Imports, Show
// Referenences to.. is working) // Referenences to.. is working)
// Setting the RefType.INVALID works for some reason! // Setting the RefType.INVALID works for some reason!
// If the set it to DATA, everything is treated like DATA, and if we use // If the set it to DATA, everything is treated like DATA, and if we use
// something like "UNCONDITIONAL_CALL" for functions // something like "UNCONDITIONAL_CALL" for functions
// then decompiler doesn't get the right function names anymore. // 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); 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. // Add a comment to easily see from which rpl the function is coming.
program.getListing().setComment(addr, 0, rplName + "::" + symbol.getNameAsString()); program.getListing().setComment(addr, 0, rplName + "::" + symbol.getNameAsString());