Search in sources :

Example 1 with InnerClassAttribute

use of soot.tagkit.InnerClassAttribute in project soot by Sable.

the class DexPrinter method buildClassAnnotations.

private Set<Annotation> buildClassAnnotations(SootClass c) {
    Set<String> skipList = new HashSet<String>();
    Set<Annotation> annotations = buildCommonAnnotations(c, skipList);
    // so we test for enclosing methods first.
    if (c.hasTag("EnclosingMethodTag")) {
        EnclosingMethodTag eMethTag = (EnclosingMethodTag) c.getTag("EnclosingMethodTag");
        Annotation enclosingMethodItem = buildEnclosingMethodTag(eMethTag, skipList);
        if (enclosingMethodItem != null)
            annotations.add(enclosingMethodItem);
    } else if (c.hasOuterClass()) {
        if (skipList.add("Ldalvik/annotation/EnclosingClass;")) {
            // EnclosingClass annotation
            ImmutableAnnotationElement enclosingElement = new ImmutableAnnotationElement("value", new ImmutableTypeEncodedValue(SootToDexUtils.getDexClassName(c.getOuterClass().getName())));
            annotations.add(new ImmutableAnnotation(AnnotationVisibility.SYSTEM, "Ldalvik/annotation/EnclosingClass;", Collections.singleton(enclosingElement)));
        }
    }
    // respective inner classes.
    if (c.hasOuterClass()) {
        InnerClassAttribute icTag = (InnerClassAttribute) c.getOuterClass().getTag("InnerClassAttribute");
        if (icTag != null) {
            List<Annotation> innerClassItem = buildInnerClassAttribute(c, icTag, skipList);
            if (innerClassItem != null)
                annotations.addAll(innerClassItem);
        }
    }
    // Write the MemberClasses tag
    InnerClassAttribute icTag = (InnerClassAttribute) c.getTag("InnerClassAttribute");
    if (icTag != null) {
        List<Annotation> memberClassesItem = buildMemberClassesAttribute(c, icTag, skipList);
        if (memberClassesItem != null)
            annotations.addAll(memberClassesItem);
    }
    for (Tag t : c.getTags()) {
        if (t.getName().equals("VisibilityAnnotationTag")) {
            List<ImmutableAnnotation> visibilityItems = buildVisibilityAnnotationTag((VisibilityAnnotationTag) t, skipList);
            annotations.addAll(visibilityItems);
        }
    }
    // Write default-annotation tags
    List<AnnotationElem> defaults = new ArrayList<AnnotationElem>();
    for (SootMethod method : c.getMethods()) {
        AnnotationDefaultTag tag = (AnnotationDefaultTag) method.getTag("AnnotationDefaultTag");
        if (tag != null) {
            tag.getDefaultVal().setName(method.getName());
            defaults.add(tag.getDefaultVal());
        }
    }
    if (defaults.size() > 0) {
        VisibilityAnnotationTag defaultAnnotationTag = new VisibilityAnnotationTag(AnnotationConstants.RUNTIME_INVISIBLE);
        AnnotationTag a = new AnnotationTag("Ldalvik/annotation/AnnotationDefault;");
        defaultAnnotationTag.addAnnotation(a);
        AnnotationTag at = new AnnotationTag(SootToDexUtils.getDexClassName(c.getName()));
        AnnotationAnnotationElem ae = new AnnotationAnnotationElem(at, '@', "value");
        a.addElem(ae);
        for (AnnotationElem aelem : defaults) at.addElem(aelem);
        List<ImmutableAnnotation> visibilityItems = buildVisibilityAnnotationTag(defaultAnnotationTag, skipList);
        annotations.addAll(visibilityItems);
    }
    return annotations;
}
Also used : InnerClassAttribute(soot.tagkit.InnerClassAttribute) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem) ImmutableAnnotationElement(org.jf.dexlib2.immutable.ImmutableAnnotationElement) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) ArrayList(java.util.ArrayList) ImmutableTypeEncodedValue(org.jf.dexlib2.immutable.value.ImmutableTypeEncodedValue) ImmutableAnnotation(org.jf.dexlib2.immutable.ImmutableAnnotation) Annotation(org.jf.dexlib2.iface.Annotation) ImmutableAnnotation(org.jf.dexlib2.immutable.ImmutableAnnotation) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) AnnotationTag(soot.tagkit.AnnotationTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) SootMethod(soot.SootMethod) ConstantValueTag(soot.tagkit.ConstantValueTag) SourceFileTag(soot.tagkit.SourceFileTag) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) InnerClassTag(soot.tagkit.InnerClassTag) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) AnnotationTag(soot.tagkit.AnnotationTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) Tag(soot.tagkit.Tag) LineNumberTag(soot.tagkit.LineNumberTag) ParamNamesTag(soot.tagkit.ParamNamesTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) SignatureTag(soot.tagkit.SignatureTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag) AnnotationElem(soot.tagkit.AnnotationElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem) HashSet(java.util.HashSet)

Example 2 with InnerClassAttribute

use of soot.tagkit.InnerClassAttribute in project soot by Sable.

the class AbstractASMBackend method generateInnerClassReferences.

/**
 * Emits the bytecode for all references to inner classes if present
 */
protected void generateInnerClassReferences() {
    if (sc.hasTag("InnerClassAttribute") && !Options.v().no_output_inner_classes_attribute()) {
        InnerClassAttribute ica = (InnerClassAttribute) sc.getTag("InnerClassAttribute");
        List<InnerClassTag> sortedTags = new ArrayList<InnerClassTag>(ica.getSpecs());
        Collections.sort(sortedTags, new SootInnerClassComparator());
        for (InnerClassTag ict : sortedTags) {
            String name = slashify(ict.getInnerClass());
            String outerClassName = slashify(ict.getOuterClass());
            String innerName = slashify(ict.getShortName());
            int access = ict.getAccessFlags();
            cv.visitInnerClass(name, outerClassName, innerName, access);
        }
    }
}
Also used : InnerClassAttribute(soot.tagkit.InnerClassAttribute) InnerClassTag(soot.tagkit.InnerClassTag) ArrayList(java.util.ArrayList)

Example 3 with InnerClassAttribute

use of soot.tagkit.InnerClassAttribute in project soot by Sable.

the class DexAnnotation method handleClassAnnotation.

/**
 * Converts Class annotations from Dexlib to Jimple.
 *
 * @param h
 * @param classDef
 */
// .annotation "Ldalvik/annotation/AnnotationDefault;"
// .annotation "Ldalvik/annotation/EnclosingClass;"
// .annotation "Ldalvik/annotation/EnclosingMethod;"
// .annotation "Ldalvik/annotation/InnerClass;"
// .annotation "Ldalvik/annotation/MemberClasses;"
// .annotation "Ldalvik/annotation/Signature;"
// .annotation "Ldalvik/annotation/Throws;"
public void handleClassAnnotation(ClassDef classDef) {
    Set<? extends Annotation> aSet = classDef.getAnnotations();
    if (aSet == null || aSet.isEmpty())
        return;
    List<Tag> tags = handleAnnotation(aSet, classDef.getType());
    if (tags == null)
        return;
    InnerClassAttribute ica = null;
    for (Tag t : tags) if (t != null) {
        if (t instanceof InnerClassTag) {
            if (ica == null) {
                // Do we already have an InnerClassAttribute?
                ica = (InnerClassAttribute) clazz.getTag("InnerClassAttribute");
                // If not, create one
                if (ica == null) {
                    ica = new InnerClassAttribute();
                    clazz.addTag(ica);
                }
            }
            ica.add((InnerClassTag) t);
        } else if (t instanceof VisibilityAnnotationTag) {
            // If a dalvik/annotation/AnnotationDefault tag is present
            // in a class, its AnnotationElements must be propagated
            // to methods through the creation of new
            // AnnotationDefaultTag.
            VisibilityAnnotationTag vt = (VisibilityAnnotationTag) t;
            for (AnnotationTag a : vt.getAnnotations()) {
                if (a.getType().equals("Ldalvik/annotation/AnnotationDefault;")) {
                    for (AnnotationElem ae : a.getElems()) {
                        if (ae instanceof AnnotationAnnotationElem) {
                            AnnotationAnnotationElem aae = (AnnotationAnnotationElem) ae;
                            AnnotationTag at = aae.getValue();
                            // extract default elements
                            Map<String, AnnotationElem> defaults = new HashMap<String, AnnotationElem>();
                            for (AnnotationElem aelem : at.getElems()) {
                                defaults.put(aelem.getName(), aelem);
                            }
                            // and add tags on methods
                            for (SootMethod sm : clazz.getMethods()) {
                                String methodName = sm.getName();
                                if (defaults.containsKey(methodName)) {
                                    AnnotationElem e = defaults.get(methodName);
                                    // Okay, the name is the same, but
                                    // is it actually the same type?
                                    Type annotationType = getSootType(e);
                                    boolean isCorrectType = false;
                                    if (annotationType == null) {
                                        // we do not know the type of
                                        // the annotation, so we guess
                                        // it's the correct type.
                                        isCorrectType = true;
                                    } else {
                                        if (annotationType.equals(sm.getReturnType())) {
                                            isCorrectType = true;
                                        } else if (annotationType.equals(ARRAY_TYPE)) {
                                            if (sm.getReturnType() instanceof ArrayType)
                                                isCorrectType = true;
                                        }
                                    }
                                    if (isCorrectType && sm.getParameterCount() == 0) {
                                        e.setName("default");
                                        AnnotationDefaultTag d = new AnnotationDefaultTag(e);
                                        sm.addTag(d);
                                        // In case there is more than
                                        // one matching method, we only
                                        // use the first one
                                        defaults.remove(sm.getName());
                                    }
                                }
                            }
                            for (Entry<String, AnnotationElem> leftOverEntry : defaults.entrySet()) {
                                // We were not able to find a matching
                                // method for the tag, because the
                                // return signature
                                // does not match
                                SootMethod found = clazz.getMethodByNameUnsafe(leftOverEntry.getKey());
                                AnnotationElem element = leftOverEntry.getValue();
                                if (found != null) {
                                    element.setName("default");
                                    AnnotationDefaultTag d = new AnnotationDefaultTag(element);
                                    found.addTag(d);
                                }
                            }
                        }
                    }
                }
            }
            if (!(vt.getVisibility() == AnnotationConstants.RUNTIME_INVISIBLE))
                clazz.addTag(vt);
        } else {
            clazz.addTag(t);
        }
    }
}
Also used : InnerClassAttribute(soot.tagkit.InnerClassAttribute) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem) HashMap(java.util.HashMap) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) ArrayType(soot.ArrayType) InnerClassTag(soot.tagkit.InnerClassTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) AnnotationTag(soot.tagkit.AnnotationTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) RefType(soot.RefType) Type(soot.Type) ArrayType(soot.ArrayType) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) SootMethod(soot.SootMethod) Tag(soot.tagkit.Tag) ParamNamesTag(soot.tagkit.ParamNamesTag) DeprecatedTag(soot.tagkit.DeprecatedTag) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) VisibilityAnnotationTag(soot.tagkit.VisibilityAnnotationTag) InnerClassTag(soot.tagkit.InnerClassTag) SignatureTag(soot.tagkit.SignatureTag) AnnotationTag(soot.tagkit.AnnotationTag) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) VisibilityParameterAnnotationTag(soot.tagkit.VisibilityParameterAnnotationTag) AnnotationElem(soot.tagkit.AnnotationElem) AnnotationAnnotationElem(soot.tagkit.AnnotationAnnotationElem)

Example 4 with InnerClassAttribute

use of soot.tagkit.InnerClassAttribute in project soot by Sable.

the class DexClassLoader method makeSootClass.

public Dependencies makeSootClass(SootClass sc, ClassDef defItem, DexFile dexFile) {
    String superClass = defItem.getSuperclass();
    Dependencies deps = new Dependencies();
    // source file
    String sourceFile = defItem.getSourceFile();
    if (sourceFile != null) {
        sc.addTag(new SourceFileTag(sourceFile));
    }
    // super class for hierarchy level
    if (superClass != null) {
        String superClassName = Util.dottedClassName(superClass);
        SootClass sootSuperClass = SootResolver.v().makeClassRef(superClassName);
        sc.setSuperclass(sootSuperClass);
        deps.typesToHierarchy.add(sootSuperClass.getType());
    }
    // access flags
    int accessFlags = defItem.getAccessFlags();
    sc.setModifiers(accessFlags);
    // Retrieve interface names
    if (defItem.getInterfaces() != null) {
        for (String interfaceName : defItem.getInterfaces()) {
            String interfaceClassName = Util.dottedClassName(interfaceName);
            if (sc.implementsInterface(interfaceClassName))
                continue;
            SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceClassName);
            interfaceClass.setModifiers(interfaceClass.getModifiers() | Modifier.INTERFACE);
            sc.addInterface(interfaceClass);
            deps.typesToHierarchy.add(interfaceClass.getType());
        }
    }
    if (Options.v().oaat() && sc.resolvingLevel() <= SootClass.HIERARCHY) {
        return deps;
    }
    DexAnnotation da = new DexAnnotation(sc, deps);
    // get the fields of the class
    for (Field sf : defItem.getStaticFields()) {
        loadField(sc, da, sf);
    }
    for (Field f : defItem.getInstanceFields()) {
        loadField(sc, da, f);
    }
    // get the methods of the class
    DexMethod dexMethod = createDexMethodFactory(dexFile, sc);
    for (Method method : defItem.getDirectMethods()) {
        loadMethod(method, sc, da, dexMethod);
    }
    for (Method method : defItem.getVirtualMethods()) {
        loadMethod(method, sc, da, dexMethod);
    }
    da.handleClassAnnotation(defItem);
    // In contrast to Java, Dalvik associates the InnerClassAttribute
    // with the inner class, not the outer one. We need to copy the
    // tags over to correspond to the Soot semantics.
    InnerClassAttribute ica = (InnerClassAttribute) sc.getTag("InnerClassAttribute");
    if (ica != null) {
        Iterator<InnerClassTag> innerTagIt = ica.getSpecs().iterator();
        while (innerTagIt.hasNext()) {
            Tag t = innerTagIt.next();
            if (t instanceof InnerClassTag) {
                InnerClassTag ict = (InnerClassTag) t;
                // Get the outer class name
                String outer = DexInnerClassParser.getOuterClassNameFromTag(ict);
                if (outer == null) {
                    // If we don't have any clue what the outer class is, we
                    // just remove
                    // the reference entirely
                    innerTagIt.remove();
                    continue;
                }
                // we leave it as it is
                if (outer.equals(sc.getName()))
                    continue;
                // Check the inner class to make sure that this tag actually
                // refers to the current class as the inner class
                String inner = ict.getInnerClass().replaceAll("/", ".");
                if (!inner.equals(sc.getName())) {
                    innerTagIt.remove();
                    continue;
                }
                SootClass osc = SootResolver.v().makeClassRef(outer);
                if (osc == sc) {
                    if (!sc.hasOuterClass())
                        continue;
                    osc = sc.getOuterClass();
                } else
                    deps.typesToHierarchy.add(osc.getType());
                // Get the InnerClassAttribute of the outer class
                InnerClassAttribute icat = (InnerClassAttribute) osc.getTag("InnerClassAttribute");
                if (icat == null) {
                    icat = new InnerClassAttribute();
                    osc.addTag(icat);
                }
                // Transfer the tag from the inner class to the outer class
                InnerClassTag newt = new InnerClassTag(ict.getInnerClass(), ict.getOuterClass(), ict.getShortName(), ict.getAccessFlags());
                icat.add(newt);
                // Remove the tag from the inner class as inner classes do
                // not have these tags in the Java / Soot semantics. The
                // DexPrinter will copy it back if we do dex->dex.
                innerTagIt.remove();
                // within the PackManager in method handleInnerClasses().
                if (!sc.hasTag("InnerClassTag")) {
                    if (((InnerClassTag) t).getInnerClass().replaceAll("/", ".").equals(sc.toString())) {
                        sc.addTag(t);
                    }
                }
            }
        }
        // remove tag if empty
        if (ica.getSpecs().isEmpty()) {
            sc.getTags().remove(ica);
        }
    }
    return deps;
}
Also used : InnerClassAttribute(soot.tagkit.InnerClassAttribute) SourceFileTag(soot.tagkit.SourceFileTag) SootMethod(soot.SootMethod) Method(org.jf.dexlib2.iface.Method) SootClass(soot.SootClass) SootField(soot.SootField) Field(org.jf.dexlib2.iface.Field) InnerClassTag(soot.tagkit.InnerClassTag) Dependencies(soot.javaToJimple.IInitialResolver.Dependencies) Tag(soot.tagkit.Tag) SourceFileTag(soot.tagkit.SourceFileTag) InnerClassTag(soot.tagkit.InnerClassTag)

Aggregations

InnerClassAttribute (soot.tagkit.InnerClassAttribute)4 InnerClassTag (soot.tagkit.InnerClassTag)4 SootMethod (soot.SootMethod)3 Tag (soot.tagkit.Tag)3 ArrayList (java.util.ArrayList)2 AnnotationAnnotationElem (soot.tagkit.AnnotationAnnotationElem)2 AnnotationDefaultTag (soot.tagkit.AnnotationDefaultTag)2 AnnotationElem (soot.tagkit.AnnotationElem)2 AnnotationTag (soot.tagkit.AnnotationTag)2 EnclosingMethodTag (soot.tagkit.EnclosingMethodTag)2 ParamNamesTag (soot.tagkit.ParamNamesTag)2 SignatureTag (soot.tagkit.SignatureTag)2 SourceFileTag (soot.tagkit.SourceFileTag)2 VisibilityAnnotationTag (soot.tagkit.VisibilityAnnotationTag)2 VisibilityParameterAnnotationTag (soot.tagkit.VisibilityParameterAnnotationTag)2 HashMap (java.util.HashMap)1 HashSet (java.util.HashSet)1 Annotation (org.jf.dexlib2.iface.Annotation)1 Field (org.jf.dexlib2.iface.Field)1 Method (org.jf.dexlib2.iface.Method)1