mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 02:39:44 +02:00
Merge remote-tracking branch
'origin/GP-751_ghizard_VarnodeContext_Needs_OverlayAddressSpace' (Closes #2785, Closes #2787)
This commit is contained in:
commit
79fce9b032
2 changed files with 63 additions and 36 deletions
|
@ -47,20 +47,20 @@ public class VarnodeContext implements ProcessorContext {
|
|||
protected DisassemblerContextImpl spaceContext;
|
||||
|
||||
// holds temp memory values for computation
|
||||
protected HashMap<Varnode, Varnode> memoryVals = new HashMap<Varnode, Varnode>();
|
||||
protected HashMap<Varnode, Varnode> memoryVals = new HashMap<>();
|
||||
|
||||
// holds temp values for computation
|
||||
private HashMap<Varnode, Varnode> tempVals = new HashMap<Varnode, Varnode>();
|
||||
protected HashMap<Varnode, Varnode> tempUniqueVals = new HashMap<Varnode, Varnode>();
|
||||
private HashMap<Varnode, Varnode> tempVals = new HashMap<>();
|
||||
protected HashMap<Varnode, Varnode> tempUniqueVals = new HashMap<>();
|
||||
protected boolean keepTempUniqueValues = false;
|
||||
|
||||
protected HashSet<Varnode> clearVals = new HashSet<Varnode>();
|
||||
protected HashSet<Varnode> clearVals = new HashSet<>();
|
||||
|
||||
// locations where registers were last set to a constant value
|
||||
protected HashMap<Varnode, Address> lastSet = new HashMap<Varnode, Address>();
|
||||
protected HashMap<Varnode, Address> lastSet = new HashMap<>();
|
||||
|
||||
// all locations where a register was last explicitly set to a value, not just has the value
|
||||
protected HashMap<Varnode, AddressSet> allLastSet = new HashMap<Varnode, AddressSet>();
|
||||
protected HashMap<Varnode, AddressSet> allLastSet = new HashMap<>();
|
||||
|
||||
protected Program program;
|
||||
protected VarnodeTranslator trans; // translator for varnodes<-->registers
|
||||
|
@ -68,7 +68,7 @@ public class VarnodeContext implements ProcessorContext {
|
|||
protected Varnode[] retVarnodes = null; // varnodes used to return values
|
||||
protected Varnode stackVarnode = null; // varnode that represents the stack
|
||||
protected Register stackReg = null;
|
||||
private HashSet<String> validSymbolicStackNames = new HashSet<String>(); // list of stack related register names
|
||||
private HashSet<String> validSymbolicStackNames = new HashSet<>(); // list of stack related register names
|
||||
|
||||
protected static final NotFoundException notFoundExc = new NotFoundException();
|
||||
|
||||
|
@ -88,9 +88,7 @@ public class VarnodeContext implements ProcessorContext {
|
|||
this.program = program;
|
||||
|
||||
// make a copy, because we could be making new spaces.
|
||||
// TODO: This could be a problem if some of the Pcode comes up with Overlay Address Spaces.
|
||||
// TODO: This doesn't get Stack space, or other overlay spaces...
|
||||
this.addrFactory = new OffsetAddressFactory(program.getLanguage().getAddressFactory());
|
||||
this.addrFactory = new OffsetAddressFactory(program.getAddressFactory());
|
||||
|
||||
BAD_ADDRESS = addrFactory.getAddress(getAddressSpace("BAD_ADDRESS_SPACE"), 0);
|
||||
|
||||
|
@ -168,7 +166,7 @@ public class VarnodeContext implements ProcessorContext {
|
|||
|
||||
currentAddress = toAddr;
|
||||
|
||||
this.lastSet = new HashMap<Varnode, Address>(); // clear out any interim last sets... rely on allLastSet now
|
||||
this.lastSet = new HashMap<>(); // clear out any interim last sets... rely on allLastSet now
|
||||
|
||||
offsetContext.flowStart(fromAddr, toAddr);
|
||||
spaceContext.flowStart(fromAddr, toAddr);
|
||||
|
@ -755,10 +753,10 @@ public class VarnodeContext implements ProcessorContext {
|
|||
}
|
||||
if (clearContext) {
|
||||
if (!keepTempUniqueValues) {
|
||||
tempUniqueVals = new HashMap<Varnode, Varnode>();
|
||||
tempUniqueVals = new HashMap<>();
|
||||
}
|
||||
tempVals = new HashMap<Varnode, Varnode>();
|
||||
clearVals = new HashSet<Varnode>();
|
||||
tempVals = new HashMap<>();
|
||||
clearVals = new HashSet<>();
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -867,9 +865,6 @@ public class VarnodeContext implements ProcessorContext {
|
|||
|
||||
public Varnode getVarnode(int spaceID, long offset, int size) {
|
||||
AddressSpace space = addrFactory.getAddressSpace(spaceID);
|
||||
if (space == null) {
|
||||
return new Varnode(null, size);
|
||||
}
|
||||
Address target = space.getTruncatedAddress(offset, true);
|
||||
Varnode vt = new Varnode(target, size);
|
||||
return vt;
|
||||
|
@ -1242,8 +1237,7 @@ public class VarnodeContext implements ProcessorContext {
|
|||
throws NotFoundException {
|
||||
// degenerate case, don't need to know the value
|
||||
if (val1.equals(val2)) {
|
||||
return createVarnode(0, addrFactory.getConstantSpace().getSpaceID(),
|
||||
val1.getSize());
|
||||
return createVarnode(0, addrFactory.getConstantSpace().getSpaceID(), val1.getSize());
|
||||
}
|
||||
int spaceID = val1.getSpace();
|
||||
long valbase = 0;
|
||||
|
@ -1442,7 +1436,7 @@ public class VarnodeContext implements ProcessorContext {
|
|||
class OffsetAddressFactory extends DefaultAddressFactory {
|
||||
|
||||
OffsetAddressFactory(AddressFactory baseFactory) {
|
||||
super(baseFactory.getAllAddressSpaces());
|
||||
super(filterSpaces(baseFactory.getAllAddressSpaces()));
|
||||
}
|
||||
|
||||
private int getNextUniqueID() {
|
||||
|
@ -1471,4 +1465,18 @@ class OffsetAddressFactory extends DefaultAddressFactory {
|
|||
int type = AddressSpace.ID_TYPE_MASK & spaceID;
|
||||
return (type == AddressSpace.TYPE_SYMBOL);
|
||||
}
|
||||
|
||||
private static AddressSpace[] filterSpaces(AddressSpace[] allSpaces) {
|
||||
List<AddressSpace> spaces = new ArrayList<>();
|
||||
for (AddressSpace space : allSpaces) {
|
||||
int type = space.getType();
|
||||
if (type == AddressSpace.TYPE_VARIABLE || type == AddressSpace.TYPE_STACK ||
|
||||
type == AddressSpace.TYPE_EXTERNAL || type == AddressSpace.TYPE_JOIN) {
|
||||
continue;
|
||||
}
|
||||
spaces.add(space);
|
||||
}
|
||||
return spaces.toArray(new AddressSpace[0]);
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ package ghidra.program.model.address;
|
|||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
|
||||
import ghidra.program.model.lang.BasicCompilerSpec;
|
||||
import ghidra.util.datastruct.IntObjectHashtable;
|
||||
import ghidra.util.exception.DuplicateNameException;
|
||||
|
||||
|
@ -59,9 +60,9 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
*/
|
||||
public DefaultAddressFactory(AddressSpace[] addrSpaces, AddressSpace defaultSpace) {
|
||||
memoryAddressSet = new AddressSet();
|
||||
spaces = new ArrayList<AddressSpace>(addrSpaces.length);
|
||||
spaceLookup = new IntObjectHashtable<AddressSpace>();
|
||||
spaceNameTable = new HashMap<String, AddressSpace>();
|
||||
spaces = new ArrayList<>(addrSpaces.length);
|
||||
spaceLookup = new IntObjectHashtable<>();
|
||||
spaceNameTable = new HashMap<>();
|
||||
|
||||
for (AddressSpace space : addrSpaces) {
|
||||
checkReservedSpace(space);
|
||||
|
@ -78,9 +79,6 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
else if (space.getType() == AddressSpace.TYPE_UNIQUE) {
|
||||
uniqueSpace = space;
|
||||
}
|
||||
else if (space.getType() == AddressSpace.TYPE_STACK) {
|
||||
throw new IllegalArgumentException("Stack space should not be specified");
|
||||
}
|
||||
else if (space.getType() == AddressSpace.TYPE_REGISTER) {
|
||||
if (registerSpace != null || !space.getName().equalsIgnoreCase("register")) {
|
||||
// Ghidra address encoding only handles a single register space
|
||||
|
@ -89,9 +87,6 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
}
|
||||
registerSpace = space;
|
||||
}
|
||||
else if (space.getType() == AddressSpace.TYPE_VARIABLE) {
|
||||
throw new IllegalArgumentException("Variable space must be defined by language");
|
||||
}
|
||||
// build up an address set for all possible "real" addresses
|
||||
if (space.isMemorySpace()) {
|
||||
memoryAddressSet.addRange(space.getMinAddress(), space.getMaxAddress());
|
||||
|
@ -118,17 +113,40 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
}
|
||||
|
||||
private void checkReservedSpace(AddressSpace space) {
|
||||
checkReservedVariable(space);
|
||||
checkReservedJoin(space);
|
||||
checkReservedExternal(space);
|
||||
checkReservedStack(space);
|
||||
}
|
||||
|
||||
private void checkReservedVariable(AddressSpace space) {
|
||||
if (space.getType() == AddressSpace.TYPE_VARIABLE ||
|
||||
space.getName().equalsIgnoreCase(AddressSpace.VARIABLE_SPACE.getName()) ||
|
||||
space.getName().equals("join")) {
|
||||
space.getName().equalsIgnoreCase(AddressSpace.VARIABLE_SPACE.getName())) {
|
||||
throw new IllegalArgumentException("Variable space should not be specified");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkReservedJoin(AddressSpace space) {
|
||||
if (space.getType() == AddressSpace.TYPE_JOIN ||
|
||||
space.getName().equals(BasicCompilerSpec.JOIN_SPACE_NAME)) {
|
||||
throw new IllegalArgumentException("Join space should not be specified");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkReservedExternal(AddressSpace space) {
|
||||
if (space.getType() == AddressSpace.TYPE_EXTERNAL ||
|
||||
space.getName().equalsIgnoreCase(AddressSpace.EXTERNAL_SPACE.getName())) {
|
||||
throw new IllegalArgumentException("External space should not be specified");
|
||||
}
|
||||
}
|
||||
|
||||
private void checkReservedStack(AddressSpace space) {
|
||||
if (space.getType() == AddressSpace.TYPE_STACK ||
|
||||
space.getName().equalsIgnoreCase(BasicCompilerSpec.STACK_SPACE_NAME)) {
|
||||
throw new IllegalArgumentException("Stack space should not be specified");
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* @see ghidra.program.model.address.AddressFactory#getAddress(java.lang.String)
|
||||
*/
|
||||
|
@ -141,6 +159,7 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
}
|
||||
}
|
||||
catch (AddressFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
|
||||
for (AddressSpace space : spaces) {
|
||||
|
@ -155,6 +174,7 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
}
|
||||
}
|
||||
catch (AddressFormatException e) {
|
||||
// ignore
|
||||
}
|
||||
}
|
||||
return null;
|
||||
|
@ -167,8 +187,8 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
|
||||
@Override
|
||||
public Address[] getAllAddresses(String addrString, boolean caseSensitive) {
|
||||
ArrayList<Address> loadedMemoryList = new ArrayList<Address>();
|
||||
ArrayList<Address> otherList = new ArrayList<Address>();
|
||||
ArrayList<Address> loadedMemoryList = new ArrayList<>();
|
||||
ArrayList<Address> otherList = new ArrayList<>();
|
||||
|
||||
for (AddressSpace space : spaces) {
|
||||
// Only parse against true physical spaces first
|
||||
|
@ -210,7 +230,6 @@ public class DefaultAddressFactory implements AddressFactory {
|
|||
return defaultSpace;
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public AddressSpace[] getAddressSpaces() {
|
||||
return getPhysicalSpaces();// we avoid returning analysis spaces here
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue