mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-25 17:00:36 -09:00
GP-3499 Fixed inlined functions causing lockups in stack depth field and analysis
This commit is contained in:
@@ -63,7 +63,7 @@ public class SymbolicPropogator {
|
||||
protected boolean readExecutableAddress;
|
||||
protected VarnodeContext context;
|
||||
|
||||
protected AddressSet body; // body of processed instructions
|
||||
protected AddressSet visitedBody; // body of processed instructions
|
||||
protected boolean hitCodeFlow = false; // no branching so far
|
||||
|
||||
protected boolean debug = false;
|
||||
@@ -409,7 +409,7 @@ public class SymbolicPropogator {
|
||||
public AddressSet flowConstants(Address fromAddr, Address startAddr, AddressSetView restrictSet,
|
||||
ContextEvaluator eval, VarnodeContext vContext, TaskMonitor monitor)
|
||||
throws CancelledException {
|
||||
body = new AddressSet();
|
||||
visitedBody = new AddressSet();
|
||||
AddressSet conflicts = new AddressSet();
|
||||
|
||||
// prime the context stack with the entry point address
|
||||
@@ -425,8 +425,8 @@ public class SymbolicPropogator {
|
||||
while (!contextStack.isEmpty()) {
|
||||
monitor.checkCancelled();
|
||||
if (canceled) {
|
||||
body.add(conflicts); // put the conflict/redone addresses back in
|
||||
return body;
|
||||
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||
return visitedBody;
|
||||
}
|
||||
|
||||
// if we run into a flow that has already been done, flow until
|
||||
@@ -440,7 +440,7 @@ public class SymbolicPropogator {
|
||||
nextFlow.restoreState(vContext);
|
||||
|
||||
// already done it!
|
||||
if (body.contains(nextAddr)) {
|
||||
if (visitedBody.contains(nextAddr)) {
|
||||
// allow it to keep flowing until the next branch/call/ret flow!
|
||||
hitOtherFlow = true;
|
||||
if (!continueAfterHittingFlow) {
|
||||
@@ -461,7 +461,7 @@ public class SymbolicPropogator {
|
||||
monitor.checkCancelled();
|
||||
|
||||
// already done it!
|
||||
if (body.contains(nextAddr)) {
|
||||
if (visitedBody.contains(nextAddr)) {
|
||||
// allow it to keep flowing until the next branch/call/ret flow!
|
||||
hitOtherFlow = true;
|
||||
if (!continueAfterHittingFlow) {
|
||||
@@ -499,8 +499,8 @@ public class SymbolicPropogator {
|
||||
|
||||
if (evaluator != null) {
|
||||
if (evaluator.evaluateContextBefore(vContext, instr)) {
|
||||
body.add(conflicts); // put the conflict/redone addresses back in
|
||||
return body;
|
||||
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||
return visitedBody;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -510,7 +510,7 @@ public class SymbolicPropogator {
|
||||
Address retAddr = applyPcode(vContext, instr, monitor);
|
||||
|
||||
// add this instruction to processed body set
|
||||
body.addRange(minInstrAddress, maxAddr);
|
||||
visitedBody.addRange(minInstrAddress, maxAddr);
|
||||
|
||||
/* Allow evaluateContext routine to change override the flowtype of an instruction.
|
||||
* Jumps Changed to calls will now continue processing.
|
||||
@@ -519,8 +519,8 @@ public class SymbolicPropogator {
|
||||
*/
|
||||
if (evaluator != null) {
|
||||
if (evaluator.evaluateContext(vContext, instr)) {
|
||||
body.add(conflicts); // put the conflict/redone addresses back in
|
||||
return body;
|
||||
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||
return visitedBody;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -533,7 +533,7 @@ public class SymbolicPropogator {
|
||||
}
|
||||
}
|
||||
|
||||
Address inlineCall = null;
|
||||
Address callFlowAddr = null;
|
||||
|
||||
boolean simpleFlow = isSimpleFallThrough(instrFlow);
|
||||
// once we encounter any flow, must set the hitCodeFlow flag
|
||||
@@ -568,7 +568,7 @@ public class SymbolicPropogator {
|
||||
}
|
||||
}
|
||||
else {
|
||||
inlineCall = flows[0];
|
||||
callFlowAddr = flows[0];
|
||||
}
|
||||
}
|
||||
else if (instrFlow.isComputed() && instrFlow.isCall()) {
|
||||
@@ -577,12 +577,17 @@ public class SymbolicPropogator {
|
||||
}
|
||||
}
|
||||
|
||||
if (inlineCall != null) {
|
||||
Function func = program.getFunctionManager().getFunctionAt(inlineCall);
|
||||
if (callFlowAddr != null) {
|
||||
Function func = program.getFunctionManager().getFunctionAt(callFlowAddr);
|
||||
if (func != null && func.isInline()) {
|
||||
vContext.mergeToFutureFlowState(maxAddr, inlineCall);
|
||||
vContext.mergeToFutureFlowState(maxAddr, callFlowAddr);
|
||||
vContext.flowEnd(maxAddr);
|
||||
flowConstants(maxAddr, inlineCall, func.getBody(), eval, vContext, monitor);
|
||||
// Body will get re-initialized.
|
||||
// The inlined function may be called multiple times, so body of inlined function
|
||||
// should not be included in the already visited body.
|
||||
AddressSet savedBody = visitedBody;
|
||||
flowConstants(maxAddr, callFlowAddr, func.getBody(), eval, vContext, monitor);
|
||||
visitedBody = savedBody;
|
||||
vContext.mergeToFutureFlowState(minInstrAddress, maxAddr);
|
||||
|
||||
//
|
||||
@@ -641,8 +646,8 @@ public class SymbolicPropogator {
|
||||
vContext.flowEnd(maxAddr);
|
||||
}
|
||||
|
||||
body.add(conflicts); // put the conflict/redone addresses back in
|
||||
return body;
|
||||
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||
return visitedBody;
|
||||
}
|
||||
|
||||
private boolean isSimpleFallThrough(FlowType instrFlow) {
|
||||
@@ -2200,7 +2205,7 @@ public class SymbolicPropogator {
|
||||
for (Reference ref : refs) {
|
||||
Address refAddr = ref.getToAddress();
|
||||
Address addr = refAddr.getAddressSpace().getTruncatedAddress(val, true);
|
||||
if (ref.getReferenceType() == RefType.PARAM && !body.contains(ref.getFromAddress())) {
|
||||
if (ref.getReferenceType() == RefType.PARAM && !visitedBody.contains(ref.getFromAddress())) {
|
||||
// if reference address is not in body yet, this is the first time at this location
|
||||
// get rid of the reference, reference could be changed to new AddressSpace or value
|
||||
instr.removeOperandReference(ref.getOperandIndex(), refAddr);
|
||||
|
||||
Reference in New Issue
Block a user