Package ghidra.app.util
Class PseudoDisassembler
java.lang.Object
ghidra.app.util.PseudoDisassembler
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
ConstructorDescriptionPseudoDisassembler
(Program program) Create a pseudo disassembler for the given program. -
Method Summary
Modifier and TypeMethodDescriptionapplyDataType
(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 addressboolean
checkValidSubroutine
(Address entryPoint, PseudoDisassemblerContext procContext, boolean allowExistingInstructions, boolean mustTerminate) Check if there is a valid subroutine at the target addressboolean
checkValidSubroutine
(Address entryPoint, PseudoDisassemblerContext procContext, boolean allowExistingInstructions, boolean mustTerminate, boolean requireContiguous) Check if there is a valid subroutine at the target addressdisassemble
(Address addr) Disassemble a single instruction.disassemble
(Address addr, byte[] bytes) Disassemble a location in memory with the given set of bytes.disassemble
(Address addr, byte[] bytes, PseudoDisassemblerContext disassemblerContext) Disassemble a location in memory with the given set of bytes.disassemble
(Address addr, PseudoDisassemblerContext disassemblerContext, boolean isInDelaySlot) Disassemble a single instruction.followSubFlows
(Address entryPoint, int maxInstr, PseudoFlowProcessor processor) Process a subroutine using the processor function.followSubFlows
(Address entryPoint, PseudoDisassemblerContext procContext, int maxInstr, PseudoFlowProcessor processor) Process a subroutine using the processor function.getIndirectAddr
(Address toAddr) Interpret the bytes at a location in memory as an address and return the address.int
Get the last number of disassembled instructions or the number of initial contiguous instruction if requireContiguous is truestatic 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. The intent is that it be valid code, not nice code. Hit no bad instructions. It should return.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.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 checkvoid
setRespectExecuteFlag
(boolean respect) Set flag to respect Execute bit on memory if present on any memorystatic 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.
-
Constructor Details
-
PseudoDisassembler
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 disassemblebytes
- 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 disassemblebytes
- bytes to use instead of those currently defined in programdisassemblerContext
- the disassembler context to use.- Returns:
- PseudoInstruction.
- Throws:
InsufficientBytesException
UnknownInstructionException
UnknownContextException
-
applyDataType
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 fordt
- the data type to be applied- Returns:
PseudoData
that acts like Data
-
getIndirectAddr
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
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
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 checkallowExistingCode
- 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 checkallowExistingCode
- 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
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
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 codecontext
- disassembly context for program- Returns:
- true if the entry point leads to valid code
-
followSubFlows
Process a subroutine using the processor function. The process function can control what flows are followed and when to stop.- Parameters:
entryPoint
- start addressmaxInstr
- maximum number of instructions to evaluateprocessor
- 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 addressprocContext
- initial processor context for disassemblymaxInstr
- maximum number of instructions to evaluateprocessor
- 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 checkallowExistingInstructions
- true to allow running into existing instructionsmustTerminate
- true if the subroutine must hit a terminator (return) instructionrequireContiguous
- 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 checkprocContext
- processor context to use when pseudo disassembling instructionsallowExistingInstructions
- true to allow running into existing instructionsmustTerminate
- 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 checkprocContext
- processor context to use when pseudo disassembling instructionsallowExistingInstructions
- true to allow running into existing instructionsmustTerminate
- true if the subroutine must hit a terminator (return) instructionrequireContiguous
- 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
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 fromaddr
- 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
- Returns:
- true if program has uses the low bit of an address to change Instruction Set mode
-
setTargetContextForDisassembly
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
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 changeaddr
- destination address that will be disassembled (possible pseudo disassembled)- Returns:
- the correct disassembly location if the address needed to be adjusted.
-