Java Code Examples for ghidra.program.model.listing.Instruction#getFlowType()

The following examples show how to use ghidra.program.model.listing.Instruction#getFlowType() . You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example 1
Source File: ConstantPropagationContextEvaluator.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Add instructions to destination set for unknown computed branches.
 */
@Override
public boolean evaluateDestination(VarnodeContext context, Instruction instruction) {
	FlowType flowType = instruction.getFlowType();
	if (!flowType.isJump()) {
		return false;
	}

	/**
	 * For jump targets, that have no computed reference, add the jump location to a set
	 * to evaluate as a potential switch statement.
	 */
	Reference[] refs = instruction.getReferencesFrom();
	if (refs.length <= 0 || (refs.length == 1 && refs[0].getReferenceType().isData())) {
		destSet.addRange(instruction.getMinAddress(), instruction.getMinAddress());
	}
	return false;
}
 
Example 2
Source File: BasicBlockModel.java    From ghidra with Apache License 2.0 5 votes vote down vote up
@Override
protected boolean hasEndOfBlockFlow(Instruction instr) {
	FlowType flowType = instr.getFlowType();
	if (flowType.isJump() || flowType.isTerminal()) {
		return true;
	}
	for (Reference ref : instr.getReferencesFrom()) {
		RefType refType = ref.getReferenceType();
		if (refType.isJump() || refType.isTerminal()) {
			return true;
		}
	}
	return false;
}
 
Example 3
Source File: RefTypeFactory.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Determine default computed FlowType for a specified instruction.  It is assumed 
 * that all computed flows utilize a register in its destination specification/computation.
 * @param instr instruction
 * @return FlowType or null if unable to determine
 */
public static FlowType getDefaultComputedFlowType(Instruction instr) {

	if (instr.getFlowType() != RefType.INVALID && instr.getDefaultFlows().length <= 1) {
		// Don't bother looking if not complex flow
		return getDefaultJumpOrCallFlowType(instr);
	}

	// Assumption - it is assumed that any complex flow type is due to the presence of
	// multiple conditional flows.  

	// TODO: Verify that above assumption is valid !!

	FlowType flowType = null;
	PcodeOp[] pcodeOps = instr.getPcode();
	for (PcodeOp op : pcodeOps) {
		int opcode = op.getOpcode();
		if (opcode == PcodeOp.BRANCHIND) {
			if (flowType == RefType.CONDITIONAL_COMPUTED_CALL) {
				return null; // more than one flow type
			}
			flowType = RefType.CONDITIONAL_COMPUTED_JUMP;
		}
		else if (opcode == PcodeOp.CALLIND) {
			if (flowType == RefType.CONDITIONAL_COMPUTED_JUMP) {
				return null; // more than one flow type
			}
			flowType = RefType.CONDITIONAL_COMPUTED_CALL;
		}
	}

	return flowType;
}
 
Example 4
Source File: RefTypeFactory.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Return default flow-type without terminator
 * @param inst
 * @return call/jump flow type or null
 */
private static FlowType getDefaultJumpOrCallFlowType(Instruction inst) {
	FlowType flowType = inst.getFlowType();
	if (flowType.isConditional()) {
		if (flowType.isComputed()) {
			if (flowType.isCall()) {
				return RefType.CONDITIONAL_COMPUTED_CALL;
			}
			else if (flowType.isJump()) {
				return RefType.CONDITIONAL_COMPUTED_JUMP;
			}
		}
		else if (flowType.isCall()) {
			return RefType.CONDITIONAL_CALL;
		}
		else if (flowType.isJump()) {
			return RefType.CONDITIONAL_JUMP;
		}
	}
	if (flowType.isComputed()) {
		if (flowType.isCall()) {
			return RefType.COMPUTED_CALL;
		}
		else if (flowType.isJump()) {
			return RefType.COMPUTED_JUMP;
		}
	}
	else if (flowType.isCall()) {
		return RefType.UNCONDITIONAL_CALL;
	}
	else if (flowType.isJump()) {
		return RefType.UNCONDITIONAL_JUMP;
	}
	return null;
}
 
Example 5
Source File: RefTypeFactory.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Determine default FlowType for a specified instruction and flow destination toAddr.
 * @param instr instruction
 * @param toAddr flow destination address
 * @param allowComputedFlowType if true and an absolute flow type is not found
 * a computed flow type will be returned if only one exists.
 * @return FlowType or null if unable to determine
 */
public static FlowType getDefaultFlowType(Instruction instr, Address toAddr,
		boolean allowComputedFlowType) {

	if (!toAddr.isMemoryAddress() && !toAddr.isExternalAddress()) {
		throw new IllegalArgumentException("Unsupported toAddr address space type");
	}

	FlowType flowType = null;
	boolean simpleFlow =
		(instr.getFlowType() != RefType.INVALID && instr.getDefaultFlows().length <= 1);
	if (simpleFlow) {
		// only use default if simple flow 
		flowType = getDefaultJumpOrCallFlowType(instr);
	}

	if (flowType != null && (!flowType.isComputed() || allowComputedFlowType)) {
		return flowType;
	}

	if (simpleFlow || toAddr.isExternalAddress()) {
		// Don't bother looking if not complex flow or address is external
		return null;
	}

	// Assumption - it is assumed that any complex flow type is due to the presence of
	// multiple conditional flows.  Does not handle use of constant offsets since 
	// language should be using Address locations for all flow pcode!

	// TODO: Verify that above assumption is valid !!

	PcodeOp[] pcodeOps = instr.getPcode();
	for (PcodeOp op : pcodeOps) {
		int opcode = op.getOpcode();
		if (opcode == PcodeOp.CBRANCH || opcode == PcodeOp.BRANCH) {
			if (op.getInput(0).getAddress().equals(toAddr)) {
				return RefType.CONDITIONAL_JUMP;
			}
		}
		else if (opcode == PcodeOp.CALL) {
			if (op.getInput(0).getAddress().equals(toAddr)) {
				return RefType.CONDITIONAL_CALL;
			}
		}
	}

	if (flowType == null && allowComputedFlowType) {
		flowType = getDefaultComputedFlowType(instr);
	}
	return flowType;
}
 
Example 6
Source File: FindInvalidFlowType.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
protected void run() throws Exception {

	if (currentProgram == null) {
		return;
	}

	for (Instruction instr : currentProgram.getListing().getInstructions(currentAddress.add(1),
		true)) {

		if (instr.getFlowType() == RefType.INVALID) {

			goTo(instr.getAddress());
			return;

		}

	}

	popup("Invalid FlowType not found below current point");

}
 
Example 7
Source File: FindUnrecoveredSwitchesScript.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public void run() throws Exception {

	InstructionIterator iIter = currentProgram.getListing().getInstructions(true);

	AddressSet set = new AddressSet();

	while (iIter.hasNext()) {
		Instruction instruction = iIter.next();
		FlowType flow = instruction.getFlowType();

		if (flow.isJump() && flow.isComputed()) {
			Reference[] refs = instruction.getReferencesFrom();
			boolean hasFlowRef = false;
			for (Reference ref : refs) {
				RefType refType = ref.getReferenceType();
				if (refType.isFlow() && !refType.isFallthrough()) {
					hasFlowRef = true;
					break;
				}
			}
			if (!hasFlowRef) {
				set.addRange(instruction.getMinAddress(), instruction.getMaxAddress());
			}
		}
	}

	Address[] addresses = new Address[set.getNumAddressRanges()];
	int i = 0;
	for (AddressRange range : set) {
		addresses[i++] = range.getMinAddress();
	}

	if (SystemUtilities.isInHeadlessMode()) {
		Msg.error(
			this,
			"POSSIBLE BAD SWITCHES: The number of possible bad switches is: " +
				set.getNumAddressRanges());
	}
	else {
		this.show(addresses);

	}

}