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

The following examples show how to use ghidra.program.model.lang.Register#getMinimumByteSize() . 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: 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 2
Source File: VariableImpl.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private Varnode expandVarnode(Varnode varnode, int sizeIncrease, VariableStorage curStorage,
		int newSize, DataType type) throws InvalidInputException {

	Address addr = varnode.getAddress();
	if (addr.isStackAddress()) {
		return resizeStackVarnode(varnode, varnode.getSize() + sizeIncrease, curStorage,
			newSize, type);
	}
	int size = varnode.getSize() + sizeIncrease;
	boolean bigEndian = program.getMemory().isBigEndian();
	Register reg = program.getRegister(varnode);
	Address vnAddr = varnode.getAddress();
	if (reg != null) {
		// Register expansion
		Register newReg = reg;
		while ((newReg.getMinimumByteSize() < size)) {
			newReg = newReg.getParentRegister();
			if (newReg == null) {
				throw new InvalidInputException("Current storage can't be expanded to " +
					newSize + " bytes: " + curStorage.toString());
			}
		}
		if (bigEndian) {
			vnAddr = vnAddr.add(newReg.getMinimumByteSize() - size);
			return new Varnode(vnAddr, size);
		}
	}
	boolean complexDt = (type instanceof Composite) || (type instanceof Array);
	if (bigEndian && !complexDt) {
		return new Varnode(vnAddr.subtract(sizeIncrease), size);
	}
	return new Varnode(vnAddr, size);
}
 
Example 3
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 4
Source File: VariableStorage.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Translate register varnode address offsetStr
 * @param translator
 * @param space
 * @param offsetStr
 * @param sizeStr
 * @return translated offsetStr or null if BAD translation
 */
private static String translateRegisterVarnodeOffset(Address oldRegAddr, int varnodeSize,
		LanguageTranslator translator, AddressSpace newRegisterSpace) {
	// Handle register movement within register space only
	// Assumes all translators will map register space properly
	// If old or new register not found no adjustment is made
	// The original addrStr may refer to an offcut location within a register 
	long offset = oldRegAddr.getOffset();
	Register oldReg = translator.getOldRegister(oldRegAddr, varnodeSize);
	if (oldReg == null) {
		// possible offcut register varnode
		oldReg = translator.getOldRegisterContaining(oldRegAddr);
	}
	if (oldReg != null && !(oldReg instanceof UnknownRegister)) {
		Register newReg = translator.getNewRegister(oldReg);
		if (newReg != null) { // assume reg endianess unchanged
			// NOTE: could produce bad results if not careful with mapping
			int origByteShift = (int) offset - oldReg.getOffset();
			offset = newReg.getOffset() + origByteShift;
			if (newReg.isBigEndian()) {
				// maintain right alignment for BE
				int regSizeDiff = newReg.getMinimumByteSize() - oldReg.getMinimumByteSize();
				offset += regSizeDiff;
				if (offset < newReg.getOffset()) {
					return null; // BE - did not fit
				}
			}
			else if ((origByteShift + varnodeSize) > newReg.getMinimumByteSize()) {
				return null; // LE - did not fit
			}
			return Long.toHexString(offset);
		}
	}
	return null; // translation failed
}
 
Example 5
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 6
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 7
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 8
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 9
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 10
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 11
Source File: PcodeFormatter.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private void formatAddress(Program program, AddressSpace addrSpace, ConstTpl offset,
		ConstTpl size, List<AttributedString> lineList) {
	if (offset.getType() != ConstTpl.REAL) {
		throw new RuntimeException("Unsupported address offset type: " + offset.getType());
	}

	long offsetValue = offset.getReal();
	if (addrSpace == null) {
		lineList.add(STAR);
		lineList.add(new AttributedString("0x" + Long.toHexString(offsetValue), addressColor,
			metrics));
		if (size.getType() != ConstTpl.J_CURSPACE_SIZE) {
			formatSize(size, lineList);
		}
		return;
	}

	int sizeValue = (int) size.getReal();
	Register reg = program.getRegister(addrSpace.getAddress(offsetValue), sizeValue);
	if (reg != null) {
		lineList.add(new AttributedString(reg.getName(), registerColor, metrics));
		if (reg.getMinimumByteSize() > sizeValue) {
			lineList.add(COLON);
			lineList.add(new AttributedString(Integer.toString(sizeValue), this.scalarColor, metrics));
		}
		return;
	}
	lineList.add(STAR);
	lineList.add(LEFT_BRACKET);
	lineList.add(new AttributedString(addrSpace.getName(), Color.BLUE, metrics));
	lineList.add(RIGHT_BRACKET);
	
	long wordOffset = offsetValue / addrSpace.getAddressableUnitSize();
	long offcut = offsetValue % addrSpace.getAddressableUnitSize();
	String str = "0x" + Long.toHexString(wordOffset);
	if (offcut != 0) {
		str += "." + offset;
	}
	lineList.add(new AttributedString(str, addressColor, metrics));
	formatSize(size, lineList);
}
 
Example 12
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;
}