Merge branch 'GP-3117_ryanmkurtz_PR-4912_moralrecordings_omf_patches'

(Closes #4912)
This commit is contained in:
Ryan Kurtz
2023-02-21 07:17:54 -05:00
9 changed files with 100 additions and 31 deletions

View File

@@ -0,0 +1,49 @@
/* ###
* IP: GHIDRA
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package ghidra.app.util.bin.format.omf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.util.bin.BinaryReader;
public class OmfComdatExternalSymbol extends OmfExternalSymbol {
public record ExternalLookup(int nameIndex, int type) {}
protected List<ExternalLookup> externalLookups = new ArrayList<>();
public OmfComdatExternalSymbol(BinaryReader reader) throws IOException {
super(false);
readRecordHeader(reader);
long max = reader.getPointerIndex() + getRecordLength() - 1;
while (reader.getPointerIndex() < max) {
int nameIndex = OmfRecord.readIndex(reader);
int type = OmfRecord.readIndex(reader);
externalLookups.add(new ExternalLookup(nameIndex, type));
}
readCheckSumByte(reader);
}
public void loadNames(List<String> nameList) {
for (ExternalLookup ext : externalLookups) {
String name = nameList.get(ext.nameIndex - 1);
symbols.add(new OmfSymbol(name, ext.type, 0, 0, 0));
}
}
}

View File

@@ -16,7 +16,6 @@
package ghidra.app.util.bin.format.omf;
import java.io.IOException;
import java.util.ArrayList;
import ghidra.app.util.bin.BinaryReader;
@@ -25,9 +24,8 @@ public class OmfComdefRecord extends OmfExternalSymbol {
public OmfComdefRecord(BinaryReader reader, boolean isStatic) throws IOException, OmfException {
super(isStatic);
readRecordHeader(reader);
long max = reader.getPointerIndex() + getRecordLength() - 1;
ArrayList<OmfSymbol> symbollist = new ArrayList<OmfSymbol>();
long max = reader.getPointerIndex() + getRecordLength() - 1;
while (reader.getPointerIndex() < max) {
String name = OmfRecord.readString(reader);
int typeIndex = OmfRecord.readIndex(reader);
@@ -42,12 +40,9 @@ public class OmfComdefRecord extends OmfExternalSymbol {
// Values 1 thru 5f plus 61, read the byte length
byteLength = readCommunalLength(reader);
}
OmfSymbol sym = new OmfSymbol(name, typeIndex, 0, dataType, byteLength);
symbollist.add(sym);
symbols.add(new OmfSymbol(name, typeIndex, 0, dataType, byteLength));
}
readCheckSumByte(reader);
symbol = new OmfSymbol[symbollist.size()];
symbollist.toArray(symbol);
}
private static int readCommunalLength(BinaryReader reader) throws OmfException, IOException {

View File

@@ -17,12 +17,14 @@ package ghidra.app.util.bin.format.omf;
import java.io.IOException;
import java.util.ArrayList;
import java.util.List;
import ghidra.app.util.bin.BinaryReader;
public class OmfExternalSymbol extends OmfRecord {
private boolean isStatic;
protected OmfSymbol[] symbol;
protected List<OmfSymbol> symbols = new ArrayList<>();
protected OmfExternalSymbol(boolean isStatic) {
this.isStatic = isStatic;
@@ -31,23 +33,19 @@ public class OmfExternalSymbol extends OmfRecord {
public OmfExternalSymbol(BinaryReader reader, boolean isStatic) throws IOException {
this.isStatic = isStatic;
readRecordHeader(reader);
long max = reader.getPointerIndex() + getRecordLength() - 1;
ArrayList<OmfSymbol> symbollist = new ArrayList<OmfSymbol>();
long max = reader.getPointerIndex() + getRecordLength() - 1;
while (reader.getPointerIndex() < max) {
String name = OmfRecord.readString(reader);
int type = OmfRecord.readIndex(reader);
OmfSymbol subrec = new OmfSymbol(name, type, 0, 0, 0);
symbollist.add(subrec);
symbols.add(new OmfSymbol(name, type, 0, 0, 0));
}
readCheckSumByte(reader);
symbol = new OmfSymbol[symbollist.size()];
symbollist.toArray(symbol);
}
public OmfSymbol[] getSymbols() {
return symbol;
public List<OmfSymbol> getSymbols() {
return symbols;
}
public boolean isStatic() {

View File

@@ -235,8 +235,7 @@ public class OmfFileHeader extends OmfRecord {
}
private void evaluateComdef(OmfComdefRecord comdef) {
OmfSymbol[] coms = comdef.getSymbols();
for (OmfSymbol sym : coms) {
for (OmfSymbol sym : comdef.getSymbols()) {
int dt = sym.getDataType();
if (dt > 0 && dt < 0x60) { // A special borland segment symbol
int count = (extraSeg == null) ? 1 : extraSeg.size() + 1;
@@ -332,6 +331,10 @@ public class OmfFileHeader extends OmfRecord {
header.evaluateComdef(comdef);
header.externsymbols.add((OmfExternalSymbol) record);
}
else if (record instanceof OmfComdatExternalSymbol comdat) {
comdat.loadNames(header.nameList);
header.externsymbols.add(comdat);
}
else if (record instanceof OmfExternalSymbol external) {
header.externsymbols.add(external);
}

View File

@@ -147,11 +147,11 @@ public class OmfFixupRecord extends OmfRecord {
ThreadSubrecord thread = new ThreadSubrecord();
thread.type = reader.readNextByte();
int method = thread.getMethod();
if (method < 4) {
thread.index = OmfRecord.readInt1Or2(reader, hasBigFields);
if (method >= 4 && thread.isFrameThread()) {
thread.index = -1;
}
else {
thread.index = -1;
thread.index = OmfRecord.readInt1Or2(reader, hasBigFields);
}
return thread;
}

View File

@@ -53,7 +53,7 @@ public class OmfLibraryRecord extends OmfRecord {
return members;
}
public static boolean checkMagicNumer(BinaryReader reader) throws IOException {
public static boolean checkMagicNumber(BinaryReader reader) throws IOException {
byte type = reader.readNextByte();
if (type != (byte) 0xF0) {
return false;

View File

@@ -173,6 +173,8 @@ public abstract class OmfRecord {
yield new OmfSymbolRecord(reader, true);
case LCOMDEF:
yield new OmfComdefRecord(reader, true);
case CEXTDEF:
yield new OmfComdatExternalSymbol(reader);
case RHEADR:
case REGINT:
case REDATA:
@@ -192,7 +194,6 @@ public abstract class OmfRecord {
yield new OmfObsoleteRecord(reader);
case LOCSYM:
case TYPDEF:
case CEXTDEF:
case COMDAT:
case LINSYM:
case ALIAS:

View File

@@ -25,8 +25,8 @@ import ghidra.app.util.bin.ByteProvider;
import ghidra.app.util.bin.format.omf.*;
import ghidra.app.util.bin.format.omf.OmfFixupRecord.Subrecord;
import ghidra.app.util.importer.MessageLog;
import ghidra.program.model.address.Address;
import ghidra.program.model.address.AddressOverflowException;
import ghidra.program.database.function.OverlappingFunctionException;
import ghidra.program.model.address.*;
import ghidra.program.model.data.DataType;
import ghidra.program.model.data.Undefined;
import ghidra.program.model.lang.Language;
@@ -390,12 +390,14 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
break;
}
Address addrBase = null;
boolean tagFunction = false;
if (symbolrec.getSegmentIndex() != 0) {
// TODO: What does it mean if both the segment and group index are non-zero?
// Is the segment index group relative?
// For now we assume if a segment index is present, we don't need the group index
OmfSegmentHeader baseSegment = segments.get(symbolrec.getSegmentIndex() - 1);
addrBase = baseSegment.getAddress(language);
tagFunction = baseSegment.isCode();
}
else if (symbolrec.getGroupIndex() != 0) {
OmfGroupRecord baseGroup = groups.get(symbolrec.getGroupIndex() - 1);
@@ -409,10 +411,32 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
int numSymbols = symbolrec.numSymbols();
for (int i = 0; i < numSymbols; ++i) {
OmfSymbol symbol = symbolrec.getSymbol(i);
Address address = addrBase.add(symbol.getOffset());
symbol.setAddress(address);
try {
Address address = addrBase.add(symbol.getOffset());
symbol.setAddress(address);
createSymbol(symbol, address, symbolTable, log);
createSymbol(symbol, address, symbolTable, log);
if (tagFunction) {
// Create a dummy function so that EntryPointAnalyzer will disassemble it
try {
program.getFunctionManager()
.createFunction(symbol.getName(), address,
new AddressSet(address), SourceType.IMPORTED);
}
catch (OverlappingFunctionException e) {
log.appendMsg("Function already exists at address " + address + ": " +
e.getMessage());
}
catch (InvalidInputException e) {
log.appendMsg("Unable to create function with invalid name " +
symbol.getName() + ": " + e.getMessage());
}
}
}
catch (AddressOutOfBoundsException e) {
log.appendMsg(
"Unable to create symbol " + symbol.getName() + ": " + e.getMessage());
}
}
}
}
@@ -477,9 +501,8 @@ public class OmfLoader extends AbstractProgramWrapperLoader {
monitor.setMessage("Creating External Symbols");
for (OmfExternalSymbol symbolrec : symbolrecs) {
OmfSymbol[] symbols = symbolrec.getSymbols();
// TODO: Check instanceof OmfComdefRecord
for (OmfSymbol symbol : symbols) {
for (OmfSymbol symbol : symbolrec.getSymbols()) {
if (monitor.isCancelled()) {
break;
}

View File

@@ -52,7 +52,7 @@ public class OmfArchiveFileSystemFactory implements
try {
BinaryReader reader = OmfFileHeader.createReader(byteProvider);
return OmfLibraryRecord.checkMagicNumer(reader);
return OmfLibraryRecord.checkMagicNumber(reader);
}
catch (IOException e) {
return false;