diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfString.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfString.java index 04eb443054..8182e0b88d 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfString.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfString.java @@ -18,8 +18,7 @@ package ghidra.app.util.bin.format.omf; import java.io.IOException; import ghidra.app.util.bin.StructConverter; -import ghidra.program.model.data.DataType; -import ghidra.program.model.data.PascalString255DataType; +import ghidra.program.model.data.*; import ghidra.util.exception.DuplicateNameException; /** @@ -29,9 +28,10 @@ public class OmfString implements StructConverter { private int length; private String str; + private boolean big; /** - * Creates a new {@link OmfString} + * Creates a new small {@link OmfString} * * @param length The length of the string * @param str The string @@ -41,6 +41,19 @@ public class OmfString implements StructConverter { this.str = str; } + /** + * Creates a new {@link OmfString} + * + * @param length The length of the string + * @param str The string + * @param isBig True if this is a big string; otherwise, false + */ + public OmfString(int length, String str, boolean isBig) { + this.length = length; + this.str = str; + this.big = isBig; + } + /** * {@return the length of the string} */ @@ -55,11 +68,18 @@ public class OmfString implements StructConverter { return str; } + /** + * {@return whether or not this is a "big" string} + */ + public boolean isBig() { + return big; + } + /** * {@return the length (in bytes) of this data type} */ public int getDataTypeSize() { - return BYTE.getLength() + length; + return (big ? WORD.getLength() : BYTE.getLength()) + length; } @Override @@ -73,6 +93,6 @@ public class OmfString implements StructConverter { return BYTE; } - return new PascalString255DataType(); + return big ? new PascalStringDataType() : new PascalString255DataType(); } } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfUtils.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfUtils.java index 52371a11ba..ea1c3468f6 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfUtils.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/OmfUtils.java @@ -62,7 +62,19 @@ public class OmfUtils { */ public static OmfString readString(BinaryReader reader) throws IOException { int count = reader.readNextUnsignedByte(); - return new OmfString(count, reader.readNextAsciiString(count)); + return new OmfString(count, count != 0 ? reader.readNextAsciiString(count) : ""); + } + + /** + * Read the OMF big string format: 2-byte length, followed by that many ascii characters + * + * @param reader A {@link BinaryReader} positioned at the start of the string + * @return the read OMF big string + * @throws IOException if an IO-related error occurred + */ + public static OmfString readBigString(BinaryReader reader) throws IOException { + int count = reader.readNextUnsignedShort(); + return new OmfString(count, count != 0 ? reader.readNextAsciiString(count) : "", true); } /** diff --git a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/omf166/Omf166DepList.java b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/omf166/Omf166DepList.java index 31293f0aae..05b5d52df3 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/omf166/Omf166DepList.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/app/util/bin/format/omf/omf166/Omf166DepList.java @@ -26,7 +26,7 @@ import ghidra.util.exception.DuplicateNameException; public class Omf166DepList extends OmfRecord { - private record Info(byte type, Byte mark, Integer time, OmfString name) {} + private record Info(byte type, Byte mark, Integer time, OmfString name, OmfString bigName) {} private List infoList = new ArrayList<>(); @@ -47,11 +47,16 @@ public class Omf166DepList extends OmfRecord { byte mark = dataReader.readNextByte(); int time = dataReader.readNextInt(); OmfString name = OmfUtils.readString(dataReader); - infoList.add(new Info(iTyp, mark, time, name)); + infoList.add(new Info(iTyp, mark, time, name, null)); break; case (byte) 0xff: OmfString invocation = OmfUtils.readString(dataReader); - infoList.add(new Info(iTyp, null, null, invocation)); + OmfString bigName = null; + if (invocation.length() == 0) { + // We assume that a "big string" follows + bigName = OmfUtils.readBigString(dataReader); + } + infoList.add(new Info(iTyp, null, null, invocation, bigName)); break; default: throw new OmfException("Unexpected DEPLST iTyp: 0x%x".formatted(iTyp)); @@ -73,6 +78,10 @@ public class Omf166DepList extends OmfRecord { struct.add(DWORD, "time32", null); } struct.add(info.name.toDataType(), info.name.getDataTypeSize(), "name", null); + if (info.bigName != null) { + struct.add(info.bigName.toDataType(), info.bigName.getDataTypeSize(), "bigName", + null); + } } struct.add(BYTE, "checksum", null); struct.setCategoryPath(new CategoryPath(OmfUtils.CATEGORY_PATH));