Class PseudoDisassembler

java.lang.Object
ghidra.app.util.PseudoDisassembler

public class PseudoDisassembler extends Object
PseudoDisassembler.java Useful for disassembling and getting an Instruction or creating Data at a location in memory when you don't want the program to be changed. The Instructions or Data that area created are PseudoInstruction's and PseudoData's. They act like regular instructions in most respects, but they don't exist in the program. No references, symbols, are created or will be saved when the program is saved. You do not need to have an open transaction on the program to use the PseudoDisassembler. The PseudoDisassembler can also be used to check if something is a valid subroutine. The algorithm it uses could definitely use some tuning, but it generally works well.
  • Constructor Details

    • PseudoDisassembler

      public PseudoDisassembler(Program program)
      Create a pseudo disassembler for the given program.
  • Method Details

    • setMaxInstructions

      public void setMaxInstructions(int maxNumInstructions)
      Set the maximum number of instructions to check
      Parameters:
      maxNumInstructions - - maximum number of instructions to check before returning
    • getLastCheckValidInstructionCount

      public int getLastCheckValidInstructionCount()
      Get the last number of disassembled instructions or the number of initial contiguous instruction if requireContiguous is true
    • setRespectExecuteFlag

      public void setRespectExecuteFlag(boolean respect)
      Set flag to respect Execute bit on memory if present on any memory
      Parameters:
      respect - - true, respect execute bit on memory blocks
    • disassemble

      Disassemble a single instruction. The program is not affected.
      Parameters:
      addr - location to disassemble
      Returns:
      a PseudoInstruction
      Throws:
      InsufficientBytesException
      UnknownInstructionException
      UnknownContextException
    • disassemble

      public PseudoInstruction disassemble(Address addr, PseudoDisassemblerContext disassemblerContext, boolean isInDelaySlot) throws InsufficientBytesException, UnknownInstructionException, UnknownContextException
      Disassemble a single instruction. The program is not affected.
      Parameters:
      addr -
      disassemblerContext -
      isInDelaySlot -
      Returns:
      Throws:
      InsufficientBytesException
      UnknownInstructionException
      UnknownContextException
    • disassemble

      Disassemble a location in memory with the given set of bytes. Useful when the address has no actual bytes defined, or you want to use your own bytes instead of what is in the program at the address.
      Parameters:
      addr - address to disassemble
      bytes - bytes to use instead of those currently defined in program
      Returns:
      PseudoInstruction.
      Throws:
      InsufficientBytesException
      UnknownInstructionException
      UnknownContextException
    • disassemble

      Disassemble a location in memory with the given set of bytes. Useful when the address has no actual bytes defined, or you want to use your own bytes instead of what is in the program at the address.
      Parameters:
      addr - address to disassemble
      bytes - bytes to use instead of those currently defined in program
      disassemblerContext - the disassembler context to use.
      Returns:
      PseudoInstruction.
      Throws:
      InsufficientBytesException
      UnknownInstructionException
      UnknownContextException
    • applyDataType

      public PseudoData applyDataType(Address addr, DataType dt)
      Apply a dataType to the program at the given address. The program is not affected. A PseudoData item that acts like a Data item retrieved from a program is returned. This is useful if you have a datatype and you want to use it to get values from the program at a given address.
      Parameters:
      addr - location to get a PseudoData item for
      dt - the data type to be applied
      Returns:
      PseudoData that acts like Data
    • getIndirectAddr

      public Address getIndirectAddr(Address toAddr)
      Interpret the bytes at a location in memory as an address and return the address. This routine assumes that the bytes needed to create the address are the same size as the bytes needed to represent the toAddr. So this is somewhat generic.
      Parameters:
      toAddr - location of the bytes in memory
      Returns:
      the address value
    • isValidSubroutine

      public boolean isValidSubroutine(Address entryPoint)
      Check that this entry point leads to a well behaved subroutine:
      • It should return.
      • Hit no bad instructions.
      • Have only one entry point.
      • Not overlap any existing data or instructions.
      Parameters:
      entryPoint - entry point to check
      Returns:
      true if entry point leads to a well behaved subroutine
    • isValidSubroutine

      public boolean isValidSubroutine(Address entryPoint, boolean allowExistingCode)
      Check that this entry point leads to a well behaved subroutine, allow it to fall into existing code.
      • It should return.
      • Hit no bad instructions.
      • Have only one entry point.
      • Not overlap any existing data or cause offcut references.
      Parameters:
      entryPoint - entry point to check
      allowExistingCode - true allows this subroutine to flow into existing instructions.
      Returns:
      true if entry point leads to a well behaved subroutine
    • isValidSubroutine

      public boolean isValidSubroutine(Address entryPoint, boolean allowExistingCode, boolean mustTerminate)
      Check that this entry point leads to a well behaved subroutine, allow it to fall into existing code.
      • Hit no bad instructions.
      • Have only one entry point.
      • Not overlap any existing data or cause offcut references.
      Parameters:
      entryPoint - entry point to check
      allowExistingCode - true allows this subroutine to flow into existing instructions.
      mustTerminate - true if the subroutine must terminate
      Returns:
      true if entry point leads to a well behaved subroutine
    • isValidCode

      public boolean isValidCode(Address entryPoint)
      Check that this entry point leads to valid code:
      • May have multiple entries into the body of the code.
      • The intent is that it be valid code, not nice code.
      • Hit no bad instructions.
      • It should return.
      Parameters:
      entryPoint -
      Returns:
      true if the entry point leads to valid code
    • isValidCode

      public boolean isValidCode(Address entryPoint, PseudoDisassemblerContext context)
      Check that this entry point leads to valid code:
      • May have multiple entries into the body of the code.
      • The intent is that it be valid code, not nice code.
      • Hit no bad instructions.
      • It should return.
      Parameters:
      entryPoint - location to test for valid code
      context - disassembly context for program
      Returns:
      true if the entry point leads to valid code
    • followSubFlows

      public AddressSet followSubFlows(Address entryPoint, int maxInstr, PseudoFlowProcessor processor)
      Process a subroutine using the processor function. The process function can control what flows are followed and when to stop.
      Parameters:
      entryPoint - start address
      maxInstr - maximum number of instructions to evaluate
      processor - processor to use
      Returns:
      the address set of instructions that were followed
    • followSubFlows

      public AddressSet followSubFlows(Address entryPoint, PseudoDisassemblerContext procContext, int maxInstr, PseudoFlowProcessor processor)
      Process a subroutine using the processor function. The process function can control what flows are followed and when to stop.
      Parameters:
      entryPoint - start address
      procContext - initial processor context for disassembly
      maxInstr - maximum number of instructions to evaluate
      processor - processor to use
      Returns:
      the address set of instructions that were followed
    • checkValidSubroutine

      public boolean checkValidSubroutine(Address entryPoint, boolean allowExistingInstructions, boolean mustTerminate, boolean requireContiguous)
      Check if there is a valid subroutine at the target address
      Parameters:
      entryPoint - address to check
      allowExistingInstructions - true to allow running into existing instructions
      mustTerminate - true if the subroutine must hit a terminator (return) instruction
      requireContiguous - true if the caller will require some number of contiguous instructions call getLastCheckValidInstructionCount() to get the initial number of contiguous instructions if this is true
      Returns:
      true if entryPoint is the probable subroutine start
    • checkValidSubroutine

      public boolean checkValidSubroutine(Address entryPoint, PseudoDisassemblerContext procContext, boolean allowExistingInstructions, boolean mustTerminate)
      Check if there is a valid subroutine at the target address
      Parameters:
      entryPoint - address to check
      procContext - processor context to use when pseudo disassembling instructions
      allowExistingInstructions - true to allow running into existing instructions
      mustTerminate - true if the subroutine must hit a terminator (return) instruction
      Returns:
      true if entryPoint is the probable subroutine start
    • checkValidSubroutine

      public boolean checkValidSubroutine(Address entryPoint, PseudoDisassemblerContext procContext, boolean allowExistingInstructions, boolean mustTerminate, boolean requireContiguous)
      Check if there is a valid subroutine at the target address
      Parameters:
      entryPoint - address to check
      procContext - processor context to use when pseudo disassembling instructions
      allowExistingInstructions - true to allow running into existing instructions
      mustTerminate - true if the subroutine must hit a terminator (return) instruction
      requireContiguous - true if the caller will require some number of contiguous instructions call getLastCheckValidInstructionCount() to get the initial number of contiguous instructions if this is true
      Returns:
      true if entryPoint is the probable subroutine start
    • getNormalizedDisassemblyAddress

      public static Address getNormalizedDisassemblyAddress(Program program, Address addr)
      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.
      Parameters:
      program - to get address from
      addr - to be normallized/aligned for disassembly
      Returns:
      the normalized/aligned address for disassembly
    • getTargetContextRegisterValueForDisassembly

      public static RegisterValue getTargetContextRegisterValueForDisassembly(Program program, Address addr)
      Returns:
      RegisterValue setting for the context register to disassemble correctly at the given address or null, if no setting is needed.
    • hasLowBitCodeModeInAddrValues

      public static boolean hasLowBitCodeModeInAddrValues(Program program)
      Returns:
      true if program has uses the low bit of an address to change Instruction Set mode
    • setTargetContextForDisassembly

      public static Address setTargetContextForDisassembly(Program program, Address addr)
      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.
      Parameters:
      program -
      addr - the raw address
      Returns:
      the correct address to disassemble at if it needs to be aligned
    • setTargetContextForDisassembly

      public static Address setTargetContextForDisassembly(DisassemblerContext procContext, Address addr)
      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.
      Parameters:
      procContext - context to change
      addr - destination address that will be disassembled (possible pseudo disassembled)
      Returns:
      the correct disassembly location if the address needed to be adjusted.