Package ghidra.app.util

# 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 Summary

  Constructors
  Constructor
  Description
  `PseudoDisassembler(Program program)`
  Create a pseudo disassembler for the given program.

- ## Method Summary

  Modifier and Type
  Method
  Description
  `PseudoData`
  `applyDataType(Address addr, DataType dt)`
  Apply a dataType to the program at the given address.
  `boolean`
  `checkValidSubroutine(Address entryPoint, boolean allowExistingInstructions, boolean mustTerminate, boolean requireContiguous)`
  Check if there is a valid subroutine at the target address
  `boolean`
  `checkValidSubroutine(Address entryPoint, PseudoDisassemblerContext procContext, boolean allowExistingInstructions, boolean mustTerminate)`
  Check if there is a valid subroutine at the target address
  `boolean`
  `checkValidSubroutine(Address entryPoint, PseudoDisassemblerContext procContext, boolean allowExistingInstructions, boolean mustTerminate, boolean requireContiguous)`
  Check if there is a valid subroutine at the target address
  `PseudoInstruction`
  `disassemble(Address addr)`
  Disassemble a single instruction.
  `PseudoInstruction`
  `disassemble(Address addr, byte[] bytes)`
  Disassemble a location in memory with the given set of bytes.
  `PseudoInstruction`
  `disassemble(Address addr, byte[] bytes, PseudoDisassemblerContext disassemblerContext)`
  Disassemble a location in memory with the given set of bytes.
  `PseudoInstruction`
  `disassemble(Address addr, PseudoDisassemblerContext disassemblerContext, boolean isInDelaySlot)`
  Disassemble a single instruction.
  `AddressSet`
  `followSubFlows(Address entryPoint, int maxInstr, PseudoFlowProcessor processor)`
  Process a subroutine using the processor function.
  `AddressSet`
  `followSubFlows(Address entryPoint, PseudoDisassemblerContext procContext, int maxInstr, PseudoFlowProcessor processor)`
  Process a subroutine using the processor function.
  `Address`
  `getIndirectAddr(Address toAddr)`
  Interpret the bytes at a location in memory as an address and return the address.
  `int`
  `getLastCheckValidInstructionCount()`
  Get the last number of disassembled instructions or the number of initial contiguous instruction if requireContiguous is true
  `static Address`
  `getNormalizedDisassemblyAddress(Program program, Address addr)`
  Get an address that can be used for disassembly.
  `static RegisterValue`
  `getTargetContextRegisterValueForDisassembly(Program program, Address addr)`
  `static boolean`
  `hasLowBitCodeModeInAddrValues(Program program)`
  `boolean`
  `isValidCode(Address entryPoint)`
  Check that this entry point leads to valid code: May have multiple entries into the body of the code.
  `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.
  `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.
  `boolean`
  `isValidSubroutine(Address entryPoint, boolean allowExistingCode)`
  Check that this entry point leads to a well behaved subroutine, allow it to fall into existing code.
  `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.
  `void`
  `setMaxInstructions(int maxNumInstructions)`
  Set the maximum number of instructions to check
  `void`
  `setRespectExecuteFlag(boolean respect)`
  Set flag to respect Execute bit on memory if present on any memory
  `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.
  `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.

  ### Methods inherited from class java.lang.Object

  `clone, equals, finalize, getClass, hashCode, notify, notifyAll, toString, wait, wait, wait`

- ## 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

    public PseudoInstruction disassemble(Address addr) throws InsufficientBytesException, UnknownInstructionException, UnknownContextException
    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

    public PseudoInstruction disassemble(Address addr, byte[] bytes) throws InsufficientBytesException, UnknownInstructionException, UnknownContextException
    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

    public PseudoInstruction disassemble(Address addr, byte[] bytes, PseudoDisassemblerContext disassemblerContext) throws InsufficientBytesException, UnknownInstructionException, UnknownContextException
    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.