Merge remote-tracking branch

'origin/GP-751_ghizard_VarnodeContext_Needs_OverlayAddressSpace' (Closes
#2785, Closes #2787)
This commit is contained in:
ghidra1 2021-03-10 13:28:20 -05:00
commit 79fce9b032
2 changed files with 63 additions and 36 deletions

View file

@ -47,20 +47,20 @@ public class VarnodeContext implements ProcessorContext {
protected DisassemblerContextImpl spaceContext; protected DisassemblerContextImpl spaceContext;
// holds temp memory values for computation // 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 // holds temp values for computation
private HashMap<Varnode, Varnode> tempVals = new HashMap<Varnode, Varnode>(); private HashMap<Varnode, Varnode> tempVals = new HashMap<>();
protected HashMap<Varnode, Varnode> tempUniqueVals = new HashMap<Varnode, Varnode>(); protected HashMap<Varnode, Varnode> tempUniqueVals = new HashMap<>();
protected boolean keepTempUniqueValues = false; 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 // 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 // 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 Program program;
protected VarnodeTranslator trans; // translator for varnodes<-->registers 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[] retVarnodes = null; // varnodes used to return values
protected Varnode stackVarnode = null; // varnode that represents the stack protected Varnode stackVarnode = null; // varnode that represents the stack
protected Register stackReg = null; 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(); protected static final NotFoundException notFoundExc = new NotFoundException();
@ -88,9 +88,7 @@ public class VarnodeContext implements ProcessorContext {
this.program = program; this.program = program;
// make a copy, because we could be making new spaces. // 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. this.addrFactory = new OffsetAddressFactory(program.getAddressFactory());
// TODO: This doesn't get Stack space, or other overlay spaces...
this.addrFactory = new OffsetAddressFactory(program.getLanguage().getAddressFactory());
BAD_ADDRESS = addrFactory.getAddress(getAddressSpace("BAD_ADDRESS_SPACE"), 0); BAD_ADDRESS = addrFactory.getAddress(getAddressSpace("BAD_ADDRESS_SPACE"), 0);
@ -168,7 +166,7 @@ public class VarnodeContext implements ProcessorContext {
currentAddress = toAddr; 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); offsetContext.flowStart(fromAddr, toAddr);
spaceContext.flowStart(fromAddr, toAddr); spaceContext.flowStart(fromAddr, toAddr);
@ -755,10 +753,10 @@ public class VarnodeContext implements ProcessorContext {
} }
if (clearContext) { if (clearContext) {
if (!keepTempUniqueValues) { if (!keepTempUniqueValues) {
tempUniqueVals = new HashMap<Varnode, Varnode>(); tempUniqueVals = new HashMap<>();
} }
tempVals = new HashMap<Varnode, Varnode>(); tempVals = new HashMap<>();
clearVals = new HashSet<Varnode>(); clearVals = new HashSet<>();
} }
} }
@ -867,9 +865,6 @@ public class VarnodeContext implements ProcessorContext {
public Varnode getVarnode(int spaceID, long offset, int size) { public Varnode getVarnode(int spaceID, long offset, int size) {
AddressSpace space = addrFactory.getAddressSpace(spaceID); AddressSpace space = addrFactory.getAddressSpace(spaceID);
if (space == null) {
return new Varnode(null, size);
}
Address target = space.getTruncatedAddress(offset, true); Address target = space.getTruncatedAddress(offset, true);
Varnode vt = new Varnode(target, size); Varnode vt = new Varnode(target, size);
return vt; return vt;
@ -1242,8 +1237,7 @@ public class VarnodeContext implements ProcessorContext {
throws NotFoundException { throws NotFoundException {
// degenerate case, don't need to know the value // degenerate case, don't need to know the value
if (val1.equals(val2)) { if (val1.equals(val2)) {
return createVarnode(0, addrFactory.getConstantSpace().getSpaceID(), return createVarnode(0, addrFactory.getConstantSpace().getSpaceID(), val1.getSize());
val1.getSize());
} }
int spaceID = val1.getSpace(); int spaceID = val1.getSpace();
long valbase = 0; long valbase = 0;
@ -1442,7 +1436,7 @@ public class VarnodeContext implements ProcessorContext {
class OffsetAddressFactory extends DefaultAddressFactory { class OffsetAddressFactory extends DefaultAddressFactory {
OffsetAddressFactory(AddressFactory baseFactory) { OffsetAddressFactory(AddressFactory baseFactory) {
super(baseFactory.getAllAddressSpaces()); super(filterSpaces(baseFactory.getAllAddressSpaces()));
} }
private int getNextUniqueID() { private int getNextUniqueID() {
@ -1471,4 +1465,18 @@ class OffsetAddressFactory extends DefaultAddressFactory {
int type = AddressSpace.ID_TYPE_MASK & spaceID; int type = AddressSpace.ID_TYPE_MASK & spaceID;
return (type == AddressSpace.TYPE_SYMBOL); 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]);
}
} }

View file

@ -18,6 +18,7 @@ package ghidra.program.model.address;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.HashMap; import java.util.HashMap;
import ghidra.program.model.lang.BasicCompilerSpec;
import ghidra.util.datastruct.IntObjectHashtable; import ghidra.util.datastruct.IntObjectHashtable;
import ghidra.util.exception.DuplicateNameException; import ghidra.util.exception.DuplicateNameException;
@ -59,9 +60,9 @@ public class DefaultAddressFactory implements AddressFactory {
*/ */
public DefaultAddressFactory(AddressSpace[] addrSpaces, AddressSpace defaultSpace) { public DefaultAddressFactory(AddressSpace[] addrSpaces, AddressSpace defaultSpace) {
memoryAddressSet = new AddressSet(); memoryAddressSet = new AddressSet();
spaces = new ArrayList<AddressSpace>(addrSpaces.length); spaces = new ArrayList<>(addrSpaces.length);
spaceLookup = new IntObjectHashtable<AddressSpace>(); spaceLookup = new IntObjectHashtable<>();
spaceNameTable = new HashMap<String, AddressSpace>(); spaceNameTable = new HashMap<>();
for (AddressSpace space : addrSpaces) { for (AddressSpace space : addrSpaces) {
checkReservedSpace(space); checkReservedSpace(space);
@ -78,9 +79,6 @@ public class DefaultAddressFactory implements AddressFactory {
else if (space.getType() == AddressSpace.TYPE_UNIQUE) { else if (space.getType() == AddressSpace.TYPE_UNIQUE) {
uniqueSpace = space; 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) { else if (space.getType() == AddressSpace.TYPE_REGISTER) {
if (registerSpace != null || !space.getName().equalsIgnoreCase("register")) { if (registerSpace != null || !space.getName().equalsIgnoreCase("register")) {
// Ghidra address encoding only handles a single register space // Ghidra address encoding only handles a single register space
@ -89,9 +87,6 @@ public class DefaultAddressFactory implements AddressFactory {
} }
registerSpace = space; 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 // build up an address set for all possible "real" addresses
if (space.isMemorySpace()) { if (space.isMemorySpace()) {
memoryAddressSet.addRange(space.getMinAddress(), space.getMaxAddress()); memoryAddressSet.addRange(space.getMinAddress(), space.getMaxAddress());
@ -118,17 +113,40 @@ public class DefaultAddressFactory implements AddressFactory {
} }
private void checkReservedSpace(AddressSpace space) { private void checkReservedSpace(AddressSpace space) {
checkReservedVariable(space);
checkReservedJoin(space);
checkReservedExternal(space);
checkReservedStack(space);
}
private void checkReservedVariable(AddressSpace space) {
if (space.getType() == AddressSpace.TYPE_VARIABLE || if (space.getType() == AddressSpace.TYPE_VARIABLE ||
space.getName().equalsIgnoreCase(AddressSpace.VARIABLE_SPACE.getName()) || space.getName().equalsIgnoreCase(AddressSpace.VARIABLE_SPACE.getName())) {
space.getName().equals("join")) {
throw new IllegalArgumentException("Variable space should not be specified"); 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 || if (space.getType() == AddressSpace.TYPE_EXTERNAL ||
space.getName().equalsIgnoreCase(AddressSpace.EXTERNAL_SPACE.getName())) { space.getName().equalsIgnoreCase(AddressSpace.EXTERNAL_SPACE.getName())) {
throw new IllegalArgumentException("External space should not be specified"); 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) * @see ghidra.program.model.address.AddressFactory#getAddress(java.lang.String)
*/ */
@ -141,6 +159,7 @@ public class DefaultAddressFactory implements AddressFactory {
} }
} }
catch (AddressFormatException e) { catch (AddressFormatException e) {
// ignore
} }
for (AddressSpace space : spaces) { for (AddressSpace space : spaces) {
@ -155,11 +174,12 @@ public class DefaultAddressFactory implements AddressFactory {
} }
} }
catch (AddressFormatException e) { catch (AddressFormatException e) {
// ignore
} }
} }
return null; return null;
} }
@Override @Override
public Address[] getAllAddresses(String addrString) { public Address[] getAllAddresses(String addrString) {
return getAllAddresses(addrString, true); return getAllAddresses(addrString, true);
@ -167,8 +187,8 @@ public class DefaultAddressFactory implements AddressFactory {
@Override @Override
public Address[] getAllAddresses(String addrString, boolean caseSensitive) { public Address[] getAllAddresses(String addrString, boolean caseSensitive) {
ArrayList<Address> loadedMemoryList = new ArrayList<Address>(); ArrayList<Address> loadedMemoryList = new ArrayList<>();
ArrayList<Address> otherList = new ArrayList<Address>(); ArrayList<Address> otherList = new ArrayList<>();
for (AddressSpace space : spaces) { for (AddressSpace space : spaces) {
// Only parse against true physical spaces first // Only parse against true physical spaces first
@ -210,7 +230,6 @@ public class DefaultAddressFactory implements AddressFactory {
return defaultSpace; return defaultSpace;
} }
@Override @Override
public AddressSpace[] getAddressSpaces() { public AddressSpace[] getAddressSpaces() {
return getPhysicalSpaces();// we avoid returning analysis spaces here return getPhysicalSpaces();// we avoid returning analysis spaces here