Search in sources :

Example 36 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class AnnotationGen method addThrows.

@SuppressWarnings("unchecked")
public void addThrows(MethodNode mth, CodeWriter code) {
    Annotation an = mth.getAnnotation(Consts.DALVIK_THROWS);
    if (an != null) {
        Object exs = an.getDefaultValue();
        code.add(" throws ");
        for (Iterator<ArgType> it = ((List<ArgType>) exs).iterator(); it.hasNext(); ) {
            ArgType ex = it.next();
            classGen.useType(code, ex);
            if (it.hasNext()) {
                code.add(", ");
            }
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) AnnotationsList(jadx.core.dex.attributes.annotations.AnnotationsList) List(java.util.List) Annotation(jadx.core.dex.attributes.annotations.Annotation)

Example 37 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class ModVisitor method makeFilledArrayInsn.

private static InsnNode makeFilledArrayInsn(MethodNode mth, FillArrayNode insn) {
    ArgType insnArrayType = insn.getResult().getType();
    ArgType insnElementType = insnArrayType.getArrayElement();
    ArgType elType = insn.getElementType();
    if (!elType.isTypeKnown() && insnElementType.isPrimitive()) {
        if (elType.contains(insnElementType.getPrimitiveType())) {
            elType = insnElementType;
        }
    }
    if (!elType.equals(insnElementType) && !insnArrayType.equals(ArgType.OBJECT)) {
        ErrorsCounter.methodError(mth, "Incorrect type for fill-array insn " + InsnUtils.formatOffset(insn.getOffset()) + ", element type: " + elType + ", insn element type: " + insnElementType);
    }
    if (!elType.isTypeKnown()) {
        LOG.warn("Unknown array element type: {} in mth: {}", elType, mth);
        elType = insnElementType.isTypeKnown() ? insnElementType : elType.selectFirst();
        if (elType == null) {
            throw new JadxRuntimeException("Null array element type");
        }
    }
    insn.mergeElementType(mth.dex(), elType);
    elType = insn.getElementType();
    List<LiteralArg> list = insn.getLiteralArgs();
    InsnNode filledArr = new FilledNewArrayNode(elType, list.size());
    filledArr.setResult(insn.getResult());
    for (LiteralArg arg : list) {
        FieldNode f = mth.getParentClass().getConstFieldByLiteralArg(arg);
        if (f != null) {
            InsnNode fGet = new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0);
            filledArr.addArg(InsnArg.wrapArg(fGet));
        } else {
            filledArr.addArg(arg);
        }
    }
    return filledArr;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) FieldNode(jadx.core.dex.nodes.FieldNode) FilledNewArrayNode(jadx.core.dex.instructions.FilledNewArrayNode) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) JadxRuntimeException(jadx.core.utils.exceptions.JadxRuntimeException) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 38 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class EnumVisitor method visit.

@Override
public boolean visit(ClassNode cls) throws JadxException {
    if (!cls.isEnum()) {
        return true;
    }
    // search class init method
    MethodNode staticMethod = null;
    for (MethodNode mth : cls.getMethods()) {
        MethodInfo mi = mth.getMethodInfo();
        if (mi.isClassInit()) {
            staticMethod = mth;
            break;
        }
    }
    if (staticMethod == null) {
        ErrorsCounter.classError(cls, "Enum class init method not found");
        return true;
    }
    ArgType clsType = cls.getClassInfo().getType();
    String enumConstructor = "<init>(Ljava/lang/String;I)V";
    // TODO: detect these methods by analyzing method instructions
    String valuesOfMethod = "valueOf(Ljava/lang/String;)" + TypeGen.signature(clsType);
    String valuesMethod = "values()" + TypeGen.signature(ArgType.array(clsType));
    // collect enum fields, remove synthetic
    List<FieldNode> enumFields = new ArrayList<FieldNode>();
    for (FieldNode f : cls.getFields()) {
        if (f.getAccessFlags().isEnum()) {
            enumFields.add(f);
            f.add(AFlag.DONT_GENERATE);
        } else if (f.getAccessFlags().isSynthetic()) {
            f.add(AFlag.DONT_GENERATE);
        }
    }
    // remove synthetic methods
    for (MethodNode mth : cls.getMethods()) {
        MethodInfo mi = mth.getMethodInfo();
        if (mi.isClassInit()) {
            continue;
        }
        String shortId = mi.getShortId();
        boolean isSynthetic = mth.getAccessFlags().isSynthetic();
        if (mi.isConstructor() && !isSynthetic) {
            if (shortId.equals(enumConstructor)) {
                mth.add(AFlag.DONT_GENERATE);
            }
        } else if (isSynthetic || shortId.equals(valuesMethod) || shortId.equals(valuesOfMethod)) {
            mth.add(AFlag.DONT_GENERATE);
        }
    }
    EnumClassAttr attr = new EnumClassAttr(enumFields.size());
    cls.addAttr(attr);
    attr.setStaticMethod(staticMethod);
    ClassInfo classInfo = cls.getClassInfo();
    // move enum specific instruction from static method to separate list
    BlockNode staticBlock = staticMethod.getBasicBlocks().get(0);
    List<InsnNode> enumPutInsns = new ArrayList<InsnNode>();
    List<InsnNode> list = staticBlock.getInstructions();
    int size = list.size();
    for (int i = 0; i < size; i++) {
        InsnNode insn = list.get(i);
        if (insn.getType() != InsnType.SPUT) {
            continue;
        }
        FieldInfo f = (FieldInfo) ((IndexInsnNode) insn).getIndex();
        if (!f.getDeclClass().equals(classInfo)) {
            continue;
        }
        FieldNode fieldNode = cls.searchField(f);
        if (fieldNode != null && isEnumArrayField(classInfo, fieldNode)) {
            if (i == size - 1) {
                staticMethod.add(AFlag.DONT_GENERATE);
            } else {
                list.subList(0, i + 1).clear();
            }
            break;
        } else {
            enumPutInsns.add(insn);
        }
    }
    for (InsnNode putInsn : enumPutInsns) {
        ConstructorInsn co = getConstructorInsn(putInsn);
        if (co == null || co.getArgsCount() < 2) {
            continue;
        }
        ClassInfo clsInfo = co.getClassType();
        ClassNode constrCls = cls.dex().resolveClass(clsInfo);
        if (constrCls == null) {
            continue;
        }
        if (!clsInfo.equals(classInfo) && !constrCls.getAccessFlags().isEnum()) {
            continue;
        }
        FieldInfo fieldInfo = (FieldInfo) ((IndexInsnNode) putInsn).getIndex();
        String name = getConstString(cls.dex(), co.getArg(0));
        if (name != null && !fieldInfo.getAlias().equals(name) && NameMapper.isValidIdentifier(name)) {
            // LOG.debug("Rename enum field: '{}' to '{}' in {}", fieldInfo.getName(), name, cls);
            fieldInfo.setAlias(name);
        }
        EnumField field = new EnumField(fieldInfo, co, 2);
        attr.getFields().add(field);
        if (!co.getClassType().equals(classInfo)) {
            // enum contains additional methods
            for (ClassNode innerCls : cls.getInnerClasses()) {
                processEnumInnerCls(co, field, innerCls);
            }
        }
    }
    return false;
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) BlockNode(jadx.core.dex.nodes.BlockNode) ClassNode(jadx.core.dex.nodes.ClassNode) EnumField(jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField) FieldNode(jadx.core.dex.nodes.FieldNode) ArrayList(java.util.ArrayList) EnumClassAttr(jadx.core.dex.attributes.nodes.EnumClassAttr) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) MethodNode(jadx.core.dex.nodes.MethodNode) MethodInfo(jadx.core.dex.info.MethodInfo) ConstructorInsn(jadx.core.dex.instructions.mods.ConstructorInsn) FieldInfo(jadx.core.dex.info.FieldInfo) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 39 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class ConstInlineVisitor method replaceConst.

private static boolean replaceConst(MethodNode mth, InsnNode constInsn, long literal) {
    SSAVar sVar = constInsn.getResult().getSVar();
    List<RegisterArg> use = new ArrayList<RegisterArg>(sVar.getUseList());
    int replaceCount = 0;
    for (RegisterArg arg : use) {
        InsnNode useInsn = arg.getParentInsn();
        if (useInsn == null || useInsn.getType() == InsnType.PHI || useInsn.getType() == InsnType.MERGE) {
            continue;
        }
        LiteralArg litArg;
        ArgType argType = arg.getType();
        if (argType.isObject() && literal != 0) {
            argType = ArgType.NARROW_NUMBERS;
        }
        if (use.size() == 1 || arg.isTypeImmutable()) {
            // arg used only in one place
            litArg = InsnArg.lit(literal, argType);
        } else if (useInsn.getType() == InsnType.MOVE && !useInsn.getResult().getType().isTypeKnown()) {
            // save type for 'move' instructions (hard to find type in chains of 'move')
            litArg = InsnArg.lit(literal, argType);
        } else {
            // in most cases type not equal arg.getType()
            // just set unknown type and run type fixer
            litArg = InsnArg.lit(literal, ArgType.UNKNOWN);
        }
        if (useInsn.replaceArg(arg, litArg)) {
            fixTypes(mth, useInsn, litArg);
            replaceCount++;
            if (useInsn.getType() == InsnType.RETURN) {
                useInsn.setSourceLine(constInsn.getSourceLine());
            }
            FieldNode f = null;
            ArgType litArgType = litArg.getType();
            if (litArgType.isTypeKnown()) {
                f = mth.getParentClass().getConstFieldByLiteralArg(litArg);
            } else if (litArgType.contains(PrimitiveType.INT)) {
                f = mth.getParentClass().getConstField((int) literal, false);
            }
            if (f != null) {
                litArg.wrapInstruction(new IndexInsnNode(InsnType.SGET, f.getFieldInfo(), 0));
            }
        }
    }
    return replaceCount == use.size();
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode) InsnNode(jadx.core.dex.nodes.InsnNode) RegisterArg(jadx.core.dex.instructions.args.RegisterArg) SSAVar(jadx.core.dex.instructions.args.SSAVar) FieldNode(jadx.core.dex.nodes.FieldNode) ArrayList(java.util.ArrayList) LiteralArg(jadx.core.dex.instructions.args.LiteralArg) IndexInsnNode(jadx.core.dex.instructions.IndexInsnNode)

Example 40 with ArgType

use of jadx.core.dex.instructions.args.ArgType in project jadx by skylot.

the class DependencyCollector method addDep.

private static void addDep(DexNode dex, Set<ClassNode> depList, ArgType type) {
    if (type != null) {
        if (type.isObject()) {
            addDep(dex, depList, ClassInfo.fromName(dex, type.getObject()));
            ArgType[] genericTypes = type.getGenericTypes();
            if (type.isGeneric() && genericTypes != null) {
                for (ArgType argType : genericTypes) {
                    addDep(dex, depList, argType);
                }
            }
        } else if (type.isArray()) {
            addDep(dex, depList, type.getArrayRootElement());
        }
    }
}
Also used : ArgType(jadx.core.dex.instructions.args.ArgType)

Aggregations

ArgType (jadx.core.dex.instructions.args.ArgType)48 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)12 InsnNode (jadx.core.dex.nodes.InsnNode)11 InsnArg (jadx.core.dex.instructions.args.InsnArg)9 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)8 LiteralArg (jadx.core.dex.instructions.args.LiteralArg)6 SSAVar (jadx.core.dex.instructions.args.SSAVar)6 JadxRuntimeException (jadx.core.utils.exceptions.JadxRuntimeException)5 ArrayList (java.util.ArrayList)5 FieldNode (jadx.core.dex.nodes.FieldNode)4 MethodNode (jadx.core.dex.nodes.MethodNode)4 Annotation (jadx.core.dex.attributes.annotations.Annotation)3 FieldInfo (jadx.core.dex.info.FieldInfo)3 FilledNewArrayNode (jadx.core.dex.instructions.FilledNewArrayNode)3 InvokeNode (jadx.core.dex.instructions.InvokeNode)3 BlockNode (jadx.core.dex.nodes.BlockNode)3 ClassNode (jadx.core.dex.nodes.ClassNode)3 DexNode (jadx.core.dex.nodes.DexNode)3 List (java.util.List)3 MethodInfo (jadx.core.dex.info.MethodInfo)2