Search in sources :

Example 6 with IMethodDetails

use of jadx.core.dex.nodes.IMethodDetails in project jadx by skylot.

the class OverrideMethodVisitor method processOverrideMethods.

private MethodOverrideAttr processOverrideMethods(MethodNode mth, SuperTypesData superData) {
    MethodOverrideAttr result = mth.get(AType.METHOD_OVERRIDE);
    if (result != null) {
        return result;
    }
    ClassNode cls = mth.getParentClass();
    String signature = mth.getMethodInfo().makeSignature(false);
    List<IMethodDetails> overrideList = new ArrayList<>();
    Set<IMethodDetails> baseMethods = new HashSet<>();
    for (ArgType superType : superData.getSuperTypes()) {
        ClassNode classNode = mth.root().resolveClass(superType);
        if (classNode != null) {
            MethodNode ovrdMth = searchOverriddenMethod(classNode, signature);
            if (ovrdMth != null) {
                if (isMethodVisibleInCls(ovrdMth, cls)) {
                    overrideList.add(ovrdMth);
                    MethodOverrideAttr attr = ovrdMth.get(AType.METHOD_OVERRIDE);
                    if (attr != null) {
                        addBaseMethod(superData, overrideList, baseMethods, superType);
                        return buildOverrideAttr(mth, overrideList, baseMethods, attr);
                    }
                }
            }
        } else {
            ClspClass clsDetails = mth.root().getClsp().getClsDetails(superType);
            if (clsDetails != null) {
                Map<String, ClspMethod> methodsMap = clsDetails.getMethodsMap();
                for (Map.Entry<String, ClspMethod> entry : methodsMap.entrySet()) {
                    String mthShortId = entry.getKey();
                    if (mthShortId.startsWith(signature)) {
                        overrideList.add(entry.getValue());
                        break;
                    }
                }
            }
        }
        addBaseMethod(superData, overrideList, baseMethods, superType);
    }
    return buildOverrideAttr(mth, overrideList, baseMethods, null);
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) ClassNode(jadx.core.dex.nodes.ClassNode) ClspClass(jadx.core.clsp.ClspClass) ClspMethod(jadx.core.clsp.ClspMethod) ArrayList(java.util.ArrayList) MethodOverrideAttr(jadx.core.dex.attributes.nodes.MethodOverrideAttr) MethodNode(jadx.core.dex.nodes.MethodNode) Map(java.util.Map) IMethodDetails(jadx.core.dex.nodes.IMethodDetails) HashSet(java.util.HashSet)

Example 7 with IMethodDetails

use of jadx.core.dex.nodes.IMethodDetails in project jadx by skylot.

the class TypeBoundInvokeAssign method getReturnType.

private ArgType getReturnType(ArgType instanceType) {
    ArgType mthDeclType;
    IMethodDetails methodDetails = root.getMethodUtils().getMethodDetails(invokeNode);
    if (methodDetails != null) {
        // use methods detail to resolve declaration class for virtual invokes
        mthDeclType = methodDetails.getMethodInfo().getDeclClass().getType();
    } else {
        mthDeclType = instanceType;
    }
    ArgType resultGeneric = root.getTypeUtils().replaceClassGenerics(instanceType, mthDeclType, genericReturnType);
    if (resultGeneric != null && !resultGeneric.isWildcard()) {
        return resultGeneric;
    }
    return invokeNode.getCallMth().getReturnType();
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IMethodDetails(jadx.core.dex.nodes.IMethodDetails)

Example 8 with IMethodDetails

use of jadx.core.dex.nodes.IMethodDetails in project jadx by skylot.

the class TypeUpdate method invokeListener.

private TypeUpdateResult invokeListener(TypeUpdateInfo updateInfo, InsnNode insn, InsnArg arg, ArgType candidateType) {
    BaseInvokeNode invoke = (BaseInvokeNode) insn;
    if (isAssign(invoke, arg)) {
        // TODO: implement backward type propagation (from result to instance)
        return SAME;
    }
    if (invoke.getInstanceArg() == arg) {
        IMethodDetails methodDetails = root.getMethodUtils().getMethodDetails(invoke);
        if (methodDetails == null) {
            return SAME;
        }
        TypeUtils typeUtils = root.getTypeUtils();
        Set<ArgType> knownTypeVars = typeUtils.getKnownTypeVarsAtMethod(updateInfo.getMth());
        Map<ArgType, ArgType> typeVarsMap = typeUtils.getTypeVariablesMapping(candidateType);
        ArgType returnType = methodDetails.getReturnType();
        List<ArgType> argTypes = methodDetails.getArgTypes();
        int argsCount = argTypes.size();
        if (typeVarsMap.isEmpty()) {
            // generics can't be resolved => use as is
            return applyInvokeTypes(updateInfo, invoke, argsCount, knownTypeVars, () -> returnType, argTypes::get);
        }
        // resolve types before apply
        return applyInvokeTypes(updateInfo, invoke, argsCount, knownTypeVars, () -> typeUtils.replaceTypeVariablesUsingMap(returnType, typeVarsMap), argNum -> typeUtils.replaceClassGenerics(candidateType, argTypes.get(argNum)));
    }
    return SAME;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) BaseInvokeNode(jadx.core.dex.instructions.BaseInvokeNode) TypeUtils(jadx.core.dex.nodes.utils.TypeUtils) IMethodDetails(jadx.core.dex.nodes.IMethodDetails)

Example 9 with IMethodDetails

use of jadx.core.dex.nodes.IMethodDetails in project jadx by skylot.

the class MethodUtils method getMethodOriginDeclClass.

public ClassInfo getMethodOriginDeclClass(MethodNode mth) {
    IMethodDetails baseMth = getOverrideBaseMth(mth);
    if (baseMth != null) {
        return baseMth.getMethodInfo().getDeclClass();
    }
    MethodBridgeAttr bridgeAttr = mth.get(AType.BRIDGED_BY);
    if (bridgeAttr != null) {
        return getMethodOriginDeclClass(bridgeAttr.getBridgeMth());
    }
    return mth.getMethodInfo().getDeclClass();
}
Also used : MethodBridgeAttr(jadx.core.dex.attributes.nodes.MethodBridgeAttr) IMethodDetails(jadx.core.dex.nodes.IMethodDetails)

Example 10 with IMethodDetails

use of jadx.core.dex.nodes.IMethodDetails in project jadx by skylot.

the class InlineMethods method inlineMethod.

private void inlineMethod(MethodNode mth, MethodNode callMth, MethodInlineAttr mia, BlockNode block, InvokeNode insn) {
    InsnNode inlCopy = mia.getInsn().copyWithoutResult();
    RegisterArg resultArg = insn.getResult();
    if (resultArg != null) {
        inlCopy.setResult(resultArg.duplicate());
    } else if (isAssignNeeded(mia.getInsn(), insn, callMth)) {
        // add fake result to make correct java expression (see test TestGetterInlineNegative)
        inlCopy.setResult(makeFakeArg(mth, callMth.getReturnType(), "unused"));
    }
    if (!callMth.getMethodInfo().getArgumentsTypes().isEmpty()) {
        // remap args
        InsnArg[] regs = new InsnArg[callMth.getRegsCount()];
        int[] regNums = mia.getArgsRegNums();
        for (int i = 0; i < regNums.length; i++) {
            InsnArg arg = insn.getArg(i);
            regs[regNums[i]] = arg;
        }
        // replace args
        List<RegisterArg> inlArgs = new ArrayList<>();
        inlCopy.getRegisterArgs(inlArgs);
        for (RegisterArg r : inlArgs) {
            int regNum = r.getRegNum();
            if (regNum >= regs.length) {
                LOG.warn("Unknown register number {} in method call: {} from {}", r, callMth, mth);
            } else {
                InsnArg repl = regs[regNum];
                if (repl == null) {
                    LOG.warn("Not passed register {} in method call: {} from {}", r, callMth, mth);
                } else {
                    inlCopy.replaceArg(r, repl);
                }
            }
        }
    }
    IMethodDetails methodDetailsAttr = inlCopy.get(AType.METHOD_DETAILS);
    if (!BlockUtils.replaceInsn(mth, block, insn, inlCopy)) {
        mth.addWarnComment("Failed to inline method: " + callMth);
    }
    // replaceInsn replaces the attributes as well, make sure to preserve METHOD_DETAILS
    if (methodDetailsAttr != null) {
        inlCopy.addAttr(methodDetailsAttr);
    }
    updateUsageInfo(mth, callMth, mia.getInsn());
}
Also used : IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) InsnArg(jadx.core.dex.instructions.args.InsnArg) ArrayList(java.util.ArrayList) IMethodDetails(jadx.core.dex.nodes.IMethodDetails)

Aggregations

IMethodDetails (jadx.core.dex.nodes.IMethodDetails)14 ArgType (jadx.core.dex.instructions.args.ArgType)7 MethodNode (jadx.core.dex.nodes.MethodNode)6 ArrayList (java.util.ArrayList)4 MethodOverrideAttr (jadx.core.dex.attributes.nodes.MethodOverrideAttr)3 MethodInfo (jadx.core.dex.info.MethodInfo)2 InsnArg (jadx.core.dex.instructions.args.InsnArg)2 ClassNode (jadx.core.dex.nodes.ClassNode)2 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)2 ClspClass (jadx.core.clsp.ClspClass)1 ClspMethod (jadx.core.clsp.ClspMethod)1 MethodBridgeAttr (jadx.core.dex.attributes.nodes.MethodBridgeAttr)1 MethodInlineAttr (jadx.core.dex.attributes.nodes.MethodInlineAttr)1 SkipMethodArgsAttr (jadx.core.dex.attributes.nodes.SkipMethodArgsAttr)1 AccessInfo (jadx.core.dex.info.AccessInfo)1 ClassInfo (jadx.core.dex.info.ClassInfo)1 BaseInvokeNode (jadx.core.dex.instructions.BaseInvokeNode)1 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)1 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)1 InsnNode (jadx.core.dex.nodes.InsnNode)1