mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-10-01 17:11:44 -09:00
Merge branch 'GP-3117_ryanmkurtz_PR-4912_moralrecordings_omf_patches'
(Closes #4912)
This commit is contained in:
@@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -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 {
|
||||
|
||||
@@ -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() {
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -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:
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
|
||||
Reference in New Issue
Block a user