mirror of
https://github.com/NationalSecurityAgency/ghidra.git
synced 2026-09-28 17:11:11 -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 boolean readExecutableAddress;
|
||||||
protected VarnodeContext context;
|
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 hitCodeFlow = false; // no branching so far
|
||||||
|
|
||||||
protected boolean debug = false;
|
protected boolean debug = false;
|
||||||
@@ -409,7 +409,7 @@ public class SymbolicPropogator {
|
|||||||
public AddressSet flowConstants(Address fromAddr, Address startAddr, AddressSetView restrictSet,
|
public AddressSet flowConstants(Address fromAddr, Address startAddr, AddressSetView restrictSet,
|
||||||
ContextEvaluator eval, VarnodeContext vContext, TaskMonitor monitor)
|
ContextEvaluator eval, VarnodeContext vContext, TaskMonitor monitor)
|
||||||
throws CancelledException {
|
throws CancelledException {
|
||||||
body = new AddressSet();
|
visitedBody = new AddressSet();
|
||||||
AddressSet conflicts = new AddressSet();
|
AddressSet conflicts = new AddressSet();
|
||||||
|
|
||||||
// prime the context stack with the entry point address
|
// prime the context stack with the entry point address
|
||||||
@@ -425,8 +425,8 @@ public class SymbolicPropogator {
|
|||||||
while (!contextStack.isEmpty()) {
|
while (!contextStack.isEmpty()) {
|
||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
if (canceled) {
|
if (canceled) {
|
||||||
body.add(conflicts); // put the conflict/redone addresses back in
|
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||||
return body;
|
return visitedBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
// if we run into a flow that has already been done, flow until
|
// if we run into a flow that has already been done, flow until
|
||||||
@@ -440,7 +440,7 @@ public class SymbolicPropogator {
|
|||||||
nextFlow.restoreState(vContext);
|
nextFlow.restoreState(vContext);
|
||||||
|
|
||||||
// already done it!
|
// already done it!
|
||||||
if (body.contains(nextAddr)) {
|
if (visitedBody.contains(nextAddr)) {
|
||||||
// allow it to keep flowing until the next branch/call/ret flow!
|
// allow it to keep flowing until the next branch/call/ret flow!
|
||||||
hitOtherFlow = true;
|
hitOtherFlow = true;
|
||||||
if (!continueAfterHittingFlow) {
|
if (!continueAfterHittingFlow) {
|
||||||
@@ -461,7 +461,7 @@ public class SymbolicPropogator {
|
|||||||
monitor.checkCancelled();
|
monitor.checkCancelled();
|
||||||
|
|
||||||
// already done it!
|
// already done it!
|
||||||
if (body.contains(nextAddr)) {
|
if (visitedBody.contains(nextAddr)) {
|
||||||
// allow it to keep flowing until the next branch/call/ret flow!
|
// allow it to keep flowing until the next branch/call/ret flow!
|
||||||
hitOtherFlow = true;
|
hitOtherFlow = true;
|
||||||
if (!continueAfterHittingFlow) {
|
if (!continueAfterHittingFlow) {
|
||||||
@@ -499,8 +499,8 @@ public class SymbolicPropogator {
|
|||||||
|
|
||||||
if (evaluator != null) {
|
if (evaluator != null) {
|
||||||
if (evaluator.evaluateContextBefore(vContext, instr)) {
|
if (evaluator.evaluateContextBefore(vContext, instr)) {
|
||||||
body.add(conflicts); // put the conflict/redone addresses back in
|
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||||
return body;
|
return visitedBody;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -510,7 +510,7 @@ public class SymbolicPropogator {
|
|||||||
Address retAddr = applyPcode(vContext, instr, monitor);
|
Address retAddr = applyPcode(vContext, instr, monitor);
|
||||||
|
|
||||||
// add this instruction to processed body set
|
// 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.
|
/* Allow evaluateContext routine to change override the flowtype of an instruction.
|
||||||
* Jumps Changed to calls will now continue processing.
|
* Jumps Changed to calls will now continue processing.
|
||||||
@@ -519,8 +519,8 @@ public class SymbolicPropogator {
|
|||||||
*/
|
*/
|
||||||
if (evaluator != null) {
|
if (evaluator != null) {
|
||||||
if (evaluator.evaluateContext(vContext, instr)) {
|
if (evaluator.evaluateContext(vContext, instr)) {
|
||||||
body.add(conflicts); // put the conflict/redone addresses back in
|
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||||
return body;
|
return visitedBody;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -533,7 +533,7 @@ public class SymbolicPropogator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
Address inlineCall = null;
|
Address callFlowAddr = null;
|
||||||
|
|
||||||
boolean simpleFlow = isSimpleFallThrough(instrFlow);
|
boolean simpleFlow = isSimpleFallThrough(instrFlow);
|
||||||
// once we encounter any flow, must set the hitCodeFlow flag
|
// once we encounter any flow, must set the hitCodeFlow flag
|
||||||
@@ -568,7 +568,7 @@ public class SymbolicPropogator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
inlineCall = flows[0];
|
callFlowAddr = flows[0];
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (instrFlow.isComputed() && instrFlow.isCall()) {
|
else if (instrFlow.isComputed() && instrFlow.isCall()) {
|
||||||
@@ -577,12 +577,17 @@ public class SymbolicPropogator {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (inlineCall != null) {
|
if (callFlowAddr != null) {
|
||||||
Function func = program.getFunctionManager().getFunctionAt(inlineCall);
|
Function func = program.getFunctionManager().getFunctionAt(callFlowAddr);
|
||||||
if (func != null && func.isInline()) {
|
if (func != null && func.isInline()) {
|
||||||
vContext.mergeToFutureFlowState(maxAddr, inlineCall);
|
vContext.mergeToFutureFlowState(maxAddr, callFlowAddr);
|
||||||
vContext.flowEnd(maxAddr);
|
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);
|
vContext.mergeToFutureFlowState(minInstrAddress, maxAddr);
|
||||||
|
|
||||||
//
|
//
|
||||||
@@ -641,8 +646,8 @@ public class SymbolicPropogator {
|
|||||||
vContext.flowEnd(maxAddr);
|
vContext.flowEnd(maxAddr);
|
||||||
}
|
}
|
||||||
|
|
||||||
body.add(conflicts); // put the conflict/redone addresses back in
|
visitedBody.add(conflicts); // put the conflict/redone addresses back in
|
||||||
return body;
|
return visitedBody;
|
||||||
}
|
}
|
||||||
|
|
||||||
private boolean isSimpleFallThrough(FlowType instrFlow) {
|
private boolean isSimpleFallThrough(FlowType instrFlow) {
|
||||||
@@ -2200,7 +2205,7 @@ public class SymbolicPropogator {
|
|||||||
for (Reference ref : refs) {
|
for (Reference ref : refs) {
|
||||||
Address refAddr = ref.getToAddress();
|
Address refAddr = ref.getToAddress();
|
||||||
Address addr = refAddr.getAddressSpace().getTruncatedAddress(val, true);
|
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
|
// 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
|
// get rid of the reference, reference could be changed to new AddressSpace or value
|
||||||
instr.removeOperandReference(ref.getOperandIndex(), refAddr);
|
instr.removeOperandReference(ref.getOperandIndex(), refAddr);
|
||||||
|
|||||||
Reference in New Issue
Block a user