Class BlockUtils

java.lang.Object
jadx.core.utils.BlockUtils

public class BlockUtils extends Object
  • Constructor Details

    • BlockUtils

      private BlockUtils()
  • Method Details

    • getBlockByOffset

      public static BlockNode getBlockByOffset(int offset, Iterable<BlockNode> casesBlocks)
    • selectOther

      public static BlockNode selectOther(BlockNode node, List<BlockNode> blocks)
    • selectOtherSafe

      public static BlockNode selectOtherSafe(BlockNode node, List<BlockNode> blocks)
    • isExceptionHandlerPath

      public static boolean isExceptionHandlerPath(BlockNode b)
    • cleanBlockList

      private static List<BlockNode> cleanBlockList(List<BlockNode> list)
      Remove exception handlers from block nodes list
    • cleanBitSet

      public static void cleanBitSet(MethodNode mth, BitSet bs)
      Remove exception handlers from block nodes bitset
    • isBackEdge

      public static boolean isBackEdge(BlockNode from, BlockNode to)
    • isFollowBackEdge

      public static boolean isFollowBackEdge(BlockNode block)
    • blockContains

      public static boolean blockContains(BlockNode block, InsnNode insn)
      Check if instruction contains in block (use == for comparison, not equals)
    • checkFirstInsn

      public static boolean checkFirstInsn(IBlock block, Predicate<InsnNode> predicate)
    • checkLastInsnType

      public static boolean checkLastInsnType(IBlock block, InsnType expectedType)
    • getLastInsnWithType

      public static InsnNode getLastInsnWithType(IBlock block, InsnType expectedType)
    • getFirstSourceLine

      public static int getFirstSourceLine(IBlock block)
    • getFirstInsn

      @Nullable public static @Nullable InsnNode getFirstInsn(@Nullable @Nullable IBlock block)
    • getLastInsn

      @Nullable public static @Nullable InsnNode getLastInsn(@Nullable @Nullable IBlock block)
    • isExitBlock

      public static boolean isExitBlock(MethodNode mth, BlockNode block)
    • isExitBlock

      public static boolean isExitBlock(BlockNode block)
    • containsExitInsn

      public static boolean containsExitInsn(IBlock block)
    • 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

      public static BlockNode searchBlockWithPhi(MethodNode mth, PhiInsn insn)
    • getBlockByWrappedInsn

      private static BlockNode getBlockByWrappedInsn(MethodNode mth, InsnNode insn)
    • searchInsnParent

      public static InsnNode searchInsnParent(MethodNode mth, InsnNode insn)
    • searchWrappedInsnParent

      public static InsnArg searchWrappedInsnParent(MethodNode mth, InsnNode insn)
    • foundWrappedInsn

      private static InsnArg foundWrappedInsn(InsnNode container, InsnNode insn)
    • foundWrappedInsnInCondition

      private static InsnArg foundWrappedInsnInCondition(IfCondition cond, InsnNode insn)
    • newBlocksBitSet

      public static BitSet newBlocksBitSet(MethodNode mth)
    • copyBlocksBitSet

      public static BitSet copyBlocksBitSet(MethodNode mth, BitSet bitSet)
    • blocksToBitSet

      public static BitSet blocksToBitSet(MethodNode mth, Collection<BlockNode> blocks)
    • bitSetToOneBlock

      @Nullable public static @Nullable BlockNode bitSetToOneBlock(MethodNode mth, BitSet bs)
    • bitSetToBlocks

      public static List<BlockNode> bitSetToBlocks(MethodNode mth, BitSet bs)
    • forEachBlockFromBitSet

      public static void forEachBlockFromBitSet(MethodNode mth, BitSet bs, Consumer<BlockNode> consumer)
    • getNextBlock

      @Nullable public static @Nullable BlockNode getNextBlock(BlockNode block)
      Return first successor which not exception handler and not follow loop back edge
    • getPrevBlock

      @Nullable public static @Nullable BlockNode getPrevBlock(BlockNode block)
    • getNextBlockToPath

      public static BlockNode getNextBlockToPath(BlockNode block, BlockNode pathEnd)
      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

      public static List<BlockNode> collectAllPredecessors(MethodNode mth, BlockNode startBlock)
    • collectAllSuccessors

      public static List<BlockNode> collectAllSuccessors(MethodNode mth, BlockNode startBlock, boolean clean)
    • collectAllSuccessorsUntil

      public static List<BlockNode> collectAllSuccessorsUntil(MethodNode mth, BlockNode startBlock, boolean clean, Predicate<BlockNode> stopCondition)
    • collectAllSuccessorsUntil

      private static void collectAllSuccessorsUntil(MethodNode mth, List<BlockNode> blocks, BlockNode currentBlock, boolean clean, Predicate<BlockNode> stopCondition)
    • getBottomCommonPredecessor

      @Nullable public static @Nullable BlockNode getBottomCommonPredecessor(MethodNode mth, List<BlockNode> blocks, Set<BlockNode> containedBlocks)
    • getBottomCommonPredecessor

      @Nullable public static @Nullable BlockNode getBottomCommonPredecessor(MethodNode mth, List<BlockNode> blocks, Set<BlockNode> containedBlocks, boolean addTopBlock)
    • 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

      public static void visitDFS(MethodNode mth, Consumer<BlockNode> visitor)
    • visitReverseDFS

      public static void visitReverseDFS(MethodNode mth, Consumer<BlockNode> visitor)
    • visitDFS

      private static void visitDFS(MethodNode mth, BlockNode startBlock, Function<BlockNode,List<BlockNode>> nextFunc, Consumer<BlockNode> visitor)
    • 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

      public static Set<BlockNode> getAllPathsBlocks(BlockNode start, BlockNode end)
      Collect blocks from all possible execution paths from 'start' to 'end'
    • getOneEmptyPath

      public static List<BlockNode> getOneEmptyPath(BlockNode start, BlockNode end)
      Collect blocks from one possible execution path from 'start' to 'end' containing no instructions
    • getOnePath

      public static List<BlockNode> getOnePath(BlockNode start, BlockNode end)
      Collect blocks from one possible execution path from 'start' to 'end'
    • addPredecessors

      private static void addPredecessors(Set<BlockNode> set, BlockNode from, BlockNode until)
    • traverseSuccessorsUntil

      private static boolean traverseSuccessorsUntil(BlockNode from, BlockNode until, BitSet visited, boolean clean)
    • 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 traversing
      until - the destination node to halt traversing
      visited - the set of visited blocks so far
      clean - use only clean successors
      pred - 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 traversing
      until - the destination node to halt traversing
      clean - use only clean successors
      pred - 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 traversing
      until - the destination node to halt traversing
      visited - the set of visited blocks so far
      clean - use only clean successors
      pred - 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

      public static boolean atLeastOnePathExists(Collection<BlockNode> startBlocks, BlockNode end)
      Search at least one path from startBlocks to end
    • isAllPathExists

      public static boolean isAllPathExists(Collection<BlockNode> startBlocks, BlockNode end)
      Check if exist path from every startBlocks to end
    • isPathExists

      public static boolean isPathExists(BlockNode start, BlockNode end)
    • isAnyPathExists

      public static boolean isAnyPathExists(BlockNode start, BlockNode end)
    • isPathExists

      public static boolean isPathExists(BlockNode start, BlockNode end, Predicate<BlockNode> pred)
    • getTopBlock

      public static BlockNode getTopBlock(List<BlockNode> blocks)
    • getBottomBlock

      @Nullable public static @Nullable BlockNode getBottomBlock(List<BlockNode> blocks)
      Search last block in control flow graph from input set.
    • getBottomBlock

      public static BlockNode getBottomBlock(List<BlockNode> blocks, boolean clean)
    • isOnlyOnePathExists

      public static boolean isOnlyOnePathExists(BlockNode start, BlockNode end)
    • traverseWhileDominates

      public static BlockNode traverseWhileDominates(BlockNode dom, BlockNode start)
      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

      public static BitSet getDomFrontierThroughEdge(Edge edge)
      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

      private static void addExcHandler(MethodNode mth, ExceptionHandler handler, BitSet set)
    • getPathCross

      public static BlockNode getPathCross(MethodNode mth, BlockNode b1, BlockNode b2)
    • 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

      public static void visitSinglePath(BlockNode startBlock, Consumer<BlockNode> visitor)
      Visit blocks on path without branching or merging paths.
    • getNextSinglePathBlock

      @Nullable public static @Nullable BlockNode getNextSinglePathBlock(BlockNode block)
    • buildSimplePath

      public static List<BlockNode> buildSimplePath(BlockNode block)
    • skipPredSyntheticPaths

      public static void skipPredSyntheticPaths(BlockNode block)
      Set 'SKIP' flag for all synthetic predecessors from start block.
    • followEmptyPath

      public static BlockNode followEmptyPath(BlockNode start)
      Follow empty blocks and return end of path block (first not empty). Return start block if no such path.
    • followEmptyPath

      public static BlockNode followEmptyPath(BlockNode start, Boolean reverse)
    • followEmptyPath

      public static BlockNode followEmptyPath(BlockNode start, Boolean reverse, boolean cleanOnly)
    • 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

      public static void visitBlocksOnEmptyPath(BlockNode start, Consumer<BlockNode> visitor)
    • visitBlocksOnEmptyPath

      public static void visitBlocksOnEmptyPath(BlockNode start, Consumer<BlockNode> visitor, boolean reverse)
    • getNextBlockOnEmptyPath

      @Nullable private static @Nullable BlockNode getNextBlockOnEmptyPath(BlockNode block)
    • getNextBlockOnEmptyPath

      @Nullable private static @Nullable BlockNode getNextBlockOnEmptyPath(BlockNode block, Boolean reverse)
    • getNextBlockOnEmptyPath

      @Nullable private static @Nullable BlockNode getNextBlockOnEmptyPath(BlockNode block, Boolean reverse, boolean cleanOnly)
    • isEmptySimplePath

      public static boolean isEmptySimplePath(BlockNode start, BlockNode end)
      Return true if on path from start to end no instructions and no branches.
    • skipSyntheticPredecessor

      public static BlockNode skipSyntheticPredecessor(BlockNode block)
      Return predecessor of synthetic block or same block otherwise.
    • isAllBlocksEmpty

      public static boolean isAllBlocksEmpty(List<BlockNode> blocks)
    • collectAllInsns

      public static List<InsnNode> collectAllInsns(List<BlockNode> blocks)
    • collectInsnsWithLimit

      public static List<InsnNode> collectInsnsWithLimit(List<BlockNode> blocks, int limit)
      Return limited number of instructions from method. Return empty list if method contains more than limit.
    • getOnlyOneInsnFromMth

      @Nullable public static @Nullable InsnNode getOnlyOneInsnFromMth(MethodNode mth)
      Return insn if it is only one instruction in this method. Return null otherwise.
    • isFirstInsn

      public static boolean isFirstInsn(MethodNode mth, InsnNode insn)
    • replaceInsn

      public static void replaceInsn(MethodNode mth, BlockNode block, int i, InsnNode insn)
      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

      public static void removeInstructions(List<IBlock> blocks)
    • insertBeforeInsn

      public static boolean insertBeforeInsn(BlockNode block, InsnNode insn, InsnNode newInsn)
    • insertAfterInsn

      public static boolean insertAfterInsn(BlockNode block, InsnNode insn, InsnNode newInsn)
    • getInsnIndexInBlock

      public static int getInsnIndexInBlock(BlockNode block, InsnNode insn)
    • replaceInsn

      public static boolean replaceInsn(MethodNode mth, InsnNode oldInsn, InsnNode newInsn)
    • getTopSplitterForHandler

      public static BlockNode getTopSplitterForHandler(BlockNode handlerBlock)
    • 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

      @Nullable public static @Nullable BlockNode getBlockWithFlag(List<BlockNode> blocks, AFlag flag)
    • getCatchAttrForInsn

      @Nullable public static @Nullable CatchAttr getCatchAttrForInsn(MethodNode mth, InsnNode insn)
    • isEqualPaths

      public static boolean isEqualPaths(BlockNode b1, BlockNode b2)
    • isEmptySyntheticPath

      private static boolean isEmptySyntheticPath(BlockNode b1, BlockNode b2)
    • isEqualReturnBlocks

      public static boolean isEqualReturnBlocks(BlockNode b1, BlockNode b2)
    • isDuplicateBlockPath

      public static boolean isDuplicateBlockPath(BlockNode first, BlockNode second)
    • isSameInsnsBlocks

      public static boolean isSameInsnsBlocks(BlockNode first, BlockNode second)
    • isInsnDeepEquals

      private static boolean isInsnDeepEquals(InsnNode first, InsnNode second)
    • resultIsSameReg

      private static boolean resultIsSameReg(RegisterArg first, RegisterArg second)