mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Null pointer checks for NoisyStructureBuilder and FillOutStructureCmd
This commit is contained in:
parent
0a8db1e0ad
commit
703b368b78
4 changed files with 44 additions and 29 deletions
|
@ -46,7 +46,6 @@ import ghidra.util.task.TaskMonitor;
|
|||
*/
|
||||
public class FillOutStructureCmd extends BackgroundCommand {
|
||||
|
||||
|
||||
/**
|
||||
* Varnode with data-flow traceable to original pointer
|
||||
*/
|
||||
|
@ -75,8 +74,8 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
|||
private TaskMonitor monitor;
|
||||
private PluginTool tool;
|
||||
|
||||
private List<OffsetPcodeOpPair> storePcodeOps = new ArrayList<OffsetPcodeOpPair>();
|
||||
private List<OffsetPcodeOpPair> loadPcodeOps = new ArrayList<OffsetPcodeOpPair>();
|
||||
private List<OffsetPcodeOpPair> storePcodeOps = new ArrayList<>();
|
||||
private List<OffsetPcodeOpPair> loadPcodeOps = new ArrayList<>();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
|
@ -155,8 +154,8 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
|||
DataType pointerDT = new PointerDataType(structDT);
|
||||
|
||||
// Delay adding to the manager until full structure is accumulated
|
||||
pointerDT = currentProgram.getDataTypeManager().addDataType(pointerDT,
|
||||
DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
pointerDT = currentProgram.getDataTypeManager()
|
||||
.addDataType(pointerDT, DataTypeConflictHandler.DEFAULT_HANDLER);
|
||||
commitVariable(var, pointerDT, isThisParam);
|
||||
}
|
||||
catch (Exception e) {
|
||||
|
@ -225,7 +224,6 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
|||
return loadPcodeOps;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Retrieve the (likely) storage address of a function parameter given
|
||||
* the inputs to a CALL p-code op and particular Varnode slot within the inputs.
|
||||
|
@ -379,15 +377,15 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
|||
sym = highFunc.getMappedSymbol(storageAddress, function.getEntryPoint());
|
||||
}
|
||||
if (sym == null) {
|
||||
sym = highFunc.getLocalSymbolMap().findLocal(storageAddress,
|
||||
function.getEntryPoint().subtractWrap(1L));
|
||||
sym = highFunc.getLocalSymbolMap()
|
||||
.findLocal(storageAddress, function.getEntryPoint().subtractWrap(1L));
|
||||
}
|
||||
if (sym == null) {
|
||||
sym = highFunc.getLocalSymbolMap().findLocal(storageAddress, null);
|
||||
}
|
||||
if (sym == null) {
|
||||
sym = highFunc.getLocalSymbolMap().findLocal(storageAddress,
|
||||
function.getEntryPoint());
|
||||
sym = highFunc.getLocalSymbolMap()
|
||||
.findLocal(storageAddress, function.getEntryPoint());
|
||||
}
|
||||
if (sym == null) {
|
||||
return null;
|
||||
|
@ -525,9 +523,8 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
|||
}
|
||||
String structName = createUniqueStructName(var, DEFAULT_CATEGORY, DEFAULT_BASENAME);
|
||||
|
||||
StructureDataType dt =
|
||||
new StructureDataType(new CategoryPath(DEFAULT_CATEGORY), structName, size,
|
||||
f.getProgram().getDataTypeManager());
|
||||
StructureDataType dt = new StructureDataType(new CategoryPath(DEFAULT_CATEGORY), structName,
|
||||
size, f.getProgram().getDataTypeManager());
|
||||
return dt;
|
||||
}
|
||||
|
||||
|
@ -613,7 +610,7 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
|||
*/
|
||||
private void fillOutStructureDef(HighVariable var) {
|
||||
Varnode startVN = var.getRepresentative();
|
||||
ArrayList<PointerRef> todoList = new ArrayList<PointerRef>();
|
||||
ArrayList<PointerRef> todoList = new ArrayList<>();
|
||||
HashSet<Varnode> doneList = new HashSet<>();
|
||||
|
||||
todoList.add(new PointerRef(startVN, 0)); // Base Varnode on the todo list
|
||||
|
@ -661,8 +658,7 @@ public class FillOutStructureCmd extends BackgroundCommand {
|
|||
if (!inputs[1].isConstant() || !inputs[2].isConstant()) {
|
||||
break;
|
||||
}
|
||||
newOff =
|
||||
currentRef.offset + getSigned(inputs[1]) * inputs[2].getOffset();
|
||||
newOff = currentRef.offset + getSigned(inputs[1]) * inputs[2].getOffset();
|
||||
if (sanityCheck(newOff)) { // should this offset create a location in the structure?
|
||||
putOnList(output, newOff, todoList, doneList);
|
||||
// Don't do componentMap.addReference() as data-type info here is likely uninformed
|
||||
|
|
|
@ -72,15 +72,15 @@ public enum MetaDataType {
|
|||
}
|
||||
|
||||
public static DataType getMostSpecificDataType(DataType a, DataType b) {
|
||||
if (a == null) {
|
||||
return b;
|
||||
}
|
||||
if (b == null) {
|
||||
return a;
|
||||
}
|
||||
DataType aCopy = a;
|
||||
DataType bCopy = b;
|
||||
for (;;) {
|
||||
if (a == null) {
|
||||
return bCopy;
|
||||
}
|
||||
if (b == null) {
|
||||
return aCopy;
|
||||
}
|
||||
MetaDataType aMeta = MetaDataType.getMeta(a);
|
||||
MetaDataType bMeta = MetaDataType.getMeta(b);
|
||||
int compare = aMeta.compareTo(bMeta);
|
||||
|
|
|
@ -31,7 +31,7 @@ import java.util.TreeMap;
|
|||
* the final field entries.
|
||||
*/
|
||||
public class NoisyStructureBuilder {
|
||||
private TreeMap<Long, DataType> offsetToDataTypeMap = new TreeMap<Long, DataType>();
|
||||
private TreeMap<Long, DataType> offsetToDataTypeMap = new TreeMap<>();
|
||||
private Structure structDT = null;
|
||||
private long sizeOfStruct = 0;
|
||||
|
||||
|
@ -83,12 +83,15 @@ public class NoisyStructureBuilder {
|
|||
computeMax(offset, 1);
|
||||
return;
|
||||
}
|
||||
if (dt instanceof Pointer && ((Pointer) dt).getDataType().equals(structDT)) {
|
||||
if (dt instanceof Pointer) {
|
||||
DataType baseType = ((Pointer) dt).getDataType();
|
||||
if (baseType != null && baseType.equals(structDT)) {
|
||||
// Be careful of taking a pointer to the structure when the structure
|
||||
// is not fully defined
|
||||
DataTypeManager manager = dt.getDataTypeManager();
|
||||
dt = manager.getPointer(DataType.DEFAULT, dt.getLength());
|
||||
}
|
||||
}
|
||||
computeMax(offset, dt.getLength());
|
||||
Entry<Long, DataType> firstEntry = checkForOverlap(offset, dt.getLength());
|
||||
if (firstEntry != null) {
|
||||
|
@ -127,7 +130,7 @@ public class NoisyStructureBuilder {
|
|||
public void addReference(long offset, DataType dt) {
|
||||
if (dt != null && dt instanceof Pointer) {
|
||||
dt = ((Pointer) dt).getDataType();
|
||||
if (dt.equals(structDT)) {
|
||||
if (dt != null && dt.equals(structDT)) {
|
||||
return; // Don't allow structure to contain itself
|
||||
}
|
||||
if (dt instanceof Structure) {
|
||||
|
|
|
@ -98,4 +98,20 @@ public class NoisyStructureBuilderTest extends AbstractGTest {
|
|||
testNextField(iter, 8, DWordDataType.dataType);
|
||||
Assert.assertFalse(iter.hasNext());
|
||||
}
|
||||
|
||||
@Test
|
||||
public void testPointerNulls() {
|
||||
NoisyStructureBuilder builder = new NoisyStructureBuilder();
|
||||
DataType pointerNull = new Pointer32DataType(null);
|
||||
builder.addDataType(4, Undefined4DataType.dataType);
|
||||
builder.addDataType(8, Undefined4DataType.dataType);
|
||||
builder.addDataType(4, pointerNull);
|
||||
builder.addReference(16, pointerNull);
|
||||
|
||||
Iterator<Entry<Long, DataType>> iter = builder.iterator();
|
||||
testNextField(iter, 4, pointerNull);
|
||||
testNextField(iter, 8, Undefined4DataType.dataType);
|
||||
Assert.assertFalse(iter.hasNext());
|
||||
Assert.assertEquals(builder.getSize(), 17);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue