From 22064a49c774d09ae9477d6d34bec63ee891a5db Mon Sep 17 00:00:00 2001 From: yetmorecode Date: Sun, 5 Dec 2021 08:19:01 +0100 Subject: [PATCH] Implemented fixups for types 3 (16:16 pointer) and 8 (32bit self-ref) --- .../ghidra/format/lx/FixupRecord.java | 5 - .../ghidra/format/lx/LxExecutable.java | 7 +- .../ghidra/format/lx/LxHeader.java | 7 +- .../ghidra/format/lx/ObjectMapEntry.java | 20 -- .../ghidra/format/lx/ObjectTableEntry.java | 44 +++ .../ghidra/loader/lx/LxLoader.java | 314 +++++++++++++++--- 6 files changed, 312 insertions(+), 85 deletions(-) delete mode 100644 src/main/java/yetmorecode/ghidra/format/lx/FixupRecord.java delete mode 100644 src/main/java/yetmorecode/ghidra/format/lx/ObjectMapEntry.java create mode 100644 src/main/java/yetmorecode/ghidra/format/lx/ObjectTableEntry.java diff --git a/src/main/java/yetmorecode/ghidra/format/lx/FixupRecord.java b/src/main/java/yetmorecode/ghidra/format/lx/FixupRecord.java deleted file mode 100644 index ff199f9..0000000 --- a/src/main/java/yetmorecode/ghidra/format/lx/FixupRecord.java +++ /dev/null @@ -1,5 +0,0 @@ -package yetmorecode.ghidra.format.lx; - -public class FixupRecord { - -} diff --git a/src/main/java/yetmorecode/ghidra/format/lx/LxExecutable.java b/src/main/java/yetmorecode/ghidra/format/lx/LxExecutable.java index df89754..cd9103f 100644 --- a/src/main/java/yetmorecode/ghidra/format/lx/LxExecutable.java +++ b/src/main/java/yetmorecode/ghidra/format/lx/LxExecutable.java @@ -7,7 +7,6 @@ import ghidra.app.util.bin.ByteProvider; import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; import ghidra.app.util.bin.format.mz.DOSHeader; -import yetmorecode.file.format.lx.ObjectTableEntry; import yetmorecode.ghidra.format.lx.exception.InvalidHeaderException; @@ -15,7 +14,7 @@ public class LxExecutable extends yetmorecode.file.format.lx.LxExecutable { private FactoryBundledWithBinaryReader reader; DOSHeader mzHeader; - public ArrayList objects = new ArrayList<>(); + public ArrayList objects = new ArrayList<>(); public LxExecutable(GenericFactory factory, ByteProvider bp) throws IOException, InvalidHeaderException { reader = new FactoryBundledWithBinaryReader(factory, bp, true); @@ -27,7 +26,7 @@ public LxExecutable(GenericFactory factory, ByteProvider bp) throws IOException, //objectTable = new ArrayList(header.objectCount); int objectTableOffset = mzHeader.e_lfanew() + header.objectTableOffset; for (int i = 0; i < header.objectCount; i++) { - ObjectMapEntry e = new ObjectMapEntry(reader, objectTableOffset + i * ObjectTableEntry.SIZE); + ObjectTableEntry e = new ObjectTableEntry(reader, objectTableOffset + i * yetmorecode.file.format.lx.ObjectTableEntry.SIZE); e.number = i+1; //objectTable.add(e); objects.add(e); @@ -55,7 +54,7 @@ public LxHeader getLeHeader() { return (LxHeader) header; } - public ArrayList getObjects() { + public ArrayList getObjects() { return objects; } } diff --git a/src/main/java/yetmorecode/ghidra/format/lx/LxHeader.java b/src/main/java/yetmorecode/ghidra/format/lx/LxHeader.java index bc17dcc..6733b54 100644 --- a/src/main/java/yetmorecode/ghidra/format/lx/LxHeader.java +++ b/src/main/java/yetmorecode/ghidra/format/lx/LxHeader.java @@ -4,7 +4,6 @@ import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; import ghidra.util.Conv; -import ghidra.util.Msg; import yetmorecode.ghidra.format.lx.exception.InvalidHeaderException; public class LxHeader extends yetmorecode.file.format.lx.LxHeader { @@ -14,8 +13,10 @@ public LxHeader(FactoryBundledWithBinaryReader reader, short index) throws IOExc reader.setPointerIndex(Conv.shortToInt(index)); signature = reader.readNextShort(); - if (signature != yetmorecode.file.format.lx.LxHeader.SIGNATURE_LE) { - Msg.info("LE", String.format("wrong magic %x", signature)); + if (signature != yetmorecode.file.format.lx.LxHeader.SIGNATURE_LE && + signature != yetmorecode.file.format.lx.LxHeader.SIGNATURE_LX && + signature != yetmorecode.file.format.lx.LxHeader.SIGNATURE_LC + ) { throw new InvalidHeaderException(); } diff --git a/src/main/java/yetmorecode/ghidra/format/lx/ObjectMapEntry.java b/src/main/java/yetmorecode/ghidra/format/lx/ObjectMapEntry.java deleted file mode 100644 index b772e67..0000000 --- a/src/main/java/yetmorecode/ghidra/format/lx/ObjectMapEntry.java +++ /dev/null @@ -1,20 +0,0 @@ -package yetmorecode.ghidra.format.lx; - -import java.io.IOException; - -import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; -import yetmorecode.file.format.lx.ObjectTableEntry; - -public class ObjectMapEntry extends ObjectTableEntry { - - public ObjectMapEntry(FactoryBundledWithBinaryReader reader, int index) throws IOException { - long oldIndex = reader.getPointerIndex(); - reader.setPointerIndex(index); - size = reader.readNextInt(); - base = reader.readNextInt(); - flags = reader.readNextInt(); - pageTableIndex = reader.readNextInt(); - pageCount = reader.readNextInt(); - reader.setPointerIndex(oldIndex); - } -} \ No newline at end of file diff --git a/src/main/java/yetmorecode/ghidra/format/lx/ObjectTableEntry.java b/src/main/java/yetmorecode/ghidra/format/lx/ObjectTableEntry.java new file mode 100644 index 0000000..86f9028 --- /dev/null +++ b/src/main/java/yetmorecode/ghidra/format/lx/ObjectTableEntry.java @@ -0,0 +1,44 @@ +package yetmorecode.ghidra.format.lx; + +import java.io.IOException; +import java.util.ArrayList; + +import ghidra.app.util.bin.format.FactoryBundledWithBinaryReader; + +public class ObjectTableEntry extends yetmorecode.file.format.lx.ObjectTableEntry { + + public ObjectTableEntry(FactoryBundledWithBinaryReader reader, int index) throws IOException { + long oldIndex = reader.getPointerIndex(); + reader.setPointerIndex(index); + size = reader.readNextInt(); + base = reader.readNextInt(); + flags = reader.readNextInt(); + pageTableIndex = reader.readNextInt(); + pageCount = reader.readNextInt(); + reader.setPointerIndex(oldIndex); + } + + public String getPermissionFlagsLabel() { + return String.format( + "%s%s%s", + (flags & FLAG_READABLE) > 0 ? "r" : "-", + (flags & FLAG_WRITEABLE) > 0 ? "w" : "-", + (flags & FLAG_EXECUTABLE) > 0 ? "x" : "-" + ); + } + + public String getExtraFlagsLabel() { + ArrayList f = new ArrayList<>(); + f.add(getPermissionFlagsLabel()); + if ((flags & FLAG_PRELOAD_PAGES) > 0) { + f.add("preload pages"); + } + if ((flags & FLAG_1616_ALIAS) > 0) { + f.add("16:16 alias"); + } + if ((flags & FLAG_BIG_DEFAULT_BIT) > 0) { + f.add("big default"); + } + return String.format("%04x (%s)", flags, String.join(", ", f)); + } +} \ No newline at end of file diff --git a/src/main/java/yetmorecode/ghidra/loader/lx/LxLoader.java b/src/main/java/yetmorecode/ghidra/loader/lx/LxLoader.java index 84f6c01..363ffab 100644 --- a/src/main/java/yetmorecode/ghidra/loader/lx/LxLoader.java +++ b/src/main/java/yetmorecode/ghidra/loader/lx/LxLoader.java @@ -23,9 +23,9 @@ import ghidra.program.model.listing.Program; import ghidra.util.exception.CancelledException; import ghidra.util.task.TaskMonitor; +import yetmorecode.file.format.lx.LxFixupRecord; import yetmorecode.ghidra.format.lx.LxExecutable; -import yetmorecode.ghidra.format.lx.LxHeader; -import yetmorecode.ghidra.format.lx.ObjectMapEntry; +import yetmorecode.ghidra.format.lx.ObjectTableEntry; import yetmorecode.ghidra.format.lx.PageMapEntry; import yetmorecode.ghidra.format.lx.exception.InvalidHeaderException; @@ -34,14 +34,39 @@ */ public class LxLoader extends AbstractLibrarySupportLoader { - private final static String OPTION_BASE_ADDRESSES = "Override object base addresses (comma-seperated)"; + private final static String GROUP_OVERRIDES = "Runtime overrides (comma-separated)"; + private final static String GROUP_LOGGING = "Logging"; + private final static String GROUP_INIT = "Initialization"; + + private final static String OPTION_LOG_32BIT_OFFSET = "Log 32-bit offset fixups"; + private final static String OPTION_LOG_16BIT_OFFSET = "Log 16-bit offset fixups"; + private final static String OPTION_LOG_32BIT_SELFREL = "Log 32-bit self-rel fixups"; + private final static String OPTION_LOG_1616_POINTER = "Log 16:16 pointer fixups"; + private final static String OPTION_WARN_UNHANDLED_FIXUP = "Warn on unhandled fixups"; + private final static String OPTION_BASE_ADDRESSES = "Object base addresses"; + private final static String OPTION_OBJECT_SELECTORS = "Object segment selectors"; + private final static String OPTION_OMIT_ENTRY = "Omit entry point"; + private final static String OPTION_DISASSEMBLE = "Disassemble from entry"; + private MessageLog log; + + private boolean logOffsets32bit = false; + private boolean logOffsets16bit = false; + private boolean logSelfRel = false; + private boolean log1616pointer = false; + private boolean warnUnhandled = true; + private boolean omitEntry = false; + private boolean disassembleEntry = true; + private int[] baseAddresses; + private int[] selectors; + + private String name = "Linear Executable (LX/LE/LC)"; @Override public String getName() { - return "Linear Executable (LE/LX)"; + return name; } @Override @@ -57,7 +82,7 @@ public Collection findSupportedLoadSpecs(ByteProvider provider) throws } catch (IOException e) { e.printStackTrace(); } catch (InvalidHeaderException e) { - // Everything is ok, but the provided data is not a valid LX/LE header + // Everything is ok, but the provided data is not a valid LX/LE/LC } return loadSpecs; } @@ -79,20 +104,22 @@ protected void load(ByteProvider provider, LoadSpec loadSpec, List