Search in sources :

Example 1 with MethodInfo

use of jadx.core.dex.info.MethodInfo in project jadx by skylot.

the class RenameVisitor method checkMethods.

private void checkMethods(ClassNode cls) {
    Set<String> names = new HashSet<String>();
    for (MethodNode mth : cls.getMethods()) {
        if (mth.contains(AFlag.DONT_GENERATE)) {
            continue;
        }
        MethodInfo methodInfo = mth.getMethodInfo();
        String signature = makeMethodSignature(methodInfo);
        if (!names.add(signature)) {
            methodInfo.setAlias(deobfuscator.makeMethodAlias(mth));
        }
    }
}
Also used : MethodNode(jadx.core.dex.nodes.MethodNode) MethodInfo(jadx.core.dex.info.MethodInfo) HashSet(java.util.HashSet)

Example 2 with MethodInfo

use of jadx.core.dex.info.MethodInfo 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 3 with MethodInfo

use of jadx.core.dex.info.MethodInfo in project jadx by skylot.

the class PostTypeInference method process.

public static boolean process(MethodNode mth, InsnNode insn) {
    DexNode dex = mth.dex();
    switch(insn.getType()) {
        case CONST:
            RegisterArg res = insn.getResult();
            LiteralArg litArg = (LiteralArg) insn.getArg(0);
            if (res.getType().isObject()) {
                long lit = litArg.getLiteral();
                if (lit != 0) {
                    // incorrect literal value for object
                    ArgType type = lit == 1 ? ArgType.BOOLEAN : ArgType.INT;
                    // can't merge with object -> force it
                    litArg.setType(type);
                    res.getSVar().setType(type);
                    return true;
                }
            }
            return litArg.merge(dex, res);
        case MOVE:
            {
                boolean change = false;
                if (insn.getResult().merge(dex, insn.getArg(0))) {
                    change = true;
                }
                if (insn.getArg(0).merge(dex, insn.getResult())) {
                    change = true;
                }
                return change;
            }
        case AGET:
            return fixArrayTypes(dex, insn.getArg(0), insn.getResult());
        case APUT:
            return fixArrayTypes(dex, insn.getArg(0), insn.getArg(2));
        case IF:
            {
                boolean change = false;
                if (insn.getArg(1).merge(dex, insn.getArg(0))) {
                    change = true;
                }
                if (insn.getArg(0).merge(dex, insn.getArg(1))) {
                    change = true;
                }
                return change;
            }
        // check argument types for overloaded methods
        case INVOKE:
            {
                boolean change = false;
                InvokeNode inv = (InvokeNode) insn;
                MethodInfo callMth = inv.getCallMth();
                MethodNode node = mth.dex().resolveMethod(callMth);
                if (node != null && node.isArgsOverload()) {
                    List<ArgType> args = callMth.getArgumentsTypes();
                    int j = inv.getArgsCount() - 1;
                    for (int i = args.size() - 1; i >= 0; i--) {
                        ArgType argType = args.get(i);
                        InsnArg insnArg = inv.getArg(j--);
                        if (insnArg.isRegister() && !argType.equals(insnArg.getType())) {
                            insnArg.setType(argType);
                            change = true;
                        }
                    }
                }
                return change;
            }
        case CHECK_CAST:
            {
                ArgType castType = (ArgType) ((IndexInsnNode) insn).getIndex();
                RegisterArg result = insn.getResult();
                ArgType resultType = result.getType();
                // don't override generic types of same base class
                boolean skip = castType.isObject() && resultType.isObject() && castType.getObject().equals(resultType.getObject());
                if (!skip) {
                    // workaround for compiler bug (see TestDuplicateCast)
                    result.getSVar().setType(castType);
                }
                return true;
            }
        case PHI:
        case MERGE:
            {
                ArgType type = insn.getResult().getType();
                if (!type.isTypeKnown()) {
                    for (InsnArg arg : insn.getArguments()) {
                        if (arg.getType().isTypeKnown()) {
                            type = arg.getType();
                            break;
                        }
                    }
                }
                boolean changed = false;
                if (updateType(insn.getResult(), type)) {
                    changed = true;
                }
                for (int i = 0; i < insn.getArgsCount(); i++) {
                    RegisterArg arg = (RegisterArg) insn.getArg(i);
                    if (updateType(arg, type)) {
                        changed = true;
                    }
                }
                return changed;
            }
        default:
            break;
    }
    return false;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) MethodNode(jadx.core.dex.nodes.MethodNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) DexNode(jadx.core.dex.nodes.DexNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) MethodInfo(jadx.core.dex.info.MethodInfo) List(java.util.List) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 4 with MethodInfo

use of jadx.core.dex.info.MethodInfo in project jadx by skylot.

the class InsnGen method makeInvoke.

private void makeInvoke(InvokeNode insn, CodeWriter code) throws CodegenException {
    MethodInfo callMth = insn.getCallMth();
    // inline method
    MethodNode callMthNode = mth.dex().deepResolveMethod(callMth);
    if (callMthNode != null) {
        if (inlineMethod(callMthNode, insn, code)) {
            return;
        }
        callMth = callMthNode.getMethodInfo();
    }
    int k = 0;
    InvokeType type = insn.getInvokeType();
    switch(type) {
        case DIRECT:
        case VIRTUAL:
        case INTERFACE:
            InsnArg arg = insn.getArg(0);
            // FIXME: add 'this' for equals methods in scope
            if (!arg.isThis()) {
                addArgDot(code, arg);
            }
            k++;
            break;
        case SUPER:
            // use 'super' instead 'this' in 0 arg
            code.add("super").add('.');
            k++;
            break;
        case STATIC:
            ClassInfo insnCls = mth.getParentClass().getAlias();
            ClassInfo declClass = callMth.getDeclClass();
            if (!insnCls.equals(declClass)) {
                useClass(code, declClass);
                code.add('.');
            }
            break;
    }
    if (callMthNode != null) {
        code.attachAnnotation(callMthNode);
    }
    code.add(callMth.getAlias());
    generateMethodArguments(code, insn, k, callMthNode);
}
Also used : MethodNode(jadx.core.dex.nodes.MethodNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InvokeType(jadx.core.dex.instructions.InvokeType) MethodInfo(jadx.core.dex.info.MethodInfo) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 5 with MethodInfo

use of jadx.core.dex.info.MethodInfo in project jadx by skylot.

the class DeobfPresets method dumpMapping.

/**
	 * Saves DefaultDeobfuscator presets
	 */
private void dumpMapping() throws IOException {
    List<String> list = new ArrayList<String>();
    // packages
    for (PackageNode p : deobfuscator.getRootPackage().getInnerPackages()) {
        for (PackageNode pp : p.getInnerPackages()) {
            dfsPackageName(list, p.getName(), pp);
        }
        if (p.hasAlias()) {
            list.add(String.format("p %s = %s", p.getName(), p.getAlias()));
        }
    }
    // classes
    for (DeobfClsInfo deobfClsInfo : deobfuscator.getClsMap().values()) {
        if (deobfClsInfo.getAlias() != null) {
            list.add(String.format("c %s = %s", deobfClsInfo.getCls().getClassInfo().getFullName(), deobfClsInfo.getAlias()));
        }
    }
    for (FieldInfo fld : deobfuscator.getFldMap().keySet()) {
        list.add(String.format("f %s = %s", fld.getFullId(), fld.getAlias()));
    }
    for (MethodInfo mth : deobfuscator.getMthMap().keySet()) {
        list.add(String.format("m %s = %s", mth.getFullId(), mth.getAlias()));
    }
    Collections.sort(list);
    FileUtils.writeLines(deobfMapFile, MAP_FILE_CHARSET, list);
    list.clear();
}
Also used : ArrayList(java.util.ArrayList) MethodInfo(jadx.core.dex.info.MethodInfo) FieldInfo(jadx.core.dex.info.FieldInfo)

Aggregations

MethodInfo (jadx.core.dex.info.MethodInfo)39 MethodNode (jadx.core.dex.nodes.MethodNode)13 ArgType (jadx.core.dex.instructions.args.ArgType)10 InvokeNode (jadx.core.dex.instructions.InvokeNode)9 InsnArg (jadx.core.dex.instructions.args.InsnArg)9 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)8 InsnNode (jadx.core.dex.nodes.InsnNode)8 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)6 ConstructorInsn (jadx.core.dex.instructions.mods.ConstructorInsn)6 ClassInfo (jadx.core.dex.info.ClassInfo)4 FieldInfo (jadx.core.dex.info.FieldInfo)4 ClassNode (jadx.core.dex.nodes.ClassNode)4 FieldNode (jadx.core.dex.nodes.FieldNode)4 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)4 ArrayList (java.util.ArrayList)4 BaseInvokeNode (jadx.core.dex.instructions.BaseInvokeNode)3 IMethodRef (jadx.api.plugins.input.data.IMethodRef)2 InvokeType (jadx.core.dex.instructions.InvokeType)2 IMethodDetails (jadx.core.dex.nodes.IMethodDetails)2 HashSet (java.util.HashSet)2