use of soot.tagkit.SourceFileTag 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));
}
}
}
use of soot.tagkit.SourceFileTag 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;
}
Aggregations