Interface IDInstruction
- All Superinterfaces:
IDElement
,IDExpression
,IInstruction
,IInstructionOperand
,ILocatedInstruction
dexdec
IR instruction object. Each intermediate representation instruction has:- an opcode: refer to
DOpcodeType
- zero, one, or two operands, of type
IDElement
- an offset (in the IR)
- a size
IR CFGs consist of basic blocks made of IR instructions. An IDMethodContext
references it
IR CFG. IR instructions can also be created via the createXxx
methods of the context
object.
When creating IR instructions, the default size is set to 1. The offset is not set (-1), and needs to be set manually. The size of an IR instruction can be set to any strictly positive value. In a CFG, it is important that all instructions be contiguous (i.e. there is no gap): if an instruction has offset O and size S, the next instruction must be at offset O+S.
-
Field Summary
FieldsFields inherited from interface com.pnfsoftware.jeb.core.units.code.android.ir.IDElement
DEFAULT_COMPARE_WITH_FULL_EQUALITY
-
Method Summary
Modifier and TypeMethodDescriptionvoid
adjustSize
(int delta) Adjust this instruction's IR size.copy
(DCopyOptions opt) Copy this element.void
copyBaseFields
(IDInstruction sourceInsn) Copy all base fields, that is all fields but the opcode and operands of the source instruction to this instruction.int
countUsedVariable
(IDVar var) Count the number of times the provided variable is used (read) by this instruction.Deep copy of this instruction.duplicateForReplacement
(IDInstruction replacedInsn) Duplicate this instruction with the intent to replace the source instruction.duplicateWithOffsetAndSize
(long offset, int size) Convenience method: evaluate the IR instruction using the provided set a variable values.int
Retrieve the IR method context to which this instruction belongs.Get the identifier defined (written) by this method, if there is one.Get the condition predicate (if the instruction is a JCOND).long
IR offsets are 32-bit integers; they can be safely cast to int.long
Retrieve the end offset (exclusive) of this instructionGet this instruction opcode.Get the first operand.Get the second operand.Get the variables used (read) by this instruction.boolean
hasUseSideEffects
(boolean includeCanThrow) Determine whether the used components of the statement may have side-effects.boolean
isAssign()
default boolean
default boolean
isAssignFromVar
(int wantedVarId) default boolean
default boolean
isAssignFromVarToVar
(int wantedSrcVarId, int wantedDstVarId) default boolean
default boolean
isAssignToVar
(int wantedVarId) boolean
isInvoke()
boolean
isJcond()
boolean
boolean
isJcondTo
(int wantedTarget) boolean
isJump()
boolean
boolean
isJumpOrJcondTo
(int wantedTarget) boolean
isJumpTo
(int wantedTarget) boolean
boolean
boolean
isNop()
boolean
isOpcode
(DOpcodeType... candidateOpcodes) Determine if this instruction's opcode is any of the provided candidates.boolean
isReturn()
boolean
boolean
boolean
isSwitch()
boolean
boolean
boolean
isThrow()
void
morph
(DOpcodeType opcode, IDElement opnd1, IDElement opnd2) This dangerous method allows changing an IR instruction into a different one, while keeping metadata (e.g.int
replaceDefinedVariable
(IDVar var, IDExpression repl) Replace the variable defined by this statement (if there is any).int
replaceUsedVariable
(IDVar var, IDExpression repl) Deep replace all matching used variables of this instruction.void
int
setBranchTarget
(int offset) Update the branch target for unconditional and conditional jumps only.Update the instruction context.void
setOffset
(long offset) Set this instruction's IR offset.void
setOpcode
(DOpcodeType opcode) Change the instruction opcode.void
setOperand1
(IDElement opnd) Change the instruction first operand.void
setOperand2
(IDElement opnd) Change the instruction second operand.void
setSize
(int size) Set this instruction's IR size.setSwitchData
(IDSwitchData swdata) void
Transform a conditional jump instruction to a conditional-predicate assignment.void
Transform a conditional jump instruction to a jump.boolean
Transform a single-case switch into a conditional jump.void
transformToJump
(int offset) Transform any instruction to a jump, and update the jump target.void
transformToJump
(IDTarget target) Transform any instruction to a jump, and update the jump target.void
Transform any instruction to a NOP.int
updateTargets
(Map<Integer, Integer> oldToNewOffsets) Update the targets of a branching instruction.int
updateTargets
(Map<Integer, Integer> oldToNewOffsets, boolean failOnMissedEntry) Update the targets of a branching instruction.void
verify()
Verify this instruction.boolean
visitInstruction
(IDVisitor visitor) Visit this instruction and its constituents.boolean
visitInstruction
(IDVisitor visitor, boolean skipAssignmentDestination) Visit this instruction and its constituents.boolean
visitInstructionPostOrder
(IDVisitor visitor, boolean skipAssignmentDestination) Visit this instruction and its constituents.boolean
visitInstructionPreOrder
(IDVisitor visitor, boolean skipAssignmentDestination) Visit this instruction and its constituents.withOffset
(long offset) Update the instruction offset.withSize
(int size) Update the instruction size.Methods inherited from interface com.pnfsoftware.jeb.core.units.code.android.ir.IDElement
equalsEx, format, toString, toString
Methods inherited from interface com.pnfsoftware.jeb.core.units.code.android.ir.IDExpression
asArrayElt, asCallInfo, asImm, asInstanceField, asInstruction, asNewArrayInfo, asNewInfo, asOperation, asReferenceType, asStaticField, asVar, canThrow, checkType, collectAllPhysicalMethodIndices, collectAllPhysicalOffsets, collectSubExpressions, collectVarIds, countVariable, evaluate, evaluate, evaluate, find, findByType, findByType, findParent, findParent, generateAST, getCustomCanThrow, getData, getOrigin, getPhysicalMethodIndex, getPhysicalOffset, getSubExpressions, getType, getVarIds, hasSideEffects, isArrayElt, isCallInfo, isCallInfo, isCastOperation, isCastOperation, isConstantImm, isConstantImm, isImm, isInstanceField, isInstruction, isNewArrayInfo, isNewInfo, isOperation, isOperation, isOperation, isOperation, isOperation, isOperation, isOperation, isReferenceType, isStaticField, isStringImm, isVar, isVar, removeData, replaceSubExpression, replaceVariable, setCustomCanThrow, setData, setOrigin, setPhysicalMethodIndex, setPhysicalOffset, setType, setType, setType, spawn, transferMetadataFrom, updateAllPhysicalMethodIndices, updateAllPhysicalOffsets, updateTypes, visitDepthPost, visitDepthPost, visitDepthPost, visitDepthPre, visitDepthPre, visitDepthPre
Methods inherited from interface com.pnfsoftware.jeb.core.units.code.IInstruction
canThrow, collectIndirectCallReferences, format, getACS, getBreakingFlow, getCode, getCountOfOperands, getDefUse, getDefUse, getDefUseInfo, getInstructionFlags, getMnemonic, getOperand, getOperands, getPrefix, getPrimaryBranchAddress, getProcessorMode, getRoutineCall, getSize
Methods inherited from interface com.pnfsoftware.jeb.core.units.code.IInstructionOperand
format
Methods inherited from interface com.pnfsoftware.jeb.core.units.code.ILocatedInstruction
collectIndirectCallReferences, getBreakingFlow, getPrimaryBranchAddress, getRoutineCall
-
Field Details
-
Method Details
-
duplicate
IDInstruction duplicate()Deep copy of this instruction.- Specified by:
duplicate
in interfaceIDElement
- Specified by:
duplicate
in interfaceIDExpression
- Returns:
- a deep copy of this element; the type of the duplicated element should be the same as this element's type
-
copy
Description copied from interface:IDElement
Copy this element. This operation can be seen as a custom duplication; the resulting element may not be of the same type as this element.- Specified by:
copy
in interfaceIDElement
- Specified by:
copy
in interfaceIDExpression
- Parameters:
opt
- optional; if one is provided,DCopyOptions.onDup(IDExpression)
will be tried first to create a copy- Returns:
- the copied element
-
duplicateForReplacement
Duplicate this instruction with the intent to replace the source instruction. The offset and size of the source instruction are copied over to the newly created instruction.- Returns:
-
duplicateWithOffsetAndSize
- Parameters:
offset
-size
-- Returns:
-
copyBaseFields
Copy all base fields, that is all fields but the opcode and operands of the source instruction to this instruction.- Parameters:
sourceInsn
-
-
getContext
IDMethodContext getContext()Retrieve the IR method context to which this instruction belongs. The method context holds all information regarding a current method decompilation. It is also a factory to create moreIDInstruction
objects.- Returns:
-
setContext
Update the instruction context. It is important to update the context when transferring the instructions from a CFG (from context A) to another CFG (of contextB).- Parameters:
ctx
- new context- Returns:
- the previous context
-
getOffset
long getOffset()IR offsets are 32-bit integers; they can be safely cast to int.- Specified by:
getOffset
in interfaceILocatedInstruction
- Returns:
- the instruction offset/address
-
getOffsetEnd
long getOffsetEnd()Retrieve the end offset (exclusive) of this instruction- Specified by:
getOffsetEnd
in interfaceILocatedInstruction
- Returns:
getOffset()
+IInstruction.getSize()
-
setOffset
void setOffset(long offset) Set this instruction's IR offset. Dangerous method. Make sure to ensure CFG consistency if this instruction is part of a CFG.- Parameters:
offset
-
-
withOffset
Update the instruction offset.- Parameters:
offset
- new offset- Returns:
- this object
-
setSize
void setSize(int size) Set this instruction's IR size. Dangerous method. Make sure to ensure CFG consistency if this instruction is part of a CFG.- Parameters:
size
- new size
-
withSize
Update the instruction size.- Parameters:
size
- new size- Returns:
- this object
-
adjustSize
void adjustSize(int delta) Adjust this instruction's IR size. Dangerous method. Make sure to ensure CFG consistency if this instruction is part of a CFG.- Parameters:
delta
- added to the currentsize
-
getOpcode
DOpcodeType getOpcode()Get this instruction opcode.- Returns:
-
setOpcode
Change the instruction opcode. This method is dangerous. Instruction operands may require an update as well.- Parameters:
opcode
-
-
isOpcode
Determine if this instruction's opcode is any of the provided candidates.- Parameters:
candidateOpcodes
- a list of candidate opcodes- Returns:
- true if this instruction's opcode was one of the candidates
-
getOperand1
IDElement getOperand1()Get the first operand. May be null if the opcode does not specify one. Refer togetOpcode()
andDOpcodeType
.- Returns:
-
setOperand1
Change the instruction first operand. This method is dangerous. Other instruction attributes may require an update as well.- Parameters:
opnd
-
-
getOperand2
IDElement getOperand2()Get the second operand. May be null if the opcode does not specify one. Refer togetOpcode()
andDOpcodeType
.- Returns:
-
setOperand2
Change the instruction second operand. This method is dangerous. Other instruction attributes may require an update as well.- Parameters:
opnd
-
-
hasUseSideEffects
boolean hasUseSideEffects(boolean includeCanThrow) Determine whether the used components of the statement may have side-effects.This method is not fail-safe, it works on a best-effort basis. Refer to
IDExpression.hasSideEffects(IDMethodContext, boolean)
for more information.- Parameters:
includeCanThrow
-- Returns:
-
isNop
boolean isNop()- Returns:
- true if this instruction is a
nop
-
isAssign
boolean isAssign()- Returns:
- true if this instruction is an
assignment
-
getAssignDestination
IDExpression getAssignDestination() -
setAssignDestination
-
getAssignSource
IDExpression getAssignSource() -
setAssignSource
-
isAssignToVar
default boolean isAssignToVar() -
isAssignToVar
default boolean isAssignToVar(int wantedVarId) -
isAssignFromVar
default boolean isAssignFromVar() -
isAssignFromVar
default boolean isAssignFromVar(int wantedVarId) -
isAssignFromVarToVar
default boolean isAssignFromVarToVar() -
isAssignFromVarToVar
default boolean isAssignFromVarToVar(int wantedSrcVarId, int wantedDstVarId) -
isInvoke
boolean isInvoke()- Returns:
- true if this instruction is an
invocation
(call, new, new-array, alloc-object)
-
getInvokeData
IDInvokeInfo getInvokeData()- Returns:
- the invocation information, if the instruction
is an invocation
-
setBranchTarget
int setBranchTarget(int offset) Update the branch target for unconditional and conditional jumps only. This function fails for all other opcodes, including switches.- Parameters:
offset
- the new offset- Returns:
- previous value
-
getBranchTarget
int getBranchTarget() -
isJump
boolean isJump()- Returns:
- true if this instruction is a
jump
(goto)
-
isJumpTo
boolean isJumpTo(int wantedTarget) -
isJcond
boolean isJcond()- Returns:
- true if this instruction is a
conditional jump
-
isJcondTo
boolean isJcondTo(int wantedTarget) -
isJumpOrJcond
boolean isJumpOrJcond() -
isJumpOrJcondTo
boolean isJumpOrJcondTo(int wantedTarget) -
isJcondOrSwitch
boolean isJcondOrSwitch() -
getJcondCondition
IDExpression getJcondCondition()Get the condition predicate (if the instruction is a JCOND).- Returns:
-
setJcondCondition
- Parameters:
cond
-- Returns:
-
reverseJcondCondition
void reverseJcondCondition() -
isSwitch
boolean isSwitch()- Returns:
- true if this instruction is a
switch
-
isSwitchOnInt
boolean isSwitchOnInt() -
isSwitchOnString
boolean isSwitchOnString() -
getSwitchData
IDSwitchData getSwitchData() -
setSwitchData
-
getSwitchExpression
IDExpression getSwitchExpression() -
setSwitchExpression
-
isReturn
boolean isReturn()- Returns:
- true if this instruction is a
return
-
getReturnExpression
IDExpression getReturnExpression() -
setReturnExpression
-
isThrow
boolean isThrow()- Returns:
- true if this instruction is a
throw
-
getThrowExpression
IDExpression getThrowExpression() -
setThrowExpression
-
isReturnOrThrow
boolean isReturnOrThrow() -
isStoreException
boolean isStoreException()- Returns:
- true if this instruction is a
store-exception
(special opcode)
-
getStoredExceptionVariable
IDVar getStoredExceptionVariable()- Returns:
- the exception variable set up by a
store-exception
instruction
-
setStoredExceptionVariable
- Parameters:
ex
- a new exception variable for astore-exception
instruction- Returns:
- the previous variable
-
isMonitorEnter
boolean isMonitorEnter()- Returns:
- true if this instruction is a
monitor-enter
-
isMonitorExit
boolean isMonitorExit()- Returns:
- true if this instruction is a
monitor-exit
-
transformToNop
void transformToNop()Transform any instruction to a NOP. -
transformJcondToJump
void transformJcondToJump()Transform a conditional jump instruction to a jump. It is the caller's responsibility to verify that the instruction is a JCOND.IF pred GOTO target ==> GOTO target
-
transformToJump
void transformToJump(int offset) Transform any instruction to a jump, and update the jump target.- Parameters:
offset
- target offset
-
transformToJump
Transform any instruction to a jump, and update the jump target.- Parameters:
target
- a target
-
transformJcondToAssign
Transform a conditional jump instruction to a conditional-predicate assignment. It is the caller's responsibility to verify that the instruction is a JCOND.IF pred GOTO target ==> dst = pred
- Parameters:
dst
- the destination operand for the predicate
-
transformSwitchToJcond
boolean transformSwitchToJcond()Transform a single-case switch into a conditional jump.SWITCH(VAR) { CASE X: GOTO target; } // fall-through => IF VAR==X GOTO target; // fall-through
- Returns:
- success indicators (if the switch has several cases, this method will fail)
-
updateTargets
Update the targets of a branching instruction. This method has no effect on IR opcodes other thanJUMP
,JCOND
, andSWITCH
.- Parameters:
oldToNewOffsets
- a map of current IR offsets to new IR offsets- Returns:
- the number of updated targets
-
updateTargets
Update the targets of a branching instruction. This method has no effect on IR opcodes other thanJUMP
,JCOND
, andSWITCH
.- Parameters:
oldToNewOffsets
- a map of current IR offsets to new IR offsetsfailOnMissedEntry
- if true, the method will raise if a (current) branch target cannot be mapped to a new target (i.e., if there is no entry for a branch target in the map)- Returns:
- the number of updated targets
-
morph
This dangerous method allows changing an IR instruction into a different one, while keeping metadata (e.g. offset, size, etc.) intact. If possible, use one of thetransformXxx
instructions instead.- Parameters:
opcode
- new opcodeopnd1
- new operand 1 (if any) - refer toDOpcodeType
's type for operand typeopnd2
- new operand 2 (if any) - refer toDOpcodeType
's type for operand type
-
verify
Verify this instruction.Currently, this method verifies that the instruction operands match the
current opcode
specifications (seeDOpcodeType
).- Throws:
IllegalStateException
- throw on error
-
replaceUsedVariable
Deep replace all matching used variables of this instruction. The replacement expression is duplicated to avoid reuse. Defined identifiers (if any) are not replaced.- Parameters:
var
- target variable to be replacedrepl
- expression that will replace the variable- Returns:
- the number of replacements
-
replaceDefinedVariable
Replace the variable defined by this statement (if there is any).- Parameters:
var
- target variable to be replacedrepl
- expression that will replace the variable- Returns:
- the number of replacements (usually 0, potentially 1 for an assigment-like instruction)
-
getUsedVariables
Get the variables used (read) by this instruction.- Returns:
- the list of all variables used, which may contain duplicates variables if the
instruction uses the same variable multiple times (example:
z = x + (y * x)
would return[y, x, x]
.
-
getDefinedVariable
IDVar getDefinedVariable()Get the identifier defined (written) by this method, if there is one. OnlyDOpcodeType.IR_ASSIGN
andDOpcodeType.IR_STORE_EXCEPTION
may define (write) identifiers.- Returns:
-
countUsedVariable
Count the number of times the provided variable is used (read) by this instruction.Example (ASSIGN opcode):
x = y * (y + z)
=> x is not used; y is used twice; z is used once- Parameters:
var
-- Returns:
-
visitInstruction
Visit this instruction and its constituents. The visit is made depth-first, pre-order, and parents are recorded. (Refer toIVisitResults
for details.)Same as
visitInstructionPreOrder
. Replacements must be reported (refer toIDExpression.visitDepthPre(IDVisitor)
for details).- Parameters:
visitor
- visitor object- Returns:
- success indicator; true unless a different value was specified in
DVisitResults
when visiting an element
-
visitInstruction
Visit this instruction and its constituents. The visit is made depth-first, pre-order, and parents are recorded. (Refer toIVisitResults
for details.)Same as
visitInstructionPreOrder
. Replacements must be reported (refer toIDExpression.visitDepthPre(IDVisitor)
for details).- Parameters:
visitor
- visitor objectskipAssignmentDestination
- true to skip visiting the destination ofDOpcodeType.IR_ASSIGN
orDOpcodeType.IR_STORE_EXCEPTION
- Returns:
- success indicator; true unless a different value was specified in
DVisitResults
when visiting an element
-
visitInstructionPreOrder
Visit this instruction and its constituents. The visit is made depth-first, pre-order, and parents are recorded. (Refer toIVisitResults
for details.)Replacements must be reported (refer to
IDExpression.visitDepthPre(IDVisitor)
for details).- Parameters:
visitor
- visitor objectskipAssignmentDestination
- true to skip visiting the destination ofDOpcodeType.IR_ASSIGN
orDOpcodeType.IR_STORE_EXCEPTION
- Returns:
- success indicator; true unless a different value was specified in
DVisitResults
when visiting an element
-
visitInstructionPostOrder
Visit this instruction and its constituents. The visit is made depth-first, post-order, and parents are recorded. (Refer toIVisitResults
for details.)Replacements need not be reported.
- Parameters:
visitor
- visitor objectskipAssignmentDestination
- true to skip visiting the destination ofDOpcodeType.IR_ASSIGN
orDOpcodeType.IR_STORE_EXCEPTION
- Returns:
- success indicator; true unless a different value was specified in
DVisitResults
when visiting an element
-
evaluate
Convenience method: evaluate the IR instruction using the provided set a variable values.- Parameters:
varmap
- a map of variable values to be used when evaluating the expression (this map will not be modified after evaluation of the instruction; for full-control of the emulation, useIDExpression.evaluate(IDState)
instead of this method)- Returns:
- the offset of the next IR instruction to be executed; null if none (e.g. a Return was executed)
- Throws:
DexDecEvaluationException
-