Search in sources :

Example 16 with IRegion

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

the class CheckRegions method visit.

@Override
public void visit(MethodNode mth) throws JadxException {
    if (mth.isNoCode() || mth.getRegion() == null || mth.getBasicBlocks().isEmpty() || mth.contains(AType.JADX_ERROR)) {
        return;
    }
    // check if all blocks included in regions
    Set<BlockNode> blocksInRegions = new HashSet<>();
    DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {

        @Override
        public void processBlock(MethodNode mth, IBlock container) {
            if (!(container instanceof BlockNode)) {
                return;
            }
            BlockNode block = (BlockNode) container;
            if (blocksInRegions.add(block)) {
                return;
            }
            if (LOG.isDebugEnabled() && !block.contains(AFlag.RETURN) && !block.contains(AFlag.REMOVE) && !block.contains(AFlag.SYNTHETIC) && !block.getInstructions().isEmpty()) {
                LOG.debug("Duplicated block: {} - {}", mth, block);
            }
        }
    });
    if (mth.getBasicBlocks().size() != blocksInRegions.size()) {
        for (BlockNode block : mth.getBasicBlocks()) {
            if (!blocksInRegions.contains(block) && !block.getInstructions().isEmpty() && !block.contains(AFlag.ADDED_TO_REGION) && !block.contains(AFlag.DONT_GENERATE) && !block.contains(AFlag.REMOVE)) {
                String blockCode = getBlockInsnStr(mth, block).replace("*/", "*\\/");
                mth.addWarn("Code restructure failed: missing block: " + block + ", code lost:" + blockCode);
            }
        }
    }
    DepthRegionTraversal.traverse(mth, new AbstractRegionVisitor() {

        @Override
        public boolean enterRegion(MethodNode mth, IRegion region) {
            if (region instanceof LoopRegion) {
                // check loop conditions
                BlockNode loopHeader = ((LoopRegion) region).getHeader();
                if (loopHeader != null && loopHeader.getInstructions().size() != 1) {
                    mth.addWarn("Incorrect condition in loop: " + loopHeader);
                }
            }
            return true;
        }
    });
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) IBlock(jadx.core.dex.nodes.IBlock) MethodNode(jadx.core.dex.nodes.MethodNode) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) IRegion(jadx.core.dex.nodes.IRegion) HashSet(java.util.HashSet)

Example 17 with IRegion

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

the class IfRegionVisitor method removeRedundantElseBlock.

private static boolean removeRedundantElseBlock(MethodNode mth, IfRegion ifRegion) {
    if (ifRegion.getElseRegion() == null || ifRegion.contains(AFlag.ELSE_IF_CHAIN) || ifRegion.getElseRegion().contains(AFlag.ELSE_IF_CHAIN)) {
        return false;
    }
    if (!RegionUtils.hasExitBlock(ifRegion.getThenRegion())) {
        return false;
    }
    // see #jadx.tests.integration.conditions.TestConditions9
    if (mth.isVoidReturn() && insnsCount(ifRegion.getThenRegion()) == 2 && insnsCount(ifRegion.getElseRegion()) == 2) {
        return false;
    }
    IRegion parent = ifRegion.getParent();
    Region newRegion = new Region(parent);
    if (parent.replaceSubBlock(ifRegion, newRegion)) {
        newRegion.add(ifRegion);
        newRegion.add(ifRegion.getElseRegion());
        ifRegion.setElseRegion(null);
        return true;
    }
    return false;
}
Also used : IRegion(jadx.core.dex.nodes.IRegion) IfRegion(jadx.core.dex.regions.conditions.IfRegion) Region(jadx.core.dex.regions.Region) IRegion(jadx.core.dex.nodes.IRegion)

Example 18 with IRegion

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

the class TracedRegionVisitor method processBlock.

@Override
public void processBlock(MethodNode mth, IBlock container) {
    IRegion curRegion = regionStack.peek();
    processBlockTraced(mth, container, curRegion);
}
Also used : IRegion(jadx.core.dex.nodes.IRegion)

Example 19 with IRegion

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

the class ProcessVariables method isAllUseAfter.

/**
 * Check if all {@code usePlaces} are after {@code checkPlace}
 */
private static boolean isAllUseAfter(UsePlace checkPlace, List<UsePlace> usePlaces) {
    IRegion region = checkPlace.getRegion();
    IBlock block = checkPlace.getBlock();
    Set<UsePlace> toCheck = new HashSet<>(usePlaces);
    boolean blockFound = false;
    for (IContainer subBlock : region.getSubBlocks()) {
        if (!blockFound && subBlock == block) {
            blockFound = true;
        }
        if (blockFound) {
            toCheck.removeIf(usePlace -> isContainerContainsUsePlace(subBlock, usePlace));
            if (toCheck.isEmpty()) {
                return true;
            }
        }
    }
    return false;
}
Also used : IBlock(jadx.core.dex.nodes.IBlock) IContainer(jadx.core.dex.nodes.IContainer) IRegion(jadx.core.dex.nodes.IRegion) HashSet(java.util.HashSet)

Example 20 with IRegion

use of jadx.core.dex.nodes.IRegion 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)26 IContainer (jadx.core.dex.nodes.IContainer)14 Region (jadx.core.dex.regions.Region)12 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)11 BlockNode (jadx.core.dex.nodes.BlockNode)10 IBlock (jadx.core.dex.nodes.IBlock)10 IfRegion (jadx.core.dex.regions.conditions.IfRegion)8 IBranchRegion (jadx.core.dex.nodes.IBranchRegion)7 SwitchRegion (jadx.core.dex.regions.SwitchRegion)7 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)7 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)5 HashSet (java.util.HashSet)4 InsnNode (jadx.core.dex.nodes.InsnNode)3 MethodNode (jadx.core.dex.nodes.MethodNode)3 ArrayList (java.util.ArrayList)3 LinkedHashMap (java.util.LinkedHashMap)3 LoopInfo (jadx.core.dex.attributes.nodes.LoopInfo)2 Edge (jadx.core.dex.nodes.Edge)2 AbstractRegion (jadx.core.dex.regions.AbstractRegion)2 TryCatchRegion (jadx.core.dex.regions.TryCatchRegion)2