Search in sources :

Example 1 with ConstructorInsn

use of jadx.core.dex.instructions.mods.ConstructorInsn 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 2 with ConstructorInsn

use of jadx.core.dex.instructions.mods.ConstructorInsn 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 3 with ConstructorInsn

use of jadx.core.dex.instructions.mods.ConstructorInsn in project jadx by skylot.

the class ClassGen method addEnumFields.

private void addEnumFields(CodeWriter code) throws CodegenException {
    EnumClassAttr enumFields = cls.get(AType.ENUM_CLASS);
    if (enumFields == null) {
        return;
    }
    InsnGen igen = null;
    for (Iterator<EnumField> it = enumFields.getFields().iterator(); it.hasNext(); ) {
        EnumField f = it.next();
        code.startLine(f.getField().getAlias());
        ConstructorInsn constrInsn = f.getConstrInsn();
        if (constrInsn.getArgsCount() > f.getStartArg()) {
            if (igen == null) {
                igen = makeInsnGen(enumFields.getStaticMethod());
            }
            MethodNode callMth = cls.dex().resolveMethod(constrInsn.getCallMth());
            igen.generateMethodArguments(code, constrInsn, f.getStartArg(), callMth);
        }
        if (f.getCls() != null) {
            code.add(' ');
            new ClassGen(f.getCls(), this).addClassBody(code);
        }
        if (it.hasNext()) {
            code.add(',');
        }
    }
    if (isMethodsPresents() || isFieldsPresents() || isInnerClassesPresents()) {
        if (enumFields.getFields().isEmpty()) {
            code.startLine();
        }
        code.add(';');
        if (isFieldsPresents()) {
            code.startLine();
        }
    }
}
Also used : EnumField(jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField) MethodNode(jadx.core.dex.nodes.MethodNode) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) EnumClassAttr(jadx.core.dex.attributes.nodes.EnumClassAttr)

Example 4 with ConstructorInsn

use of jadx.core.dex.instructions.mods.ConstructorInsn in project jadx by skylot.

the class NameGen method makeNameFromInsn.

private String makeNameFromInsn(InsnNode insn) {
    switch(insn.getType()) {
        case INVOKE:
            InvokeNode inv = (InvokeNode) insn;
            return makeNameFromInvoke(inv.getCallMth());
        case CONSTRUCTOR:
            ConstructorInsn co = (ConstructorInsn) insn;
            return makeNameForObject(co.getClassType().getType());
        case ARRAY_LENGTH:
            return "length";
        case ARITH:
        case TERNARY:
        case CAST:
            for (InsnArg arg : insn.getArguments()) {
                if (arg.isInsnWrap()) {
                    InsnNode wrapInsn = ((InsnWrapArg) arg).getWrapInsn();
                    String wName = makeNameFromInsn(wrapInsn);
                    if (wName != null) {
                        return wName;
                    }
                }
            }
            break;
        default:
            break;
    }
    return null;
}
Also used : InsnNode(jadx.core.dex.nodes.InsnNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InvokeNode(jadx.core.dex.instructions.InvokeNode) InsnWrapArg(jadx.core.dex.instructions.args.InsnWrapArg) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn)

Example 5 with ConstructorInsn

use of jadx.core.dex.instructions.mods.ConstructorInsn in project jadx by skylot.

the class ModVisitor method processInvoke.

private static void processInvoke(MethodNode mth, BlockNode block, int insnNumber, InstructionRemover remover) {
    ClassNode parentClass = mth.getParentClass();
    InsnNode insn = block.getInstructions().get(insnNumber);
    InvokeNode inv = (InvokeNode) insn;
    MethodInfo callMth = inv.getCallMth();
    if (!callMth.isConstructor()) {
        return;
    }
    InsnNode instArgAssignInsn = ((RegisterArg) inv.getArg(0)).getAssignInsn();
    ConstructorInsn co = new ConstructorInsn(mth, inv);
    boolean remove = false;
    if (co.isSuper() && (co.getArgsCount() == 0 || parentClass.isEnum())) {
        remove = true;
    } else if (co.isThis() && co.getArgsCount() == 0) {
        MethodNode defCo = parentClass.searchMethodByName(callMth.getShortId());
        if (defCo == null || defCo.isNoCode()) {
            // default constructor not implemented
            remove = true;
        }
    }
    // remove super() call in instance initializer
    if (parentClass.isAnonymous() && mth.isDefaultConstructor() && co.isSuper()) {
        remove = true;
    }
    if (remove) {
        remover.add(insn);
        return;
    }
    if (co.isNewInstance()) {
        InsnNode newInstInsn = removeAssignChain(instArgAssignInsn, remover, InsnType.NEW_INSTANCE);
        if (newInstInsn != null) {
            RegisterArg instArg = newInstInsn.getResult();
            RegisterArg resultArg = co.getResult();
            if (!resultArg.equals(instArg)) {
                // replace all usages of 'instArg' with result of this constructor instruction
                for (RegisterArg useArg : new ArrayList<RegisterArg>(instArg.getSVar().getUseList())) {
                    RegisterArg dup = resultArg.duplicate();
                    InsnNode parentInsn = useArg.getParentInsn();
                    parentInsn.replaceArg(useArg, dup);
                    dup.setParentInsn(parentInsn);
                    resultArg.getSVar().use(dup);
                }
            }
        }
    }
    ConstructorInsn replace = processConstructor(mth, co);
    if (replace != null) {
        co = replace;
    }
    replaceInsn(block, insnNumber, co);
    processAnonymousConstructor(mth, co);
}
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) MethodNode(jadx.core.dex.nodes.MethodNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) ArrayList(java.util.ArrayList) MethodInfo(jadx.core.dex.info.MethodInfo) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn)

Aggregations

ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)8 InsnNode (jadx.core.dex.nodes.InsnNode)6 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)5 MethodNode (jadx.core.dex.nodes.MethodNode)5 ClassNode (jadx.core.dex.nodes.ClassNode)4 MethodInfo (jadx.core.dex.info.MethodInfo)3 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)3 InvokeNode (jadx.core.dex.instructions.InvokeNode)3 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)3 EnumClassAttr (jadx.core.dex.attributes.nodes.EnumClassAttr)2 EnumField (jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField)2 FieldInfo (jadx.core.dex.info.FieldInfo)2 InsnArg (jadx.core.dex.instructions.args.InsnArg)2 InsnWrapArg (jadx.core.dex.instructions.args.InsnWrapArg)2 FieldNode (jadx.core.dex.nodes.FieldNode)2 ArrayList (java.util.ArrayList)2 AccessInfo (jadx.core.dex.info.AccessInfo)1 ClassInfo (jadx.core.dex.info.ClassInfo)1 ConstStringNode (jadx.core.dex.instructions.ConstStringNode)1 ArgType (jadx.core.dex.instructions.args.ArgType)1