Java Code Examples for ghidra.program.model.lang.Register#getAddress()

The following examples show how to use ghidra.program.model.lang.Register#getAddress() . 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: CreateThunkFunctionCmd.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Check if the setRegisters contains the varnode or any of its parents.
 * If a parent register has been set, then this varnode is set
 */
private static boolean containsRegister(Program program, HashSet<Varnode> setRegisters,
		Varnode regVarnode) {
	if (setRegisters.contains(regVarnode)) {
		return true;
	}
	// check the parent varnode
	Register register = program.getRegister(regVarnode);
	Register parentRegister = register.getParentRegister();
	if (parentRegister == null) {
		return false;
	}
	Varnode parentVarnode =
		new Varnode(parentRegister.getAddress(), parentRegister.getBitLength() / 8);
	return setRegisters.contains(parentVarnode);
}
 
Example 2
Source File: ResultsState.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * 
 * @return Varnode that represents the stack pointer register
 */
public Varnode getStackPointerVarnode() {
	if (stackVarnode != null) {
		return stackVarnode;
	}

	// figure out what register is used for return values, it must be assumed to be unknown upon return.
	Register stackReg = program.getCompilerSpec().getStackPointer();
	if (stackReg == null) {
		return null;
	}

	stackVarnode = new Varnode(stackReg.getAddress(), stackReg.getMinimumByteSize());
	return stackVarnode;
}
 
Example 3
Source File: MemoryState.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private Varnode getVarnode(Register reg) {
	Varnode varnode = regVarnodeCache.get(reg);
	if (varnode == null) {
		varnode = new Varnode(reg.getAddress(), reg.getMinimumByteSize());
		regVarnodeCache.put(reg, varnode);
	}
	return varnode;
}
 
Example 4
Source File: ResultsState.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private boolean isPreserved(Register reg) {
	Varnode v = new Varnode(reg.getAddress(), reg.getMinimumByteSize());
	Set<Varnode> returnValues = getReturnValues(v);
	if (returnValues.isEmpty()) {
		// TODO: Register was modified but value appears to be unknown ??
		return false;
	}
	for (Varnode val : returnValues) {
		if (!v.equals(val)) {
			return false;
		}
	}
	return true;
}
 
Example 5
Source File: CodeUnitFormat.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private boolean registersOverlap(Register reg1, Register reg2) {
	if (reg1 == null || reg2 == null) {
		return false;
	}
	Address reg1MinAddr = reg1.getAddress();
	Address reg2MinAddr = reg2.getAddress();

	Address reg1MaxAddr = reg1MinAddr;
	int size = reg1.getMinimumByteSize();
	if (size > 1) {
		reg1MaxAddr = reg1MinAddr.add(size - 1);
	}
	if (reg2MinAddr.compareTo(reg1MaxAddr) > 0) {
		return false;
	}
	if (reg1MaxAddr.compareTo(reg2MinAddr) < 0) {
		return false;
	}

	Address reg2MaxAddr = reg2MinAddr;
	size = reg1.getMinimumByteSize();
	if (size > 1) {
		reg2MaxAddr = reg2MinAddr.add(size - 1);
	}
	if (reg1MinAddr.compareTo(reg2MaxAddr) > 0) {
		return false;
	}
	if (reg2MaxAddr.compareTo(reg1MinAddr) < 0) {
		return false;
	}

	return true;
}
 
Example 6
Source File: StorageAddressModel.java    From ghidra with Apache License 2.0 5 votes vote down vote up
void setVarnode(VarnodeInfo info, Register reg) {
	Address addr = reg.getAddress();
	int size;
	int currentSize = getCurrentSize();
	int regSize = reg.getBitLength() / 8;
	if (unconstrained) {
		setVarnode(info, addr, regSize);
		return;
	}
	Integer curVarnodeSize = info.getSize();
	if (reg.hasChildren() || curVarnodeSize == null || regSize < curVarnodeSize ||
		currentSize < requiredSize) {
		size = reg.getBitLength() / 8;
		if (curVarnodeSize != null) {
			currentSize -= curVarnodeSize;
		}
		if (currentSize < requiredSize) {
			size = Math.min(size, requiredSize - currentSize);
		}
	}
	else {
		size = curVarnodeSize;
	}
	if (reg.isBigEndian()) {
		// adjust address for big endian register
		int s = Math.min(reg.getMinimumByteSize(), size);
		addr = addr.add(reg.getMinimumByteSize() - s);
	}
	setVarnode(info, addr, size);

}
 
Example 7
Source File: OldFunctionDataDB.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private Parameter getRegisterParameter(Record record, int ordinal) {
	String name = record.getString(OldRegisterVariableDBAdapter.REG_VAR_NAME_COL);
	long dataTypeId =
		record.getLongValue(OldRegisterVariableDBAdapter.REG_VAR_DATA_TYPE_ID_COL);
	String regName = record.getString(OldRegisterVariableDBAdapter.REG_VAR_REGNAME_COL);

	DataType dataType = functionManager.getDataType(dataTypeId);

	try {
		VariableStorage storage = VariableStorage.BAD_STORAGE;
		Register register =
			functionManager.getProgram().getProgramContext().getRegister(regName);
		if (register == null) {
			Msg.error(this, "Invalid parameter, register not found: " + regName);
		}
		else {
			storage = new VariableStorage(program, register.getAddress(), dataType.getLength());
		}
		return new OldFunctionParameter(name, ordinal, dataType, storage, program,
			SourceType.USER_DEFINED);
	}
	catch (InvalidInputException e) {
		Msg.error(this,
			"Invalid parameter '" + name + "' in function at " + entryPoint.toString());
		try {
			return new OldFunctionParameter(name, ordinal, dataType,
				VariableStorage.BAD_STORAGE, program, SourceType.USER_DEFINED);
		}
		catch (InvalidInputException e1) {
			// should not occur
			throw new RuntimeException(e1);
		}
	}
}
 
Example 8
Source File: VariableStorage.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Determine if this storage intersects the specified register
 * @param reg the register
 * @return true if this storage intersects the specified register
 */
public boolean intersects(Register reg) {
	if (varnodes == null || reg == null) {
		return false;
	}
	Varnode regVarnode = new Varnode(reg.getAddress(), reg.getMinimumByteSize());
	for (int i = 0; i < varnodes.length; i++) {
		if (varnodes[i].intersects(regVarnode)) {
			return true;
		}
	}
	return false;
}
 
Example 9
Source File: SimpleDiffUtility.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Convert a varnode from the specified program to a comparable varnode in the
 * specified otherProgram.  Certain varnode addresses spaces (UNIQUE, HASH) will
 * always produce a null return varnode.
 * @param program program which contains the specified address instance
 * @param varnode varnode in program
 * @param otherProgram other program
 * @return varnode for otherProgram or null if varnode can not be mapped to other program
 */
public static Varnode getCompatibleVarnode(Program program, Varnode varnode,
		Program otherProgram) {
	if (varnode == null || varnode.isConstant()) {
		return varnode;
	}
	Address addr = varnode.getAddress();
	if (addr.isRegisterAddress()) {
		if (program.getLanguageID().equals(otherProgram.getLanguageID())) {
			return varnode;
		}
		// TODO: Handle improperly aligned offcut register varnodes.
		Register reg = program.getRegister(addr, varnode.getSize());
		if (reg != null) {
			Register otherReg = otherProgram.getRegister(reg.getName());
			if (otherReg != null && reg.getMinimumByteSize() == otherReg.getMinimumByteSize()) {
				long delta = addr.subtract(reg.getAddress());
				if (delta != 0) {
					return new Varnode(otherReg.getAddress().add(delta), varnode.getSize());
				}
				return new Varnode(otherReg.getAddress(), varnode.getSize());
			}
		}
		return null;
	}
	else if (addr.isMemoryAddress() || addr.isStackAddress()) {
		Address otherAddr = getCompatibleAddress(program, addr, otherProgram);
		if (otherAddr != null) {
			return new Varnode(otherAddr, varnode.getSize());
		}
	}
	return null;
}
 
Example 10
Source File: VariableImpl.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Construct a variable.  Only one storage/location may be specified (storage, storageAddr,
 * stackOffset, register) - all others should be null.  If no storage/location is specified
 * or is UNASSIGNED, a Void data type may be specified and will be assumed if this type returns
 * true for {@link #isVoidAllowed()}.
 * @param name variable name
 * @param dataType a fixed-length datatype.  (NOTE: Should be cloned to program datatype manager
 * prior to determining storage elements since their length may change)
 * @param storage variable storage or null for unassigned storage (may be null)
 * @param storageAddr storage address or null if no storage has been identified (may be null)
 * @param stackOffset signed stack offset (may be null)
 * @param register register storage (may be null)
 * @param force if true storage will be forced even if mismatch with datatype size
 * @param program target program
 * @param sourceType source type
 * @throws InvalidInputException if dataType restrictions are violated or an error occurs while 
 * resolving storage for specified datatype
 * @throws AddressOutOfBoundsException if invalid stack offset specified
 */
VariableImpl(String name, DataType dataType, VariableStorage storage, Address storageAddr,
		Integer stackOffset, Register register, boolean force, Program program,
		SourceType sourceType) throws InvalidInputException {

	checkUsage(storage, storageAddr, stackOffset, register);
	checkProgram(program);

	this.program = program;
	this.name = name;

	if (storage == null) {
		if (register != null) {
			this.dataType = VariableUtilities.checkDataType(dataType, false,
				register.getMinimumByteSize(), program);
			int size = this.dataType.getLength();
			storageAddr = register.getAddress();
			int regSize = register.getMinimumByteSize();
			if (regSize < size) { // datatype larger than register
				if (!force) {
					throw new InvalidInputException("Register '" + register.getName() +
						"' size too small for specified data type size: " +
						dataType.getLength());
				}
				// allow size mismatch if forced and bypass normal storage computation
				this.variableStorage = new VariableStorage(program, register);
				return;
			}
			else if (register.isBigEndian() && regSize > size) {
				storageAddr = storageAddr.add(regSize - size);
			}
		}
		else {
			if (stackOffset != null) {
				storageAddr =
					program.getAddressFactory().getStackSpace().getAddress(stackOffset);
			}
			this.dataType = VariableUtilities.checkDataType(dataType,
				storageAddr == null && isVoidAllowed(), 1, program);
		}
		this.variableStorage = computeStorage(storageAddr);
	}
	else {
		this.dataType = VariableUtilities.checkDataType(dataType,
			(storage.isVoidStorage() || storage.isUnassignedStorage()) && isVoidAllowed(),
			storage.size(), program);
		VariableUtilities.checkStorage(storage, this.dataType, force);
		this.variableStorage = storage;
	}

	this.sourceType = hasDefaultName() ? SourceType.DEFAULT : sourceType;
}
 
Example 11
Source File: ShowConstantUse.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private HighSymbol computeVariableLocation(Program currProgram, ProgramLocation location) {
	HighSymbol highVar = null;
	Address storageAddress = null;

	// make sure what we are over can be mapped to decompiler
	// param, local, etc...

	if (location instanceof VariableLocation) {
		VariableLocation varLoc = (VariableLocation) location;
		storageAddress = varLoc.getVariable().getMinAddress();
	}
	else if (location instanceof FunctionParameterFieldLocation) {
		FunctionParameterFieldLocation funcPFL = (FunctionParameterFieldLocation) location;
		storageAddress = funcPFL.getParameter().getMinAddress();
	}
	else if (location instanceof OperandFieldLocation) {
		OperandFieldLocation opLoc = (OperandFieldLocation) location;
		int opindex = opLoc.getOperandIndex();
		if (opindex >= 0) {
			Instruction instr = currProgram.getListing().getInstructionAt(opLoc.getAddress());
			if (instr != null) {
				Register reg = instr.getRegister(opindex);
				if (reg != null) {
					storageAddress = reg.getAddress();
				}
			}
		}
	}

	if (storageAddress == null) {
		return null;
	}

	Address addr = currentLocation.getAddress();
	if (addr == null) {
		return null;
	}

	Function f = currProgram.getFunctionManager().getFunctionContaining(addr);
	if (f == null) {
		return null;
	}

	DecompileResults results = decompileFunction(f, decomplib);

	HighFunction hf = results.getHighFunction();
	if (hf == null) {
		return null;
	}

	// try to map the variable
	highVar = hf.getMappedSymbol(storageAddress, f.getEntryPoint().subtractWrap(1L));
	if (highVar == null) {
		highVar = hf.getMappedSymbol(storageAddress, null);
	}
	if (highVar == null) {
		highVar = hf.getMappedSymbol(storageAddress, f.getEntryPoint());
	}

	if (highVar != null) {
		// fixupParams(results, location.getAddress());
	}

	return highVar;
}
 
Example 12
Source File: SimpleDiffUtility.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
	 * Convert an address from the specified program to a comparable address in the
	 * specified otherProgram.
	 * @param program program which contains the specified address instance
	 * @param addr address in program
	 * @param otherProgram other program
	 * @return address for otherProgram or null if no such address exists.
	 */
	public static Address getCompatibleAddress(Program program, Address addr,
			Program otherProgram) {
		if (addr == null) {
			return null;
		}
		if (addr.isMemoryAddress()) {
			return translateMemoryAddress(addr, otherProgram, true);
		}
		else if (addr.isVariableAddress()) {
// TODO: We should not attempt to correlate variables by their variable address
			throw new IllegalArgumentException(
				"correlation of variables by their variable address not allowed");
//          Address storageAddr = program.getVariableStorageManager().getStorageAddress(addr);
//          if (storageAddr == null) {
//              return null;
//          }
//          Address otherStorageAddr = getCompatibleAddress(program, storageAddr, otherProgram);
//          if (otherStorageAddr == null) {
//              return null;
//          }
//
//          Namespace namespace = program.getVariableStorageManager().getNamespace(addr);
//          Namespace otherNamespace = getNamespace(program, namespace, otherProgram);
//          if (otherNamespace == null) {
//              return null;
//          }
//          return otherProgram.getVariableStorageManager().findVariableAddress(otherNamespace.getID(), otherStorageAddr);
		}
		else if (addr.isStackAddress()) {
			return otherProgram.getAddressFactory().getStackSpace().getAddress(addr.getOffset());
		}
		else if (addr.isRegisterAddress()) {
			if (program.getLanguage().getLanguageID().equals(
				otherProgram.getLanguage().getLanguageID())) {
				return addr;
			}
			// TODO: should we handle small varnodes within big endian registers
			Register reg = program.getRegister(addr);
			if (reg != null) {
				Register otherReg = otherProgram.getRegister(reg.getName());
				if (otherReg != null && reg.getMinimumByteSize() == otherReg.getMinimumByteSize()) {
					long delta = addr.subtract(reg.getAddress());
					if (delta != 0) {
						return otherReg.getAddress().add(delta);
					}
					return otherReg.getAddress();
				}
			}
			return null;
		}
		else if (addr.isExternalAddress()) {
			Symbol s = program.getSymbolTable().getPrimarySymbol(addr);
			if (s != null && s.isExternal()) {
				s = getSymbol(s, otherProgram);
				if (s != null) {
					return s.getAddress();
				}
			}
			return null;
		}
		else if (addr.getAddressSpace().getType() == AddressSpace.TYPE_NONE ||
			addr.getAddressSpace().getType() == AddressSpace.TYPE_UNKNOWN) {
// TODO: Not sure if this is correct ??
			return addr;
		}
		throw new IllegalArgumentException("Unsupported address type");
	}
 
Example 13
Source File: Pic12Analyzer.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Attempt to markup FReg access instruction with register reference.
 * 
 * @param instr
 * @return register name if identified, else null
 */
private String markupFRegInstruction(Instruction instr) {
	Object[] objs = instr.getOpObjects(0);
	if (objs.length != 1) {
		return null;
	}

	Address addr;
	Register reg = null;
	if (objs[0] instanceof Register) {
		reg = ((Register) objs[0]);
		addr = reg.getAddress();
	}
	else if (objs[0] instanceof Address) {
		addr = (Address) objs[0];
		reg = program.getRegister(addr, 1);
	}
	else if (objs[0] instanceof Scalar) {
		long offset = ((Scalar) objs[0]).getUnsignedValue();
		if ((offset & 0x1f) >= 0x10) {
			if (!fsrContext.hasValue()) {
				return null;
			}
			offset = (fsrContext.longValue() & 0x60) + offset;
		}
		addr = program.getAddressFactory().getAddressSpace("DATA").getAddress(offset);
		reg = program.getRegister(addr);
	}
	else {
		return null;
	}

	// Determine RefType
	String mnemonic = instr.getMnemonicString();
	RefType refType = RefType.READ;
	if ("CLRF".equals(mnemonic) || "MOVWF".equals(mnemonic)) {
		refType = RefType.WRITE;
	}
	else if (FREG_BIT_INSTRUCTIONS.contains(mnemonic)) {
		if ("BCF".equals(mnemonic) || "BSF".equals(mnemonic)) {
			refType = RefType.READ_WRITE;
		}
	}
	else if (instr.getNumOperands() == 2) {
		List<?> repObjs = instr.getDefaultOperandRepresentationList(1);
		if (repObjs.size() == 1 && DEST_FREG.equals(repObjs.get(0))) {
			refType = RefType.READ_WRITE;
		}
	}

	if (statusReg.equals(reg)) {
		addr = status0Reg.getAddress();
	}
	else if (fsrReg.equals(reg)) {
		addr = fsr0Reg.getAddress();
	}
	else if (pclReg.equals(reg)) {
		addr = pcl0Reg.getAddress();
	}

	if (addr.isMemoryAddress()) {
		refMgr.addMemoryReference(instr.getMinAddress(), addr, refType, SourceType.DEFAULT, 0);
	}

	return reg != null ? reg.getName() : null;
}
 
Example 14
Source File: Pic18Analyzer.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
	 * Attempt to markup FReg access instruction with register reference.
	 * 
	 * @param instr
	 * @return register name if identified, else null
	 */
	private String markupFRegInstruction(Instruction instr, int opIndex, RefType refType) {
		Object[] objs = instr.getOpObjects(opIndex);
		if (objs.length != 1) {
			return null;
		}

		Address addr;
		Register reg = null;
		if (objs[0] instanceof Register) {
			reg = ((Register) objs[0]);
			addr = reg.getAddress();
		}
		else if (objs[0] instanceof Address) {
			addr = (Address) objs[0];
			reg = program.getRegister(addr, 1);
		}
		else if (objs[0] instanceof Scalar) {

//			long offset = ((Scalar)objs[0]).getUnsignedValue();
//			Object[] accessObjs = instr.getOpObjects(instr.getNumOperands()-1);
//			if (objs.length == 1 && "BANKED".equals(accessObjs[0])) {
//				// BANKED mode
//				if (bsrSetAddr == null || !(objs[0] instanceof Scalar)) {
//					return null;
//				}
//				offset += ((long)(bsrVal & 0x0f) << 8);
//			}
//			else {
//				// ACCESS mode
//				offset = ((Scalar)objs[0]).getUnsignedValue();
//			}

			if (!bsrContext.hasValue() || !(objs[0] instanceof Scalar)) {
				return null;
			}
			long offset =
				((bsrContext.longValue() & 0x0f) << 8) + ((Scalar) objs[0]).getUnsignedValue();
			addr = program.getAddressFactory().getAddressSpace("DATA").getAddress(offset);
			reg = program.getRegister(addr);
		}
		else {
			return null;
		}

		// Determine RefType
		String mnemonic = instr.getMnemonicString();
		if (refType == null) {
			refType = RefType.READ;
			if ("CLRF".equals(mnemonic) || "MOVWF".equals(mnemonic) || "LFSR".equals(mnemonic)) {
				refType = RefType.WRITE;
			}
			else if (FREG_BIT_INSTRUCTIONS.contains(mnemonic)) {
				if ("BCF".equals(mnemonic) || "BSF".equals(mnemonic)) {
					refType = RefType.READ_WRITE;
				}
			}
			else if (opIndex == 0 && instr.getNumOperands() == 3) {
				// Detect read/write update of register
				List<?> repObjs = instr.getDefaultOperandRepresentationList(1);
				if (repObjs.size() == 1 && DEST_FREG.equals(repObjs.get(0))) {
					refType = RefType.READ_WRITE;
				}
			}
		}

		if (stkptrReg.equals(reg)) {
			addr = stkptr0Reg.getAddress();
		}

		if (addr.isMemoryAddress()) {
			refMgr.addMemoryReference(instr.getMinAddress(), addr, refType, SourceType.ANALYSIS,
				opIndex);
		}

		return reg != null ? reg.getName() : null;
	}
 
Example 15
Source File: VarnodeTranslator.java    From ghidra with Apache License 2.0 2 votes vote down vote up
/**
 * Get a varnode that maps to the given register
 * 
 * @param register
 *            register to translate into a varnode
 * @return varnode that reprents the register
 */
public Varnode getVarnode(Register register) {
	Varnode node = new Varnode(register.getAddress(), register.getMinimumByteSize());
	return node;
}
 
Example 16
Source File: MemoryState.java    From ghidra with Apache License 2.0 2 votes vote down vote up
/**
 * A convenience method for reading a value directly from a register rather
 * than querying for the offset and space
 * @param reg the register location to be read
 * @return the unsigned value read from the register location
 */
public final BigInteger getBigInteger(Register reg) {
	Address addr = reg.getAddress();
	return getBigInteger(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(),
		false);
}
 
Example 17
Source File: MemoryState.java    From ghidra with Apache License 2.0 2 votes vote down vote up
/**
 * A convenience method for setting a value directly on a register rather than
 * breaking out the components
 * @param reg the register location to be written
 * @param cval the value to write into the register location
 */
public final void setValue(Register reg, BigInteger cval) {
	Address addr = reg.getAddress();
	setValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(), cval);
}
 
Example 18
Source File: MemoryState.java    From ghidra with Apache License 2.0 2 votes vote down vote up
/**
 * A convenience method for reading a value directly from a register rather
 * than querying for the offset and space
 * @param reg the register location to be read
 * @return the value read from the register location
 */
public final long getValue(Register reg) {
	Address addr = reg.getAddress();
	return getValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize());
}
 
Example 19
Source File: MemoryState.java    From ghidra with Apache License 2.0 2 votes vote down vote up
/**
 * A convenience method for setting a value directly on a register rather than
 * breaking out the components
 * @param reg the register location to be written
 * @param cval the value to write into the register location
 */
public final void setValue(Register reg, long cval) {
	Address addr = reg.getAddress();
	setValue(addr.getAddressSpace(), addr.getOffset(), reg.getMinimumByteSize(), cval);
}