diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java index 36ea43a5f1..18f64cd11f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/SymbolicPropogator.java @@ -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; } diff --git a/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java b/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java index 19ef99e621..f270ee384f 100644 --- a/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java +++ b/Ghidra/Features/Base/src/main/java/ghidra/program/util/VarnodeContext.java @@ -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(); // 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 conflicts = offsetContext.mergeToFutureFlowState(fromAddr, toAddr); ArrayList 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 childRegisters = reg.getChildRegisters(); - for (Iterator 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; }