Search in sources :

Example 11 with IContainer

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

the class ProcessTryCatchRegions method wrapBlocks.

/**
	 * Extract all block dominated by 'dominator' to separate region and mark as try/catch block
	 */
private static boolean wrapBlocks(IRegion replaceRegion, TryCatchBlock tb, BlockNode dominator) {
    if (replaceRegion == null) {
        return false;
    }
    if (replaceRegion instanceof LoopRegion) {
        LoopRegion loop = (LoopRegion) replaceRegion;
        return wrapBlocks(loop.getBody(), tb, dominator);
    }
    if (replaceRegion instanceof IBranchRegion) {
        return wrapBlocks(replaceRegion.getParent(), tb, dominator);
    }
    Region tryRegion = new Region(replaceRegion);
    List<IContainer> subBlocks = replaceRegion.getSubBlocks();
    for (IContainer cont : subBlocks) {
        if (RegionUtils.hasPathThroughBlock(dominator, cont)) {
            if (isHandlerPath(tb, cont)) {
                break;
            }
            tryRegion.getSubBlocks().add(cont);
        }
    }
    if (tryRegion.getSubBlocks().isEmpty()) {
        return false;
    }
    TryCatchRegion tryCatchRegion = new TryCatchRegion(replaceRegion, tryRegion);
    tryRegion.setParent(tryCatchRegion);
    tryCatchRegion.setTryCatchBlock(tb.getCatchAttr().getTryBlock());
    // replace first node by region
    IContainer firstNode = tryRegion.getSubBlocks().get(0);
    if (!replaceRegion.replaceSubBlock(firstNode, tryCatchRegion)) {
        return false;
    }
    subBlocks.removeAll(tryRegion.getSubBlocks());
    // fix parents for tryRegion sub blocks
    for (IContainer cont : tryRegion.getSubBlocks()) {
        if (cont instanceof AbstractRegion) {
            AbstractRegion aReg = (AbstractRegion) cont;
            aReg.setParent(tryRegion);
        }
    }
    return true;
}
Also used : TryCatchRegion(jadx.core.dex.regions.TryCatchRegion) IBranchRegion(jadx.core.dex.nodes.IBranchRegion) IRegion(jadx.core.dex.nodes.IRegion) TryCatchRegion(jadx.core.dex.regions.TryCatchRegion) IBranchRegion(jadx.core.dex.nodes.IBranchRegion) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) AbstractRegion(jadx.core.dex.regions.AbstractRegion) Region(jadx.core.dex.regions.Region) LoopRegion(jadx.core.dex.regions.loops.LoopRegion) AbstractRegion(jadx.core.dex.regions.AbstractRegion) IContainer(jadx.core.dex.nodes.IContainer)

Example 12 with IContainer

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

the class ProcessVariables method visit.

@Override
public void visit(MethodNode mth) throws JadxException {
    if (mth.isNoCode()) {
        return;
    }
    final Map<Variable, Usage> usageMap = new LinkedHashMap<Variable, Usage>();
    for (RegisterArg arg : mth.getArguments(true)) {
        addToUsageMap(arg, usageMap);
    }
    // collect all variables usage
    IRegionVisitor collect = new CollectUsageRegionVisitor(usageMap);
    DepthRegionTraversal.traverse(mth, collect);
    // reduce assigns map
    List<RegisterArg> mthArgs = mth.getArguments(true);
    for (RegisterArg arg : mthArgs) {
        usageMap.remove(new Variable(arg));
    }
    Iterator<Entry<Variable, Usage>> umIt = usageMap.entrySet().iterator();
    while (umIt.hasNext()) {
        Entry<Variable, Usage> entry = umIt.next();
        Usage u = entry.getValue();
        // if no assigns => remove
        if (u.getAssigns().isEmpty()) {
            umIt.remove();
            continue;
        }
        // variable declared at 'catch' clause
        InsnNode parentInsn = u.getArg().getParentInsn();
        if (parentInsn == null || parentInsn.getType() == InsnType.MOVE_EXCEPTION) {
            umIt.remove();
        }
    }
    if (usageMap.isEmpty()) {
        return;
    }
    Map<IContainer, Integer> regionsOrder = new HashMap<IContainer, Integer>();
    calculateOrder(mth.getRegion(), regionsOrder, 0, true);
    for (Iterator<Entry<Variable, Usage>> it = usageMap.entrySet().iterator(); it.hasNext(); ) {
        Entry<Variable, Usage> entry = it.next();
        Usage u = entry.getValue();
        // check if variable can be declared at current assigns
        for (IRegion assignRegion : u.getAssigns()) {
            if (u.getArgRegion() == assignRegion && canDeclareInRegion(u, assignRegion, regionsOrder)) {
                if (declareAtAssign(u)) {
                    it.remove();
                    break;
                }
            }
        }
    }
    if (usageMap.isEmpty()) {
        return;
    }
    // apply
    for (Entry<Variable, Usage> entry : usageMap.entrySet()) {
        Usage u = entry.getValue();
        // find region which contain all usage regions
        Set<IRegion> set = u.getUseRegions();
        for (Iterator<IRegion> it = set.iterator(); it.hasNext(); ) {
            IRegion r = it.next();
            IRegion parent = r.getParent();
            if (parent != null && set.contains(parent)) {
                it.remove();
            }
        }
        IRegion region = null;
        if (!set.isEmpty()) {
            region = set.iterator().next();
        } else if (!u.getAssigns().isEmpty()) {
            region = u.getAssigns().iterator().next();
        }
        if (region == null) {
            continue;
        }
        IRegion parent = region;
        boolean declared = false;
        while (parent != null) {
            if (canDeclareInRegion(u, region, regionsOrder)) {
                declareVar(region, u.getArg());
                declared = true;
                break;
            }
            region = parent;
            parent = region.getParent();
        }
        if (!declared) {
            declareVar(mth.getRegion(), u.getArg());
        }
    }
}
Also used : HashMap(java.util.HashMap) LinkedHashMap(java.util.LinkedHashMap) IRegion(jadx.core.dex.nodes.IRegion) LinkedHashMap(java.util.LinkedHashMap) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) Entry(java.util.Map.Entry) IContainer(jadx.core.dex.nodes.IContainer)

Example 13 with IContainer

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

the class ProcessVariables method calculateOrder.

private static int calculateOrder(IContainer container, Map<IContainer, Integer> regionsOrder, int id, boolean inc) {
    if (!(container instanceof IRegion)) {
        return id;
    }
    IRegion region = (IRegion) container;
    Integer previous = regionsOrder.put(region, id);
    if (previous != null) {
        return id;
    }
    for (IContainer c : region.getSubBlocks()) {
        if (c instanceof IBranchRegion) {
            // on branch set for all inner regions same order id
            id = calculateOrder(c, regionsOrder, inc ? id + 1 : id, false);
        } else {
            List<IContainer> handlers = RegionUtils.getExcHandlersForRegion(c);
            if (!handlers.isEmpty()) {
                for (IContainer handler : handlers) {
                    id = calculateOrder(handler, regionsOrder, inc ? id + 1 : id, inc);
                }
            }
            id = calculateOrder(c, regionsOrder, inc ? id + 1 : id, inc);
        }
    }
    return id;
}
Also used : IBranchRegion(jadx.core.dex.nodes.IBranchRegion) IContainer(jadx.core.dex.nodes.IContainer) IRegion(jadx.core.dex.nodes.IRegion)

Example 14 with IContainer

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

the class RegionUtils method getLastInsn.

public static InsnNode getLastInsn(IContainer container) {
    if (container instanceof IBlock) {
        IBlock block = (IBlock) container;
        List<InsnNode> insnList = block.getInstructions();
        if (insnList.isEmpty()) {
            return null;
        }
        return insnList.get(insnList.size() - 1);
    } else if (container instanceof IBranchRegion) {
        return null;
    } else if (container instanceof IRegion) {
        IRegion region = (IRegion) container;
        List<IContainer> blocks = region.getSubBlocks();
        if (blocks.isEmpty()) {
            return null;
        }
        return getLastInsn(blocks.get(blocks.size() - 1));
    } else {
        throw new JadxRuntimeException(unknownContainerType(container));
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) IBlock(jadx.core.dex.nodes.IBlock) IBranchRegion(jadx.core.dex.nodes.IBranchRegion) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) IContainer(jadx.core.dex.nodes.IContainer) IRegion(jadx.core.dex.nodes.IRegion)

Example 15 with IContainer

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

the class RegionUtils method getExcHandlersForRegion.

public static List<IContainer> getExcHandlersForRegion(IContainer region) {
    CatchAttr cb = region.get(AType.CATCH_BLOCK);
    if (cb != null) {
        TryCatchBlock tb = cb.getTryBlock();
        List<IContainer> list = new ArrayList<IContainer>(tb.getHandlersCount());
        for (ExceptionHandler eh : tb.getHandlers()) {
            list.add(eh.getHandlerRegion());
        }
        return list;
    }
    return Collections.emptyList();
}
Also used : ExceptionHandler(jadx.core.dex.trycatch.ExceptionHandler) ArrayList(java.util.ArrayList) CatchAttr(jadx.core.dex.trycatch.CatchAttr) TryCatchBlock(jadx.core.dex.trycatch.TryCatchBlock) IContainer(jadx.core.dex.nodes.IContainer)

Aggregations

IContainer (jadx.core.dex.nodes.IContainer)22 IRegion (jadx.core.dex.nodes.IRegion)11 InsnNode (jadx.core.dex.nodes.InsnNode)6 Region (jadx.core.dex.regions.Region)6 IBlock (jadx.core.dex.nodes.IBlock)5 BlockNode (jadx.core.dex.nodes.BlockNode)4 IBranchRegion (jadx.core.dex.nodes.IBranchRegion)4 LoopRegion (jadx.core.dex.regions.loops.LoopRegion)4 ExceptionHandler (jadx.core.dex.trycatch.ExceptionHandler)4 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)3 SwitchRegion (jadx.core.dex.regions.SwitchRegion)3 SynchronizedRegion (jadx.core.dex.regions.SynchronizedRegion)3 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)3 InsnArg (jadx.core.dex.instructions.args.InsnArg)2 IfRegion (jadx.core.dex.regions.conditions.IfRegion)2 TryCatchBlock (jadx.core.dex.trycatch.TryCatchBlock)2 HashSet (java.util.HashSet)2 EdgeInsnAttr (jadx.core.dex.attributes.nodes.EdgeInsnAttr)1 InsnType (jadx.core.dex.instructions.InsnType)1 PhiInsn (jadx.core.dex.instructions.PhiInsn)1