Search in sources :

Example 1 with GenericAttribute

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

the class TagBuilder method visitAttribute.

/**
 * @see FieldVisitor#visitAttribute(Attribute)
 * @see MethodVisitor#visitAttribute(Attribute)
 * @see ClassVisitor#visitAttribute(Attribute)
 */
public void visitAttribute(Attribute attr) {
    // SA, 2017-07-21: As of ASM 5.1, there is no better way to obtain
    // attribute values.
    byte[] value = null;
    try {
        Field fld = Attribute.class.getDeclaredField("value");
        fld.setAccessible(true);
        value = (byte[]) fld.get(attr);
    } catch (Exception ex) {
    // Just carry on
    }
    host.addTag(new GenericAttribute(attr.type, value));
}
Also used : Field(java.lang.reflect.Field) GenericAttribute(soot.tagkit.GenericAttribute)

Example 2 with GenericAttribute

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

the class Util method resolveFromClassFile.

public void resolveFromClassFile(SootClass aClass, InputStream is, String filePath, Collection<Type> references) {
    SootClass bclass = aClass;
    String className = bclass.getName();
    ClassFile coffiClass = new ClassFile(className);
    // Load up class file, and retrieve bclass from class manager.
    {
        boolean success = coffiClass.loadClassFile(is);
        if (!success) {
            if (!Scene.v().allowsPhantomRefs())
                throw new RuntimeException("Could not load classfile: " + bclass.getName());
            else {
                logger.warn("" + className + " is a phantom class!");
                bclass.setPhantomClass();
                return;
            }
        }
        CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.this_class];
        String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
        name = name.replace('/', '.');
        if (!name.equals(bclass.getName())) {
            throw new RuntimeException("Error: class " + name + " read in from a classfile in which " + bclass.getName() + " was expected.");
        }
    }
    // Set modifier
    bclass.setModifiers(coffiClass.access_flags & (~0x0020));
    // don't want the ACC_SUPER flag, it is always supposed to be set
    // anyways
    // Set superclass
    {
        if (coffiClass.super_class != 0) {
            // This object is not java.lang.Object, so must have a super
            // class
            CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.super_class];
            String superName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
            superName = superName.replace('/', '.');
            references.add(RefType.v(superName));
            bclass.setSuperclass(SootResolver.v().makeClassRef(superName));
        }
    }
    // Add interfaces to the bclass
    {
        for (int i = 0; i < coffiClass.interfaces_count; i++) {
            CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[coffiClass.interfaces[i]];
            String interfaceName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
            interfaceName = interfaceName.replace('/', '.');
            references.add(RefType.v(interfaceName));
            SootClass interfaceClass = SootResolver.v().makeClassRef(interfaceName);
            interfaceClass.setModifiers(interfaceClass.getModifiers() | Modifier.INTERFACE);
            bclass.addInterface(interfaceClass);
        }
    }
    // Add every field to the bclass
    for (int i = 0; i < coffiClass.fields_count; i++) {
        field_info fieldInfo = coffiClass.fields[i];
        String fieldName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.name_index])).convert();
        String fieldDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[fieldInfo.descriptor_index])).convert();
        int modifiers = fieldInfo.access_flags;
        Type fieldType = jimpleTypeOfFieldDescriptor(fieldDescriptor);
        SootField field = Scene.v().makeSootField(fieldName, fieldType, modifiers);
        bclass.addField(field);
        references.add(fieldType);
        // add initialization constant, if any
        for (int j = 0; j < fieldInfo.attributes_count; j++) {
            // add constant value attributes
            if (fieldInfo.attributes[j] instanceof ConstantValue_attribute) {
                ConstantValue_attribute attr = (ConstantValue_attribute) fieldInfo.attributes[j];
                cp_info cval = coffiClass.constant_pool[attr.constantvalue_index];
                ConstantValueTag tag;
                switch(cval.tag) {
                    case cp_info.CONSTANT_Integer:
                        tag = new IntegerConstantValueTag((int) ((CONSTANT_Integer_info) cval).bytes);
                        break;
                    case cp_info.CONSTANT_Float:
                        // tag = new
                        // FloatConstantValueTag((int)((CONSTANT_Float_info)cval).bytes);
                        tag = new FloatConstantValueTag(((CONSTANT_Float_info) cval).convert());
                        break;
                    case cp_info.CONSTANT_Long:
                        {
                            CONSTANT_Long_info lcval = (CONSTANT_Long_info) cval;
                            tag = new LongConstantValueTag((lcval.high << 32) + lcval.low);
                            break;
                        }
                    case cp_info.CONSTANT_Double:
                        {
                            CONSTANT_Double_info dcval = (CONSTANT_Double_info) cval;
                            // tag = new DoubleConstantValueTag((dcval.high << 32) +
                            // dcval.low);
                            tag = new DoubleConstantValueTag(dcval.convert());
                            break;
                        }
                    case cp_info.CONSTANT_String:
                        {
                            CONSTANT_String_info scval = (CONSTANT_String_info) cval;
                            CONSTANT_Utf8_info ucval = (CONSTANT_Utf8_info) coffiClass.constant_pool[scval.string_index];
                            tag = new StringConstantValueTag(ucval.convert());
                            break;
                        }
                    default:
                        throw new RuntimeException("unexpected ConstantValue: " + cval);
                }
                field.addTag(tag);
            } else // add synthetic tag
            if (fieldInfo.attributes[j] instanceof Synthetic_attribute) {
                field.addTag(new SyntheticTag());
            } else // add deprecated tag
            if (fieldInfo.attributes[j] instanceof Deprecated_attribute) {
                field.addTag(new DeprecatedTag());
            } else // add signature tag
            if (fieldInfo.attributes[j] instanceof Signature_attribute) {
                String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) fieldInfo.attributes[j]).signature_index])).convert();
                field.addTag(new SignatureTag(generic_sig));
            } else if (fieldInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || fieldInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
                addAnnotationVisibilityAttribute(field, fieldInfo.attributes[j], coffiClass, references);
            } else if (fieldInfo.attributes[j] instanceof Generic_attribute) {
                Generic_attribute attr = (Generic_attribute) fieldInfo.attributes[j];
                String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
                field.addTag(new GenericAttribute(name, attr.info));
            }
        }
    }
    // Add every method to the bclass
    for (int i = 0; i < coffiClass.methods_count; i++) {
        method_info methodInfo = coffiClass.methods[i];
        if ((coffiClass.constant_pool[methodInfo.name_index]) == null) {
            logger.debug("method index: " + methodInfo.toName(coffiClass.constant_pool));
            throw new RuntimeException("method has no name");
        }
        String methodName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.name_index])).convert();
        String methodDescriptor = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[methodInfo.descriptor_index])).convert();
        List<Type> parameterTypes;
        Type returnType;
        // Generate parameterTypes & returnType
        {
            Type[] types = jimpleTypesOfFieldOrMethodDescriptor(methodDescriptor);
            parameterTypes = new ArrayList<Type>();
            for (int j = 0; j < types.length - 1; j++) {
                references.add(types[j]);
                parameterTypes.add(types[j]);
            }
            returnType = types[types.length - 1];
            references.add(returnType);
        }
        int modifiers = methodInfo.access_flags;
        SootMethod method;
        method = Scene.v().makeSootMethod(methodName, parameterTypes, returnType, modifiers);
        bclass.addMethod(method);
        methodInfo.jmethod = method;
        // add exceptions to method
        {
            for (int j = 0; j < methodInfo.attributes_count; j++) {
                if (methodInfo.attributes[j] instanceof Exception_attribute) {
                    Exception_attribute exceptions = (Exception_attribute) methodInfo.attributes[j];
                    for (int k = 0; k < exceptions.number_of_exceptions; k++) {
                        CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[exceptions.exception_index_table[k]];
                        String exceptionName = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
                        exceptionName = exceptionName.replace('/', '.');
                        references.add(RefType.v(exceptionName));
                        method.addExceptionIfAbsent(SootResolver.v().makeClassRef(exceptionName));
                    }
                } else if (methodInfo.attributes[j] instanceof Synthetic_attribute) {
                    method.addTag(new SyntheticTag());
                } else if (methodInfo.attributes[j] instanceof Deprecated_attribute) {
                    method.addTag(new DeprecatedTag());
                } else if (methodInfo.attributes[j] instanceof Signature_attribute) {
                    String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) methodInfo.attributes[j]).signature_index])).convert();
                    method.addTag(new SignatureTag(generic_sig));
                } else if (methodInfo.attributes[j] instanceof RuntimeVisibleAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleAnnotations_attribute) {
                    addAnnotationVisibilityAttribute(method, methodInfo.attributes[j], coffiClass, references);
                } else if (methodInfo.attributes[j] instanceof RuntimeVisibleParameterAnnotations_attribute || methodInfo.attributes[j] instanceof RuntimeInvisibleParameterAnnotations_attribute) {
                    addAnnotationVisibilityParameterAttribute(method, methodInfo.attributes[j], coffiClass, references);
                } else if (methodInfo.attributes[j] instanceof AnnotationDefault_attribute) {
                    AnnotationDefault_attribute attr = (AnnotationDefault_attribute) methodInfo.attributes[j];
                    element_value[] input = new element_value[1];
                    input[0] = attr.default_value;
                    ArrayList<AnnotationElem> list = createElementTags(1, coffiClass, input);
                    method.addTag(new AnnotationDefaultTag(list.get(0)));
                } else if (methodInfo.attributes[j] instanceof Generic_attribute) {
                    Generic_attribute attr = (Generic_attribute) methodInfo.attributes[j];
                    String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
                    method.addTag(new GenericAttribute(name, attr.info));
                }
            }
        }
        // Go through the constant pool, forcing all mentioned classes to be
        // resolved.
        {
            for (int k = 0; k < coffiClass.constant_pool_count; k++) {
                if (coffiClass.constant_pool[k] instanceof CONSTANT_Class_info) {
                    CONSTANT_Class_info c = (CONSTANT_Class_info) coffiClass.constant_pool[k];
                    String desc = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[c.name_index])).convert();
                    String name = desc.replace('/', '.');
                    if (name.startsWith("["))
                        references.add(jimpleTypeOfFieldDescriptor(desc));
                    else
                        references.add(RefType.v(name));
                }
                if (coffiClass.constant_pool[k] instanceof CONSTANT_Fieldref_info || coffiClass.constant_pool[k] instanceof CONSTANT_Methodref_info || coffiClass.constant_pool[k] instanceof CONSTANT_InterfaceMethodref_info) {
                    Type[] types = jimpleTypesOfFieldOrMethodDescriptor(cp_info.getTypeDescr(coffiClass.constant_pool, k));
                    for (Type element : types) {
                        references.add(element);
                    }
                }
            }
        }
    }
    // Set coffi source of method
    for (int i = 0; i < coffiClass.methods_count; i++) {
        method_info methodInfo = coffiClass.methods[i];
        // methodInfo.jmethod.setSource(coffiClass, methodInfo);
        methodInfo.jmethod.setSource(new CoffiMethodSource(coffiClass, methodInfo));
    }
    // Set "SourceFile" attribute tag
    for (int i = 0; i < coffiClass.attributes_count; i++) {
        if (coffiClass.attributes[i] instanceof SourceFile_attribute) {
            SourceFile_attribute attr = (SourceFile_attribute) coffiClass.attributes[i];
            String sourceFile = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.sourcefile_index])).convert();
            if (sourceFile.indexOf(' ') >= 0) {
                logger.debug("" + "Warning: Class " + className + " has invalid SourceFile attribute (will be ignored).");
            } else {
                bclass.addTag(new SourceFileTag(sourceFile, filePath));
            }
        } else // Set "InnerClass" attribute tag
        if (coffiClass.attributes[i] instanceof InnerClasses_attribute) {
            InnerClasses_attribute attr = (InnerClasses_attribute) coffiClass.attributes[i];
            for (int j = 0; j < attr.inner_classes_length; j++) {
                inner_class_entry e = attr.inner_classes[j];
                String inner = null;
                String outer = null;
                String name = null;
                if (e.inner_class_index != 0)
                    inner = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[e.inner_class_index]).name_index]).convert();
                if (e.outer_class_index != 0)
                    outer = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[e.outer_class_index]).name_index]).convert();
                if (e.name_index != 0)
                    name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[e.name_index])).convert();
                bclass.addTag(new InnerClassTag(inner, outer, name, e.access_flags));
            }
        } else // set synthetic tags
        if (coffiClass.attributes[i] instanceof Synthetic_attribute) {
            bclass.addTag(new SyntheticTag());
        } else // set deprectaed tags
        if (coffiClass.attributes[i] instanceof Deprecated_attribute) {
            bclass.addTag(new DeprecatedTag());
        } else if (coffiClass.attributes[i] instanceof Signature_attribute) {
            String generic_sig = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[((Signature_attribute) coffiClass.attributes[i]).signature_index])).convert();
            bclass.addTag(new SignatureTag(generic_sig));
        } else if (coffiClass.attributes[i] instanceof EnclosingMethod_attribute) {
            EnclosingMethod_attribute attr = (EnclosingMethod_attribute) coffiClass.attributes[i];
            String class_name = ((CONSTANT_Utf8_info) coffiClass.constant_pool[((CONSTANT_Class_info) coffiClass.constant_pool[attr.class_index]).name_index]).convert();
            CONSTANT_NameAndType_info info = (CONSTANT_NameAndType_info) coffiClass.constant_pool[attr.method_index];
            String method_name = "";
            String method_sig = "";
            if (info != null) {
                method_name = ((CONSTANT_Utf8_info) coffiClass.constant_pool[info.name_index]).convert();
                method_sig = ((CONSTANT_Utf8_info) coffiClass.constant_pool[info.descriptor_index]).convert();
            }
            bclass.addTag(new EnclosingMethodTag(class_name, method_name, method_sig));
        } else if (coffiClass.attributes[i] instanceof RuntimeVisibleAnnotations_attribute || coffiClass.attributes[i] instanceof RuntimeInvisibleAnnotations_attribute) {
            addAnnotationVisibilityAttribute(bclass, coffiClass.attributes[i], coffiClass, references);
        } else if (coffiClass.attributes[i] instanceof Generic_attribute) {
            Generic_attribute attr = (Generic_attribute) coffiClass.attributes[i];
            String name = ((CONSTANT_Utf8_info) (coffiClass.constant_pool[attr.attribute_name])).convert();
            bclass.addTag(new GenericAttribute(name, attr.info));
        }
    }
}
Also used : ArrayList(java.util.ArrayList) SourceFileTag(soot.tagkit.SourceFileTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) GenericAttribute(soot.tagkit.GenericAttribute) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) ConstantValueTag(soot.tagkit.ConstantValueTag) DoubleConstantValueTag(soot.tagkit.DoubleConstantValueTag) LongConstantValueTag(soot.tagkit.LongConstantValueTag) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag) SootMethod(soot.SootMethod) SootField(soot.SootField) FloatConstantValueTag(soot.tagkit.FloatConstantValueTag) SyntheticTag(soot.tagkit.SyntheticTag) InnerClassTag(soot.tagkit.InnerClassTag) StringConstantValueTag(soot.tagkit.StringConstantValueTag) DeprecatedTag(soot.tagkit.DeprecatedTag) AnnotationDefaultTag(soot.tagkit.AnnotationDefaultTag) IntegerConstantValueTag(soot.tagkit.IntegerConstantValueTag) SootClass(soot.SootClass) RefType(soot.RefType) ShortType(soot.ShortType) BooleanType(soot.BooleanType) ByteType(soot.ByteType) Type(soot.Type) UnknownType(soot.UnknownType) DoubleType(soot.DoubleType) FloatType(soot.FloatType) IntType(soot.IntType) CharType(soot.CharType) LongType(soot.LongType) ArrayType(soot.ArrayType) VoidType(soot.VoidType) EnclosingMethodTag(soot.tagkit.EnclosingMethodTag) SignatureTag(soot.tagkit.SignatureTag)

Aggregations

GenericAttribute (soot.tagkit.GenericAttribute)2 Field (java.lang.reflect.Field)1 ArrayList (java.util.ArrayList)1 ArrayType (soot.ArrayType)1 BooleanType (soot.BooleanType)1 ByteType (soot.ByteType)1 CharType (soot.CharType)1 DoubleType (soot.DoubleType)1 FloatType (soot.FloatType)1 IntType (soot.IntType)1 LongType (soot.LongType)1 RefType (soot.RefType)1 ShortType (soot.ShortType)1 SootClass (soot.SootClass)1 SootField (soot.SootField)1 SootMethod (soot.SootMethod)1 Type (soot.Type)1 UnknownType (soot.UnknownType)1 VoidType (soot.VoidType)1 AnnotationDefaultTag (soot.tagkit.AnnotationDefaultTag)1