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

The following examples show how to use ghidra.program.model.listing.Instruction#getPcode() . 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: PseudoDisassembler.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Make sure the instruction really has a return in it.
 * 
 * @param instr instruction to check
 */
private boolean isReallyReturn(Instruction instr) {
	PcodeOp[] pcode = instr.getPcode();
	for (int i = 0; i < pcode.length; i++) {
		if (pcode[i].getOpcode() == PcodeOp.RETURN) {
			return true;
		}
	}
	return false;
}
 
Example 2
Source File: DynamicHash.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Given a constant value accessed as an operand by a particular instruction,
 * calculate a (level 0) hash for (any) corresponding constant varnode
 * @param instr is the instruction referencing the constant
 * @param value of the constant
 * @return array of hash values (may be zero length)
 */
public static long[] calcConstantHash(Instruction instr,long value) {
	long[] tmp = new long[2];
	int count = 0;
	for (PcodeOp op : instr.getPcode(true)) {
		Varnode[] inputs = op.getInputs();
		for (int i = 0; i < inputs.length; i++) {
			if (inputs[i].isConstant() &&
				matchWithPossibleExtension(inputs[i].getOffset(), inputs[i].getSize(), value)) {
				if (count >= tmp.length) {
					long[] newtmp = new long[count + 10];
					for(int j=0;j<tmp.length;++j) {
						newtmp[j] = tmp[j];
					}
					tmp = newtmp;
				}
				DynamicHash dynamicHash = new DynamicHash(op,i);
				tmp[count] = dynamicHash.getHash();
				if (tmp[count] != 0) {
					count += 1;
				}
			}
		}
	}
	long[] res = new long[count];
	for(int i=0;i<count;++i) {
		res[i] = tmp[i];
	}
	return res;
}
 
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: ConstantPropagationContextEvaluator.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
    * If you override this method, and the default behavior of checking 0-256 and mask values is desired,
    * call super.evaluateReference() in your overriden method.
    */
@Override
public boolean evaluateReference(VarnodeContext context, Instruction instr,
		int pcodeop, Address address, int size, RefType refType) {
	// unless this is a direct address copy, don't trust computed accesses below minStoreLoadOffset
	//     External spaces can have low addresses... so don't check them
	AddressSpace space = address.getAddressSpace();
	if (space.isExternalSpace()) {
		return true;
	}

	long maxAddrOffset = space.getMaxAddress().getAddressableWordOffset();
	long wordOffset = address.getAddressableWordOffset();
	boolean isKnownReference = !address.isConstantAddress();

	if (pcodeop != PcodeOp.COPY && ((wordOffset >= 0 && wordOffset < minStoreLoadOffset) ||
		(Math.abs(maxAddrOffset - wordOffset) < minStoreLoadOffset))) {
		if (!isKnownReference) {
			return false;
		}
		PcodeOp[] pcode = instr.getPcode();
		if (pcode.length > 1) { // for simple pcode, assume it is a good location.
			return false;
		}
	}
	
	return true;
}
 
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: RefTypeFactory.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private static RefType getMemRefType(Instruction instr, Address memAddr) {

		long memOffset = memAddr.getAddressableWordOffset();

		RefType refType = null;
		Varnode offsetVarnode = null;
		Varnode valueVarnode = null;
		for (PcodeOp op : instr.getPcode()) {
			Varnode[] inputs = op.getInputs();
			if (op.getOpcode() == PcodeOp.INT_ZEXT || op.getOpcode() == PcodeOp.COPY) {
				if (inputs[0].isConstant() && inputs[0].getOffset() == memOffset) {
					offsetVarnode = op.getOutput();
					refType = RefType.DATA;
					continue;
				}
			} // TODO: Could track copy of offsetVarnode thus producing multiple offsetVarnodes
			if (op.getOpcode() == PcodeOp.STORE) {
				if (memAddr.getAddressSpace().getUnique() == inputs[0].getSpace() &&
					(memOffset == inputs[1].getOffset() || inputs[1].equals(offsetVarnode))) {
					if (refType != null && refType.isRead()) {
						return RefType.READ_WRITE;
					}
					refType = RefType.WRITE;
				}
			}
			else if (op.getOpcode() == PcodeOp.LOAD) {
				if (memAddr.getAddressSpace().getUniqueSpaceID() == inputs[0].getOffset() &&
					(memOffset == inputs[1].getOffset() || inputs[1].equals(offsetVarnode))) {
					if (refType != null && refType.isWrite()) {
						return RefType.READ_WRITE;
					}
					refType = RefType.READ;
					valueVarnode = op.getOutput();
				}
			}
			else {
				for (Varnode in : inputs) {
					if (refType == null && in.isConstant() && in.getOffset() == memOffset) {
						refType = RefType.DATA;
					}
					// changed to only compare the address offsets because of problem with overlay spaces
					// probably should look into why one is in an overlay and the other isn't when
					// they should match
					else if (in.isAddress() && in.getAddress().getOffset() == memAddr.getOffset()) {
						if (refType != null && refType.isWrite()) {
							return RefType.READ_WRITE;
						}
						refType = RefType.READ;
					}
				}
			}
			if (valueVarnode != null && isFlowOp(op) && valueVarnode.equals(inputs[0])) {
				return RefType.INDIRECTION;
			}
		}
		return refType;
	}