Search in sources :

Example 76 with BlockNode

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

the class RegionMaker method addEdgeInsn.

private void addEdgeInsn(IfInfo ifInfo, Region region, EdgeInsnAttr edgeInsnAttr) {
    BlockNode start = edgeInsnAttr.getStart();
    boolean fromThisIf = false;
    for (BlockNode ifBlock : ifInfo.getMergedBlocks()) {
        if (ifBlock.getSuccessors().contains(start)) {
            fromThisIf = true;
            break;
        }
    }
    if (!fromThisIf) {
        return;
    }
    region.add(start);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode)

Example 77 with BlockNode

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

the class RegionMaker method makeEndlessLoop.

private BlockNode makeEndlessLoop(IRegion curRegion, RegionStack stack, LoopInfo loop, BlockNode loopStart) {
    LoopRegion loopRegion = new LoopRegion(curRegion, loop, null, false);
    curRegion.getSubBlocks().add(loopRegion);
    loopStart.remove(AType.LOOP);
    processedBlocks.clear(loopStart.getId());
    stack.push(loopRegion);
    BlockNode out = null;
    // insert 'break' for exits
    List<Edge> exitEdges = loop.getExitEdges();
    if (exitEdges.size() == 1) {
        Edge exitEdge = exitEdges.get(0);
        BlockNode exit = exitEdge.getTarget();
        if (insertLoopBreak(stack, loop, exit, exitEdge)) {
            BlockNode nextBlock = getNextBlock(exit);
            if (nextBlock != null) {
                stack.addExit(nextBlock);
                out = nextBlock;
            }
        }
    } else {
        for (Edge exitEdge : exitEdges) {
            BlockNode exit = exitEdge.getTarget();
            List<BlockNode> blocks = BlockUtils.bitSetToBlocks(mth, exit.getDomFrontier());
            for (BlockNode block : blocks) {
                if (BlockUtils.isPathExists(exit, block)) {
                    stack.addExit(block);
                    insertLoopBreak(stack, loop, block, exitEdge);
                    out = block;
                } else {
                    insertLoopBreak(stack, loop, exit, exitEdge);
                }
            }
        }
    }
    Region body = makeRegion(loopStart, stack);
    BlockNode loopEnd = loop.getEnd();
    if (!RegionUtils.isRegionContainsBlock(body, loopEnd) && !loopEnd.contains(AType.EXC_HANDLER) && !inExceptionHandlerBlocks(loopEnd)) {
        body.getSubBlocks().add(loopEnd);
    }
    loopRegion.setBody(body);
    if (out == null) {
        BlockNode next = getNextBlock(loopEnd);
        out = RegionUtils.isRegionContainsBlock(body, next) ? null : next;
    }
    stack.pop();
    loopStart.addAttr(AType.LOOP, loop);
    return out;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) Region(jadx.core.dex.regions.Region) IRegion(jadx.core.dex.nodes.IRegion) SwitchRegion(jadx.core.dex.regions.SwitchRegion) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) Edge(jadx.core.dex.nodes.Edge)

Example 78 with BlockNode

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

the class RegionMaker method canInsertContinue.

private static boolean canInsertContinue(BlockNode pred, List<BlockNode> predecessors, BlockNode loopEnd, Set<BlockNode> loopExitNodes) {
    if (!pred.contains(AFlag.SYNTHETIC) || BlockUtils.checkLastInsnType(pred, InsnType.CONTINUE)) {
        return false;
    }
    List<BlockNode> preds = pred.getPredecessors();
    if (preds.isEmpty()) {
        return false;
    }
    BlockNode codePred = preds.get(0);
    if (codePred.contains(AFlag.ADDED_TO_REGION)) {
        return false;
    }
    if (loopEnd.isDominator(codePred) || loopExitNodes.contains(codePred)) {
        return false;
    }
    if (isDominatedOnBlocks(codePred, predecessors)) {
        return false;
    }
    boolean gotoExit = false;
    for (BlockNode exit : loopExitNodes) {
        if (BlockUtils.isPathExists(codePred, exit)) {
            gotoExit = true;
            break;
        }
    }
    return gotoExit;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode)

Example 79 with BlockNode

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

the class RegionMaker method processIf.

private BlockNode processIf(IRegion currentRegion, BlockNode block, IfNode ifnode, RegionStack stack) {
    if (block.contains(AFlag.ADDED_TO_REGION)) {
        // block already included in other 'if' region
        return ifnode.getThenBlock();
    }
    IfInfo currentIf = makeIfInfo(mth, block);
    if (currentIf == null) {
        return null;
    }
    IfInfo mergedIf = mergeNestedIfNodes(currentIf);
    if (mergedIf != null) {
        currentIf = mergedIf;
    } else {
        // invert simple condition (compiler often do it)
        currentIf = IfInfo.invert(currentIf);
    }
    IfInfo modifiedIf = IfMakerHelper.restructureIf(mth, block, currentIf);
    if (modifiedIf != null) {
        currentIf = modifiedIf;
    } else {
        if (currentIf.getMergedBlocks().size() <= 1) {
            return null;
        }
        currentIf = makeIfInfo(mth, block);
        currentIf = IfMakerHelper.restructureIf(mth, block, currentIf);
        if (currentIf == null) {
            // all attempts failed
            return null;
        }
    }
    confirmMerge(currentIf);
    IfRegion ifRegion = new IfRegion(currentRegion);
    ifRegion.updateCondition(currentIf);
    currentRegion.getSubBlocks().add(ifRegion);
    BlockNode outBlock = currentIf.getOutBlock();
    stack.push(ifRegion);
    stack.addExit(outBlock);
    ifRegion.setThenRegion(makeRegion(currentIf.getThenBlock(), stack));
    BlockNode elseBlock = currentIf.getElseBlock();
    if (elseBlock == null || stack.containsExit(elseBlock)) {
        ifRegion.setElseRegion(null);
    } else {
        ifRegion.setElseRegion(makeRegion(elseBlock, stack));
    }
    // TODO: make more common algorithm
    if (ifRegion.getElseRegion() == null && outBlock != null) {
        List<EdgeInsnAttr> edgeInsnAttrs = outBlock.getAll(AType.EDGE_INSN);
        if (!edgeInsnAttrs.isEmpty()) {
            Region elseRegion = new Region(ifRegion);
            for (EdgeInsnAttr edgeInsnAttr : edgeInsnAttrs) {
                if (edgeInsnAttr.getEnd().equals(outBlock)) {
                    addEdgeInsn(currentIf, elseRegion, edgeInsnAttr);
                }
            }
            ifRegion.setElseRegion(elseRegion);
        }
    }
    stack.pop();
    return outBlock;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) Region(jadx.core.dex.regions.Region) IRegion(jadx.core.dex.nodes.IRegion) SwitchRegion(jadx.core.dex.regions.SwitchRegion) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) IfMakerHelper.makeIfInfo(jadx.core.dex.visitors.regions.IfMakerHelper.makeIfInfo) IfInfo(jadx.core.dex.regions.conditions.IfInfo) IfRegion(jadx.core.dex.regions.conditions.IfRegion) EdgeInsnAttr(jadx.core.dex.attributes.nodes.EdgeInsnAttr)

Example 80 with BlockNode

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

the class RegionMaker method processHandlersOutBlocks.

/**
 * Search handlers successor blocks not included in any region.
 */
protected IRegion processHandlersOutBlocks(MethodNode mth, List<TryCatchBlockAttr> tcs) {
    Set<IBlock> allRegionBlocks = new HashSet<>();
    RegionUtils.getAllRegionBlocks(mth.getRegion(), allRegionBlocks);
    Set<IBlock> succBlocks = new HashSet<>();
    for (TryCatchBlockAttr tc : tcs) {
        for (ExceptionHandler handler : tc.getHandlers()) {
            IContainer region = handler.getHandlerRegion();
            if (region != null) {
                IBlock lastBlock = RegionUtils.getLastBlock(region);
                if (lastBlock instanceof BlockNode) {
                    succBlocks.addAll(((BlockNode) lastBlock).getSuccessors());
                }
                RegionUtils.getAllRegionBlocks(region, allRegionBlocks);
            }
        }
    }
    succBlocks.removeAll(allRegionBlocks);
    if (succBlocks.isEmpty()) {
        return null;
    }
    Region excOutRegion = new Region(mth.getRegion());
    for (IBlock block : succBlocks) {
        if (block instanceof BlockNode) {
            excOutRegion.add(makeRegion((BlockNode) block, new RegionStack(mth)));
        }
    }
    return excOutRegion;
}
Also used : ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) BlockNode(jadx.core.dex.nodes.BlockNode) IBlock(jadx.core.dex.nodes.IBlock) TryCatchBlockAttr(jadx.core.dex.trycatch.TryCatchBlockAttr) Region(jadx.core.dex.regions.Region) IRegion(jadx.core.dex.nodes.IRegion) SwitchRegion(jadx.core.dex.regions.SwitchRegion) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) IContainer(jadx.core.dex.nodes.IContainer) HashSet(java.util.HashSet) LinkedHashSet(java.util.LinkedHashSet)

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