diff --git a/src/main/java/ghidra/app/util/opinion/RPXLoader.java b/src/main/java/ghidra/app/util/opinion/RPXLoader.java index 4828c6f..c1d625a 100644 --- a/src/main/java/ghidra/app/util/opinion/RPXLoader.java +++ b/src/main/java/ghidra/app/util/opinion/RPXLoader.java @@ -14,11 +14,22 @@ import ghidra.app.util.bin.ByteArrayProvider; import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.format.elf.ElfException; import ghidra.app.util.bin.format.elf.ElfHeader; +import ghidra.app.util.bin.format.elf.ElfRelocation; +import ghidra.app.util.bin.format.elf.ElfRelocationTable; +import ghidra.app.util.bin.format.elf.ElfSectionHeader; +import ghidra.app.util.bin.format.elf.ElfSymbol; import ghidra.app.util.importer.MemoryConflictHandler; import ghidra.app.util.importer.MessageLog; import ghidra.app.util.importer.MessageLogContinuesFactory; +import ghidra.program.model.address.Address; +import ghidra.program.model.address.AddressSpace; import ghidra.program.model.listing.Program; +import ghidra.program.model.symbol.RefType; +import ghidra.program.model.symbol.Reference; +import ghidra.program.model.symbol.SourceType; import ghidra.util.exception.CancelledException; +import ghidra.util.exception.DuplicateNameException; +import ghidra.util.exception.InvalidInputException; import ghidra.util.task.TaskMonitor; public class RPXLoader extends ElfLoader { @@ -65,7 +76,40 @@ public class RPXLoader extends ElfLoader { GenericFactory factory = MessageLogContinuesFactory.create(log); byte[] data = RPXUtils.convertRPX(provider, monitor); ElfHeader elf = ElfHeader.createElfHeader(factory, new ByteArrayProvider(data)); + ElfProgramBuilder.loadElf(elf, program, options, log, handler, monitor); + + AddressSpace aspace = program.getAddressFactory().getDefaultAddressSpace(); + + for (ElfRelocationTable table : elf.getRelocationTables()) { + for (ElfRelocation reloc : table.getRelocations()) { + int sindex = reloc.getSymbolIndex(); + + ElfSymbol symbol = table.getAssociatedSymbolTable().getSymbols()[sindex]; + ElfSectionHeader section = elf.getSections()[symbol.getSectionHeaderIndex()]; + if (section.getType() == RPXUtils.SHT_RPL_IMPORTS) { + int offset = (int) (reloc.getOffset() & ~3); + + String rplName = section.getNameAsString(); + if (rplName.contains("import_")) { + rplName = rplName.split("import_")[1]; + if (!rplName.endsWith(".rpl")) { + rplName += ".rpl"; + } + } else { + continue; + } + + Address addr = aspace.getAddress(offset); + Reference r = program.getReferenceManager().addExternalReference(addr, rplName, + symbol.getNameAsString(), aspace.getAddress(0), SourceType.USER_DEFINED, 1, + RefType.DATA); + program.getReferenceManager().setPrimary(r, true); + program.getListing().setComment(addr, 0, rplName + "::" + symbol.getNameAsString()); + } + } + } + } catch (ElfException e) { throw new IOException(e.getMessage()); } catch (CancelledException e) { @@ -73,6 +117,10 @@ public class RPXLoader extends ElfLoader { throw new IOException(e.getMessage()); } catch (DataFormatException e) { throw new IOException(e.getMessage()); + } catch (DuplicateNameException e) { + throw new IOException(e.getMessage()); + } catch (InvalidInputException e) { + throw new IOException(e.getMessage()); } }