Search in sources :

Example 6 with LoopInfo

use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.

the class IfMakerHelper method isBadBranchBlock.

private static boolean isBadBranchBlock(IfInfo info, BlockNode block) {
    // check if block at end of loop edge
    if (block.contains(AFlag.LOOP_START) && block.getPredecessors().size() == 1) {
        BlockNode pred = block.getPredecessors().get(0);
        if (pred.contains(AFlag.LOOP_END)) {
            List<LoopInfo> startLoops = block.getAll(AType.LOOP);
            List<LoopInfo> endLoops = pred.getAll(AType.LOOP);
            // search for same loop
            for (LoopInfo startLoop : startLoops) {
                for (LoopInfo endLoop : endLoops) {
                    if (startLoop == endLoop) {
                        return true;
                    }
                }
            }
        }
    }
    return !allPathsFromIf(block, info);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo)

Example 7 with LoopInfo

use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.

the class RegionMaker method traverse.

/**
	 * Recursively traverse all blocks from 'block' until block from 'exits'
	 */
private BlockNode traverse(IRegion r, BlockNode block, RegionStack stack) {
    BlockNode next = null;
    boolean processed = false;
    List<LoopInfo> loops = block.getAll(AType.LOOP);
    int loopCount = loops.size();
    if (loopCount != 0 && block.contains(AFlag.LOOP_START)) {
        if (loopCount == 1) {
            next = processLoop(r, loops.get(0), stack);
            processed = true;
        } else {
            for (LoopInfo loop : loops) {
                if (loop.getStart() == block) {
                    next = processLoop(r, loop, stack);
                    processed = true;
                    break;
                }
            }
        }
    }
    if (!processed && block.getInstructions().size() == 1) {
        InsnNode insn = block.getInstructions().get(0);
        switch(insn.getType()) {
            case IF:
                next = processIf(r, block, (IfNode) insn, stack);
                processed = true;
                break;
            case SWITCH:
                next = processSwitch(r, block, (SwitchNode) insn, stack);
                processed = true;
                break;
            case MONITOR_ENTER:
                next = processMonitorEnter(r, block, insn, stack);
                processed = true;
                break;
            default:
                break;
        }
    }
    if (!processed) {
        r.getSubBlocks().add(block);
        next = getNextBlock(block);
    }
    if (next != null && !stack.containsExit(block) && !stack.containsExit(next)) {
        return next;
    }
    return null;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) InsnNode(jadx.core.dex.nodes.InsnNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo) IfNode(jadx.core.dex.instructions.IfNode) SwitchNode(jadx.core.dex.instructions.SwitchNode)

Example 8 with LoopInfo

use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.

the class RegionMaker method makeLoopRegion.

/**
	 * Select loop exit and construct LoopRegion
	 */
private LoopRegion makeLoopRegion(IRegion curRegion, LoopInfo loop, List<BlockNode> exitBlocks) {
    for (BlockNode block : exitBlocks) {
        if (block.contains(AType.EXC_HANDLER) || block.getInstructions().size() != 1 || block.getInstructions().get(0).getType() != InsnType.IF) {
            continue;
        }
        List<LoopInfo> loops = block.getAll(AType.LOOP);
        if (!loops.isEmpty() && loops.get(0) != loop) {
            // skip nested loop condition
            continue;
        }
        LoopRegion loopRegion = new LoopRegion(curRegion, loop, block, block == loop.getEnd());
        boolean found;
        if (block == loop.getStart() || block == loop.getEnd() || BlockUtils.isEmptySimplePath(loop.getStart(), block)) {
            found = true;
        } else if (block.getPredecessors().contains(loop.getStart())) {
            loopRegion.setPreCondition(loop.getStart());
            // if we can't merge pre-condition this is not correct header
            found = loopRegion.checkPreCondition();
        } else {
            found = false;
        }
        if (found) {
            List<LoopInfo> list = mth.getAllLoopsForBlock(block);
            if (list.size() >= 2) {
                // bad condition if successors going out of all loops
                boolean allOuter = true;
                for (BlockNode outerBlock : block.getCleanSuccessors()) {
                    List<LoopInfo> outLoopList = mth.getAllLoopsForBlock(outerBlock);
                    outLoopList.remove(loop);
                    if (!outLoopList.isEmpty()) {
                        // goes to outer loop
                        allOuter = false;
                        break;
                    }
                }
                if (allOuter) {
                    found = false;
                }
            }
        }
        if (found) {
            return loopRegion;
        }
    }
    // no exit found => endless loop
    return null;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo) LoopRegion(jadx.core.dex.regions.loops.LoopRegion)

Example 9 with LoopInfo

use of jadx.core.dex.attributes.nodes.LoopInfo in project jadx by skylot.

the class BlockProcessor method markLoops.

private static void markLoops(MethodNode mth) {
    for (BlockNode block : mth.getBasicBlocks()) {
        for (BlockNode succ : block.getSuccessors()) {
            // block -> succ is a back edge.
            if (block.getDoms().get(succ.getId())) {
                succ.add(AFlag.LOOP_START);
                block.add(AFlag.LOOP_END);
                LoopInfo loop = new LoopInfo(succ, block);
                succ.addAttr(AType.LOOP, loop);
                block.addAttr(AType.LOOP, loop);
            }
        }
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo)

Aggregations

LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)9 BlockNode (jadx.core.dex.nodes.BlockNode)7 ArrayList (java.util.ArrayList)3 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)2 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)2 IgnoreEdgeAttr (jadx.core.dex.attributes.nodes.IgnoreEdgeAttr)1 LoopLabelAttr (jadx.core.dex.attributes.nodes.LoopLabelAttr)1 IfNode (jadx.core.dex.instructions.IfNode)1 SwitchNode (jadx.core.dex.instructions.SwitchNode)1 Edge (jadx.core.dex.nodes.Edge)1 IRegion (jadx.core.dex.nodes.IRegion)1 InsnNode (jadx.core.dex.nodes.InsnNode)1 Region (jadx.core.dex.regions.Region)1 SwitchRegion (jadx.core.dex.regions.SwitchRegion)1 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)1 IfRegion (jadx.core.dex.regions.conditions.IfRegion)1 BitSet (java.util.BitSet)1 LinkedHashMap (java.util.LinkedHashMap)1 LinkedList (java.util.LinkedList)1 List (java.util.List)1