diff --git a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/DexIClass.java b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/DexIClass.java index 57eefda4a..f0d60e0b9 100644 --- a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/DexIClass.java +++ b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/DexIClass.java @@ -120,10 +120,10 @@ public class DexIClass extends BytecodeClass { //computeSuperName() // Set Super Name; - String descriptor = classDef.getSuperclass().getTypeDescriptor(); - if (descriptor.endsWith(";")) + String descriptor = classDef.getSuperclass() != null? classDef.getSuperclass().getTypeDescriptor(): null; + if (descriptor != null && descriptor.endsWith(";")) descriptor = descriptor.substring(0,descriptor.length()-1); //remove last ';' - superName = ImmutableByteArray.make(descriptor); + superName = descriptor != null? ImmutableByteArray.make(descriptor): null; //computeInterfaceNames() // Set interfaceNames @@ -268,8 +268,10 @@ public class DexIClass extends BytecodeClass { ArrayList methodsAL = new ArrayList(); logger.debug("class: " + classDef.getClassType().getTypeDescriptor()); - logger.debug("superclass: " + classDef.getSuperclass().getTypeDescriptor()); - + if (classDef.getSuperclass() != null){ + logger.debug("superclass: " + classDef.getSuperclass().getTypeDescriptor()); + } + if (methods == null && classDef.getClassData() == null) methods = new IMethod[0]; diff --git a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/WDexClassLoaderImpl.java b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/WDexClassLoaderImpl.java index 304efce93..c9dace4ce 100644 --- a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/WDexClassLoaderImpl.java +++ b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/classLoader/WDexClassLoaderImpl.java @@ -47,6 +47,8 @@ package com.ibm.wala.dalvik.classLoader; +import static com.ibm.wala.classLoader.ClassLoaderImpl.DEBUG_LEVEL; + import java.io.IOException; import java.util.Collection; import java.util.HashSet; @@ -55,7 +57,6 @@ import java.util.List; import java.util.Set; import java.util.TreeSet; -import org.slf4j.Logger; import org.slf4j.LoggerFactory; import com.ibm.wala.classLoader.ClassLoaderImpl; @@ -78,10 +79,11 @@ import com.ibm.wala.util.warnings.Warnings; * */ public class WDexClassLoaderImpl extends ClassLoaderImpl { - private static final Logger logger = LoggerFactory.getLogger(WDexClassLoaderImpl.class); - + private static final org.slf4j.Logger logger = LoggerFactory.getLogger(WDexClassLoaderImpl.class); + private IClassLoader lParent; + private final SetOfClasses exclusions; //Commented out until IBM fixes ClassLoaderFactoryImpl "protected IClassLoader makeNewClassLoader" @@ -98,7 +100,7 @@ public class WDexClassLoaderImpl extends ClassLoaderImpl { SetOfClasses exclusions, IClassHierarchy cha) { super(loader, cha.getScope().getArrayClassLoader(), parent, exclusions, cha); lParent = parent; -// lExclusions = exclusions; + this.exclusions = exclusions; //DEBUG_LEVEL = 0; } @@ -165,7 +167,8 @@ public class WDexClassLoaderImpl extends ClassLoaderImpl { // Dalvik class if (entry instanceof DexModuleEntry) { DexModuleEntry dexEntry = ((DexModuleEntry) entry); - TypeName tName = TypeName.string2TypeName(dexEntry.getClassName()); + String className = dexEntry.getClassName(); + TypeName tName = TypeName.string2TypeName(className); //if (DEBUG_LEVEL > 0) { // System.err.println("Consider dex class: " + tName); @@ -175,10 +178,10 @@ public class WDexClassLoaderImpl extends ClassLoaderImpl { //System.out.println(tName.getClassName()); if (loadedClasses.get(tName) != null) { Warnings.add(MultipleDexImplementationsWarning - .create(dexEntry.getClassName())); + .create(className)); } else if (lParent != null && lParent.lookupClass(tName) != null) { Warnings.add(MultipleDexImplementationsWarning - .create(dexEntry.getClassName())); + .create(className)); } //if the class is empty, ie an interface // else if (dexEntry.getClassDefItem().getClassData() == null) { @@ -189,10 +192,19 @@ public class WDexClassLoaderImpl extends ClassLoaderImpl { else { IClass iClass = new DexIClass(this, cha, dexEntry); if (iClass.getReference().getName().equals(tName)) { - logger.debug("Load class: " + dexEntry.getClassName()); + + // className is a descriptor, so strip the 'L' + if (exclusions != null && exclusions.contains(className.substring(1))) { + if (DEBUG_LEVEL > 0) { + System.err.println("Excluding " + className); + } + continue; + } + + logger.debug("Load class: " + className); loadedClasses.put(tName, iClass); } else { - Warnings.add(InvalidDexFile.create(dexEntry.getClassName())); + Warnings.add(InvalidDexFile.create(className)); } } } diff --git a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/dex/util/config/DexAnalysisScopeReader.java b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/dex/util/config/DexAnalysisScopeReader.java index 96d6cf282..3b8a1a8c7 100644 --- a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/dex/util/config/DexAnalysisScopeReader.java +++ b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/dex/util/config/DexAnalysisScopeReader.java @@ -78,78 +78,16 @@ public class DexAnalysisScopeReader extends AnalysisScopeReader { private static final String BASIC_FILE = "./primordial.txt"; // Path inside jar /** END Custom change: Fixes in AndroidAnalysisScope */ - public static AnalysisScope makeAndroidBinaryAnalysisScope(String classPath, String exclusionsFile) throws IOException { - if (classPath == null) { - throw new IllegalArgumentException("classPath null"); - } -/** BEGIN Custom change: Fixes in AndroidAnalysisScope */ - AnalysisScope scope = AnalysisScope.createJavaAnalysisScope(); - //AnalysisScope scope = AnalysisScopeReader.makePrimordialScope(null); - scope.setExclusions(new FileOfClasses(new FileInputStream((new FileProvider()).getFile(exclusionsFile)))); - ClassLoaderReference loader = scope.getLoader(AnalysisScope.APPLICATION); -/** END Custom change: Fixes in AndroidAnalysisScope */ - addClassPathToScope(classPath, scope, loader); - return scope; - } - - public static AnalysisScope makeTestAndroidBinaryAnalysisScope(String classPath, String exclusionsFile) throws IOException { - if (classPath == null) { - throw new IllegalArgumentException("classPath null"); - } -/** BEGIN Custom change: Fixes in AndroidAnalysisScope */ - // AnalysisScope scope = AnalysisScope.createJavaAnalysisScope(); - AnalysisScope scope = AnalysisScopeReader.makePrimordialScope((new FileProvider()).getFile(exclusionsFile)); - ClassLoaderReference loader = scope.getLoader(AnalysisScope.APPLICATION); -/** END Custom change: Fixes in AndroidAnalysisScope */ - addClassPathToScope(classPath, scope, loader); - return scope; - } - - /** - * @param classPath - * class path to analyze, delimited by File.pathSeparator - * @param exclusionsFile - * file holding class hierarchy exclusions. may be null - * @throws IOException - * @throws IllegalStateException - * if there are problems reading wala properties - */ public static AnalysisScope makeAndroidBinaryAnalysisScope( - String classPath, File exclusionsFile) throws IOException { - if (classPath == null) { - throw new IllegalArgumentException("classPath null"); - } -/** BEGIN Custom change: Fixes in AndroidAnalysisScope */ - AnalysisScope scope = AnalysisScope.createJavaAnalysisScope(); - scope.setExclusions(new FileOfClasses(new FileInputStream(exclusionsFile))); - ClassLoaderReference loader = scope.getLoader(AnalysisScope.APPLICATION); -/** END Custom change: Fixes in AndroidAnalysisScope */ - addClassPathToScope(classPath, scope, loader); - return scope; - } - - public static AnalysisScope makeAndroidBinaryAnalysisScope( - JarFile classPath, File exclusionsFile) throws IOException { - if (classPath == null) { - throw new IllegalArgumentException("classPath null"); - } - AnalysisScope scope = AnalysisScopeReader.readJavaScope(BASIC_FILE, - exclusionsFile, WALA_CLASSLOADER); - ClassLoaderReference loader = scope - .getLoader(AnalysisScope.APPLICATION); - scope.addToScope(loader, classPath); - return scope; - } - - public static AnalysisScope makeAndroidBinaryAnalysisScope(URI classPath, + URI classPath, String exclusionsFile) throws IOException { if (classPath == null) { throw new IllegalArgumentException("classPath null"); } - AnalysisScope scope = AnalysisScope.createJavaAnalysisScope(); - scope.setExclusions(new FileOfClasses(new FileInputStream(exclusionsFile))); + AnalysisScope scope = AnalysisScopeReader.readJavaScope(BASIC_FILE, + new File(exclusionsFile), WALA_CLASSLOADER); + ClassLoaderReference loader = scope.getLoader(AnalysisScope.APPLICATION); - final String path = classPath.getPath(); if (path.endsWith(".jar")) { scope.addToScope(loader, new JarFile(new File(classPath))); @@ -163,49 +101,4 @@ public class DexAnalysisScopeReader extends AnalysisScopeReader { return scope; } - - /** - * Handle .apk file. - * - * @param classPath - * @param scope - * @param loader - */ - public static void addClassPathToScope(String classPath, - AnalysisScope scope, ClassLoaderReference loader) { - if (classPath == null) { - throw new IllegalArgumentException("null classPath"); - } - try { - String[] paths = classPath.split(File.pathSeparator); - - for (int i = 0; i < paths.length; i++) { - if (paths[i].endsWith(".jar")) { // handle jar file - scope.addToScope(loader, new JarFile(paths[i])); - } else if (paths[i].endsWith(".apk") - || paths[i].endsWith(".dex")) { // Handle android file. - File f = new File(paths[i]); - scope.addToScope(loader, new DexFileModule(f)); - } else { - File f = new File(paths[i]); - if (f.isDirectory()) { // handle directory FIXME not working - // for .dex and .apk files into that - // directory - scope.addToScope(loader, new BinaryDirectoryTreeModule( - f)); - } else { // handle java class file. - try { - scope.addClassFileToScope(loader, f); - } catch (InvalidClassFileException e) { - throw new IllegalArgumentException( - "Invalid class file"); - } - } - } - } - - } catch (IOException e) { - Assertions.UNREACHABLE(e.toString()); - } - } } diff --git a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/util/AndroidAnalysisScope.java b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/util/AndroidAnalysisScope.java index 8fed960a9..51378e4ca 100644 --- a/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/util/AndroidAnalysisScope.java +++ b/com.ibm.wala.dalvik/src/com/ibm/wala/dalvik/util/AndroidAnalysisScope.java @@ -10,84 +10,98 @@ package com.ibm.wala.dalvik.util; import java.io.File; +import java.io.FileInputStream; import java.io.IOException; import java.io.InputStream; import java.net.URI; import java.util.jar.JarFile; -import java.util.jar.JarInputStream; -import com.ibm.wala.classLoader.JarStreamModule; -import com.ibm.wala.classLoader.Module; +import com.ibm.wala.classLoader.BinaryDirectoryTreeModule; import com.ibm.wala.dalvik.classLoader.DexFileModule; -import com.ibm.wala.dalvik.dex.util.config.DexAnalysisScopeReader; import com.ibm.wala.ipa.callgraph.AnalysisScope; +import com.ibm.wala.shrikeCT.InvalidClassFileException; import com.ibm.wala.types.ClassLoaderReference; -import com.ibm.wala.util.io.FileSuffixes; +import com.ibm.wala.util.config.AnalysisScopeReader; +import com.ibm.wala.util.config.FileOfClasses; +import com.ibm.wala.util.debug.Assertions; +import com.ibm.wala.util.io.FileProvider; public class AndroidAnalysisScope { - -/** BEGIN Custom change: Fixes in AndroidAnalysisScope */ - public static AnalysisScope setUpAndroidAnalysisScope(String androidLib, String classpath, String exclusions) throws IOException { + private static final ClassLoader WALA_CLASSLOADER = AnalysisScopeReader.class.getClassLoader(); + + private static final String BASIC_FILE = "./primordial.txt"; + + public static AnalysisScope setUpAndroidAnalysisScope(URI classpath, String exclusions, URI... androidLib) throws IOException { AnalysisScope scope; - if (androidLib == null) { - scope = DexAnalysisScopeReader.makeTestAndroidBinaryAnalysisScope(classpath, exclusions); + if (androidLib == null || androidLib.length == 0) { + scope = AnalysisScopeReader.readJavaScope(BASIC_FILE, new File(exclusions), WALA_CLASSLOADER); } else { - scope = DexAnalysisScopeReader.makeAndroidBinaryAnalysisScope(classpath, exclusions); - } - setUpAnalysisScope(scope, androidLib==null? null: new File(androidLib).toURI()); - return scope; - } -/** END Custom change: Fixes in AndroidAnalysisScope */ + scope = AnalysisScope.createJavaAnalysisScope(); - public static AnalysisScope setUpAndroidAnalysisScope(URI androidLib, URI classpath, String exclusions) throws IOException { - AnalysisScope scope = DexAnalysisScopeReader.makeAndroidBinaryAnalysisScope(classpath, exclusions); - setUpAnalysisScope(scope, androidLib); - return scope; - } - - private static void setUpAnalysisScope(AnalysisScope scope, URI androidLib) throws IOException { + File exclusionsFile = new File(exclusions); + InputStream fs = exclusionsFile.exists()? new FileInputStream(exclusionsFile): FileProvider.class.getClassLoader().getResourceAsStream(exclusionsFile.getName()); + scope.setExclusions(new FileOfClasses(fs)); + + scope.setLoaderImpl(ClassLoaderReference.Primordial, + "com.ibm.wala.dalvik.classLoader.WDexClassLoaderImpl"); + + for(URI al : androidLib) { + scope.addToScope(ClassLoaderReference.Primordial, new DexFileModule(new File(al))); + } + + } scope.setLoaderImpl(ClassLoaderReference.Application, "com.ibm.wala.dalvik.classLoader.WDexClassLoaderImpl"); - if (androidLib != null) { - if (FileSuffixes.isDexFile(androidLib)) { - -/** END Custom change: Fixes in AndroidAnalysisScope */ - Module dexMod = new DexFileModule(new File(androidLib)); - -// Iterator mitr = dexMod.getEntries(); -// while (mitr.hasNext()) { -// ModuleEntry moduleEntry = (ModuleEntry) mitr.next(); -// logger.error("dex module: {}", moduleEntry.getName()); -// } + scope.addToScope(ClassLoaderReference.Application, new DexFileModule(new File(classpath))); + + return scope; + } + + /** + * Handle .apk file. + * + * @param classPath + * @param scope + * @param loader + */ + public static void addClassPathToScope(String classPath, + AnalysisScope scope, ClassLoaderReference loader) { + if (classPath == null) { + throw new IllegalArgumentException("null classPath"); + } + try { + String[] paths = classPath.split(File.pathSeparator); - scope.setLoaderImpl(ClassLoaderReference.Primordial, - "com.ibm.wala.dalvik.classLoader.WDexClassLoaderImpl"); + for (int i = 0; i < paths.length; i++) { + if (paths[i].endsWith(".jar")) { // handle jar file + scope.addToScope(loader, new JarFile(paths[i])); + } else if (paths[i].endsWith(".apk") + || paths[i].endsWith(".dex")) { // Handle android file. + File f = new File(paths[i]); + scope.addToScope(loader, new DexFileModule(f)); + } else { + File f = new File(paths[i]); + if (f.isDirectory()) { // handle directory FIXME not working + // for .dex and .apk files into that + // directory + scope.addToScope(loader, new BinaryDirectoryTreeModule( + f)); + } else { // handle java class file. + try { + scope.addClassFileToScope(loader, f); + } catch (InvalidClassFileException e) { + throw new IllegalArgumentException( + "Invalid class file"); + } + } + } + } - scope.addToScope(ClassLoaderReference.Primordial, dexMod); - } else { -/** BEGIN Custom change: Fixes in AndroidAnalysisScope */ - if (FileSuffixes.isRessourceFromJar(androidLib)) { - scope.setLoaderImpl(ClassLoaderReference.Primordial, - "com.ibm.wala.dalvik.classLoader.WDexClassLoaderImpl"); - - //final FileProvider fileProvider = new FileProvider(); - final InputStream is = androidLib.toURL().openStream(); - assert (is != null); - final Module libMod = new JarStreamModule(new JarInputStream(is)); - scope.addToScope(ClassLoaderReference.Primordial, libMod); - //throw new UnsupportedOperationException("Cannot extract lib from jar"); - - } else { - // assume it is really a JVML jar file, not Android at all - scope.addToScope(ClassLoaderReference.Primordial, new JarFile(new File( - androidLib))); - } -/** END Custom change: Fixes in AndroidAnalysisScope */ + } catch (IOException e) { + Assertions.UNREACHABLE(e.toString()); } } - } - }