mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-08-08 07:40:39 -09:00
GP-7123: SomLoader parsing improvement
This commit is contained in:
@@ -0,0 +1,42 @@
|
|||||||
|
/* ###
|
||||||
|
* 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.som;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* An exception class to handle encountering invalid SOM headers
|
||||||
|
*/
|
||||||
|
public class SomException extends Exception {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new exception with the specified detail message
|
||||||
|
*
|
||||||
|
* @param message the detail message
|
||||||
|
*/
|
||||||
|
public SomException(String message) {
|
||||||
|
super(message);
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Constructs a new exception with the specified cause and a detail message
|
||||||
|
*
|
||||||
|
* @param cause the cause (which is saved for later retrieval by the {@link #getCause()}
|
||||||
|
* method (a {@code null} value is permitted, and indicates that the cause is nonexistent
|
||||||
|
* or unknown).
|
||||||
|
*/
|
||||||
|
public SomException(Exception cause) {
|
||||||
|
super(cause);
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -84,12 +84,18 @@ public class SomHeader implements StructConverter {
|
|||||||
* Creates a new {@link SomHeader}
|
* Creates a new {@link SomHeader}
|
||||||
*
|
*
|
||||||
* @param reader A {@link BinaryReader} positioned at the start of the header
|
* @param reader A {@link BinaryReader} positioned at the start of the header
|
||||||
|
* @throws SomException if the header is invalid
|
||||||
* @throws IOException if there was an IO-related error
|
* @throws IOException if there was an IO-related error
|
||||||
*/
|
*/
|
||||||
public SomHeader(BinaryReader reader) throws IOException {
|
public SomHeader(BinaryReader reader) throws SomException, IOException {
|
||||||
systemId = reader.readNextUnsignedShort();
|
systemId = reader.readNextUnsignedShort();
|
||||||
magic = reader.readNextUnsignedShort();
|
magic = reader.readNextUnsignedShort();
|
||||||
versionId = reader.readNextUnsignedInt();
|
versionId = reader.readNextUnsignedInt();
|
||||||
|
|
||||||
|
if (!hasValidMagic() || !hasValidVersionId()) {
|
||||||
|
throw new SomException("Invalid SOM header");
|
||||||
|
}
|
||||||
|
|
||||||
fileTime = new SomSysClock(reader);
|
fileTime = new SomSysClock(reader);
|
||||||
entrySpace = reader.readNextUnsignedInt();
|
entrySpace = reader.readNextUnsignedInt();
|
||||||
entrySubspace = reader.readNextUnsignedInt();
|
entrySubspace = reader.readNextUnsignedInt();
|
||||||
@@ -173,25 +179,6 @@ public class SomHeader implements StructConverter {
|
|||||||
return magic;
|
return magic;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@return true if this {@link SomHeader} has a valid magic number; otherwise false}
|
|
||||||
*/
|
|
||||||
public boolean hasValidMagic() {
|
|
||||||
return switch (magic) {
|
|
||||||
case MAGIC_LIBRARY:
|
|
||||||
case MAGIC_RELOCATABLE:
|
|
||||||
case MAGIC_NON_SHAREABLE_EXE:
|
|
||||||
case MAGIC_SHAREABLE_EXE:
|
|
||||||
case MAGIC_SHARABLE_DEMAND_LOADABLE_EXE:
|
|
||||||
case MAGIC_DYNAMIC_LOAD_LIBRARY:
|
|
||||||
case MAGIC_SHARED_LIBRARY:
|
|
||||||
case MAGIC_RELOCATABLE_LIBRARY:
|
|
||||||
yield true;
|
|
||||||
default:
|
|
||||||
yield false;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@return the version ID}
|
* {@return the version ID}
|
||||||
*/
|
*/
|
||||||
@@ -199,13 +186,6 @@ public class SomHeader implements StructConverter {
|
|||||||
return versionId;
|
return versionId;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* {@return true if this {@link SomHeader} has a valid version ID; otherwise false}
|
|
||||||
*/
|
|
||||||
public boolean hasValidVersionId() {
|
|
||||||
return versionId == 85082112 || versionId == 87102412;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* {@return the file time}
|
* {@return the file time}
|
||||||
*/
|
*/
|
||||||
@@ -558,6 +538,32 @@ public class SomHeader implements StructConverter {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return true if this {@link SomHeader} has a valid magic number; otherwise false}
|
||||||
|
*/
|
||||||
|
private boolean hasValidMagic() {
|
||||||
|
return switch (magic) {
|
||||||
|
case MAGIC_LIBRARY:
|
||||||
|
case MAGIC_RELOCATABLE:
|
||||||
|
case MAGIC_NON_SHAREABLE_EXE:
|
||||||
|
case MAGIC_SHAREABLE_EXE:
|
||||||
|
case MAGIC_SHARABLE_DEMAND_LOADABLE_EXE:
|
||||||
|
case MAGIC_DYNAMIC_LOAD_LIBRARY:
|
||||||
|
case MAGIC_SHARED_LIBRARY:
|
||||||
|
case MAGIC_RELOCATABLE_LIBRARY:
|
||||||
|
yield true;
|
||||||
|
default:
|
||||||
|
yield false;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* {@return true if this {@link SomHeader} has a valid version ID; otherwise false}
|
||||||
|
*/
|
||||||
|
private boolean hasValidVersionId() {
|
||||||
|
return versionId == 85082112 || versionId == 87102412;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public DataType toDataType() throws DuplicateNameException, IOException {
|
public DataType toDataType() throws DuplicateNameException, IOException {
|
||||||
StructureDataType struct = new StructureDataType("header", SIZE);
|
StructureDataType struct = new StructureDataType("header", SIZE);
|
||||||
|
|||||||
@@ -50,18 +50,16 @@ public class SomLoader extends AbstractProgramWrapperLoader {
|
|||||||
|
|
||||||
try {
|
try {
|
||||||
SomHeader header = new SomHeader(new BinaryReader(provider, false));
|
SomHeader header = new SomHeader(new BinaryReader(provider, false));
|
||||||
if (header.hasValidMagic() && header.hasValidVersionId()) {
|
List<QueryResult> results = QueryOpinionService.query(getName(),
|
||||||
List<QueryResult> results = QueryOpinionService.query(getName(),
|
Integer.toString(header.getSystemId()), null);
|
||||||
Integer.toString(header.getSystemId()), null);
|
for (QueryResult result : results) {
|
||||||
for (QueryResult result : results) {
|
loadSpecs.add(new LoadSpec(this, 0, result));
|
||||||
loadSpecs.add(new LoadSpec(this, 0, result));
|
}
|
||||||
}
|
if (loadSpecs.isEmpty()) {
|
||||||
if (loadSpecs.isEmpty()) {
|
loadSpecs.add(new LoadSpec(this, 0, true));
|
||||||
loadSpecs.add(new LoadSpec(this, 0, true));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (IOException e) {
|
catch (SomException | IOException e) {
|
||||||
// that's ok, not a System Object Model
|
// that's ok, not a System Object Model
|
||||||
}
|
}
|
||||||
return loadSpecs;
|
return loadSpecs;
|
||||||
|
|||||||
Reference in New Issue
Block a user