mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-30 02:20:30 +08:00
GP-0: Allowing OMF-51 files to load even if reading records caused
exception
This commit is contained in:
+9
-5
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -18,20 +18,23 @@ package ghidra.app.util.bin.format.omf;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.format.omf.omf.OmfRecordTypes;
|
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
public class OmfObsoleteRecord extends OmfRecord {
|
public class OmfObsoleteRecord extends OmfRecord {
|
||||||
|
|
||||||
|
private Class<?> recordTypesClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link OmfObsoleteRecord}
|
* Create a new {@link OmfObsoleteRecord}
|
||||||
*
|
*
|
||||||
* @param reader A {@link BinaryReader} positioned at the start of the record
|
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||||
|
* @param recordTypesClass The class that contains accessible OMF type fields
|
||||||
* @throws IOException If an IO-related error occurred
|
* @throws IOException If an IO-related error occurred
|
||||||
*/
|
*/
|
||||||
public OmfObsoleteRecord(BinaryReader reader) throws IOException {
|
public OmfObsoleteRecord(BinaryReader reader, Class<?> recordTypesClass) throws IOException {
|
||||||
super(reader);
|
super(reader);
|
||||||
|
this.recordTypesClass = recordTypesClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -41,6 +44,7 @@ public class OmfObsoleteRecord extends OmfRecord {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
return OmfUtils.toOmfRecordDataType(this, OmfRecordTypes.getName(recordType));
|
return OmfUtils.toOmfRecordDataType(this,
|
||||||
|
OmfUtils.getRecordName(recordType, recordTypesClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+9
-5
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -18,7 +18,6 @@ package ghidra.app.util.bin.format.omf;
|
|||||||
import java.io.IOException;
|
import java.io.IOException;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
import ghidra.app.util.bin.format.omf.omf.OmfRecordTypes;
|
|
||||||
import ghidra.program.model.data.DataType;
|
import ghidra.program.model.data.DataType;
|
||||||
import ghidra.util.exception.DuplicateNameException;
|
import ghidra.util.exception.DuplicateNameException;
|
||||||
|
|
||||||
@@ -27,14 +26,18 @@ import ghidra.util.exception.DuplicateNameException;
|
|||||||
*/
|
*/
|
||||||
public class OmfUnknownRecord extends OmfRecord {
|
public class OmfUnknownRecord extends OmfRecord {
|
||||||
|
|
||||||
|
private Class<?> recordTypesClass;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Create a new {@link OmfUnknownRecord}
|
* Create a new {@link OmfUnknownRecord}
|
||||||
*
|
*
|
||||||
* @param reader A {@link BinaryReader} positioned at the start of the record
|
* @param reader A {@link BinaryReader} positioned at the start of the record
|
||||||
|
* @param recordTypesClass The class that contains accessible OMF type fields
|
||||||
* @throws IOException If an IO-related error occurred
|
* @throws IOException If an IO-related error occurred
|
||||||
*/
|
*/
|
||||||
public OmfUnknownRecord(BinaryReader reader) throws IOException {
|
public OmfUnknownRecord(BinaryReader reader, Class<?> recordTypesClass) throws IOException {
|
||||||
super(reader);
|
super(reader);
|
||||||
|
this.recordTypesClass = recordTypesClass;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -44,6 +47,7 @@ public class OmfUnknownRecord extends OmfRecord {
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
return OmfUtils.toOmfRecordDataType(this, OmfRecordTypes.getName(recordType));
|
return OmfUtils.toOmfRecordDataType(this,
|
||||||
|
OmfUtils.getRecordName(recordType, recordTypesClass));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -23,6 +23,7 @@ import java.util.List;
|
|||||||
import java.util.stream.Stream;
|
import java.util.stream.Stream;
|
||||||
|
|
||||||
import ghidra.app.util.bin.BinaryReader;
|
import ghidra.app.util.bin.BinaryReader;
|
||||||
|
import ghidra.app.util.importer.MessageLog;
|
||||||
import ghidra.program.model.data.*;
|
import ghidra.program.model.data.*;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -126,19 +127,29 @@ public class OmfUtils {
|
|||||||
* {@link AbstractOmfRecordFactory}
|
* {@link AbstractOmfRecordFactory}
|
||||||
*
|
*
|
||||||
* @param factory The {@link AbstractOmfRecordFactory}
|
* @param factory The {@link AbstractOmfRecordFactory}
|
||||||
|
* @param log The log
|
||||||
* @return A {@link List} of read {@link OmfRecord records}
|
* @return A {@link List} of read {@link OmfRecord records}
|
||||||
* @throws IOException if there was an IO-related error
|
* @throws IOException if there was an IO-related error
|
||||||
* @throws OmfException if there was a problem with the OMF specification
|
* @throws OmfException if there was a problem with the OMF specification
|
||||||
*/
|
*/
|
||||||
public static List<OmfRecord> readRecords(AbstractOmfRecordFactory factory)
|
public static List<OmfRecord> readRecords(AbstractOmfRecordFactory factory, MessageLog log)
|
||||||
throws OmfException, IOException {
|
throws OmfException, IOException {
|
||||||
List<OmfRecord> records = new ArrayList<>();
|
List<OmfRecord> records = new ArrayList<>();
|
||||||
factory.reset();
|
factory.reset();
|
||||||
|
|
||||||
while (true) {
|
while (true) {
|
||||||
OmfRecord rec = factory.readNextRecord();
|
try {
|
||||||
records.add(rec);
|
OmfRecord rec = factory.readNextRecord();
|
||||||
if (rec.getRecordType() == factory.getEndRecordType()) {
|
if (!rec.validCheckSum()) {
|
||||||
|
log.appendMsg("OMF record [%s] has an invalid checksum".formatted(rec));
|
||||||
|
}
|
||||||
|
records.add(rec);
|
||||||
|
if (rec.getRecordType() == factory.getEndRecordType()) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
catch (IOException e) {
|
||||||
|
log.appendException(e);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+4
-4
@@ -4,9 +4,9 @@
|
|||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
* you may not use this file except in compliance with the License.
|
* you may not use this file except in compliance with the License.
|
||||||
* You may obtain a copy of the License at
|
* You may obtain a copy of the License at
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
@@ -91,7 +91,7 @@ public class OmfRecordFactory extends AbstractOmfRecordFactory {
|
|||||||
case LIBNAM:
|
case LIBNAM:
|
||||||
case LIBLOC:
|
case LIBLOC:
|
||||||
case LIBDIC:
|
case LIBDIC:
|
||||||
yield new OmfObsoleteRecord(reader);
|
yield new OmfObsoleteRecord(reader, OmfRecordTypes.class);
|
||||||
case LOCSYM:
|
case LOCSYM:
|
||||||
case TYPDEF:
|
case TYPDEF:
|
||||||
case COMDAT:
|
case COMDAT:
|
||||||
@@ -104,7 +104,7 @@ public class OmfRecordFactory extends AbstractOmfRecordFactory {
|
|||||||
case VENDEXT:
|
case VENDEXT:
|
||||||
yield new OmfUnsupportedRecord(reader, OmfRecordTypes.class);
|
yield new OmfUnsupportedRecord(reader, OmfRecordTypes.class);
|
||||||
default:
|
default:
|
||||||
yield new OmfUnknownRecord(reader);
|
yield new OmfUnknownRecord(reader, OmfRecordTypes.class);
|
||||||
};
|
};
|
||||||
|
|
||||||
record.parseData();
|
record.parseData();
|
||||||
|
|||||||
+1
-1
@@ -82,7 +82,7 @@ public class Omf51RecordFactory extends AbstractOmfRecordFactory {
|
|||||||
case DebugItem:
|
case DebugItem:
|
||||||
yield new OmfUnsupportedRecord(reader, Omf51RecordTypes.class);
|
yield new OmfUnsupportedRecord(reader, Omf51RecordTypes.class);
|
||||||
default:
|
default:
|
||||||
yield new OmfUnknownRecord(reader);
|
yield new OmfUnknownRecord(reader, Omf51RecordTypes.class);
|
||||||
};
|
};
|
||||||
|
|
||||||
record.parseData();
|
record.parseData();
|
||||||
|
|||||||
@@ -82,7 +82,7 @@ public class Omf51Loader extends AbstractProgramWrapperLoader {
|
|||||||
MemoryBlockUtils.createFileBytes(program, settings.provider(), monitor);
|
MemoryBlockUtils.createFileBytes(program, settings.provider(), monitor);
|
||||||
AbstractOmfRecordFactory factory = new Omf51RecordFactory(settings.provider());
|
AbstractOmfRecordFactory factory = new Omf51RecordFactory(settings.provider());
|
||||||
try {
|
try {
|
||||||
List<OmfRecord> records = OmfUtils.readRecords(factory);
|
List<OmfRecord> records = OmfUtils.readRecords(factory, settings.log());
|
||||||
Map<Integer, Address> segmentToAddr =
|
Map<Integer, Address> segmentToAddr =
|
||||||
processMemoryBlocks(program, fileBytes, records, log, monitor);
|
processMemoryBlocks(program, fileBytes, records, log, monitor);
|
||||||
Map<Integer, Address> extIdToAddr =
|
Map<Integer, Address> extIdToAddr =
|
||||||
|
|||||||
Reference in New Issue
Block a user