Search in sources :

Example 21 with MethodInfo

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

the class ClassModifier method getArgsToFieldsMapping.

private static Map<InsnArg, FieldNode> getArgsToFieldsMapping(MethodNode mth, List<InsnNode> usedInsns) {
    MethodInfo callMth = mth.getMethodInfo();
    ClassNode cls = mth.getParentClass();
    List<RegisterArg> argList = mth.getArgRegs();
    ClassNode outerCls = mth.getUseIn().get(0).getParentClass();
    int startArg = 0;
    if (callMth.getArgsCount() != 0 && callMth.getArgumentsTypes().get(0).equals(outerCls.getClassInfo().getType())) {
        startArg = 1;
    }
    Map<InsnArg, FieldNode> map = new LinkedHashMap<>();
    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();
        }
        switch(useInsn.getType()) {
            case IPUT:
                FieldNode fieldNode = cls.searchField((FieldInfo) ((IndexInsnNode) useInsn).getIndex());
                if (fieldNode == null || !fieldNode.getAccessFlags().isSynthetic()) {
                    return Collections.emptyMap();
                }
                map.put(arg, fieldNode);
                usedInsns.add(useInsn);
                break;
            case CONSTRUCTOR:
                ConstructorInsn superConstr = (ConstructorInsn) useInsn;
                if (!superConstr.isSuper()) {
                    return Collections.emptyMap();
                }
                usedInsns.add(useInsn);
                break;
            default:
                return Collections.emptyMap();
        }
    }
    return map;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) 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) MethodInfo(jadx.core.dex.info.MethodInfo) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) LinkedHashMap(java.util.LinkedHashMap)

Example 22 with MethodInfo

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

the class ClassModifier method checkSyntheticWrapper.

private static boolean checkSyntheticWrapper(MethodNode mth, InsnNode insn) {
    InsnType insnType = insn.getType();
    if (insnType != InsnType.INVOKE) {
        return false;
    }
    InvokeNode invokeInsn = (InvokeNode) insn;
    if (invokeInsn.getInvokeType() == InvokeType.SUPER) {
        return false;
    }
    MethodInfo callMth = invokeInsn.getCallMth();
    MethodNode wrappedMth = mth.root().resolveMethod(callMth);
    if (wrappedMth == null) {
        return false;
    }
    AccessInfo wrappedAccFlags = wrappedMth.getAccessFlags();
    if (wrappedAccFlags.isStatic()) {
        return false;
    }
    if (callMth.getArgsCount() != mth.getMethodInfo().getArgsCount()) {
        return false;
    }
    // rename method only from current class
    if (!mth.getParentClass().equals(wrappedMth.getParentClass())) {
        return false;
    }
    // all args must be registers passed from method args (allow only casts insns)
    for (InsnArg arg : insn.getArguments()) {
        if (!registersAndCastsOnly(arg)) {
            return false;
        }
    }
    // remove confirmed, change visibility and name if needed
    if (!wrappedAccFlags.isPublic()) {
        // must be public
        FixAccessModifiers.changeVisibility(wrappedMth, AccessFlags.PUBLIC);
    }
    String alias = mth.getAlias();
    if (!Objects.equals(wrappedMth.getAlias(), alias)) {
        wrappedMth.getMethodInfo().setAlias(alias);
    }
    return true;
}
Also used : MethodNode(jadx.core.dex.nodes.MethodNode) InsnArg(jadx.core.dex.instructions.args.InsnArg) InvokeNode(jadx.core.dex.instructions.InvokeNode) AccessInfo(jadx.core.dex.info.AccessInfo) MethodInfo(jadx.core.dex.info.MethodInfo) InsnType(jadx.core.dex.instructions.InsnType)

Example 23 with MethodInfo

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

the class LoopRegionVisitor method checkInvoke.

/**
 * Check if instruction is a interface invoke with corresponding parameters.
 */
private static boolean checkInvoke(InsnNode insn, String declClsFullName, String mthId) {
    if (insn == null) {
        return false;
    }
    if (insn.getType() == InsnType.INVOKE) {
        InvokeNode inv = (InvokeNode) insn;
        MethodInfo callMth = inv.getCallMth();
        if (inv.getInvokeType() == InvokeType.INTERFACE && callMth.getShortId().equals(mthId)) {
            if (declClsFullName == null) {
                return true;
            }
            return callMth.getDeclClass().getFullName().equals(declClsFullName);
        }
    }
    return false;
}
Also used : InvokeNode(jadx.core.dex.instructions.InvokeNode) MethodInfo(jadx.core.dex.info.MethodInfo)

Example 24 with MethodInfo

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

Example 25 with MethodInfo

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

the class MethodNode method isArgsOverload.

/**
	 * Return true if exists method with same name and arguments count
	 */
public boolean isArgsOverload() {
    int argsCount = mthInfo.getArgumentsTypes().size();
    if (argsCount == 0) {
        return false;
    }
    String name = getName();
    for (MethodNode method : parentClass.getMethods()) {
        MethodInfo otherMthInfo = method.mthInfo;
        if (this != method && otherMthInfo.getArgumentsTypes().size() == argsCount && otherMthInfo.getName().equals(name)) {
            return true;
        }
    }
    return false;
}
Also used : MethodInfo(jadx.core.dex.info.MethodInfo)

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