Search in sources :

Example 1 with InsnArg

use of jadx.core.dex.instructions.args.InsnArg in project jadx by skylot.

the class LoopRegionVisitor method checkArrayForEach.

private static LoopType checkArrayForEach(MethodNode mth, InsnNode initInsn, InsnNode incrInsn, IfCondition condition) {
    if (!(incrInsn instanceof ArithNode)) {
        return null;
    }
    ArithNode arithNode = (ArithNode) incrInsn;
    if (arithNode.getOp() != ArithOp.ADD) {
        return null;
    }
    InsnArg lit = incrInsn.getArg(1);
    if (!lit.isLiteral() || ((LiteralArg) lit).getLiteral() != 1) {
        return null;
    }
    if (initInsn.getType() != InsnType.CONST || !initInsn.getArg(0).isLiteral() || ((LiteralArg) initInsn.getArg(0)).getLiteral() != 0) {
        return null;
    }
    InsnArg condArg = incrInsn.getArg(0);
    if (!condArg.isRegister()) {
        return null;
    }
    SSAVar sVar = ((RegisterArg) condArg).getSVar();
    List<RegisterArg> args = sVar.getUseList();
    if (args.size() != 3 || args.get(2) != condArg) {
        return null;
    }
    condArg = args.get(0);
    RegisterArg arrIndex = args.get(1);
    InsnNode arrGetInsn = arrIndex.getParentInsn();
    if (arrGetInsn == null || arrGetInsn.getType() != InsnType.AGET) {
        return null;
    }
    if (!condition.isCompare()) {
        return null;
    }
    Compare compare = condition.getCompare();
    if (compare.getOp() != IfOp.LT || compare.getA() != condArg) {
        return null;
    }
    InsnNode len;
    InsnArg bCondArg = compare.getB();
    if (bCondArg.isInsnWrap()) {
        len = ((InsnWrapArg) bCondArg).getWrapInsn();
    } else if (bCondArg.isRegister()) {
        len = ((RegisterArg) bCondArg).getAssignInsn();
    } else {
        return null;
    }
    if (len == null || len.getType() != InsnType.ARRAY_LENGTH) {
        return null;
    }
    InsnArg arrayArg = len.getArg(0);
    if (!arrayArg.equals(arrGetInsn.getArg(0))) {
        return null;
    }
    RegisterArg iterVar = arrGetInsn.getResult();
    if (iterVar == null) {
        return null;
    }
    // array for each loop confirmed
    len.add(AFlag.SKIP);
    arrGetInsn.add(AFlag.SKIP);
    InstructionRemover.unbindInsn(mth, len);
    // inline array variable
    CodeShrinker.shrinkMethod(mth);
    if (arrGetInsn.contains(AFlag.WRAPPED)) {
        InsnArg wrapArg = BlockUtils.searchWrappedInsnParent(mth, arrGetInsn);
        if (wrapArg != null && wrapArg.getParentInsn() != null) {
            wrapArg.getParentInsn().replaceArg(wrapArg, iterVar);
        } else {
            LOG.debug(" checkArrayForEach: Wrapped insn not found: {}, mth: {}", arrGetInsn, mth);
        }
    }
    return new ForEachLoop(iterVar, len.getArg(0));
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) Compare(jadx.core.dex.regions.conditions.Compare) ArithNode(jadx.core.dex.instructions.ArithNode) ForEachLoop(jadx.core.dex.regions.loops.ForEachLoop)

Example 2 with InsnArg

use of jadx.core.dex.instructions.args.InsnArg in project jadx by skylot.

the class LoopRegionVisitor method checkIterableForEach.

private static boolean checkIterableForEach(MethodNode mth, LoopRegion loopRegion, IfCondition condition) {
    List<RegisterArg> condArgs = condition.getRegisterArgs();
    if (condArgs.size() != 1) {
        return false;
    }
    RegisterArg iteratorArg = condArgs.get(0);
    SSAVar sVar = iteratorArg.getSVar();
    if (sVar == null || sVar.isUsedInPhi()) {
        return false;
    }
    List<RegisterArg> useList = sVar.getUseList();
    InsnNode assignInsn = iteratorArg.getAssignInsn();
    if (useList.size() != 2 || assignInsn == null || !checkInvoke(assignInsn, null, "iterator()Ljava/util/Iterator;", 0)) {
        return false;
    }
    InsnArg iterableArg = assignInsn.getArg(0);
    InsnNode hasNextCall = useList.get(0).getParentInsn();
    InsnNode nextCall = useList.get(1).getParentInsn();
    if (hasNextCall == null || nextCall == null || !checkInvoke(hasNextCall, "java.util.Iterator", "hasNext()Z", 0) || !checkInvoke(nextCall, "java.util.Iterator", "next()Ljava/lang/Object;", 0)) {
        return false;
    }
    List<InsnNode> toSkip = new LinkedList<InsnNode>();
    RegisterArg iterVar = nextCall.getResult();
    if (iterVar == null) {
        return false;
    }
    if (nextCall.contains(AFlag.WRAPPED)) {
        InsnArg wrapArg = BlockUtils.searchWrappedInsnParent(mth, nextCall);
        if (wrapArg != null && wrapArg.getParentInsn() != null) {
            InsnNode parentInsn = wrapArg.getParentInsn();
            if (parentInsn.getType() != InsnType.CHECK_CAST) {
                if (!fixIterableType(mth, iterableArg, iterVar)) {
                    return false;
                }
                parentInsn.replaceArg(wrapArg, iterVar);
            } else {
                iterVar = parentInsn.getResult();
                if (iterVar == null || !fixIterableType(mth, iterableArg, iterVar)) {
                    return false;
                }
                InsnArg castArg = BlockUtils.searchWrappedInsnParent(mth, parentInsn);
                if (castArg != null && castArg.getParentInsn() != null) {
                    castArg.getParentInsn().replaceArg(castArg, iterVar);
                } else {
                    // cast not inlined
                    toSkip.add(parentInsn);
                }
            }
        } else {
            LOG.warn(" checkIterableForEach: Wrapped insn not found: {}, mth: {}", nextCall, mth);
            return false;
        }
    } else {
        toSkip.add(nextCall);
    }
    assignInsn.add(AFlag.SKIP);
    for (InsnNode insnNode : toSkip) {
        insnNode.add(AFlag.SKIP);
    }
    loopRegion.setType(new ForEachLoop(iterVar, iterableArg));
    return true;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) ForEachLoop(jadx.core.dex.regions.loops.ForEachLoop) LinkedList(java.util.LinkedList)

Example 3 with InsnArg

use of jadx.core.dex.instructions.args.InsnArg in project jadx by skylot.

the class SimplifyVisitor method simplifyInsn.

private static InsnNode simplifyInsn(MethodNode mth, InsnNode insn) {
    for (InsnArg arg : insn.getArguments()) {
        if (arg.isInsnWrap()) {
            InsnNode ni = simplifyInsn(mth, ((InsnWrapArg) arg).getWrapInsn());
            if (ni != null) {
                arg.wrapInstruction(ni);
            }
        }
    }
    switch(insn.getType()) {
        case ARITH:
            return simplifyArith(insn);
        case IF:
            simplifyIf((IfNode) insn);
            break;
        case TERNARY:
            simplifyTernary((TernaryInsn) insn);
            break;
        case INVOKE:
            return convertInvoke(mth, insn);
        case IPUT:
        case SPUT:
            return convertFieldArith(mth, insn);
        case CHECK_CAST:
            return processCast(mth, insn);
        case MOVE:
            InsnArg firstArg = insn.getArg(0);
            if (firstArg.isLiteral()) {
                InsnNode constInsn = new InsnNode(InsnType.CONST, 1);
                constInsn.setResult(insn.getResult());
                constInsn.addArg(firstArg);
                constInsn.copyAttributesFrom(insn);
                return constInsn;
            }
            break;
        default:
            break;
    }
    return null;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg)

Example 4 with InsnArg

use of jadx.core.dex.instructions.args.InsnArg in project jadx by skylot.

the class SimplifyVisitor method simplifyArith.

private static InsnNode simplifyArith(InsnNode insn) {
    ArithNode arith = (ArithNode) insn;
    if (arith.getArgsCount() != 2) {
        return null;
    }
    InsnArg litArg = null;
    InsnArg secondArg = arith.getArg(1);
    if (secondArg.isInsnWrap()) {
        InsnNode wr = ((InsnWrapArg) secondArg).getWrapInsn();
        if (wr.getType() == InsnType.CONST) {
            litArg = wr.getArg(0);
        }
    } else if (secondArg.isLiteral()) {
        litArg = secondArg;
    }
    if (litArg != null) {
        long lit = ((LiteralArg) litArg).getLiteral();
        // fix 'c + (-1)' => 'c - (1)'
        if (arith.getOp() == ArithOp.ADD && lit < 0) {
            return new ArithNode(ArithOp.SUB, arith.getResult(), insn.getArg(0), InsnArg.lit(-lit, litArg.getType()));
        }
    }
    return null;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) ArithNode(jadx.core.dex.instructions.ArithNode)

Example 5 with InsnArg

use of jadx.core.dex.instructions.args.InsnArg in project jadx by skylot.

the class ModVisitor method getArgsToFieldsMapping.

private static Map<InsnArg, FieldNode> getArgsToFieldsMapping(MethodNode callMthNode, ConstructorInsn co) {
    Map<InsnArg, FieldNode> map = new LinkedHashMap<InsnArg, FieldNode>();
    ClassNode parentClass = callMthNode.getParentClass();
    List<RegisterArg> argList = callMthNode.getArguments(false);
    int startArg = parentClass.getAccessFlags().isStatic() ? 0 : 1;
    int argsCount = argList.size();
    for (int i = startArg; i < argsCount; i++) {
        RegisterArg arg = argList.get(i);
        InsnNode useInsn = getParentInsnSkipMove(arg);
        if (useInsn == null) {
            return Collections.emptyMap();
        }
        FieldNode fieldNode = null;
        if (useInsn.getType() == InsnType.IPUT) {
            FieldInfo field = (FieldInfo) ((IndexInsnNode) useInsn).getIndex();
            fieldNode = parentClass.searchField(field);
            if (fieldNode == null || !fieldNode.getAccessFlags().isSynthetic()) {
                return Collections.emptyMap();
            }
        } else if (useInsn.getType() == InsnType.CONSTRUCTOR) {
            ConstructorInsn superConstr = (ConstructorInsn) useInsn;
            if (!superConstr.isSuper()) {
                return Collections.emptyMap();
            }
        } else {
            return Collections.emptyMap();
        }
        map.put(co.getArg(i), fieldNode);
    }
    return map;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) FieldNode(jadx.core.dex.nodes.FieldNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) FieldInfo(jadx.core.dex.info.FieldInfo) LinkedHashMap(java.util.LinkedHashMap)

Aggregations

InsnArg (jadx.core.dex.instructions.args.InsnArg)52 InsnNode (jadx.core.dex.nodes.InsnNode)32 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)24 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)19 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)15 ArgType (jadx.core.dex.instructions.args.ArgType)9 SSAVar (jadx.core.dex.instructions.args.SSAVar)9 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)8 BlockNode (jadx.core.dex.nodes.BlockNode)8 FieldNode (jadx.core.dex.nodes.FieldNode)7 FieldInfo (jadx.core.dex.info.FieldInfo)6 ArithNode (jadx.core.dex.instructions.ArithNode)5 InvokeNode (jadx.core.dex.instructions.InvokeNode)5 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)4 PhiInsn (jadx.core.dex.instructions.PhiInsn)4 ClassNode (jadx.core.dex.nodes.ClassNode)4 PhiListAttr (jadx.core.dex.attributes.nodes.PhiListAttr)3 MethodInfo (jadx.core.dex.info.MethodInfo)3 SwitchNode (jadx.core.dex.instructions.SwitchNode)3 MethodNode (jadx.core.dex.nodes.MethodNode)3