Search in sources :

Example 11 with LoopInfo

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

the class RegionUtils method isInsnExitContainer.

private static boolean isInsnExitContainer(IContainer rootContainer, IBlock block) {
    InsnNode lastInsn = BlockUtils.getLastInsn(block);
    if (lastInsn == null) {
        return false;
    }
    InsnType insnType = lastInsn.getType();
    if (insnType == InsnType.RETURN) {
        return true;
    }
    if (insnType == InsnType.THROW) {
        // check if after throw execution can continue in current container
        CatchAttr catchAttr = lastInsn.get(AType.EXC_CATCH);
        if (catchAttr != null) {
            for (ExceptionHandler handler : catchAttr.getHandlers()) {
                if (RegionUtils.isRegionContainsBlock(rootContainer, handler.getHandlerBlock())) {
                    return false;
                }
            }
        }
        return true;
    }
    if (insnType == InsnType.BREAK) {
        AttrList<LoopInfo> loopInfoAttrList = lastInsn.get(AType.LOOP);
        if (loopInfoAttrList != null) {
            for (LoopInfo loopInfo : loopInfoAttrList.getList()) {
                if (!RegionUtils.isRegionContainsBlock(rootContainer, loopInfo.getStart())) {
                    return true;
                }
            }
        }
        LoopLabelAttr loopLabelAttr = lastInsn.get(AType.LOOP_LABEL);
        if (loopLabelAttr != null && !RegionUtils.isRegionContainsBlock(rootContainer, loopLabelAttr.getLoop().getStart())) {
            return true;
        }
    }
    return false;
}
Also used : ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) InsnNode(jadx.core.dex.nodes.InsnNode) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo) LoopLabelAttr(jadx.core.dex.attributes.nodes.LoopLabelAttr) CatchAttr(jadx.core.dex.trycatch.CatchAttr) InsnType(jadx.core.dex.instructions.InsnType)

Example 12 with LoopInfo

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

the class BlockProcessor method checkLoops.

private static boolean checkLoops(MethodNode mth, BlockNode block) {
    if (!block.contains(AFlag.LOOP_START)) {
        return false;
    }
    List<LoopInfo> loops = block.getAll(AType.LOOP);
    int loopsCount = loops.size();
    if (loopsCount == 0) {
        return false;
    }
    for (LoopInfo loop : loops) {
        if (insertBlocksForBreak(mth, loop)) {
            return true;
        }
    }
    if (loopsCount > 1 && splitLoops(mth, block, loops)) {
        return true;
    }
    if (loopsCount == 1) {
        LoopInfo loop = loops.get(0);
        return insertBlocksForContinue(mth, loop) || insertBlockForPredecessors(mth, loop) || insertPreHeader(mth, loop);
    }
    return false;
}
Also used : LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo)

Example 13 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 14 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) {
    if (block.contains(AFlag.MTH_EXIT_BLOCK)) {
        return null;
    }
    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;
                }
            }
        }
    }
    InsnNode insn = BlockUtils.getLastInsn(block);
    if (!processed && insn != null) {
        switch(insn.getType()) {
            case IF:
                next = processIf(r, block, (IfNode) insn, stack);
                processed = true;
                break;
            case SWITCH:
                next = processSwitch(r, block, (SwitchInsn) 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) SwitchInsn(jadx.core.dex.instructions.SwitchInsn)

Example 15 with LoopInfo

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

the class RegionMaker method checkLoopExits.

private boolean checkLoopExits(LoopInfo loop, BlockNode mainExitBlock) {
    List<Edge> exitEdges = loop.getExitEdges();
    if (exitEdges.size() < 2) {
        return true;
    }
    Optional<Edge> mainEdgeOpt = exitEdges.stream().filter(edge -> edge.getSource() == mainExitBlock).findFirst();
    if (!mainEdgeOpt.isPresent()) {
        throw new JadxRuntimeException("Not found exit edge by exit block: " + mainExitBlock);
    }
    Edge mainExitEdge = mainEdgeOpt.get();
    BlockNode mainOutBlock = mainExitEdge.getTarget();
    for (Edge exitEdge : exitEdges) {
        if (exitEdge != mainExitEdge) {
            // all exit paths must be same or don't cross (will be inside loop)
            BlockNode exitBlock = exitEdge.getTarget();
            if (!isEqualPaths(mainOutBlock, exitBlock)) {
                BlockNode crossBlock = BlockUtils.getPathCross(mth, mainOutBlock, exitBlock);
                if (crossBlock != null) {
                    return false;
                }
            }
        }
    }
    return true;
}
Also used : BlockUtils.followEmptyPath(jadx.core.utils.BlockUtils.followEmptyPath) BlockUtils.isPathExists(jadx.core.utils.BlockUtils.isPathExists) MethodNode(jadx.core.dex.nodes.MethodNode) AType(jadx.core.dex.attributes.AType) IfMakerHelper.mergeNestedIfNodes(jadx.core.dex.visitors.regions.IfMakerHelper.mergeNestedIfNodes) LoggerFactory(org.slf4j.LoggerFactory) EdgeInsnAttr(jadx.core.dex.attributes.nodes.EdgeInsnAttr) IfMakerHelper.makeIfInfo(jadx.core.dex.visitors.regions.IfMakerHelper.makeIfInfo) LoopInfo(jadx.core.dex.attributes.nodes.LoopInfo) ExcHandlerAttr(jadx.core.dex.trycatch.ExcHandlerAttr) Map(java.util.Map) InsnNode(jadx.core.dex.nodes.InsnNode) Set(java.util.Set) IfInfo(jadx.core.dex.regions.conditions.IfInfo) Edge(jadx.core.dex.nodes.Edge) Objects(java.util.Objects) Nullable(org.jetbrains.annotations.Nullable) List(java.util.List) SwitchInsn(jadx.core.dex.instructions.SwitchInsn) Region(jadx.core.dex.regions.Region) IContainer(jadx.core.dex.nodes.IContainer) Entry(java.util.Map.Entry) Optional(java.util.Optional) IRegion(jadx.core.dex.nodes.IRegion) AFlag(jadx.core.dex.attributes.AFlag) IfMakerHelper.searchNestedIf(jadx.core.dex.visitors.regions.IfMakerHelper.searchNestedIf) InsnType(jadx.core.dex.instructions.InsnType) JadxOverflowException(jadx.core.utils.exceptions.JadxOverflowException) BlockUtils(jadx.core.utils.BlockUtils) SwitchRegion(jadx.core.dex.regions.SwitchRegion) ArrayList(java.util.ArrayList) HashSet(java.util.HashSet) LinkedHashMap(java.util.LinkedHashMap) IfNode(jadx.core.dex.instructions.IfNode) BlockUtils.getNextBlock(jadx.core.utils.BlockUtils.getNextBlock) TryCatchBlockAttr(jadx.core.dex.trycatch.TryCatchBlockAttr) InsnArg(jadx.core.dex.instructions.args.InsnArg) LinkedHashSet(java.util.LinkedHashSet) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) RegionUtils(jadx.core.utils.RegionUtils) Logger(org.slf4j.Logger) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) LoopLabelAttr(jadx.core.dex.attributes.nodes.LoopLabelAttr) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) BlockNode(jadx.core.dex.nodes.BlockNode) InsnContainer(jadx.core.dex.nodes.InsnContainer) ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) BitSet(java.util.BitSet) Collections(java.util.Collections) IfMakerHelper.confirmMerge(jadx.core.dex.visitors.regions.IfMakerHelper.confirmMerge) IBlock(jadx.core.dex.nodes.IBlock) Utils(jadx.core.utils.Utils) BlockNode(jadx.core.dex.nodes.BlockNode) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) Edge(jadx.core.dex.nodes.Edge)

Aggregations

LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)17 BlockNode (jadx.core.dex.nodes.BlockNode)12 InsnNode (jadx.core.dex.nodes.InsnNode)5 ArrayList (java.util.ArrayList)5 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)4 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)4 LoopLabelAttr (jadx.core.dex.attributes.nodes.LoopLabelAttr)3 Edge (jadx.core.dex.nodes.Edge)3 IRegion (jadx.core.dex.nodes.IRegion)3 Region (jadx.core.dex.regions.Region)3 SwitchRegion (jadx.core.dex.regions.SwitchRegion)3 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)3 IfRegion (jadx.core.dex.regions.conditions.IfRegion)3 IfNode (jadx.core.dex.instructions.IfNode)2 InsnType (jadx.core.dex.instructions.InsnType)2 SwitchInsn (jadx.core.dex.instructions.SwitchInsn)2 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)2 BitSet (java.util.BitSet)2 LinkedHashMap (java.util.LinkedHashMap)2 List (java.util.List)2