mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-26 17:12:11 +08:00
Add OmfRecord support for CEXTDEF
Make OmfLoader add dummy functions at entrypoints Fix conditional read when parsing FIXUP records Fix typo in function name
This commit is contained in:
committed by
Ryan Kurtz
parent
e77410ce03
commit
c4088db81c
+66
@@ -0,0 +1,66 @@
|
||||
/* ###
|
||||
* 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 ghidra.app.util.bin.BinaryReader;
|
||||
|
||||
import java.io.IOException;
|
||||
import java.util.ArrayList;
|
||||
|
||||
public class OmfComdatExternalSymbol extends OmfExternalSymbol {
|
||||
public static class ExternalLookup {
|
||||
public int nameIndex;
|
||||
public int type;
|
||||
|
||||
public ExternalLookup(int ni, int t) {
|
||||
this.nameIndex = ni;
|
||||
this.type = t;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
protected ArrayList<ExternalLookup> externalLookups;
|
||||
protected OmfSymbol[] symbol;
|
||||
|
||||
public OmfComdatExternalSymbol(BinaryReader reader) throws IOException {
|
||||
super(false);
|
||||
readRecordHeader(reader);
|
||||
long max = reader.getPointerIndex() + getRecordLength() - 1;
|
||||
this.externalLookups = new ArrayList<ExternalLookup>();
|
||||
|
||||
while(reader.getPointerIndex() < max) {
|
||||
int nameIndex = OmfRecord.readIndex(reader);
|
||||
int type = OmfRecord.readIndex(reader);
|
||||
this.externalLookups.add(new ExternalLookup(nameIndex, type));
|
||||
}
|
||||
|
||||
readCheckSumByte(reader);
|
||||
}
|
||||
|
||||
public void loadNames(ArrayList<String> namelist) {
|
||||
ArrayList<OmfSymbol> symbollist = new ArrayList<OmfSymbol>();
|
||||
for (ExternalLookup ext : this.externalLookups) {
|
||||
String name = namelist.get(ext.nameIndex-1);
|
||||
symbollist.add(new OmfSymbol(name, ext.type, 0, 0, 0));
|
||||
}
|
||||
this.symbol = new OmfSymbol[symbollist.size()];
|
||||
symbollist.toArray(this.symbol);
|
||||
}
|
||||
|
||||
public OmfSymbol[] getSymbols() {
|
||||
return symbol;
|
||||
}
|
||||
}
|
||||
@@ -332,6 +332,10 @@ public class OmfFileHeader extends OmfRecord {
|
||||
header.evaluateComdef(comdef);
|
||||
header.externsymbols.add((OmfExternalSymbol) record);
|
||||
}
|
||||
else if (record instanceof OmfComdatExternalSymbol comdat) {
|
||||
((OmfComdatExternalSymbol)record).loadNames(header.nameList);
|
||||
header.externsymbols.add((OmfExternalSymbol)record);
|
||||
}
|
||||
else if (record instanceof OmfExternalSymbol external) {
|
||||
header.externsymbols.add(external);
|
||||
}
|
||||
|
||||
+3
-5
@@ -147,12 +147,10 @@ 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);
|
||||
}
|
||||
else {
|
||||
if ((method >= 4) && thread.isFrameThread())
|
||||
thread.index = -1;
|
||||
}
|
||||
else
|
||||
thread.index = OmfRecord.readInt1Or2(reader, hasBigFields);
|
||||
return thread;
|
||||
}
|
||||
}
|
||||
|
||||
+2
-2
@@ -52,8 +52,8 @@ public class OmfLibraryRecord extends OmfRecord {
|
||||
public ArrayList<MemberHeader> getMemberHeaders() {
|
||||
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,11 @@ 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.database.function.OverlappingFunctionException;
|
||||
import ghidra.program.model.address.Address;
|
||||
import ghidra.program.model.address.AddressOutOfBoundsException;
|
||||
import ghidra.program.model.address.AddressOverflowException;
|
||||
import ghidra.program.model.address.AddressSet;
|
||||
import ghidra.program.model.data.DataType;
|
||||
import ghidra.program.model.data.Undefined;
|
||||
import ghidra.program.model.lang.Language;
|
||||
@@ -390,12 +393,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 +414,24 @@ 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.toString() + ": " + e.toString());
|
||||
} catch (InvalidInputException e) {
|
||||
log.appendMsg("Unable to create function with invalid name " + symbol.getName() + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
} catch (AddressOutOfBoundsException e) {
|
||||
log.appendMsg("Unable to create symbol " + symbol.getName() + ": " + e.toString());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
+1
-1
@@ -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