fixes for reading core libraries from dex
This commit is contained in:
parent
1a4757cf10
commit
97920a4ab9
|
@ -120,10 +120,10 @@ public class DexIClass extends BytecodeClass<IClassLoader> {
|
|||
|
||||
//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<IClassLoader> {
|
|||
ArrayList<IMethod> methodsAL = new ArrayList<IMethod>();
|
||||
|
||||
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];
|
||||
|
||||
|
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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<ModuleEntry> 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());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue