Search in sources :

Example 16 with ClassInfo

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

the class InsnGen method makeStaticFieldAccess.

public static void makeStaticFieldAccess(CodeWriter code, FieldInfo field, ClassGen clsGen) {
    ClassInfo declClass = field.getDeclClass();
    boolean fieldFromThisClass = clsGen.getClassNode().getClassInfo().equals(declClass);
    if (!fieldFromThisClass) {
        // Android specific resources class handler
        if (!handleAppResField(code, clsGen, declClass)) {
            clsGen.useClass(code, declClass);
        }
        code.add('.');
    }
    FieldNode fieldNode = clsGen.getClassNode().dex().resolveField(field);
    if (fieldNode != null) {
        code.attachAnnotation(fieldNode);
    }
    code.add(field.getAlias());
}
Also used : FieldNode(jadx.core.dex.nodes.FieldNode) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 17 with ClassInfo

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

the class ClassGen method makeClass.

public CodeWriter makeClass() throws CodegenException {
    CodeWriter clsBody = new CodeWriter();
    addClassCode(clsBody);
    CodeWriter clsCode = new CodeWriter();
    if (!"".equals(cls.getPackage())) {
        clsCode.add("package ").add(cls.getPackage()).add(';');
        clsCode.newLine();
    }
    int importsCount = imports.size();
    if (importsCount != 0) {
        List<String> sortImports = new ArrayList<String>(importsCount);
        for (ClassInfo ic : imports) {
            sortImports.add(ic.getAlias().getFullName());
        }
        Collections.sort(sortImports);
        for (String imp : sortImports) {
            clsCode.startLine("import ").add(imp).add(';');
        }
        clsCode.newLine();
        sortImports.clear();
        imports.clear();
    }
    clsCode.add(clsBody);
    return clsCode;
}
Also used : ArrayList(java.util.ArrayList) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 18 with ClassInfo

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

the class ClassGen method useClassInternal.

private String useClassInternal(ClassInfo useCls, ClassInfo extClsInfo) {
    String fullName = extClsInfo.getFullName();
    if (fallback) {
        return fullName;
    }
    String shortName = extClsInfo.getShortName();
    if (extClsInfo.getPackage().equals("java.lang") && extClsInfo.getParentClass() == null) {
        return shortName;
    }
    if (isClassInnerFor(useCls, extClsInfo)) {
        return shortName;
    }
    if (isBothClassesInOneTopClass(useCls, extClsInfo)) {
        return shortName;
    }
    // don't add import if this class from same package
    if (extClsInfo.getPackage().equals(useCls.getPackage()) && !extClsInfo.isInner()) {
        return shortName;
    }
    // don't add import if class not public (must be accessed using inheritance)
    ClassNode classNode = cls.dex().resolveClass(extClsInfo);
    if (classNode != null && !classNode.getAccessFlags().isPublic()) {
        return shortName;
    }
    if (searchCollision(cls.dex(), useCls, extClsInfo)) {
        return fullName;
    }
    // ignore classes from default package
    if (extClsInfo.isDefaultPackage()) {
        return shortName;
    }
    if (extClsInfo.getPackage().equals(useCls.getPackage())) {
        fullName = extClsInfo.getNameWithoutPackage();
    }
    for (ClassInfo importCls : getImports()) {
        if (!importCls.equals(extClsInfo) && importCls.getShortName().equals(shortName)) {
            if (extClsInfo.isInner()) {
                String parent = useClassInternal(useCls, extClsInfo.getParentClass().getAlias());
                return parent + "." + shortName;
            } else {
                return fullName;
            }
        }
    }
    addImport(extClsInfo);
    return shortName;
}
Also used : ClassNode(jadx.core.dex.nodes.ClassNode) ClassInfo(jadx.core.dex.info.ClassInfo)

Example 19 with ClassInfo

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

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

the class RootNode method searchClassByName.

public ClassNode searchClassByName(String fullName) {
    for (DexNode dexNode : dexNodes) {
        ClassInfo clsInfo = ClassInfo.fromName(dexNode, fullName);
        ClassNode cls = dexNode.resolveClass(clsInfo);
        if (cls != null) {
            return cls;
        }
    }
    return null;
}
Also used : ClassInfo(jadx.core.dex.info.ClassInfo)

Aggregations

ClassInfo (jadx.core.dex.info.ClassInfo)21 ClassNode (jadx.core.dex.nodes.ClassNode)6 FieldNode (jadx.core.dex.nodes.FieldNode)5 MethodNode (jadx.core.dex.nodes.MethodNode)5 MethodInfo (jadx.core.dex.info.MethodInfo)4 ArrayList (java.util.ArrayList)4 FieldReplaceAttr (jadx.core.dex.attributes.nodes.FieldReplaceAttr)2 FieldInfo (jadx.core.dex.info.FieldInfo)2 InsnArg (jadx.core.dex.instructions.args.InsnArg)2 HashSet (java.util.HashSet)2 CatchHandler (com.android.dex.Code.CatchHandler)1 Try (com.android.dex.Code.Try)1 EnumClassAttr (jadx.core.dex.attributes.nodes.EnumClassAttr)1 EnumField (jadx.core.dex.attributes.nodes.EnumClassAttr.EnumField)1 SourceFileAttr (jadx.core.dex.attributes.nodes.SourceFileAttr)1 ConstClassNode (jadx.core.dex.instructions.ConstClassNode)1 IndexInsnNode (jadx.core.dex.instructions.IndexInsnNode)1 InvokeType (jadx.core.dex.instructions.InvokeType)1 ArgType (jadx.core.dex.instructions.args.ArgType)1 RegisterArg (jadx.core.dex.instructions.args.RegisterArg)1