mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2025-10-05 10:49:34 +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;
|
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]);
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -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,6 +174,7 @@ public class DefaultAddressFactory implements AddressFactory {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (AddressFormatException e) {
|
catch (AddressFormatException e) {
|
||||||
|
// ignore
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return null;
|
return null;
|
||||||
|
@ -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
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue