Search in sources :

Example 16 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 17 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)

Example 18 with InsnArg

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

the class ModVisitor method replaceStep.

private static void replaceStep(MethodNode mth, InstructionRemover remover) {
    ClassNode parentClass = mth.getParentClass();
    for (BlockNode block : mth.getBasicBlocks()) {
        remover.setBlock(block);
        int size = block.getInstructions().size();
        for (int i = 0; i < size; i++) {
            InsnNode insn = block.getInstructions().get(i);
            switch(insn.getType()) {
                case INVOKE:
                    processInvoke(mth, block, i, remover);
                    break;
                case CONST:
                case CONST_STR:
                case CONST_CLASS:
                    {
                        FieldNode f;
                        if (insn.getType() == InsnType.CONST_STR) {
                            String s = ((ConstStringNode) insn).getString();
                            f = parentClass.getConstField(s);
                        } else if (insn.getType() == InsnType.CONST_CLASS) {
                            ArgType t = ((ConstClassNode) insn).getClsType();
                            f = parentClass.getConstField(t);
                        } else {
                            f = parentClass.getConstFieldByLiteralArg((LiteralArg) insn.getArg(0));
                        }
                        if (f != null) {
                            InsnNode inode = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
                            inode.setResult(insn.getResult());
                            replaceInsn(block, i, inode);
                        }
                        break;
                    }
                case SWITCH:
                    SwitchNode sn = (SwitchNode) insn;
                    for (int k = 0; k < sn.getCasesCount(); k++) {
                        FieldNode f = parentClass.getConstField(sn.getKeys()[k]);
                        if (f != null) {
                            sn.getKeys()[k] = f;
                        }
                    }
                    break;
                case NEW_ARRAY:
                    // create array in 'fill-array' instruction
                    int next = i + 1;
                    if (next < size) {
                        InsnNode ni = block.getInstructions().get(next);
                        if (ni.getType() == InsnType.FILL_ARRAY) {
                            ni.getResult().merge(mth.dex(), insn.getResult());
                            ArgType arrType = ((NewArrayNode) insn).getArrayType();
                            ((FillArrayNode) ni).mergeElementType(mth.dex(), arrType.getArrayElement());
                            remover.add(insn);
                        }
                    }
                    break;
                case FILL_ARRAY:
                    InsnNode filledArr = makeFilledArrayInsn(mth, (FillArrayNode) insn);
                    replaceInsn(block, i, filledArr);
                    break;
                case MOVE_EXCEPTION:
                    processMoveException(mth, block, insn, remover);
                    break;
                case ARITH:
                    ArithNode arithNode = (ArithNode) insn;
                    if (arithNode.getArgsCount() == 2) {
                        InsnArg litArg = arithNode.getArg(1);
                        if (litArg.isLiteral()) {
                            FieldNode f = parentClass.getConstFieldByLiteralArg((LiteralArg) litArg);
                            if (f != null) {
                                InsnNode fGet = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
                                insn.replaceArg(litArg, InsnArg.wrapArg(fGet));
                            }
                        }
                    }
                    break;
                default:
                    break;
            }
        }
        remover.perform();
    }
}
Also used : BlockNode(jadx.core.dex.nodes.BlockNode) ArgType(jadx.core.dex.instructions.args.ArgType) ClassNode(jadx.core.dex.nodes.ClassNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) FieldNode(jadx.core.dex.nodes.FieldNode) NewArrayNode(jadx.core.dex.instructions.NewArrayNode) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) ArithNode(jadx.core.dex.instructions.ArithNode) SwitchNode(jadx.core.dex.instructions.SwitchNode) FillArrayNode(jadx.core.dex.instructions.FillArrayNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 19 with InsnArg

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

the class ModVisitor method processAnonymousConstructor.

private static void processAnonymousConstructor(MethodNode mth, ConstructorInsn co) {
    MethodInfo callMth = co.getCallMth();
    MethodNode callMthNode = mth.dex().resolveMethod(callMth);
    if (callMthNode == null) {
        return;
    }
    ClassNode classNode = callMthNode.getParentClass();
    ClassInfo classInfo = classNode.getClassInfo();
    ClassNode parentClass = mth.getParentClass();
    if (!classInfo.isInner() || !Character.isDigit(classInfo.getShortName().charAt(0)) || !parentClass.getInnerClasses().contains(classNode)) {
        return;
    }
    if (!classNode.getAccessFlags().isStatic() && (callMth.getArgsCount() == 0 || !callMth.getArgumentsTypes().get(0).equals(parentClass.getClassInfo().getType()))) {
        return;
    }
    // TODO: calculate this constructor and other constructor usage
    Map<InsnArg, FieldNode> argsMap = getArgsToFieldsMapping(callMthNode, co);
    if (argsMap.isEmpty()) {
        return;
    }
    // all checks passed
    classNode.add(AFlag.ANONYMOUS_CLASS);
    callMthNode.add(AFlag.DONT_GENERATE);
    for (Map.Entry<InsnArg, FieldNode> entry : argsMap.entrySet()) {
        FieldNode field = entry.getValue();
        if (field == null) {
            continue;
        }
        InsnArg arg = entry.getKey();
        field.addAttr(new FieldReplaceAttr(arg));
        field.add(AFlag.DONT_GENERATE);
        if (arg.isRegister()) {
            RegisterArg reg = (RegisterArg) arg;
            SSAVar sVar = reg.getSVar();
            if (sVar != null) {
                sVar.add(AFlag.FINAL);
                sVar.add(AFlag.DONT_INLINE);
            }
            reg.add(AFlag.SKIP_ARG);
        }
    }
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ConstClassNode(jadx.core.dex.instructions.ConstClassNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) MethodNode(jadx.core.dex.nodes.MethodNode) FieldNode(jadx.core.dex.nodes.FieldNode) SSAVar(jadx.core.dex.instructions.args.SSAVar) InsnArg(jadx.core.dex.instructions.args.InsnArg) FieldReplaceAttr(jadx.core.dex.attributes.nodes.FieldReplaceAttr) MethodInfo(jadx.core.dex.info.MethodInfo) LinkedHashMap(java.util.LinkedHashMap) Map(java.util.Map) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 20 with InsnArg

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

the class PrepareForCodeGen method checkInsn.

/**
	 * Remove parenthesis for wrapped insn  in arith '+' or '-'
	 * ('(a + b) +c' => 'a + b + c')
	 */
private static void checkInsn(InsnNode insn) {
    if (insn.getType() == InsnType.ARITH) {
        ArithNode arith = (ArithNode) insn;
        ArithOp op = arith.getOp();
        if (op == ArithOp.ADD || op == ArithOp.SUB) {
            for (int i = 0; i < 2; i++) {
                InsnArg arg = arith.getArg(i);
                if (arg.isInsnWrap()) {
                    InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                    wrapInsn.add(AFlag.DONT_WRAP);
                    checkInsn(wrapInsn);
                }
            }
        }
    } else {
        for (InsnArg arg : insn.getArguments()) {
            if (arg.isInsnWrap()) {
                InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                checkInsn(wrapInsn);
            }
        }
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) ArithOp(jadx.core.dex.instructions.ArithOp) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) ArithNode(jadx.core.dex.instructions.ArithNode)

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