Java Code Examples for ghidra.program.model.address.Address#getOffset()

The following examples show how to use ghidra.program.model.address.Address#getOffset() . 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: VTMatchDB.java    From ghidra with Apache License 2.0 6 votes vote down vote up
@Override
public int hashCode() {
	if (doCalculateHash) {
		hash = 17;
		Address sourceAddress = getAssociation().getSourceAddress();
		if (sourceAddress != null) {
			hash = 37 * hash + (int) sourceAddress.getOffset();
		}

		Address destinationAddress = getAssociation().getDestinationAddress();
		if (destinationAddress != null) {
			hash = 37 * hash + (int) destinationAddress.getOffset();
		}

		VTProgramCorrelatorInfo info = getMatchSet().getProgramCorrelatorInfo();
		String programCorrelatorName = info.getName();
		if (programCorrelatorName != null) {
			hash = 37 * hash + programCorrelatorName.hashCode();
		}
		doCalculateHash = false;
	}

	return hash;
}
 
Example 2
Source File: RTTI3DataType.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Gets the total length of the data created when this data type is placed at the indicated 
 * address in memory.
 * @param memory the program memory for this data.
 * @param address the start address of the data.
 * @param bytes the bytes for this data.
 * @return the length of the data. zero is returned if valid data can't be created at the 
 * indicated address using this data type.
 */
public int getLength(Memory memory, Address address, byte[] bytes) {
	// RTTI3 should start on a 4 byte boundary.
	if (address.getOffset() % 4 != 0) {
		return 0;
	}
	// RTTI3 is 16 bytes.
	if (bytes.length < LENGTH) {
		return 0;
	}

	// First 8 bytes is 2 dword numeric values.
	// Next four bytes should be number of RTTI1 pointers in RTTI2.
	long rtti1Count = getRtti1Count(memory, address);
	if (rtti1Count < 0 || rtti1Count > 500) { // For now assume we shouldn't be seeing more than 500 pointers in RTTI2.
		return 0;
	}

	// Last component is either a direct reference or an image base offset to RTTI2.
	Address rtti2Address = getRtti2Address(memory, address);
	if (!memory.contains(rtti2Address)) {
		return 0;
	}

	return LENGTH;
}
 
Example 3
Source File: PseudoDisassembler.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * If this processor uses the low bit of an address to change to a new Instruction Set mode
 *   Check the low bit and change the instruction state at the address.
 *   
 * @param program
 * @param addr the raw address
 * @return the correct address to disassemble at if it needs to be aligned
 */
public static Address setTargeContextForDisassembly(Program program, Address addr) {
	Register lowBitCodeMode = program.getRegister(LOW_BIT_CODE_MODE_REGISTER_NAME);
	if (lowBitCodeMode == null) {
		return addr;
	}
	long offset = addr.getOffset();
	if ((offset & 1) == 1) {
		addr = addr.getNewAddress(addr.getOffset() & ~0x1);
		try {
			program.getProgramContext().setValue(lowBitCodeMode, addr, addr, BigInteger.ONE);
		}
		catch (ContextChangeException e) {
			// shouldn't happen
		}
	}
	return addr;
}
 
Example 4
Source File: VxWorksSymTab_Finder.java    From ghidra with Apache License 2.0 6 votes vote down vote up
/**
 * Look before/after the table to see if there is a size value there and mark it if it agrees with TableLen
 * 
 * @param symTbl
 * @param vxSymbol
 * @param tableLen
 * @throws Exception 
 */
private void markSymbolTableLen(Address symTbl, VxSymbol vxSymbol, int symTblLen)
		throws Exception {
	// NOTE: Found an example of a VxWorks symbol table that was not
	//	      directly adjacent to the symbol table length variable...

	// Name the VxWorks symbol length variable
	// (if it appears either directly before or after the symbol table)
	Address symTblLenPtr = null;
	long foreOff = symTbl.getOffset() - 4;
	long aftOff = symTbl.getOffset() + symTblLen * vxSymbol.length();
	if (isAddress(foreOff) && getInt(toAddr(foreOff)) == symTblLen) {
		symTblLenPtr = toAddr(foreOff);
	}
	else if (isAddress(aftOff) && getInt(toAddr(aftOff)) == symTblLen) {
		symTblLenPtr = toAddr(aftOff);
	}
	if (symTblLenPtr != null) {
		removeConflictingSymbols("vxSymTblLen", symTblLenPtr);
		createLabel(symTblLenPtr, "vxSymTblLen", true);
		createDWord(symTblLenPtr);
	}
	else {
		println("Warning: Symbol Table Size not found before of after table");
	}
}
 
Example 5
Source File: SymbolRenderer.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private String getStackAddressString(Address address) {
	long offset = address.getOffset();
	if (offset < 0) {
		return "Stack[-0x" + Long.toHexString(-offset) + "]";
	}
	return "Stack[0x" + Long.toHexString(offset) + "]";
}
 
Example 6
Source File: RTTI2DataType.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the total length of the data created when this data type is placed at the indicated 
 * address in memory.
 * @param memory the program memory for this data.
 * @param address the start address of the data.
 * @param bytes the bytes for this data.
 * @return the length of the data. zero is returned if valid data can't be created at the 
 * indicated address using this data type.
 */
public int getLength(Memory memory, Address address, byte[] bytes) {
	// RTTI2 should start on a 4 byte boundary.
	if (address.getOffset() % 4 != 0) {
		return 0;
	}

	int length = 0;
	Address currentAddress = address;
	while (length + 4 < bytes.length && currentAddress != null &&
		validRefData(memory, currentAddress)) {
		currentAddress = currentAddress.add(4); // Add the data type size.
	}
	return length;
}
 
Example 7
Source File: RTTI1DataType.java    From ghidra with Apache License 2.0 5 votes vote down vote up
@Override
public boolean isValid(Program program, Address startAddress,
		DataValidationOptions validationOptions) {

	Memory memory = program.getMemory();
	Listing listing = program.getListing();

	if (!memory.contains(startAddress)) {
		return false;
	}

	Address endAddress = startAddress.add(LENGTH - 1);
	try {
		MSDataTypeUtils.getBytes(memory, startAddress, LENGTH);
	}
	catch (InvalidDataTypeException e) {
		return false; // Couldn't get enough bytes from memory for an RTTI1.
	}

	if (!validationOptions.shouldIgnoreInstructions() &&
		containsInstruction(listing, startAddress, endAddress)) {
		return false;
	}

	if (!validationOptions.shouldIgnoreDefinedData() &&
		containsDefinedData(listing, startAddress, endAddress)) {
		return false;
	}

	// RTTI1 should start on 4 byte boundary.
	if (startAddress.getOffset() % 4 != 0) {
		return false;
	}

	return validateComponents(program, startAddress, validationOptions);
}
 
Example 8
Source File: RttiUtil.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Determines the number of vf addresses in the vf table that begins at the specified base 
 * address.
 * @param program the program whose memory is providing their addresses
 * @param vfTableBaseAddress the base address in the program for the vf table
 * @return the number of virtual function addresses in the vf table
 */
static int getVfTableCount(Program program, Address vfTableBaseAddress) {

	Memory memory = program.getMemory();
	MemoryBlock textBlock = memory.getBlock(".text");
	AddressSetView initializedAddresses = memory.getLoadedAndInitializedAddressSet();
	PseudoDisassembler pseudoDisassembler = new PseudoDisassembler(program);

	// Create pointers starting at the address until reaching a 0 pointer.
	// Terminate the possible table at any entry containing a cross reference that 
	// is beyond the first table entry and don't include it.
	int tableSize = 0;
	Address currentVfPointerAddress = vfTableBaseAddress;
	int defaultPointerSize = program.getDefaultPointerSize();
	while (true) {
		Address referencedAddress = getAbsoluteAddress(program, currentVfPointerAddress);
		if (referencedAddress == null) {
			break; // Cannot get a virtual function address.
		}
		if (referencedAddress.getOffset() == 0) {
			break; // Encountered 0 entry.
		}
		if (!initializedAddresses.contains(referencedAddress)) {
			break; // Not pointing to initialized memory.
		}
		if ((textBlock != null) ? !textBlock.equals(memory.getBlock(referencedAddress))
				: false) {
			break; // Not pointing to text section.
		}
		if (!pseudoDisassembler.isValidSubroutine(referencedAddress, true)) {
			break; // Not pointing to possible function.
		}

		tableSize++; // Count this entry in the table.

		// Advance to the next table entry address.
		currentVfPointerAddress = currentVfPointerAddress.add(defaultPointerSize);
	}
	return tableSize;
}
 
Example 9
Source File: PseudoDisassembler.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Get an address that can be used for disassembly.  Useful for some processors where
 * pointers to code have 1 added to them for different modes such as Thumb mode for ARM.
 * 
 * @param program to get address from
 * @param addr to be normallized/aligned for disassembly
 * 
 * @return the normalized/aligned address for disassembly
 */
public static Address getNormalizedDisassemblyAddress(Program program, Address addr) {
	if (!addr.isMemoryAddress()) {
		return addr;
	}
	Register lowBitCodeMode = program.getRegister(LOW_BIT_CODE_MODE_REGISTER_NAME);
	if (lowBitCodeMode == null) {
		return addr;
	}
	if ((addr.getOffset() & 1) == 0) {
		return addr;
	}
	return addr.getNewAddress(addr.getOffset() & ~0x1);
}
 
Example 10
Source File: PseudoDisassembler.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * 
 * @return RegisterValue setting for the context register to disassemble correctly at the given address
 *         or null, if no setting is needed.
 */
public static RegisterValue getTargetContextRegisterValueForDisassembly(Program program,
		Address addr) {
	Register lowBitCodeMode = program.getRegister(LOW_BIT_CODE_MODE_REGISTER_NAME);
	if (lowBitCodeMode == null) {
		return null;
	}
	long offset = addr.getOffset();
	if ((offset & 1) == 1) {
		return new RegisterValue(lowBitCodeMode, BigInteger.ONE);
	}
	return null;
}
 
Example 11
Source File: PseudoDisassembler.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * In order to check a location to see if it disassembles from an address reference, the
 * address is checked for low-bit code switch behavior.  If it does switch, the context
 * is changed.
 * 
 * @param procContext context to change
 * @param addr destination address that will be disassembled (possible pseudo disassembled)
 * @return the correct disassembly location if the address needed to be adjusted.
 */

public Address setTargeContextForDisassembly(PseudoDisassemblerContext procContext,
		Address addr) {
	Register lowBitCodeMode = program.getRegister(LOW_BIT_CODE_MODE_REGISTER_NAME);
	if (lowBitCodeMode == null) {
		return addr;
	}
	long offset = addr.getOffset();
	if ((offset & 1) == 1) {
		addr = addr.getNewAddress(addr.getOffset() & ~0x1);
		procContext.setValue(lowBitCodeMode, addr, BigInteger.ONE);
	}
	return addr.getNewAddress(addr.getOffset() & ~0x1);
}
 
Example 12
Source File: RTTI4DataType.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Gets the total length of the data created when this data type is placed at the indicated 
 * address in memory.
 * @param memory the program memory for this data.
 * @param address the start address of the data.
 * @param bytes the bytes for this data.
 * @return the length of the data. zero is returned if valid data can't be created at the 
 * indicated address using this data type.
 */
public int getLength(Memory memory, Address address, byte[] bytes) {
	Program program = memory.getProgram();
	// RTTI4 should start on a 4 byte boundary.
	if (address.getOffset() % 4 != 0) {
		return 0;
	}
	// check RTTI4 length in bytes.
	if (bytes.length < LENGTH) {
		return 0;
	}

	// First 12 bytes is 3 dword numeric values.
	// Next there may be bytes to align the rtti0 pointer.

	// Next component should refer to RTTI0.
	Address rtti0CompAddress = address.add(RTTI_0_OFFSET);
	Address rtti0Address = getReferencedAddress(program, rtti0CompAddress);
	if (rtti0Address == null || !memory.contains(rtti0Address)) {
		return 0;
	}

	// Last component should refer to RTTI3.
	Address rtti3CompAddress = address.add(RTTI_3_OFFSET);
	Address rtti3Address = getReferencedAddress(program, rtti3CompAddress);
	if (rtti3Address == null || !memory.contains(rtti3Address)) {
		return 0;
	}

	return LENGTH;
}
 
Example 13
Source File: AutoTableDisassemblerPlugin.java    From ghidra with Apache License 2.0 5 votes vote down vote up
private void createDisassemblyCommandsForAddress(CompoundBackgroundCommand backCmd,
		Address currentAddress) {

	Listing listing = currentProgram.getListing();
	int align = currentProgram.getLanguage().getInstructionAlignment();

	AddressTable addrTable = model.get(currentAddress);
	Address[] elements = addrTable.getTableElements();
	for (int i = offsetLen; i < elements.length; i++) {
		Address addr = elements[i];

		// check the normalized address where disassembly will actually occur
		Address targetAddr =
			PseudoDisassembler.getNormalizedDisassemblyAddress(currentProgram, addr);
		if ((targetAddr.getOffset() % align) != 0) {
			continue; // not aligned
		}

		if (listing.getUndefinedDataAt(targetAddr) == null) {
			continue;
		}

		// need to create a context for each one.  Also disassembleCmd will align the address to disassemble
		DisassembleCommand disassembleCmd = new DisassembleCommand(addr, null, true);
		RegisterValue rval = PseudoDisassembler.getTargetContextRegisterValueForDisassembly(
			currentProgram, addr);
		disassembleCmd.setInitialContext(rval);
		backCmd.add(disassembleCmd);
	}
}
 
Example 14
Source File: GNUExternalDisassembler.java    From ghidra with Apache License 2.0 5 votes vote down vote up
/**
 * Get detailed instruction list for a block of instructions.
 * 
 * @param lang
 *            processor language (corresponding LanguageID must be defined
 *            within LanguageMap.txt)
 * @param blockAddr
 *            start of block ( must be true: (offset & -(2^blockSizeFactor)
 *            == offset)
 * @param blockSizeFactor
 *            the block size factor where blockSize = 2^blockSizeFactor
 *            (must be > 0)
 * @param byteProvider
 *            provider for block of bytes to be disassembled starting at
 *            offset 0
 * @return list of instructions or null if language not supported by GNU
 *         Disassembler
 * @throws Exception
 */
public List<GnuDisassembledInstruction> getBlockDisassembly(Language lang, Address blockAddr,
		int blockSizeFactor, ByteProvider byteProvider) throws Exception {

	GdisConfig gdisConfig = checkLanguage(lang);
	if (gdisConfig == null || gdisConfig.architecture == UNSUPPORTED) {
		return null;
	}

	if (blockSizeFactor < 0 || blockSizeFactor > 8) {
		throw new IllegalArgumentException("blockSizeFactor must be > 0 and <= 8");
	}
	int blockSize = pow2(blockSizeFactor);

	if ((blockAddr.getOffset() & -blockSize) != blockAddr.getOffset()) {
		throw new IllegalArgumentException("Address must be block aligned");
	}

	long addressOffset = blockAddr.getAddressableWordOffset();
	String address = "0x" + Long.toHexString(addressOffset);

	// for aligned languages, don't try on non-aligned block addr/size.
	int alignment = lang.getInstructionAlignment();
	if (blockAddr.getOffset() % alignment != 0) {
		throw new IllegalArgumentException(
			"Address does not satisfy instruction alignment constraint: " + alignment);
	}

	String bytes = getBytes(byteProvider, blockSize);

	return runDisassembler(gdisConfig, address, bytes);
}
 
Example 15
Source File: DemangledAddressTable.java    From ghidra with Apache License 2.0 4 votes vote down vote up
/**
 * Creates pointers from start address.
 * If a pointer already exists, then skip it and continue.
 */
private void createPointers(Program program, Address start, int count) {

	DataType pointerDt = new PointerDataType(program.getDataTypeManager());

	Listing listing = program.getListing();
	Memory mem = program.getMemory();
	DumbMemBufferImpl buf = new DumbMemBufferImpl(mem, start);

	for (int i = 0; i < count; ++i) {

		Address addr = start.add(pointerDt.getLength() * i);
		buf.setPosition(addr);

		Address refAddr = (Address) pointerDt.getValue(buf, null, -1);
		if (refAddr == null) {
			// terminate table early if unable to produce address - bytes correspond to illegal offset
			return;
		}
		if (refAddr.getOffset() == 0) {
			// skip over 0 offsets which may be a result of an unsupported relocation
			// or runtime initialized bytes
			continue;
		}

		Data d = listing.getDefinedDataAt(addr);
		if (d != null && d.isPointer()) {
			// skip locations where pointer already exists
			continue;
		}

		if (!mem.contains(refAddr)) {
			// terminate table early if pointer reference address does not exist
			// within memory (demangled address tables should only refer to entities 
			// contained within program memory).
			return;
		}

		CreateDataCmd cmd = new CreateDataCmd(addr, false, false, pointerDt);
		if (!cmd.applyTo(program)) {
			Msg.debug(this, "Unable to demangled address table pointer at " + addr + ": " +
				cmd.getStatusMsg());
			return;
		}
	}
}
 
Example 16
Source File: RTTI3DataType.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public boolean isValid(Program program, Address startAddress,
		DataValidationOptions validationOptions) {

	Memory memory = program.getMemory();
	if (!memory.contains(startAddress)) {
		return false;
	}

	// RTTI4 should start on a 4 byte boundary.
	if (startAddress.getOffset() % 4 != 0) {
		return false;
	}

	Listing listing = program.getListing();
	Address endAddress = startAddress.add(LENGTH - 1);
	try {
		MSDataTypeUtils.getBytes(memory, startAddress, LENGTH);
	}
	catch (InvalidDataTypeException e) {
		return false; // Couldn't get enough bytes from memory for an RTTI3.
	}

	if (!validationOptions.shouldIgnoreInstructions() &&
		containsInstruction(listing, startAddress, endAddress)) {
		return false;
	}

	if (!validationOptions.shouldIgnoreDefinedData() &&
		containsDefinedData(listing, startAddress, endAddress)) {
		return false;
	}

	// First 8 bytes is 2 dword numeric values.

	// Next four bytes after 2 dwords should be number of RTTI1 pointers in RTTI2.
	long rtti1Count = getRtti1Count(memory, startAddress);
	if (rtti1Count < 0 || rtti1Count > MAX_RTTI_1_COUNT) { // For now assume we shouldn't be seeing more than 1000 pointers in RTTI2.
		return false;
	}

	boolean validateReferredToData = validationOptions.shouldValidateReferredToData();

	// Last component should refer to RTTI2.
	Address rtti2Address = getRtti2Address(memory, startAddress);
	RTTI2DataType rtti2 = new RTTI2DataType(rtti1Count, program.getDataTypeManager());
	if (rtti2Address == null ||
		(validateReferredToData && !rtti2.isValid(program, rtti2Address, validationOptions))) {
		return false;
	}

	return true;
}
 
Example 17
Source File: HCS12X_ElfExtension.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public Address evaluateElfSymbol(ElfLoadHelper elfLoadHelper, ElfSymbol elfSymbol,
		Address address, boolean isExternal) {

	if (isExternal) {
		return address;
	}

	String symName = elfSymbol.getNameAsString();

	long laddr = address.getOffset();

	laddr = hcs12TranslatePagedAddress(laddr);

	Address mappedAddr = address.getNewAddress(laddr);

	return mappedAddr;
}
 
Example 18
Source File: AddressBasedLocation.java    From ghidra with Apache License 2.0 4 votes vote down vote up
private static String getStackAddressRepresentation(Address address) {
	int offset = (int) address.getOffset();
	boolean neg = (offset < 0);
	return "Stack[" + (neg ? "-" : "+") + "0x" + Integer.toHexString(neg ? -offset : offset) +
		"]";
}
 
Example 19
Source File: ArmThumbFunctionTableScript.java    From ghidra with Apache License 2.0 4 votes vote down vote up
@Override
public void 
   run() throws Exception 
   { 
      Register tmode = currentProgram.getProgramContext().getRegister("TMode"); 
      Listing lst = currentProgram.getListing(); 
      if (currentSelection != null) 
      { 
         AddressIterator addrIter = currentSelection.getAddresses(true); 
         
         while (addrIter.hasNext()) 
         { 
            Address currAddr = addrIter.next(); 
            // Only look at dword-aligned boundaries for function pointers 
            if ((currAddr.getOffset() & 3) != 0) 
            { 
               continue; 
            } 
            // Skip over entries with value 0 (null pointers) 
            long dstOffset = getInt(currAddr); 
            if (dstOffset == 0) 
            { 
               continue; 
            } 
            // Clear any defined data before applying our new type 
            if (!lst.isUndefined(currAddr,currAddr.add(3))) 
            { 
               clearListing(currAddr, currAddr.add(3)); 
            } 
            // Apply a pointer data type 
            createData(currAddr, new Pointer32DataType()); 
            // Now check out what we're pointing to 
            Reference ref = getReferencesFrom(currAddr)[0]; 
            Address refAddr = ref.getToAddress(); 
            if (!currentProgram.getMemory().contains(refAddr)) 
            { 
               continue; 
            } 
            // Decide whether this is a pointer to an ARM or Thumb function 
            BigInteger tmodeValue; 
            if ((dstOffset & 1) == 1) 
            { 
               refAddr = refAddr.subtract(1); 
               tmodeValue = BigInteger.ONE; 
            } 
            else 
            { 
               // ARM function pointers should always be dword-aligned 
               if ((dstOffset & 3) != 0) 
               { 
                  println("Warning: Invalid function pointer to " + refAddr); 
                  continue; 
               } 
               tmodeValue = BigInteger.ZERO; 
            } 
             
            // Check current TMode at referenced address 
            BigInteger currVal = 
               currentProgram.getProgramContext().getValue(tmode, refAddr, false); 
            if (currVal == null) 
            { 
               currVal = BigInteger.ZERO; 
            } 
            // If the TMode isn't set correctly, fix it here 
            if (currVal.compareTo(tmodeValue) != 0) 
            { 
               currentProgram.getProgramContext().setValue( 
                     tmode, 
                     refAddr, 
                     refAddr, 
                     tmodeValue); 
               // if TMode was wrong but there is code here, 
               // clear the flow so we can disassemble it in the right mode 
               if (!lst.isUndefined(refAddr, refAddr)) 
               { 
                  ClearFlowAndRepairCmd cmd = new ClearFlowAndRepairCmd(refAddr, true, true, false); 
                  runCommand(cmd); 
               } 
            } 
            if (lst.isUndefined(refAddr, refAddr)) 
            { 
               disassemble(refAddr); 
            } 
            if (lst.getFunctionAt(refAddr) == null) 
            { 
               createFunction(refAddr, null); 
            } 
         } 
      }    
   }
 
Example 20
Source File: IPCEmulator.java    From Ghidra-Switch-Loader with ISC License 4 votes vote down vote up
public IPCTrace emulateCommand(Address procFuncAddr, int cmd, byte[] data, int bufferSize)
{
    if (!this.hasSetup)
        return null;
    
    // We allocate a fixed 0x1000 for the buffer. Therefore we only allow adjustments to less than or equal
    // to that.
    if (bufferSize < 0 || bufferSize > 0x1000)
        throw new RuntimeException("Invalid buffer size provided");
    
    this.bufferSize = bufferSize;
    
    this.instructionHandlers.clear(); // Clear any existing instruction handlers
    this.currentTrace = new IPCTrace(cmd, procFuncAddr.getOffset());
    
    // Clear out any existing IPC message data
    byte[] zeros = new byte[(int)this.messageSize];
    this.state.setChunk(zeros, this.sLang.getDefaultSpace(), this.messagePtr, zeros.length);
    
    this.setLong(messagePtr, 0x49434653); // IPC Magic
    this.setLong(messagePtr + 0x8, cmd); // Cmd ID
    
    if (data != null && data.length > 0)
        this.state.setChunk(data, this.sLang.getDefaultSpace(), this.messagePtr + 0x10, data.length);
    
    // Set registers to point to our objects.
    // We need to do this each time to reset the state
    this.state.setValue("x0", this.targetObjectPtr);
    this.state.setValue("x1", this.ipcObjectPtr);
    this.state.setValue("x2", this.messageStructPtr);
    
    // Set to the start of the process function
    emu.setExecuteAddress(procFuncAddr);
    
    // Disassemble the proc function so we can get instructions from it
    disassembler.disassemble(procFuncAddr, null);
    
    while (true)
    {
        long pc = state.getValue("pc");
        Address pcAddr = this.sLang.getDefaultSpace().getAddress(pc);
        
        // Pre-process instructions
        for (Consumer<Long> instructionHandler : this.instructionHandlers)
        {
            instructionHandler.accept(pc);
        }
        
        if (emu.getExecuteAddress().getOffset() == 0)
        {
            break;
        }
            
        try 
        {
            emu.executeInstruction(true, TaskMonitor.DUMMY);
        } 
        catch (CancelledException | LowlevelError e) 
        {
            e.printStackTrace();
        }
    }
    
    return this.currentTrace;
}