Package jadx.core.utils
Class BlockUtils
java.lang.Object
jadx.core.utils.BlockUtils
-
Constructor Summary
Constructors -
Method Summary
Modifier and TypeMethodDescriptionprivate static voidaddExcHandler(MethodNode mth, ExceptionHandler handler, BitSet set) private static voidaddPredecessors(Set<BlockNode> set, BlockNode from, BlockNode until) static booleanatLeastOnePathExists(Collection<BlockNode> startBlocks, BlockNode end) Search at least one path from startBlocks to endbitSetToBlocks(MethodNode mth, BitSet bs) static @Nullable BlockNodebitSetToOneBlock(MethodNode mth, BitSet bs) static booleanblockContains(BlockNode block, InsnNode insn) Check if instruction contains in block (use == for comparison, not equals)static BitSetblocksToBitSet(MethodNode mth, Collection<BlockNode> blocks) buildSimplePath(BlockNode block) static booleancheckFirstInsn(IBlock block, Predicate<InsnNode> predicate) static booleancheckLastInsnType(IBlock block, InsnType expectedType) static voidcleanBitSet(MethodNode mth, BitSet bs) Remove exception handlers from block nodes bitsetcleanBlockList(List<BlockNode> list) Remove exception handlers from block nodes listcollectAllInsns(List<BlockNode> blocks) collectAllPredecessors(MethodNode mth, BlockNode startBlock) collectAllSuccessors(MethodNode mth, BlockNode startBlock, boolean clean) collectAllSuccessorsUntil(MethodNode mth, BlockNode startBlock, boolean clean, Predicate<BlockNode> stopCondition) private static voidcollectAllSuccessorsUntil(MethodNode mth, List<BlockNode> blocks, BlockNode currentBlock, boolean clean, Predicate<BlockNode> stopCondition) collectBlocksDominatedBy(MethodNode mth, BlockNode dominator, BlockNode start) Collect all block dominated by 'dominator', starting from 'start'collectBlocksDominatedByWithExcHandlers(MethodNode mth, BlockNode dominator, BlockNode start) Collect all block dominated by 'dominator', starting from 'start', including exception handlerscollectInsnsWithLimit(List<BlockNode> blocks, int limit) Return limited number of instructions from method.collectPathUntil(BlockNode from, BlockNode until, boolean clean, Predicate<BlockNode> pred) Traverse succcessors until a node is found, collecting the path to the nodecollectPredecessors(MethodNode mth, BlockNode start, Collection<BlockNode> stopBlocks) private static voidcollectWhileDominates(BlockNode dominator, BlockNode child, Collection<BlockNode> result, BitSet visited, boolean includeExcHandlers) static booleancontainsExitInsn(IBlock block) static BitSetcopyBlocksBitSet(MethodNode mth, BitSet bitSet) static BlockNodefollowEmptyPath(BlockNode start) Follow empty blocks and return end of path block (first not empty).static BlockNodefollowEmptyPath(BlockNode start, Boolean reverse) static BlockNodefollowEmptyPath(BlockNode start, Boolean reverse, boolean cleanOnly) followEmptyUpPathWithinSet(BlockNode start, Collection<BlockNode> traversableBlocks) static voidfollowEmptyUpPathWithinSet(List<BlockNode> results, BlockNode start, Collection<BlockNode> traversableBlocks, Collection<BlockNode> traversedBlocks) static voidforEachBlockFromBitSet(MethodNode mth, BitSet bs, Consumer<BlockNode> consumer) private static InsnArgfoundWrappedInsn(InsnNode container, InsnNode insn) private static InsnArgfoundWrappedInsnInCondition(IfCondition cond, InsnNode insn) getAllPathsBlocks(BlockNode start, BlockNode end) Collect blocks from all possible execution paths from 'start' to 'end'static @Nullable BlockNodegetBlockByInsn(MethodNode mth, @Nullable InsnNode insn) static @Nullable BlockNodegetBlockByInsn(MethodNode mth, @Nullable InsnNode insn, List<BlockNode> blocks) static BlockNodegetBlockByOffset(int offset, Iterable<BlockNode> casesBlocks) private static BlockNodegetBlockByWrappedInsn(MethodNode mth, InsnNode insn) static @Nullable BlockNodegetBlockWithFlag(List<BlockNode> blocks, AFlag flag) static @Nullable BlockNodegetBottomBlock(List<BlockNode> blocks) Search last block in control flow graph from input set.static BlockNodegetBottomBlock(List<BlockNode> blocks, boolean clean) static @Nullable BlockNodegetBottomCommonPredecessor(MethodNode mth, List<BlockNode> blocks, Set<BlockNode> containedBlocks) static @Nullable BlockNodegetBottomCommonPredecessor(MethodNode mth, List<BlockNode> blocks, Set<BlockNode> containedBlocks, boolean addTopBlock) static @Nullable CatchAttrgetCatchAttrForInsn(MethodNode mth, InsnNode insn) static @Nullable BlockNodegetCommonDominator(MethodNode mth, List<BlockNode> blocks) Search the lowest common ancestor in dominator tree for input set.static BitSetReturn the dominace frontier of an edge - the blocks for which any path to the block must pass through this edgestatic @Nullable InsnNodegetFirstInsn(@Nullable IBlock block) static intgetFirstSourceLine(IBlock block) static intgetInsnIndexInBlock(BlockNode block, InsnNode insn) static @Nullable InsnNodegetLastInsn(@Nullable IBlock block) static InsnNodegetLastInsnWithType(IBlock block, InsnType expectedType) static @Nullable BlockNodegetNextBlock(BlockNode block) Return first successor which not exception handler and not follow loop back edgeprivate static @Nullable BlockNodegetNextBlockOnEmptyPath(BlockNode block) private static @Nullable BlockNodegetNextBlockOnEmptyPath(BlockNode block, Boolean reverse) private static @Nullable BlockNodegetNextBlockOnEmptyPath(BlockNode block, Boolean reverse, boolean cleanOnly) static BlockNodegetNextBlockToPath(BlockNode block, BlockNode pathEnd) Return successor on path to 'pathEnd' blockstatic @Nullable BlockNodegetNextSinglePathBlock(BlockNode block) getOneEmptyPath(BlockNode start, BlockNode end) Collect blocks from one possible execution path from 'start' to 'end' containing no instructionsgetOnePath(BlockNode start, BlockNode end) Collect blocks from one possible execution path from 'start' to 'end'static @Nullable InsnNodeReturn insn if it is only one instruction in this method.static BlockNodegetPathCross(MethodNode mth, BlockNode b1, BlockNode b2) static @Nullable BlockNodegetPathCross(MethodNode mth, Collection<BlockNode> blocks) Return common cross block for input set.static @Nullable BlockNodegetPrevBlock(BlockNode block) static @Nullable BlockNodegetPrevBlockOnPath(MethodNode mth, BlockNode block, BlockNode pathStart) Return predecessor on path from 'pathStart' blockstatic BlockNodegetTopBlock(List<BlockNode> blocks) static @Nullable BlockNodegetTopCommonSuccessor(MethodNode mth, List<BlockNode> blocks, boolean cleanOnly) static @Nullable BlockNodegetTopCommonSuccessor(MethodNode mth, List<BlockNode> blocks, boolean cleanOnly, boolean addTopBlock) static BlockNodegetTopSplitterForHandler(BlockNode handlerBlock) static @Nullable BlockNodegetTryAndHandlerCrossBlock(MethodNode mth, ExceptionHandler handler) Return out block of try catch, by finding where try branch meets catch branch.static booleaninsertAfterInsn(BlockNode block, InsnNode insn, InsnNode newInsn) static booleaninsertBeforeInsn(BlockNode block, InsnNode insn, InsnNode newInsn) internalCollectPathUntil(BlockNode from, BlockNode until, BitSet visited, boolean clean, Predicate<BlockNode> pred) Traverse succcessors until a node is found, collecting the path to the nodestatic booleanisAllBlocksEmpty(List<BlockNode> blocks) static booleanisAllPathExists(Collection<BlockNode> startBlocks, BlockNode end) Check if exist path from every startBlocks to endstatic booleanisAnyPathExists(BlockNode start, BlockNode end) static booleanisBackEdge(BlockNode from, BlockNode to) static booleanisDuplicateBlockPath(BlockNode first, BlockNode second) static booleanisEmptySimplePath(BlockNode start, BlockNode end) Return true if on path from start to end no instructions and no branches.private static booleanisEmptySyntheticPath(BlockNode b1, BlockNode b2) static booleanisEqualPaths(BlockNode b1, BlockNode b2) static booleanisEqualReturnBlocks(BlockNode b1, BlockNode b2) static booleanstatic booleanisExitBlock(BlockNode block) static booleanisExitBlock(MethodNode mth, BlockNode block) static booleanisFirstInsn(MethodNode mth, InsnNode insn) static booleanisFollowBackEdge(BlockNode block) private static booleanisInsnDeepEquals(InsnNode first, InsnNode second) static booleanisOnlyOnePathExists(BlockNode start, BlockNode end) static booleanisPathExists(BlockNode start, BlockNode end) static booleanisPathExists(BlockNode start, BlockNode end, Predicate<BlockNode> pred) static booleanisSameInsnsBlocks(BlockNode first, BlockNode second) static BitSetstatic voidremoveInstructions(List<IBlock> blocks) static voidreplaceInsn(MethodNode mth, BlockNode block, int i, InsnNode insn) Replace insn by index i in block, for proper copy attributes, assume attributes are not overlapstatic booleanreplaceInsn(MethodNode mth, BlockNode block, InsnNode oldInsn, InsnNode newInsn) static booleanreplaceInsn(MethodNode mth, InsnNode oldInsn, InsnNode newInsn) private static booleanresultIsSameReg(RegisterArg first, RegisterArg second) static BlockNodesearchBlockWithPhi(MethodNode mth, PhiInsn insn) static InsnNodesearchInsnParent(MethodNode mth, InsnNode insn) static InsnArgsearchWrappedInsnParent(MethodNode mth, InsnNode insn) static BlockNodeselectOther(BlockNode node, List<BlockNode> blocks) static BlockNodeselectOtherSafe(BlockNode node, List<BlockNode> blocks) static voidskipPredSyntheticPaths(BlockNode block) Set 'SKIP' flag for all synthetic predecessors from start block.static BlockNodeReturn predecessor of synthetic block or same block otherwise.private static voidtraversePredecessors(BlockNode start, BitSet visited, Predicate<BlockNode> visitor) Up BFS.private static booleantraverseSuccessorsUntil(BlockNode from, BlockNode until, BitSet visited, boolean clean) private static booleantraverseSuccessorsUntil(BlockNode from, BlockNode until, BitSet visited, boolean clean, Predicate<BlockNode> pred) Traverse succcessors until a node is foundstatic BlockNodetraverseWhileDominates(BlockNode dom, BlockNode start) Search for first node which not dominated by dom, starting from startstatic voidvisitBlocksOnEmptyPath(BlockNode start, Consumer<BlockNode> visitor) static voidvisitBlocksOnEmptyPath(BlockNode start, Consumer<BlockNode> visitor, boolean reverse) static booleanvisitBlocksOnPath(MethodNode mth, BlockNode start, BlockNode end, Consumer<BlockNode> visitor) Visit blocks on any path from start to end.private static voidvisitDFS(MethodNode mth, BlockNode startBlock, Function<BlockNode, List<BlockNode>> nextFunc, Consumer<BlockNode> visitor) static voidvisitDFS(MethodNode mth, Consumer<BlockNode> visitor) static voidvisitPredecessorsUntil(MethodNode mth, BlockNode start, Predicate<BlockNode> visitor) static voidvisitReverseDFS(MethodNode mth, Consumer<BlockNode> visitor) static voidvisitSinglePath(BlockNode startBlock, Consumer<BlockNode> visitor) Visit blocks on path without branching or merging paths.
-
Constructor Details
-
BlockUtils
private BlockUtils()
-
-
Method Details
-
getBlockByOffset
-
selectOther
-
selectOtherSafe
-
isExceptionHandlerPath
-
cleanBlockList
Remove exception handlers from block nodes list -
cleanBitSet
Remove exception handlers from block nodes bitset -
isBackEdge
-
isFollowBackEdge
-
blockContains
Check if instruction contains in block (use == for comparison, not equals) -
checkFirstInsn
-
checkLastInsnType
-
getLastInsnWithType
-
getFirstSourceLine
-
getFirstInsn
-
getLastInsn
-
isExitBlock
-
isExitBlock
-
containsExitInsn
-
getBlockByInsn
@Nullable public static @Nullable BlockNode getBlockByInsn(MethodNode mth, @Nullable @Nullable InsnNode insn) -
getBlockByInsn
@Nullable public static @Nullable BlockNode getBlockByInsn(MethodNode mth, @Nullable @Nullable InsnNode insn, List<BlockNode> blocks) -
searchBlockWithPhi
-
getBlockByWrappedInsn
-
searchInsnParent
-
searchWrappedInsnParent
-
foundWrappedInsn
-
foundWrappedInsnInCondition
-
newBlocksBitSet
-
copyBlocksBitSet
-
blocksToBitSet
-
bitSetToOneBlock
-
bitSetToBlocks
-
forEachBlockFromBitSet
-
getNextBlock
Return first successor which not exception handler and not follow loop back edge -
getPrevBlock
-
getNextBlockToPath
Return successor on path to 'pathEnd' block -
getPrevBlockOnPath
@Nullable public static @Nullable BlockNode getPrevBlockOnPath(MethodNode mth, BlockNode block, BlockNode pathStart) Return predecessor on path from 'pathStart' block -
visitBlocksOnPath
public static boolean visitBlocksOnPath(MethodNode mth, BlockNode start, BlockNode end, Consumer<BlockNode> visitor) Visit blocks on any path from start to end. Only one path will be visited! -
collectAllPredecessors
-
collectAllSuccessors
public static List<BlockNode> collectAllSuccessors(MethodNode mth, BlockNode startBlock, boolean clean) -
collectAllSuccessorsUntil
-
collectAllSuccessorsUntil
-
getBottomCommonPredecessor
-
getBottomCommonPredecessor
-
getTopCommonSuccessor
@Nullable public static @Nullable BlockNode getTopCommonSuccessor(MethodNode mth, List<BlockNode> blocks, boolean cleanOnly) -
getTopCommonSuccessor
@Nullable public static @Nullable BlockNode getTopCommonSuccessor(MethodNode mth, List<BlockNode> blocks, boolean cleanOnly, boolean addTopBlock) -
visitDFS
-
visitReverseDFS
-
visitDFS
-
collectPredecessors
public static List<BlockNode> collectPredecessors(MethodNode mth, BlockNode start, Collection<BlockNode> stopBlocks) -
visitPredecessorsUntil
public static void visitPredecessorsUntil(MethodNode mth, BlockNode start, Predicate<BlockNode> visitor) -
traversePredecessors
private static void traversePredecessors(BlockNode start, BitSet visited, Predicate<BlockNode> visitor) Up BFS. To stop return true from predicate -
getAllPathsBlocks
Collect blocks from all possible execution paths from 'start' to 'end' -
getOneEmptyPath
Collect blocks from one possible execution path from 'start' to 'end' containing no instructions -
getOnePath
Collect blocks from one possible execution path from 'start' to 'end' -
addPredecessors
-
traverseSuccessorsUntil
-
traverseSuccessorsUntil
private static boolean traverseSuccessorsUntil(BlockNode from, BlockNode until, BitSet visited, boolean clean, Predicate<BlockNode> pred) Traverse succcessors until a node is found- Parameters:
from- the source node to begin traversinguntil- the destination node to halt traversingvisited- the set of visited blocks so farclean- use only clean successorspred- a predicate that must be true to traverse a block (until or a reachable dominator of until must satisfy pred)- Returns:
- true if there is a path from `from` to `until` or a dominator of `until` through blocks that satisfy `pred`, false otherwise
-
collectPathUntil
public static List<BlockNode> collectPathUntil(BlockNode from, BlockNode until, boolean clean, Predicate<BlockNode> pred) Traverse succcessors until a node is found, collecting the path to the node- Parameters:
from- the source node to begin traversinguntil- the destination node to halt traversingclean- use only clean successorspred- a predicate that must be true to traverse a block (until must satisfy pred)- Returns:
- the list of blocks satisfying pred on a path between from and until (inclusive), or null if no such path exists
-
internalCollectPathUntil
private static List<BlockNode> internalCollectPathUntil(BlockNode from, BlockNode until, BitSet visited, boolean clean, Predicate<BlockNode> pred) Traverse succcessors until a node is found, collecting the path to the node- Parameters:
from- the source node to begin traversinguntil- the destination node to halt traversingvisited- the set of visited blocks so farclean- use only clean successorspred- a predicate that must be true to traverse a block (until must satisfy pred)- Returns:
- the list of blocks satisfying pred on a path between from (exclusive) and until (inclusive) in reverse order, or null if no such path exists
-
atLeastOnePathExists
Search at least one path from startBlocks to end -
isAllPathExists
Check if exist path from every startBlocks to end -
isPathExists
-
isAnyPathExists
-
isPathExists
-
getTopBlock
-
getBottomBlock
Search last block in control flow graph from input set. -
getBottomBlock
-
isOnlyOnePathExists
-
traverseWhileDominates
Search for first node which not dominated by dom, starting from start -
getCommonDominator
@Nullable public static @Nullable BlockNode getCommonDominator(MethodNode mth, List<BlockNode> blocks) Search the lowest common ancestor in dominator tree for input set. -
getDomFrontierThroughEdge
Return the dominace frontier of an edge - the blocks for which any path to the block must pass through this edge -
getPathCross
@Nullable public static @Nullable BlockNode getPathCross(MethodNode mth, Collection<BlockNode> blocks) Return common cross block for input set.- Returns:
- could be one of the giving blocks. null if cross is a method exit block.
-
addExcHandler
-
getPathCross
-
collectBlocksDominatedBy
public static List<BlockNode> collectBlocksDominatedBy(MethodNode mth, BlockNode dominator, BlockNode start) Collect all block dominated by 'dominator', starting from 'start' -
collectBlocksDominatedByWithExcHandlers
public static Set<BlockNode> collectBlocksDominatedByWithExcHandlers(MethodNode mth, BlockNode dominator, BlockNode start) Collect all block dominated by 'dominator', starting from 'start', including exception handlers -
collectWhileDominates
private static void collectWhileDominates(BlockNode dominator, BlockNode child, Collection<BlockNode> result, BitSet visited, boolean includeExcHandlers) -
visitSinglePath
Visit blocks on path without branching or merging paths. -
getNextSinglePathBlock
-
buildSimplePath
-
skipPredSyntheticPaths
Set 'SKIP' flag for all synthetic predecessors from start block. -
followEmptyPath
Follow empty blocks and return end of path block (first not empty). Return start block if no such path. -
followEmptyPath
-
followEmptyPath
-
followEmptyUpPathWithinSet
public static List<BlockNode> followEmptyUpPathWithinSet(BlockNode start, Collection<BlockNode> traversableBlocks) -
followEmptyUpPathWithinSet
public static void followEmptyUpPathWithinSet(List<BlockNode> results, BlockNode start, Collection<BlockNode> traversableBlocks, Collection<BlockNode> traversedBlocks) -
visitBlocksOnEmptyPath
-
visitBlocksOnEmptyPath
-
getNextBlockOnEmptyPath
-
getNextBlockOnEmptyPath
-
getNextBlockOnEmptyPath
-
isEmptySimplePath
Return true if on path from start to end no instructions and no branches. -
skipSyntheticPredecessor
Return predecessor of synthetic block or same block otherwise. -
isAllBlocksEmpty
-
collectAllInsns
-
collectInsnsWithLimit
Return limited number of instructions from method. Return empty list if method contains more than limit. -
getOnlyOneInsnFromMth
Return insn if it is only one instruction in this method. Return null otherwise. -
isFirstInsn
-
replaceInsn
Replace insn by index i in block, for proper copy attributes, assume attributes are not overlap -
replaceInsn
public static boolean replaceInsn(MethodNode mth, BlockNode block, InsnNode oldInsn, InsnNode newInsn) -
removeInstructions
-
insertBeforeInsn
-
insertAfterInsn
-
getInsnIndexInBlock
-
replaceInsn
-
getTopSplitterForHandler
-
getTryAndHandlerCrossBlock
@Nullable public static @Nullable BlockNode getTryAndHandlerCrossBlock(MethodNode mth, ExceptionHandler handler) Return out block of try catch, by finding where try branch meets catch branch. It traverse domFrontier start from handler block, find the first frontier whose predecessor is try end.
It could return null if they never meets, but this doesn't mean that catch ends at the method exit. (see TestSwitchWithTryCatch and ExcHandlersRegionMaker#processExcHandler). -
getBlockWithFlag
-
getCatchAttrForInsn
-
isEqualPaths
-
isEmptySyntheticPath
-
isEqualReturnBlocks
-
isDuplicateBlockPath
-
isSameInsnsBlocks
-
isInsnDeepEquals
-
resultIsSameReg
-