Search in sources :

Example 1 with IContainer

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

the class IfRegionVisitor method simplifyIfCondition.

private static void simplifyIfCondition(IfRegion ifRegion) {
    if (ifRegion.simplifyCondition()) {
        IfCondition condition = ifRegion.getCondition();
        if (condition.getMode() == Mode.NOT) {
            invertIfRegion(ifRegion);
        }
    }
    IContainer elseRegion = ifRegion.getElseRegion();
    if (elseRegion == null || RegionUtils.isEmpty(elseRegion)) {
        return;
    }
    boolean thenIsEmpty = RegionUtils.isEmpty(ifRegion.getThenRegion());
    if (thenIsEmpty || hasSimpleReturnBlock(ifRegion.getThenRegion())) {
        invertIfRegion(ifRegion);
    }
    if (!thenIsEmpty) {
        // move 'if' from then to make 'else if' chain
        if (isIfRegion(ifRegion.getThenRegion()) && !isIfRegion(elseRegion)) {
            invertIfRegion(ifRegion);
        }
    }
}
Also used : IfCondition(jadx.core.dex.regions.conditions.IfCondition) IContainer(jadx.core.dex.nodes.IContainer)

Example 2 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 3 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 4 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 5 with IContainer

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

the class Region method baseString.

@Override
public String baseString() {
    StringBuilder sb = new StringBuilder();
    sb.append(blocks.size());
    for (IContainer cont : blocks) {
        sb.append(cont.baseString());
    }
    return sb.toString();
}
Also used : 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