mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-05-23 09:35:50 +08:00
Merge remote-tracking branch 'origin/patch'
This commit is contained in:
@@ -834,8 +834,7 @@ public class SymbolicPropogator {
|
||||
val1 = vContext.getValue(in[0], evaluator);
|
||||
lval1 = vContext.getConstant(val1, evaluator);
|
||||
vt = vContext.getVarnode(
|
||||
minInstrAddress.getAddressSpace().getBaseSpaceID(),
|
||||
lval1, 0);
|
||||
minInstrAddress.getAddressSpace().getBaseSpaceID(), lval1, 0);
|
||||
makeReference(vContext, instruction, ptype, -1, vt,
|
||||
instruction.getFlowType(), monitor);
|
||||
}
|
||||
@@ -914,8 +913,8 @@ public class SymbolicPropogator {
|
||||
if (target != null) {
|
||||
if (target.isMemoryAddress()) {
|
||||
vContext.propogateResults(false);
|
||||
conflict |= vContext.mergeToFutureFlowState(
|
||||
minInstrAddress, target);
|
||||
conflict |=
|
||||
vContext.mergeToFutureFlowState(minInstrAddress, target);
|
||||
}
|
||||
func = prog.getFunctionManager().getFunctionAt(target);
|
||||
if (func == null && ptype == PcodeOp.CALLIND) {
|
||||
@@ -987,8 +986,8 @@ public class SymbolicPropogator {
|
||||
instruction.getAddress());
|
||||
}
|
||||
vContext.propogateResults(false);
|
||||
conflict |= vContext.mergeToFutureFlowState(minInstrAddress,
|
||||
in[0].getAddress());
|
||||
conflict |=
|
||||
vContext.mergeToFutureFlowState(minInstrAddress, in[0].getAddress());
|
||||
pcodeIndex = ops.length; // break out of the processing
|
||||
break;
|
||||
|
||||
@@ -999,8 +998,8 @@ public class SymbolicPropogator {
|
||||
int sequenceOffset = (int) in[0].getOffset();
|
||||
if ((pcodeIndex + sequenceOffset) >= ops.length) {
|
||||
vContext.propogateResults(false);
|
||||
conflict |= vContext.mergeToFutureFlowState(
|
||||
minInstrAddress, instruction.getFallThrough());
|
||||
conflict |= vContext.mergeToFutureFlowState(minInstrAddress,
|
||||
instruction.getFallThrough());
|
||||
}
|
||||
}
|
||||
else if (in[0].isAddress()) {
|
||||
@@ -1047,8 +1046,7 @@ public class SymbolicPropogator {
|
||||
if (fallThru != null) {
|
||||
// we don't know what will happen from here on, but anything before should in theory propagate
|
||||
vContext.propogateResults(true);
|
||||
conflict |= vContext.mergeToFutureFlowState(
|
||||
minInstrAddress,
|
||||
conflict |= vContext.mergeToFutureFlowState(minInstrAddress,
|
||||
instruction.getFallThrough());
|
||||
}
|
||||
// everything that is in the cache from here on should be cleared
|
||||
@@ -1075,7 +1073,8 @@ public class SymbolicPropogator {
|
||||
}
|
||||
else if (!evaluator.followFalseConditionalBranches()) {
|
||||
// pcode addresses are raw addresses, make sure address is in same instruction space
|
||||
nextAddr = minInstrAddress.getAddressSpace().getOverlayAddress(in[0].getAddress());
|
||||
nextAddr = minInstrAddress.getAddressSpace().getOverlayAddress(
|
||||
in[0].getAddress());
|
||||
pcodeIndex = ops.length; // break out of the processing
|
||||
}
|
||||
}
|
||||
@@ -1181,28 +1180,14 @@ public class SymbolicPropogator {
|
||||
case PcodeOp.INT_AND:
|
||||
val1 = vContext.getValue(in[0], false, evaluator);
|
||||
val2 = vContext.getValue(in[1], false, evaluator);
|
||||
if (val1.equals(val2)) {
|
||||
result = val1;
|
||||
}
|
||||
else {
|
||||
//lresult = context.getConstant(val1,evaluator) & context.getConstant(val2,evaluator);
|
||||
//result = context.createVarnode(lresult, val1.getSpace(), val1.getSize());
|
||||
result = vContext.and(val1, val2, evaluator);
|
||||
}
|
||||
result = vContext.and(val1, val2, evaluator);
|
||||
vContext.putValue(out, result, mustClearAll);
|
||||
break;
|
||||
|
||||
case PcodeOp.INT_OR:
|
||||
val1 = vContext.getValue(in[0], false, evaluator);
|
||||
val2 = vContext.getValue(in[1], false, evaluator);
|
||||
if (!val1.equals(val2)) {
|
||||
lresult = vContext.getConstant(val1, evaluator) |
|
||||
vContext.getConstant(val2, evaluator);
|
||||
result = vContext.createConstantVarnode(lresult, val1.getSize());
|
||||
}
|
||||
else {
|
||||
result = val1;
|
||||
}
|
||||
result = vContext.or(val1, val2, evaluator);
|
||||
vContext.putValue(out, result, mustClearAll);
|
||||
break;
|
||||
|
||||
@@ -1856,7 +1841,7 @@ public class SymbolicPropogator {
|
||||
// }
|
||||
// } else
|
||||
|
||||
if (!vContext.isStackSymbolicSpace(refLocation) && evaluator != null) {
|
||||
if (!vContext.isStackSymbolicSpace(refLocation) && evaluator != null) {
|
||||
Address constant = program.getAddressFactory().getAddress(
|
||||
(int) targetSpaceID.getOffset(), offset);
|
||||
Address newTarget = evaluator.evaluateConstant(vContext, instruction,
|
||||
@@ -1864,8 +1849,7 @@ public class SymbolicPropogator {
|
||||
if (newTarget != null) {
|
||||
makeReference(vContext, instruction, Reference.MNEMONIC,
|
||||
newTarget.getAddressSpace().getBaseSpaceID(), newTarget.getOffset(),
|
||||
0, reftype,
|
||||
pcodeType, false, monitor);
|
||||
0, reftype, pcodeType, false, monitor);
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -2043,7 +2027,8 @@ public class SymbolicPropogator {
|
||||
}
|
||||
|
||||
// only want returns that can fit in a pointer!
|
||||
returnLoc = conv.getReturnLocation(new PointerDataType(Undefined.DEFAULT,pointerSize), program);
|
||||
returnLoc =
|
||||
conv.getReturnLocation(new PointerDataType(Undefined.DEFAULT, pointerSize), program);
|
||||
|
||||
return returnLoc;
|
||||
}
|
||||
|
||||
@@ -151,7 +151,7 @@ public class VarnodeContext implements ProcessorContext {
|
||||
public void flowToAddress(Address fromAddr, Address toAddr) {
|
||||
// make sure address in same space as from, might be in an overlay
|
||||
toAddr = fromAddr.getAddressSpace().getOverlayAddress(toAddr);
|
||||
|
||||
|
||||
currentAddress = toAddr;
|
||||
offsetContext.flowToAddress(fromAddr, toAddr);
|
||||
spaceContext.flowToAddress(fromAddr, toAddr);
|
||||
@@ -165,7 +165,7 @@ public class VarnodeContext implements ProcessorContext {
|
||||
public void flowStart(Address fromAddr, Address toAddr) {
|
||||
// make sure address in same space as from, might be in an overlay
|
||||
toAddr = fromAddr.getAddressSpace().getOverlayAddress(toAddr);
|
||||
|
||||
|
||||
currentAddress = toAddr;
|
||||
|
||||
this.lastSet = new HashMap<Varnode, Address>(); // clear out any interim last sets... rely on allLastSet now
|
||||
@@ -177,7 +177,7 @@ public class VarnodeContext implements ProcessorContext {
|
||||
public void copyToFutureFlowState(Address fromAddr, Address toAddr) {
|
||||
// make sure address in same space as from, might be in an overlay
|
||||
toAddr = fromAddr.getAddressSpace().getOverlayAddress(toAddr);
|
||||
|
||||
|
||||
offsetContext.copyToFutureFlowState(fromAddr, toAddr);
|
||||
spaceContext.copyToFutureFlowState(fromAddr, toAddr);
|
||||
}
|
||||
@@ -186,10 +186,10 @@ public class VarnodeContext implements ProcessorContext {
|
||||
if (toAddr == null) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
||||
// make sure address in same space as from, might be in an overlay
|
||||
toAddr = fromAddr.getAddressSpace().getOverlayAddress(toAddr);
|
||||
|
||||
|
||||
ArrayList<RegisterValue> conflicts = offsetContext.mergeToFutureFlowState(fromAddr, toAddr);
|
||||
ArrayList<RegisterValue> spaceConflicts =
|
||||
spaceContext.mergeToFutureFlowState(fromAddr, toAddr);
|
||||
@@ -267,8 +267,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
DataType undefinedDataType = Undefined.getUndefinedDataType(pointerSize);
|
||||
VariableStorage retStorage =
|
||||
callingConvention.getReturnLocation(undefinedDataType, program);
|
||||
if (retStorage != null && retStorage.isValid())
|
||||
if (retStorage != null && retStorage.isValid()) {
|
||||
return retStorage.getVarnodes();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -281,10 +282,12 @@ public class VarnodeContext implements ProcessorContext {
|
||||
// TODO: handle multiple bonded return values in default convention. There is no way to do this now.
|
||||
DataType undefDT = Undefined.getUndefinedDataType(program.getDefaultPointerSize());
|
||||
VariableStorage retStore = defaultCallingConvention.getReturnLocation(undefDT, program);
|
||||
if (retStore != null && retStore.isValid())
|
||||
if (retStore != null && retStore.isValid()) {
|
||||
retVarnodes = retStore.getVarnodes();
|
||||
else
|
||||
}
|
||||
else {
|
||||
retVarnodes = new Varnode[0];
|
||||
}
|
||||
return retVarnodes;
|
||||
}
|
||||
|
||||
@@ -371,8 +374,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
rvnode = tempVals.get(varnode);
|
||||
}
|
||||
if (rvnode != null) {
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " Tmp " + varnode + " = " + rvnode);
|
||||
}
|
||||
if (rvnode.getAddress().equals(BAD_ADDRESS)) {
|
||||
throw notFoundExc;
|
||||
}
|
||||
@@ -391,8 +395,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
throw notFoundExc;
|
||||
}
|
||||
if (!rvnode.getAddress().equals(BAD_ADDRESS)) {
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " " + reg.getName() + " = " + print(rvnode));
|
||||
}
|
||||
|
||||
}
|
||||
return rvnode;
|
||||
@@ -417,11 +422,13 @@ public class VarnodeContext implements ProcessorContext {
|
||||
// see if we wrote a value to memory here
|
||||
Varnode lvalue = memoryVals.get(varnode);
|
||||
if (lvalue != null) {
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " " + varnode + " = " + print(lvalue));
|
||||
}
|
||||
if (isSymbolicSpace(lvalue.getSpace())) {
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " out " + varnode + " = " + print(lvalue));
|
||||
}
|
||||
throw notFoundExc;
|
||||
}
|
||||
// if this is an offset reference, ONLY allow it to be offset into the stack, no other register offset.
|
||||
@@ -519,8 +526,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
throw notFoundExc;
|
||||
}
|
||||
|
||||
if (signed)
|
||||
if (signed) {
|
||||
value = (value << 8 * (8 - size)) >> 8 * (8 - size);
|
||||
}
|
||||
|
||||
return createConstantVarnode(value, size);
|
||||
|
||||
@@ -661,9 +669,10 @@ public class VarnodeContext implements ProcessorContext {
|
||||
|
||||
if (out.isAddress() || isSymbolicSpace(out.getSpace())) {
|
||||
if (!isRegister(out)) {
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " " + print(out) + " <- " + print(result) + " at " +
|
||||
offsetContext.getAddress());
|
||||
}
|
||||
|
||||
Address location = offsetContext.getAddress();
|
||||
|
||||
@@ -685,9 +694,10 @@ public class VarnodeContext implements ProcessorContext {
|
||||
tempVals.put(out, result);
|
||||
}
|
||||
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " " + print(out) + " <- " + print(result) + " at " +
|
||||
offsetContext.getAddress());
|
||||
}
|
||||
if (mustClear) {
|
||||
clearVals.add(out);
|
||||
}
|
||||
@@ -737,8 +747,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
propogateValue(reg, node, val, offsetContext.getAddress());
|
||||
}
|
||||
else {
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " " + reg.getName() + "<-" + " Clear");
|
||||
}
|
||||
clearRegister(reg);
|
||||
}
|
||||
}
|
||||
@@ -763,8 +774,7 @@ public class VarnodeContext implements ProcessorContext {
|
||||
|
||||
// set lastSet for any children locations
|
||||
List<Register> childRegisters = reg.getChildRegisters();
|
||||
for (Iterator<Register> iterator = childRegisters.iterator(); iterator.hasNext();) {
|
||||
Register register = iterator.next();
|
||||
for (Register register : childRegisters) {
|
||||
if (register.getMinimumByteSize() >= program.getDefaultPointerSize()) {
|
||||
node = getRegisterVarnode(register);
|
||||
|
||||
@@ -874,8 +884,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
// is there an assumed value that should be returned for any unknown value?
|
||||
Instruction instr = getCurrentInstruction(offsetContext.getAddress());
|
||||
Long lval = evaluator.unknownValue(this, instr, vnode);
|
||||
if (lval != null)
|
||||
if (lval != null) {
|
||||
return lval.longValue();
|
||||
}
|
||||
throw notFoundExc;
|
||||
}
|
||||
|
||||
@@ -946,8 +957,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
return null;
|
||||
}
|
||||
if (!rvnode.getAddress().equals(BAD_ADDRESS)) {
|
||||
if (debug)
|
||||
if (debug) {
|
||||
Msg.info(this, " " + reg.getName() + " = " + print(rvnode));
|
||||
}
|
||||
return rvnode;
|
||||
}
|
||||
return null;
|
||||
@@ -1131,6 +1143,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
|
||||
public Varnode and(Varnode val1, Varnode val2, ContextEvaluator evaluator)
|
||||
throws NotFoundException {
|
||||
if (val1.equals(val2)) {
|
||||
return val1;
|
||||
}
|
||||
if (val1.isConstant() || val1.isAddress()) {
|
||||
Varnode swap = val1;
|
||||
val1 = val2;
|
||||
@@ -1138,10 +1153,7 @@ public class VarnodeContext implements ProcessorContext {
|
||||
}
|
||||
int spaceID = val1.getSpace();
|
||||
long valbase = 0;
|
||||
if (isRegister(val1) && val1.equals(val2)) {
|
||||
return val1;
|
||||
}
|
||||
else if (isRegister(val1)) {
|
||||
if (isRegister(val1)) {
|
||||
Register reg = trans.getRegister(val1);
|
||||
if (reg == null) {
|
||||
throw notFoundExc;
|
||||
@@ -1170,6 +1182,25 @@ public class VarnodeContext implements ProcessorContext {
|
||||
return createVarnode(result, spaceID, val1.getSize());
|
||||
}
|
||||
|
||||
public Varnode or(Varnode val1, Varnode val2, ContextEvaluator evaluator)
|
||||
throws NotFoundException {
|
||||
if (val1.equals(val2)) {
|
||||
return val1;
|
||||
}
|
||||
|
||||
if (val1.isConstant() || val1.isAddress()) {
|
||||
Varnode swap = val1;
|
||||
val1 = val2;
|
||||
val2 = swap;
|
||||
}
|
||||
long val2Const = getConstant(val2, null);
|
||||
if (val2Const == 0) {
|
||||
return val1;
|
||||
}
|
||||
long lresult = getConstant(val1, evaluator) | val2Const;
|
||||
return createConstantVarnode(lresult, val1.getSize());
|
||||
}
|
||||
|
||||
public Varnode left(Varnode val1, Varnode val2, ContextEvaluator evaluator)
|
||||
throws NotFoundException {
|
||||
long lresult = getConstant(val1, evaluator) << getConstant(val2, evaluator);
|
||||
@@ -1273,13 +1304,14 @@ public class VarnodeContext implements ProcessorContext {
|
||||
// too big anyway,already extended as far as it will go.
|
||||
vnodeVal = createConstantVarnode(vnodeVal.getOffset(), out.getSize());
|
||||
}
|
||||
} else if (vnodeVal.isRegister() && vnodeVal.getSize() < out.getSize()) {
|
||||
}
|
||||
else if (vnodeVal.isRegister() && vnodeVal.getSize() < out.getSize()) {
|
||||
Register reg = getRegister(vnodeVal);
|
||||
if (reg == null) {
|
||||
throw notFoundExc;
|
||||
}
|
||||
int spaceID = getAddressSpace(reg.getName());
|
||||
vnodeVal = createVarnode(0,spaceID,out.getSize());
|
||||
vnodeVal = createVarnode(0, spaceID, out.getSize());
|
||||
}
|
||||
return vnodeVal;
|
||||
}
|
||||
@@ -1323,8 +1355,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
Varnode regVnode = trans.getVarnode(register);
|
||||
try {
|
||||
Varnode value = this.getValue(regVnode, false, null);
|
||||
if (value.isConstant())
|
||||
if (value.isConstant()) {
|
||||
return new RegisterValue(register, BigInteger.valueOf(value.getOffset()));
|
||||
}
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
// Don't care, turn into a null register
|
||||
@@ -1365,8 +1398,9 @@ public class VarnodeContext implements ProcessorContext {
|
||||
Varnode regVnode = trans.getVarnode(register);
|
||||
try {
|
||||
Varnode value = this.getValue(regVnode, signed, null);
|
||||
if (value.isConstant())
|
||||
if (value.isConstant()) {
|
||||
return BigInteger.valueOf(value.getOffset());
|
||||
}
|
||||
}
|
||||
catch (NotFoundException e) {
|
||||
// Don't care, turn into a null value
|
||||
@@ -1414,8 +1448,8 @@ class OffsetAddressFactory extends DefaultAddressFactory {
|
||||
private int getNextUniqueID() {
|
||||
int maxID = 0;
|
||||
AddressSpace[] spaces = getAllAddressSpaces();
|
||||
for (int i = 0; i < spaces.length; i++) {
|
||||
maxID = Math.max(maxID, spaces[i].getUnique());
|
||||
for (AddressSpace space : spaces) {
|
||||
maxID = Math.max(maxID, space.getUnique());
|
||||
}
|
||||
return maxID + 1;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user