Search in sources :

Example 6 with InsnWrapArg

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

the class CodeShrinker method simplifyMoveInsns.

private static void simplifyMoveInsns(BlockNode block) {
    List<InsnNode> insns = block.getInstructions();
    int size = insns.size();
    for (int i = 0; i < size; i++) {
        InsnNode insn = insns.get(i);
        if (insn.getType() == InsnType.MOVE) {
            // replace 'move' with wrapped insn
            InsnArg arg = insn.getArg(0);
            if (arg.isInsnWrap()) {
                InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                wrapInsn.setResult(insn.getResult());
                wrapInsn.copyAttributesFrom(insn);
                wrapInsn.setOffset(insn.getOffset());
                wrapInsn.remove(AFlag.WRAPPED);
                block.getInstructions().set(i, wrapInsn);
            }
        }
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Example 7 with InsnWrapArg

use of jadx.core.dex.instructions.args.InsnWrapArg 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 8 with InsnWrapArg

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

the class SimplifyVisitor method convertInvoke.

private static InsnNode convertInvoke(MethodNode mth, InsnNode insn) {
    MethodInfo callMth = ((InvokeNode) insn).getCallMth();
    // convert it to STRING_CONCAT pseudo instruction.
    if (callMth.getDeclClass().getFullName().equals(Consts.CLASS_STRING_BUILDER) && callMth.getShortId().equals(Consts.MTH_TOSTRING_SIGNATURE) && insn.getArg(0).isInsnWrap()) {
        try {
            List<InsnNode> chain = flattenInsnChain(insn);
            //RAF
            int constrIndex = -1;
            // string is created using .append() calls:
            if (chain.size() > 1 && chain.get(0).getType() == InsnType.CONSTRUCTOR) {
                constrIndex = 0;
            } else if (chain.size() > 2 && chain.get(1).getType() == InsnType.CONSTRUCTOR) {
                //RAF Case where the first string element is String arg to the
                // new StringBuilder("xxx") constructor
                constrIndex = 1;
            } else if (chain.size() > 3 && chain.get(2).getType() == InsnType.CONSTRUCTOR) {
                //RAF Case where the first string element is String.valueOf() arg
                // to the new StringBuilder(String.valueOf(zzz)) constructor
                constrIndex = 2;
            }
            if (constrIndex != -1) {
                // If we found a CONSTRUCTOR, is it a StringBuilder?
                ConstructorInsn constr = (ConstructorInsn) chain.get(constrIndex);
                if (constr.getClassType().getFullName().equals(Consts.CLASS_STRING_BUILDER)) {
                    int len = chain.size(), argInd = 1;
                    InsnNode concatInsn = new InsnNode(InsnType.STR_CONCAT, len - 1);
                    InsnNode argInsn;
                    if (constrIndex > 0) {
                        // There was an arg to the StringBuilder constr
                        InsnWrapArg iwa;
                        if (constrIndex == 2 && (argInsn = chain.get(1)).getType() == InsnType.INVOKE && ((InvokeNode) argInsn).getCallMth().getName().compareTo("valueOf") == 0) {
                            // The argument of new StringBuilder() is a String.valueOf(chainElement0)
                            iwa = (InsnWrapArg) argInsn.getArg(0);
                            // Cause for loop below to skip to after the constructor
                            argInd = 3;
                        } else {
                            InsnNode firstNode = chain.get(0);
                            if (firstNode instanceof ConstStringNode) {
                                ConstStringNode csn = (ConstStringNode) firstNode;
                                iwa = new InsnWrapArg(csn);
                                // Cause for loop below to skip to after the constructor
                                argInd = 2;
                            } else {
                                return null;
                            }
                        }
                        concatInsn.addArg(iwa);
                    }
                    for (; argInd < len; argInd++) {
                        // Add the .append(xxx) arg string to concat
                        concatInsn.addArg(chain.get(argInd).getArg(1));
                    }
                    concatInsn.setResult(insn.getResult());
                    return concatInsn;
                }
            // end of if constructor is for StringBuilder
            }
        // end of if we found a constructor early in the chain
        } catch (Throwable e) {
            LOG.debug("Can't convert string concatenation: {} insn: {}", mth, insn, e);
        }
    }
    return null;
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) ConstStringNode(jadx.core.dex.instructions.ConstStringNode) MethodInfo(jadx.core.dex.info.MethodInfo) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn)

Example 9 with InsnWrapArg

use of jadx.core.dex.instructions.args.InsnWrapArg 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)

Example 10 with InsnWrapArg

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

the class PrepareForCodeGen method checkInline.

private static void checkInline(BlockNode block) {
    List<InsnNode> list = block.getInstructions();
    for (int i = 0; i < list.size(); i++) {
        InsnNode insn = list.get(i);
        // replace 'move' with inner wrapped instruction
        if (insn.getType() == InsnType.MOVE && insn.getArg(0).isInsnWrap()) {
            InsnNode wrapInsn = ((InsnWrapArg) insn.getArg(0)).getWrapInsn();
            wrapInsn.setResult(insn.getResult());
            wrapInsn.copyAttributesFrom(insn);
            list.set(i, wrapInsn);
        }
    }
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg)

Aggregations

InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)22 InsnNode (jadx.core.dex.nodes.InsnNode)19 InsnArg (jadx.core.dex.instructions.args.InsnArg)15 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)11 ArithNode (jadx.core.dex.instructions.ArithNode)4 InvokeNode (jadx.core.dex.instructions.InvokeNode)4 FieldInfo (jadx.core.dex.info.FieldInfo)3 InsnType (jadx.core.dex.instructions.InsnType)3 FieldNode (jadx.core.dex.nodes.FieldNode)3 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)2 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)2 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)2 ClassNode (jadx.core.dex.nodes.ClassNode)2 EnumMapAttr (jadx.core.dex.attributes.nodes.EnumMapAttr)1 MethodInfo (jadx.core.dex.info.MethodInfo)1 ArithOp (jadx.core.dex.instructions.ArithOp)1 ConstStringNode (jadx.core.dex.instructions.ConstStringNode)1 IfNode (jadx.core.dex.instructions.IfNode)1 ArgType (jadx.core.dex.instructions.args.ArgType)1 FieldArg (jadx.core.dex.instructions.args.FieldArg)1