Search in sources :

Example 56 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockUtils method getPathCross.

/**
 * Return common cross block for input set.
 *
 * @return null if cross is a method exit block.
 */
@Nullable
public static BlockNode getPathCross(MethodNode mth, Collection<BlockNode> blocks) {
    BitSet domFrontBS = newBlocksBitSet(mth);
    boolean first = true;
    for (BlockNode b : blocks) {
        if (first) {
            domFrontBS.or(b.getDomFrontier());
            first = false;
        } else {
            domFrontBS.and(b.getDomFrontier());
        }
    }
    domFrontBS.clear(mth.getExitBlock().getId());
    if (domFrontBS.isEmpty()) {
        return null;
    }
    BlockNode oneBlock = bitSetToOneBlock(mth, domFrontBS);
    if (oneBlock != null) {
        return oneBlock;
    }
    BitSet excluded = newBlocksBitSet(mth);
    // exclude method exit and loop start blocks
    excluded.set(mth.getExitBlock().getId());
    // exclude loop start blocks
    mth.getLoops().forEach(l -> excluded.set(l.getStart().getId()));
    if (!mth.isNoExceptionHandlers()) {
        // exclude exception handlers paths
        mth.getExceptionHandlers().forEach(h -> mergeExcHandlerDomFrontier(mth, h, excluded));
    }
    domFrontBS.andNot(excluded);
    oneBlock = bitSetToOneBlock(mth, domFrontBS);
    if (oneBlock != null) {
        return oneBlock;
    }
    BitSet combinedDF = newBlocksBitSet(mth);
    int k = mth.getBasicBlocks().size();
    while (true) {
        // collect dom frontier blocks from current set until only one block left
        forEachBlockFromBitSet(mth, domFrontBS, block -> {
            BitSet domFrontier = block.getDomFrontier();
            if (!domFrontier.isEmpty()) {
                combinedDF.or(domFrontier);
                combinedDF.clear(block.getId());
            }
        });
        combinedDF.andNot(excluded);
        int cardinality = combinedDF.cardinality();
        if (cardinality == 1) {
            return bitSetToOneBlock(mth, combinedDF);
        }
        if (cardinality == 0) {
            return null;
        }
        if (k-- < 0) {
            mth.addWarnComment("Path cross not found for " + blocks + ", limit reached: " + mth.getBasicBlocks().size());
            return null;
        }
        // replace domFrontBS with combinedDF
        domFrontBS.clear();
        domFrontBS.or(combinedDF);
        combinedDF.clear();
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) BitSet(java.util.BitSet) Nullable(org.jetbrains.annotations.Nullable)

Example 57 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockUtils method followEmptyPath.

/**
 * Follow empty blocks and return end of path block (first not empty).
 * Return start block if no such path.
 */
public static BlockNode followEmptyPath(BlockNode start) {
    while (true) {
        BlockNode next = getNextBlockOnEmptyPath(start);
        if (next == null) {
            return start;
        }
        start = next;
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode)

Example 58 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockUtils method isFirstInsn.

public static boolean isFirstInsn(MethodNode mth, InsnNode insn) {
    BlockNode startBlock = followEmptyPath(mth.getEnterBlock());
    if (startBlock != null && !startBlock.getInstructions().isEmpty()) {
        return startBlock.getInstructions().get(0) == insn;
    }
    // handle branching with empty blocks
    BlockNode block = getBlockByInsn(mth, insn);
    if (block == null) {
        throw new JadxRuntimeException("Insn not found in method: " + insn);
    }
    if (block.getInstructions().get(0) != insn) {
        return false;
    }
    Set<BlockNode> allPathsBlocks = getAllPathsBlocks(mth.getEnterBlock(), block);
    for (BlockNode pathBlock : allPathsBlocks) {
        if (!pathBlock.getInstructions().isEmpty() && pathBlock != block) {
            return false;
        }
    }
    return true;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException)

Example 59 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockUtils method visitSinglePath.

/**
 * Visit blocks on path without branching or merging paths.
 */
public static void visitSinglePath(BlockNode startBlock, Consumer<BlockNode> visitor) {
    if (startBlock == null) {
        return;
    }
    visitor.accept(startBlock);
    BlockNode next = getNextSinglePathBlock(startBlock);
    while (next != null) {
        visitor.accept(next);
        next = getNextSinglePathBlock(next);
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode)

Example 60 with BlockNode

use of jadx.core.dex.nodes.BlockNode in project jadx by skylot.

the class BlockUtils method visitBlocksOnEmptyPath.

public static void visitBlocksOnEmptyPath(BlockNode start, Consumer<BlockNode> visitor) {
    while (true) {
        BlockNode next = getNextBlockOnEmptyPath(start);
        if (next == null) {
            return;
        }
        visitor.accept(next);
        start = next;
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode)

Aggregations

BlockNode (jadx.core.dex.nodes.BlockNode)220 InsnNode (jadx.core.dex.nodes.InsnNode)91 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)43 ArrayList (java.util.ArrayList)41 BitSet (java.util.BitSet)31 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)29 InsnArg (jadx.core.dex.instructions.args.InsnArg)25 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)21 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)19 PhiInsn (jadx.core.dex.instructions.PhiInsn)14 SSAVar (jadx.core.dex.instructions.args.SSAVar)14 Nullable (org.jetbrains.annotations.Nullable)14 LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)13 IRegion (jadx.core.dex.nodes.IRegion)13 HashSet (java.util.HashSet)13 MethodNode (jadx.core.dex.nodes.MethodNode)12 Region (jadx.core.dex.regions.Region)12 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)12 InsnType (jadx.core.dex.instructions.InsnType)11 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)11