Search in sources :

Example 6 with Region

use of jadx.core.dex.regions.Region in project jadx by skylot.

the class RegionMaker method makeRegion.

public Region makeRegion(BlockNode startBlock, RegionStack stack) {
    if (Consts.DEBUG) {
        int id = startBlock.getId();
        if (processedBlocks.get(id)) {
            LOG.debug(" Block already processed: {}, mth: {}", startBlock, mth);
        } else {
            processedBlocks.set(id);
        }
    }
    regionsCount++;
    if (regionsCount > REGIONS_LIMIT) {
        throw new JadxOverflowException("Regions count limit reached");
    }
    Region r = new Region(stack.peekRegion());
    BlockNode next = startBlock;
    while (next != null) {
        next = traverse(r, next, stack);
    }
    return r;
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) JadxOverflowException(jadx.core.utils.exceptions.JadxOverflowException) 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)

Example 7 with Region

use of jadx.core.dex.regions.Region 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.SKIP)) {
        // block already included in other 'if' region
        return ifnode.getThenBlock();
    }
    IfInfo currentIf = makeIfInfo(block);
    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(block);
        currentIf = IfMakerHelper.restructureIf(mth, block, currentIf);
        if (currentIf == null) {
            // all attempts failed
            return null;
        }
    }
    confirmMerge(currentIf);
    IfRegion ifRegion = new IfRegion(currentRegion, block);
    ifRegion.setCondition(currentIf.getCondition());
    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 8 with Region

use of jadx.core.dex.regions.Region in project jadx by skylot.

the class RegionMaker method processHandlersOutBlocks.

/**
	 * Search handlers successor blocks not included in any region.
	 */
protected IRegion processHandlersOutBlocks(MethodNode mth, Set<TryCatchBlock> tcs) {
    Set<IBlock> allRegionBlocks = new HashSet<IBlock>();
    RegionUtils.getAllRegionBlocks(mth.getRegion(), allRegionBlocks);
    Set<IBlock> succBlocks = new HashSet<IBlock>();
    for (TryCatchBlock 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) 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) TryCatchBlock(jadx.core.dex.trycatch.TryCatchBlock) IContainer(jadx.core.dex.nodes.IContainer) HashSet(java.util.HashSet)

Example 9 with Region

use of jadx.core.dex.regions.Region in project jadx by skylot.

the class RegionMakerVisitor method removeSynchronized.

private static void removeSynchronized(MethodNode mth) {
    Region startRegion = mth.getRegion();
    List<IContainer> subBlocks = startRegion.getSubBlocks();
    if (!subBlocks.isEmpty() && subBlocks.get(0) instanceof SynchronizedRegion) {
        SynchronizedRegion synchRegion = (SynchronizedRegion) subBlocks.get(0);
        InsnNode synchInsn = synchRegion.getEnterInsn();
        if (!synchInsn.getArg(0).isThis()) {
            LOG.warn("In synchronized method {}, top region not synchronized by 'this' {}", mth, synchInsn);
            return;
        }
        // replace synchronized block with inner region
        startRegion.getSubBlocks().set(0, synchRegion.getRegion());
        // remove 'monitor-enter' instruction
        InstructionRemover.remove(mth, synchInsn);
        // remove 'monitor-exit' instruction
        for (InsnNode exit : synchRegion.getExitInsns()) {
            InstructionRemover.remove(mth, exit);
        }
        // run region cleaner again
        CleanRegions.process(mth);
    // assume that CodeShrinker will be run after this
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) SynchronizedRegion(jadx.core.dex.regions.SynchronizedRegion) 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) Region(jadx.core.dex.regions.Region) IContainer(jadx.core.dex.nodes.IContainer)

Example 10 with Region

use of jadx.core.dex.regions.Region in project jadx by skylot.

the class CleanRegions method process.

public static void process(MethodNode mth) {
    if (mth.isNoCode() || mth.getBasicBlocks().isEmpty()) {
        return;
    }
    IRegionVisitor removeEmptyBlocks = new AbstractRegionVisitor() {

        @Override
        public boolean enterRegion(MethodNode mth, IRegion region) {
            if (!(region instanceof Region)) {
                return true;
            }
            for (Iterator<IContainer> it = region.getSubBlocks().iterator(); it.hasNext(); ) {
                IContainer container = it.next();
                if (container instanceof BlockNode) {
                    BlockNode block = (BlockNode) container;
                    if (block.getInstructions().isEmpty()) {
                        try {
                            it.remove();
                        } catch (UnsupportedOperationException e) {
                            LOG.warn("Can't remove block: {} from: {}, mth: {}", block, region, mth);
                        }
                    }
                }
            }
            return true;
        }
    };
    DepthRegionTraversal.traverse(mth, removeEmptyBlocks);
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) MethodNode(jadx.core.dex.nodes.MethodNode) IRegion(jadx.core.dex.nodes.IRegion) Region(jadx.core.dex.regions.Region) IContainer(jadx.core.dex.nodes.IContainer) IRegion(jadx.core.dex.nodes.IRegion)

Aggregations

IRegion (jadx.core.dex.nodes.IRegion)12 Region (jadx.core.dex.regions.Region)12 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)9 BlockNode (jadx.core.dex.nodes.BlockNode)8 SwitchRegion (jadx.core.dex.regions.SwitchRegion)8 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)8 IfRegion (jadx.core.dex.regions.conditions.IfRegion)8 IContainer (jadx.core.dex.nodes.IContainer)6 Edge (jadx.core.dex.nodes.Edge)2 IBlock (jadx.core.dex.nodes.IBlock)2 IfInfo (jadx.core.dex.regions.conditions.IfInfo)2 IfMakerHelper.makeIfInfo (jadx.core.dex.visitors.regions.IfMakerHelper.makeIfInfo)2 ArrayList (java.util.ArrayList)2 HashSet (java.util.HashSet)2 EdgeInsnAttr (jadx.core.dex.attributes.nodes.EdgeInsnAttr)1 LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)1 IBranchRegion (jadx.core.dex.nodes.IBranchRegion)1 InsnNode (jadx.core.dex.nodes.InsnNode)1 MethodNode (jadx.core.dex.nodes.MethodNode)1 AbstractRegion (jadx.core.dex.regions.AbstractRegion)1