Search in sources :

Example 1 with DexNode

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

the class ConstInlineVisitor method fixTypes.

/**
	 * This is method similar to PostTypeInference.process method,
	 * but contains some expensive operations needed only after constant inline
	 */
private static void fixTypes(MethodNode mth, InsnNode insn, LiteralArg litArg) {
    DexNode dex = mth.dex();
    PostTypeInference.process(mth, insn);
    switch(insn.getType()) {
        case CONST:
            insn.getArg(0).merge(dex, insn.getResult());
            break;
        case MOVE:
            insn.getResult().merge(dex, insn.getArg(0));
            insn.getArg(0).merge(dex, insn.getResult());
            break;
        case IPUT:
        case SPUT:
            IndexInsnNode node = (IndexInsnNode) insn;
            insn.getArg(0).merge(dex, ((FieldInfo) node.getIndex()).getType());
            break;
        case IF:
            {
                InsnArg arg0 = insn.getArg(0);
                InsnArg arg1 = insn.getArg(1);
                if (arg0 == litArg) {
                    arg0.merge(dex, arg1);
                } else {
                    arg1.merge(dex, arg0);
                }
                break;
            }
        case CMP_G:
        case CMP_L:
            InsnArg arg0 = insn.getArg(0);
            InsnArg arg1 = insn.getArg(1);
            if (arg0 == litArg) {
                arg0.merge(dex, arg1);
            } else {
                arg1.merge(dex, arg0);
            }
            break;
        case RETURN:
            if (insn.getArgsCount() != 0) {
                insn.getArg(0).merge(dex, mth.getReturnType());
            }
            break;
        case INVOKE:
            InvokeNode inv = (InvokeNode) insn;
            List<ArgType> types = inv.getCallMth().getArgumentsTypes();
            int count = insn.getArgsCount();
            int k = types.size() == count ? 0 : -1;
            for (int i = 0; i < count; i++) {
                InsnArg arg = insn.getArg(i);
                if (!arg.getType().isTypeKnown()) {
                    ArgType type;
                    if (k >= 0) {
                        type = types.get(k);
                    } else {
                        type = mth.getParentClass().getClassInfo().getType();
                    }
                    arg.merge(dex, type);
                }
                k++;
            }
            break;
        case ARITH:
            litArg.merge(dex, insn.getResult());
            break;
        case APUT:
        case AGET:
            if (litArg == insn.getArg(1)) {
                litArg.merge(dex, ArgType.INT);
            }
            break;
        case NEW_ARRAY:
            if (litArg == insn.getArg(0)) {
                litArg.merge(dex, ArgType.INT);
            }
            break;
        default:
            break;
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) InsnArg(jadx.core.dex.instructions.args.InsnArg) DexNode(jadx.core.dex.nodes.DexNode) InvokeNode(jadx.core.dex.instructions.InvokeNode) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 2 with DexNode

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

the class DependencyCollector method visit.

@Override
public boolean visit(ClassNode cls) throws JadxException {
    DexNode dex = cls.dex();
    Set<ClassNode> depList = cls.getDependencies();
    processClass(cls, dex, depList);
    for (ClassNode inner : cls.getInnerClasses()) {
        processClass(inner, dex, depList);
    }
    depList.remove(cls);
    return false;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) DexNode(jadx.core.dex.nodes.DexNode)

Example 3 with DexNode

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

the class ConstStorage method getConstField.

@Nullable
public FieldNode getConstField(ClassNode cls, Object value, boolean searchGlobal) {
    DexNode dex = cls.dex();
    if (value instanceof Integer) {
        String str = resourcesNames.get(value);
        if (str != null) {
            return new ResRefField(dex, str.replace('/', '.'));
        }
    }
    if (!replaceEnabled) {
        return null;
    }
    boolean foundInGlobal = globalValues.contains(value);
    if (foundInGlobal && !searchGlobal) {
        return null;
    }
    ClassNode current = cls;
    while (current != null) {
        Values classValues = classes.get(current);
        if (classValues != null) {
            FieldNode field = classValues.get(value);
            if (field != null) {
                if (foundInGlobal) {
                    return null;
                }
                return field;
            }
        }
        ClassInfo parentClass = current.getClassInfo().getParentClass();
        if (parentClass == null) {
            break;
        }
        current = dex.resolveClass(parentClass);
    }
    if (searchGlobal) {
        return globalValues.get(value);
    }
    return null;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) FieldNode(jadx.core.dex.nodes.FieldNode) DexNode(jadx.core.dex.nodes.DexNode) ResRefField(jadx.core.dex.nodes.ResRefField) Nullable(org.jetbrains.annotations.Nullable)

Example 4 with DexNode

use of jadx.core.dex.nodes.DexNode 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 5 with DexNode

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

the class AndroidResourcesUtils method makeClass.

private static ClassNode makeClass(RootNode root, String clsName) {
    DexNode firstDex = root.getDexNodes().get(0);
    ClassInfo r = ClassInfo.fromName(firstDex, clsName);
    return new ClassNode(firstDex, r);
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) DexNode(jadx.core.dex.nodes.DexNode) ClassInfo(jadx.core.dex.info.ClassInfo)

Aggregations

DexNode (jadx.core.dex.nodes.DexNode)9 ClassNode (jadx.core.dex.nodes.ClassNode)5 ArgType (jadx.core.dex.instructions.args.ArgType)3 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)2 InvokeNode (jadx.core.dex.instructions.InvokeNode)2 InsnArg (jadx.core.dex.instructions.args.InsnArg)2 ClassInfo (jadx.core.dex.info.ClassInfo)1 MethodInfo (jadx.core.dex.info.MethodInfo)1 PhiInsn (jadx.core.dex.instructions.PhiInsn)1 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)1 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)1 SSAVar (jadx.core.dex.instructions.args.SSAVar)1 BlockNode (jadx.core.dex.nodes.BlockNode)1 FieldNode (jadx.core.dex.nodes.FieldNode)1 InsnNode (jadx.core.dex.nodes.InsnNode)1 MethodNode (jadx.core.dex.nodes.MethodNode)1 ResRefField (jadx.core.dex.nodes.ResRefField)1 List (java.util.List)1 Nullable (org.jetbrains.annotations.Nullable)1