java.lang.Object | |
↳ | com.pnfsoftware.jeb.core.units.code.android.ir.DUtil |
dexdec
IR access and manipulation utility methods.
Public Constructors | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
DUtil() |
Public Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
static int |
calculateComplexity(IDExpression e)
Calculate the trivial complexity metric for the provided IR expression.
| ||||||||||
static boolean | canHandlerCatchException(IDMethodContext ctx, IDExceptionHandler h, String exceptionSig) | ||||||||||
static boolean |
checkBlock(BasicBlock<IDInstruction> b, DOpcodeType... opcodes)
Check for instruction matching in the provided block.
| ||||||||||
static int |
checkSequence(CFG<IDInstruction> cfg, int blkindex, DOpcodeType... opcodes)
Check for instruction matching in a sequence of blocks.
| ||||||||||
static int |
cleanGraph(IDMethodContext ctx)
Clean the graph of an IR method context.
| ||||||||||
static Set<Integer> |
collectUniqueVarIds(IDExpression e)
Collect the unique list of variable ids making up this expression, including the expression
itself if is an
IDVar . | ||||||||||
static List<IDVar> |
collectVars(IDExpression e)
Collect all the
variables making up this expression, including the expression
itself if is a variable. | ||||||||||
static CFG<IDInstruction> |
copyGraph(CFG<IDInstruction> cfg, boolean deepCopy, IDMethodContext newContext)
Copy an IR-CFG.
| ||||||||||
static int |
countVariable(IDExpression e, IDVar var)
Count the number of occurrences of a given variable in the provided IR expression.
| ||||||||||
static int |
createRegisterVarId(int regnum, boolean dualSlot)
Create the primary variable mapping to a register or couple of registers.
| ||||||||||
static void |
dump(CFG<IDInstruction> cfg, String filename, String title)
Dump an IR-CFG to a Graphviz
dot file in the user's temporary folder. | ||||||||||
static void |
dump(CFG<IDInstruction> cfg, String filename)
Dump an IR-CFG to a Graphviz
dot file in the user's temporary folder. | ||||||||||
static String |
formatVarId(int varid)
Generate the standard variable name associated with the provided variable id.
| ||||||||||
static String |
formatVarIds(Collection<Integer> varids)
A convenience method to format a collection of variable ids into a comma-separated string.
| ||||||||||
static SortedMap<Integer, Integer> |
generateBlockOffsetMap(IDMethodContext ctx)
Generate an offset IR-to-native offset conversion map.
| ||||||||||
static String | generateNativeAddress(IDMethodContext ctx, IDExpression elt) | ||||||||||
static ICodeCoordinates | generateNativeCoordinates(IDMethodContext ctx, IDExpression elt) | ||||||||||
static ContextAccessType |
getCAT(IDInstruction insn, boolean inclAssigDst)
Determine the aggregated context type of an instruction.
| ||||||||||
static String | getExceptionSignature(IDMethodContext ctx, IDExceptionHandler h) | ||||||||||
static Collection<BasicBlock<IDInstruction>> |
getReachableBlocks(CFG<IDInstruction> cfg)
Get the list of reachable blocks of the provided IR-CFG.
| ||||||||||
static boolean |
hasInvokeInfo(IDExpression e)
Determine whether the IR expression makes invocations (general invocations, new, new-array).
| ||||||||||
static boolean |
hasVariable(IDExpression e, int varid)
Determine whether the provided expression is or contains the provided variable.
| ||||||||||
static boolean |
hasVariables(IDExpression e)
Determine whether the provided expression contains
variables . | ||||||||||
static void |
insertHeaderBlock(IDMethodContext ctx, int reqInsnCount, int reqInsnSize)
Insert a header block filled with NOP instructions.
| ||||||||||
static boolean | isDoubleSlotVarId(int varid) | ||||||||||
static boolean |
isImmNonZero(IDExpression exp)
Determine if an expression is an IR immediate not holding the value 0.
| ||||||||||
static boolean |
isImmValue(IDExpression exp, long value)
Determine if an expression is an IR immediate holding the provided value.
| ||||||||||
static boolean |
isImmZero(IDExpression exp)
Determine if an expression is an IR immediate holding the value 0.
| ||||||||||
static boolean | isLegalVarId(int varid) | ||||||||||
static boolean | isRegisterVarId(int varid) | ||||||||||
static boolean | isSingleSlotVarId(int varid) | ||||||||||
static boolean | isUsingCaughtException(IDMethodContext ctx, BasicBlock<IDInstruction> b) | ||||||||||
static boolean | isVirtualVarId(int varid) | ||||||||||
static boolean |
mayBeFinal(IDField f, IDexUnit dex)
Determine whether the provided field is or appears to be
final . | ||||||||||
static int |
modifyInstructionSizes(IDMethodContext ctx, Function<IDInstruction, Integer> modifier)
Update the instruction sizes of a CFG.
| ||||||||||
static IDInstruction |
nextInstruction(CFG<IDInstruction> cfg, BasicBlock<IDInstruction> b, int i)
Determine the meaningful next instruction in the execution flow, assuming no exception was
raised.
| ||||||||||
static int |
normalizeGraph(IDMethodContext ctx)
Normalize the IR by resetting all instructions to the unit size (1).
| ||||||||||
static int |
normalizeGraph(IDMethodContext ctx, int wantedInstructionSize)
Normalize the IR by resetting all instructions to the required size.
| ||||||||||
static int |
parseVarIdFromStandardName(String varname, boolean softFail)
Parse a standard variable name (as generated by
formatVarId(int) ) and retrieve the
associated variable id. | ||||||||||
static int |
removeGaps(CFG<IDInstruction> cfg)
Remove all gaps from the provided IR-CFG.
| ||||||||||
static boolean |
removeInstruction(BasicBlock<IDInstruction> b, int idx)
Remove an instruction in a block.
| ||||||||||
static int |
removeUnreachableBlocks(CFG<IDInstruction> cfg, IDTryData ex)
Remove unreachable blocks from an IR-CFG.
| ||||||||||
static int |
removeUnreachableBlocks(IDMethodContext ctx)
Remove unreachable blocks from an IR-CFG.
| ||||||||||
static boolean |
removeUnreachableTrampoline(CFG<IDInstruction> cfg, BasicBlock<IDInstruction> b)
Remove an unreachable trampoline block (ending on a JCOND or JUMP).
| ||||||||||
static boolean |
replaceInExpression(IDExpression e, IDExpression target, IDExpression repl)
Replace an IR expression located inside another IR.
| ||||||||||
static int |
simplifyJCondsAndSwitches(IDMethodContext ctx)
Simply DOpcodeType#JCOND and
IR_SWITCH IR instructions:- JCOND: the target branch must not point to the fallthrough instruction; if it is, the JCOND must be replaced by a JUMP (while taking care of potential side-effects introduced by the evaluation of the JCOND predicate) - SWITCH: the case targets must not point to the fallthrough instruction; if any does, the case entry must be removed (and will be taken care by the switch's default entry)
Illegal JCOND/SWITCH are tolerated during an optimization phase; however, an optimizer, or any code modifying the IR, must provide a legal IR to subsequent components. | ||||||||||
static BasicBlock<IDInstruction> |
splitBlock(IDMethodContext ctx, BasicBlock<IDInstruction> blk, int index)
Split a block of the context's CFG into two blocks.
| ||||||||||
static boolean |
unprotectBlock(CFG<IDInstruction> cfg, IDTryData exdata, int blkAddress)
Unprotect a basic block.
| ||||||||||
static List<IDInstruction> |
unroll(IDMethodContext ctx, IDVar pivotVar, long addrStart, long addrEnd, int maxProcessedInsnCount, int maxUnrolledInsnCount, int maxLoopIterCnt)
Attempt to unroll some code whose pivot is a single
variable . | ||||||||||
static int | updateTargets(IDMethodContext ctx, Map<Integer, Integer> oldToNewOffsets) | ||||||||||
static boolean |
usesReferences(IDExpression e)
Determine whether the IR expression uses references, defined as any of: accessing fields,
accessing array elements, creating arrays.
| ||||||||||
static void |
verifyGraph(IDMethodContext ctx, String info)
Verify an IR-CFG from a method context.
| ||||||||||
static void |
verifyGraph(IDMethodContext ctx)
Verify an IR-CFG from a method context.
| ||||||||||
static void |
verifyGraph(IDMethodContext ctx, String dumpFilename, String info)
Verify an IR-CFG.
| ||||||||||
static void |
verifyGraph(IDMethodContext ctx, CFG<IDInstruction> cfg, IDTryData exdata, String dumpFilename, String info)
Verify an IR-CFG.
|
[Expand]
Inherited Methods | |||||||||||
---|---|---|---|---|---|---|---|---|---|---|---|
![]() |
Calculate the trivial complexity metric for the provided IR expression. Every IR element has a weight of 1.
e | an IR expression |
---|
Check for instruction matching in the provided block. The block must be fully matched.
Check for instruction matching in a sequence of blocks. Blocks must be fully contiguous and
fully matched.
This is an extended version of #checkBlock(BasicBlock, DOpcodeType...), which
performs matching on a single block.
Clean the graph of an IR method context.
Collect the unique list of variable ids making up this expression, including the expression
itself if is an IDVar
.
e | an IR expression |
---|
Collect all the variables
making up this expression, including the expression
itself if is a variable. The returned collection may contain duplicates. Example: If the
provided expression if ((var1 + var2 + 5) / var1)
, this method will return
[var1, var2, var1]
. Note that the collection is done in post-order, so ordering is
predictable.
e | an IR expression |
---|
Copy an IR-CFG.
cfg | a CFG |
---|---|
deepCopy | if false, the CFG is only structurally duplicated (that is, the copy is
shallow: the instructions of the new CFG are reused in the new CFG); if true, the
instructions are duplicated as well). |
newContext | if performing deep copy, the optional new context to be
set up for the IR instructions |
Count the number of occurrences of a given variable in the provided IR expression.
e | an IR expression |
---|
Create the primary variable mapping to a register or couple of registers. A primary variable has an id that can be mapped directly to the underlying Dalvik register id(s).
Dump an IR-CFG to a Graphviz dot
file in the user's temporary folder.
cfg | CFG |
---|---|
filename | filename (the ".dot" extension will be appended if necessary) |
title | optional title or header string |
Dump an IR-CFG to a Graphviz dot
file in the user's temporary folder.
Generate the standard variable name associated with the provided variable id.
varid | a variable id |
---|
A convenience method to format a collection of variable ids into a comma-separated string.
varids | collection of variable ids |
---|
Generate an offset IR-to-native offset conversion map.
Determine the aggregated context type of an instruction.
insn | instruction |
---|---|
inclAssigDst | if true and the instruction is an assignment, the destination is included when calculated the CAT; else, the right-side only is considered |
Get the list of reachable blocks of the provided IR-CFG. They are the blocks that can be reached, regularly or irregularly, from the entry-point block (i.e. the first block, at offset 0).
Determine whether the IR expression makes invocations (general invocations, new, new-array).
e | an IR expression |
---|
Determine whether the provided expression is or contains the provided variable.
e | an expression |
---|---|
varid | the searched variable id |
Determine whether the provided expression contains variables
.
e | an IR expression |
---|
Insert a header block filled with NOP instructions. Essentially, the CFG is shifted downward to accommodate the insertion of a number of lead instructions (to be executed before the entry point).
This method never fails. The returned CFG and IR context information is updated to maintain consistency.
ctx | an IR context |
---|---|
reqInsnCount | number of NOP instructions to be prepended |
reqInsnSize | size set for each individual instruction |
Determine if an expression is an IR immediate not holding the value 0.
exp | an IR expression |
---|
Determine if an expression is an IR immediate holding the provided value. The immediate value is determined according to its type. If the type of the expression is undetermined, a signed type is assumed.
exp | an IR expression |
---|---|
value | the value to check against |
Determine if an expression is an IR immediate holding the value 0.
exp | an IR expression |
---|
Determine whether the provided field is or appears to be final
.
Update the instruction sizes of a CFG. This method is a general version of
normalizeGraph()
. No CFG block is inserted or deleted. Only instructions' sizes and
offsets are updated. Note that the CFG is modified, but the CFG reference within the context
is not changed (i.e. no new CFG is created).
ctx | IR context |
---|---|
modifier | instruction size provider; the function may return null to indicate that the instruction size should not change |
Determine the meaningful next instruction in the execution flow, assuming no exception was raised. Jump targets are followed, no-operations are skipped.
cfg | current CFG |
---|---|
b | current block |
i | index of the current instruction in the block |
Normalize the IR by resetting all instructions to the unit size (1). Exception data is updated as well. The modification are done in-place: the CFG and other objects references remain valid.
ctx | IR context |
---|
Normalize the IR by resetting all instructions to the required size. Exception data is updated as well. The modification are done in-place: the CFG and other objects references remain valid.
ctx | IR context |
---|---|
wantedInstructionSize | required instruction size, must be 1 or above |
Parse a standard variable name (as generated by formatVarId(int)
) and retrieve the
associated variable id.
varname | a variable name |
---|---|
softFail | if true, return -1 on error; else, the method will throw IllegalArgumentException on error |
Remove all gaps from the provided IR-CFG.
Gaps are illegal in an IR-CFG. They are tolerated during an optimization phase; however, an optimizer, or any code modifying the IR, must provide a legal IR to subsequent components.
Remove an instruction in a block. Throws on error (watch out: the boolean return value does not indicate failure).
b | basic block |
---|---|
idx | index of the instruction to remove in this block |
Remove unreachable blocks from an IR-CFG. They are blocks that cannot be reached, regularly or irregularly, from the entry-point block (i.e. the first block, at offset 0).
Unreachable blocks are illegal in an IR-CFG. They are tolerated during an optimization phase; however, an optimizer, or any code modifying the IR, must provide a legal IR to subsequent components.
Remove unreachable blocks from an IR-CFG. They are blocks that cannot be reached, regularly or irregularly, from the entry-point block (i.e. the first block, at offset 0).
Unreachable blocks are illegal in an IR-CFG. They are tolerated during an optimization phase; however, an optimizer, or any code modifying the IR, must provide a legal IR to subsequent components.
Remove an unreachable trampoline block (ending on a JCOND or JUMP).
b | the block must be an unreachable (no input) trampoline (single-instruction jump/jcc); if the block is the first block in the CFG, the method will fail |
---|
Replace an IR expression located inside another IR. This method is a deep version of
replaceSubExpression(IDExpression, IDExpression)
. Comparison is done by
identity.
e | parent IR |
---|---|
target | the target to be replaced; should not be the same as `e` |
repl | the replacement IR |
Simply DOpcodeType#JCOND and IR_SWITCH
IR instructions:
- JCOND: the target branch must not point to the fallthrough instruction; if it is, the JCOND
must be replaced by a JUMP (while taking care of potential side-effects introduced by the
evaluation of the JCOND predicate)
- SWITCH: the case targets must not point to the fallthrough instruction; if any does, the
case entry must be removed (and will be taken care by the switch's default
entry)
Illegal JCOND/SWITCH are tolerated during an optimization phase; however, an optimizer, or any code modifying the IR, must provide a legal IR to subsequent components.
Split a block of the context's CFG into two blocks. The newly-created block will be set up to have the same irregular outputs as the original block. The context's exception information data will be updated accordingly.
index | index of the "split instruction" in the block; that instruction will be the first instruction of the newly-created block |
---|
Unprotect a basic block. The CFG is adjusted and cleaned afterward.
blkAddress | block address |
---|
Attempt to unroll some code whose pivot is a single variable
. The generated
code will not contain branching instructions JUMP, JCOND, SWITCH, RETURN, THROW, etc.).
ctx | IR method context (which references the CFG to operate on) |
---|---|
pivotVar | pivot variable |
addrStart | start address (inclusive) - generally, the instruction at that address initializes the pivot variable, although it is not a requirement |
addrEnd | end address (exclusive), will stop the unrolling process |
maxProcessedInsnCount | maximum amount of instructions to process until the end is reached |
maxUnrolledInsnCount | maximum amount of unrolled instructions that may be generated |
maxLoopIterCnt | maximum count of iterations to be unrolled (note: keep in mind for values greater than 1, the resulting IR is likely to be larger than the original IR) |
duplicate()
to
create unique instructions)
ctx | IR context |
---|---|
oldToNewOffsets | a mapping of the old offsets to the corresponding new offsets |
Determine whether the IR expression uses references, defined as any of: accessing fields, accessing array elements, creating arrays.
e | an IR expression |
---|
Verify an IR-CFG from a method context. On failure, the CFG will be dumped to "failed.dot"
ctx | IR context, from which the CFG and optional exception-info object will be pulled |
---|---|
info | optional string added to the generated DOT file's header containing the CFG (if verification failed) |
RuntimeException | (or derived, such as IllegalArgumentException or IllegalStateException) if the verification failed |
---|
Verify an IR-CFG from a method context. On failure, the CFG will be dumped to "failed.dot"
ctx | IR context, from which the CFG and optional exception-info object will be pulled |
---|
RuntimeException | (or derived, such as IllegalArgumentException or IllegalStateException) if the verification failed |
---|
Verify an IR-CFG.
dumpFilename | optional path to filename where the CFG will be dumped if the verification filed |
---|---|
info | optional string added to the generated DOT file's header containing the CFG (if verification failed) |
RuntimeException | (or derived, such as IllegalArgumentException or IllegalStateException) if the verification failed |
---|
Verify an IR-CFG.
cfg | CFG |
---|---|
exdata | optional exception-info object |
dumpFilename | optional path to filename where the CFG will be dumped if the verification filed |
info | optional string added to the generated DOT file's header containing the CFG (if verification failed) |
RuntimeException | (or derived, such as IllegalArgumentException or IllegalStateException) if the verification failed |
---|