make Android entrypoint locator work for source code
This commit is contained in:
parent
21340b44cf
commit
76286a330c
@ -12,4 +12,5 @@ Require-Bundle: com.ibm.wala.cast.java,
|
||||
com.ibm.wala.cast,
|
||||
com.ibm.wala.shrike
|
||||
Export-Package: com.ibm.wala.cast.java.client,
|
||||
com.ibm.wala.cast.java.translator.jdt
|
||||
com.ibm.wala.cast.java.translator.jdt,
|
||||
com.ibm.wala.cast.java.translator.jdt.ejc
|
||||
|
||||
@ -74,10 +74,10 @@ public abstract class TestJavaScriptSlicer extends TestJSCallGraphShape {
|
||||
private Collection<Statement> slice(String file, DataDependenceOptions data, ControlDependenceOptions ctrl) throws IOException, WalaException, CancelException {
|
||||
JSCFABuilder B = JSCallGraphBuilderUtil.makeScriptCGBuilder("tests", file);
|
||||
CallGraph CG = B.makeCallGraph(B.getOptions());
|
||||
|
||||
final Collection<Statement> ss = findTargetStatement(CG);
|
||||
|
||||
SDG sdg = new SDG(CG, B.getPointerAnalysis(), new JavaScriptModRef(), data, ctrl);
|
||||
|
||||
final Collection<Statement> ss = findTargetStatement(CG);
|
||||
Collection<Statement> result = Slicer.computeBackwardSlice(sdg, ss);
|
||||
return result;
|
||||
}
|
||||
|
||||
@ -16,6 +16,7 @@ import java.util.Map;
|
||||
import java.util.Set;
|
||||
|
||||
import com.ibm.wala.analysis.pointers.HeapGraph;
|
||||
import com.ibm.wala.cast.ipa.callgraph.AstHeapModel;
|
||||
import com.ibm.wala.cast.ir.ssa.AstGlobalWrite;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.AbstractVertexVisitor;
|
||||
import com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices.CreationSiteVertex;
|
||||
@ -57,6 +58,7 @@ import com.ibm.wala.types.TypeReference;
|
||||
import com.ibm.wala.util.CancelException;
|
||||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.Predicate;
|
||||
import com.ibm.wala.util.collections.CompoundIterator;
|
||||
import com.ibm.wala.util.collections.HashMapFactory;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
@ -283,13 +285,20 @@ public class FlowGraph implements Iterable<Vertex> {
|
||||
|
||||
@Override
|
||||
public Iterable<PointerKey> getPointerKeys() {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
return new Iterable<PointerKey> () {
|
||||
@Override
|
||||
public Iterator<PointerKey> iterator() {
|
||||
return new CompoundIterator<PointerKey>(factory.getArgVertices().iterator(),
|
||||
new CompoundIterator<PointerKey>(factory.getRetVertices().iterator(),
|
||||
new CompoundIterator<PointerKey>(factory.getVarVertices().iterator(),
|
||||
factory.getPropVertices().iterator())));
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@Override
|
||||
public HeapModel getHeapModel() {
|
||||
return new HeapModel() {
|
||||
return new AstHeapModel() {
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForLocal(CGNode node, int valueNumber) {
|
||||
@ -387,6 +396,30 @@ public class FlowGraph implements Iterable<Vertex> {
|
||||
public IClassHierarchy getClassHierarchy() {
|
||||
assert false;
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForArrayLength(InstanceKey I) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PointerKey> getPointerKeysForReflectedFieldRead(InstanceKey I, InstanceKey F) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Iterator<PointerKey> getPointerKeysForReflectedFieldWrite(InstanceKey I, InstanceKey F) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public PointerKey getPointerKeyForObjectCatalog(InstanceKey I) {
|
||||
// TODO Auto-generated method stub
|
||||
return null;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@ -10,6 +10,8 @@
|
||||
*****************************************************************************/
|
||||
package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
||||
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
|
||||
|
||||
|
||||
/**
|
||||
* A return vertex represents the 'arguments' array of a given function.
|
||||
@ -17,7 +19,7 @@ package com.ibm.wala.cast.js.callgraph.fieldbased.flowgraph.vertices;
|
||||
* @author Julian Dolby (dolby@us.ibm.com)
|
||||
*
|
||||
*/
|
||||
public class ArgVertex extends Vertex {
|
||||
public class ArgVertex extends Vertex implements PointerKey {
|
||||
private final FuncVertex func;
|
||||
|
||||
ArgVertex(FuncVertex func) {
|
||||
|
||||
@ -102,6 +102,10 @@ public class VertexFactory {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Iterable<RetVertex> getRetVertices() {
|
||||
return retVertexCache.values();
|
||||
}
|
||||
|
||||
public ArgVertex makeArgVertex(FuncVertex func) {
|
||||
ArgVertex value = argVertexCache.get(func);
|
||||
if(value == null)
|
||||
@ -109,6 +113,10 @@ public class VertexFactory {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Iterable<ArgVertex> getArgVertices() {
|
||||
return argVertexCache.values();
|
||||
}
|
||||
|
||||
public UnknownVertex makeUnknownVertex() {
|
||||
return UnknownVertex.INSTANCE;
|
||||
}
|
||||
@ -121,6 +129,10 @@ public class VertexFactory {
|
||||
return value;
|
||||
}
|
||||
|
||||
public Iterable<VarVertex> getVarVertices() {
|
||||
return varVertexCache.values();
|
||||
}
|
||||
|
||||
public LexicalVarVertex makeLexicalAccessVertex(String definer, String name) {
|
||||
Pair<String, String> key = Pair.make(definer, name);
|
||||
LexicalVarVertex value = lexicalAccessVertexCache.get(key);
|
||||
|
||||
@ -684,7 +684,7 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
||||
this.preprocessor = preprocessor;
|
||||
}
|
||||
|
||||
class JavaScriptClass extends AstClass {
|
||||
public class JavaScriptClass extends AstClass {
|
||||
private IClass superClass;
|
||||
|
||||
private JavaScriptClass(IClassLoader loader, TypeReference classRef, TypeReference superRef,
|
||||
@ -720,7 +720,7 @@ public class JavaScriptLoader extends CAstAbstractModuleLoader {
|
||||
}
|
||||
}
|
||||
|
||||
class JavaScriptRootClass extends AstDynamicPropertyClass {
|
||||
public class JavaScriptRootClass extends AstDynamicPropertyClass {
|
||||
|
||||
private JavaScriptRootClass(IClassLoader loader, CAstSourcePositionMap.Position sourcePosition) {
|
||||
super(sourcePosition, JavaScriptTypes.Root.getName(), loader, (short) 0, emptyMap1, JavaScriptTypes.Root);
|
||||
|
||||
@ -26,12 +26,12 @@ import com.ibm.wala.util.collections.HashSetFactory;
|
||||
|
||||
public abstract class ScriptEntryPoints implements Iterable<Entrypoint> {
|
||||
|
||||
private final IClassHierarchy cha;
|
||||
protected final IClassHierarchy cha;
|
||||
|
||||
private final IClass scriptType;
|
||||
protected final IClass scriptType;
|
||||
|
||||
private class ScriptEntryPoint extends Entrypoint {
|
||||
ScriptEntryPoint(IMethod scriptCodeBody) {
|
||||
public class ScriptEntryPoint extends Entrypoint {
|
||||
public ScriptEntryPoint(IMethod scriptCodeBody) {
|
||||
super(scriptCodeBody);
|
||||
}
|
||||
|
||||
|
||||
@ -932,7 +932,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
||||
checkForRealizedExitEdges(bb);
|
||||
}
|
||||
|
||||
void setCurrentBlockAsHandler() {
|
||||
public void setCurrentBlockAsHandler() {
|
||||
currentBlock.makeHandlerBlock();
|
||||
}
|
||||
|
||||
@ -1395,7 +1395,7 @@ public abstract class AstTranslator extends CAstVisitor<AstTranslator.WalkContex
|
||||
private final String _name;
|
||||
private final CAstType type;
|
||||
|
||||
private FinalCAstSymbol(String _name, CAstType type) {
|
||||
public FinalCAstSymbol(String _name, CAstType type) {
|
||||
this._name = _name;
|
||||
this.type = type;
|
||||
assert _name != null;
|
||||
|
||||
@ -31,8 +31,16 @@ import com.ibm.wala.util.CancelException;
|
||||
|
||||
public class DynamicCallGraphTest extends DynamicCallGraphTestBase {
|
||||
|
||||
private static String testJarLocation = getClasspathEntry("com.ibm.wala.core.testdata");
|
||||
protected final String testJarLocation;
|
||||
|
||||
protected DynamicCallGraphTest(String testJarLocation) {
|
||||
this.testJarLocation = testJarLocation;
|
||||
}
|
||||
|
||||
public DynamicCallGraphTest() {
|
||||
this(getClasspathEntry("com.ibm.wala.core.testdata"));
|
||||
}
|
||||
|
||||
private CallGraph staticCG(String mainClass, String exclusionsFile) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
|
||||
AnalysisScope scope = CallGraphTestUtil.makeJ2SEAnalysisScope(TestConstants.WALA_TESTDATA, exclusionsFile != null? exclusionsFile: CallGraphTestUtil.REGRESSION_EXCLUSIONS);
|
||||
ClassHierarchy cha = ClassHierarchy.make(scope);
|
||||
|
||||
@ -17,6 +17,9 @@ import java.io.FileInputStream;
|
||||
import java.io.IOException;
|
||||
import java.io.InputStreamReader;
|
||||
import java.lang.reflect.InvocationTargetException;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import java.util.StringTokenizer;
|
||||
import java.util.zip.GZIPInputStream;
|
||||
@ -44,6 +47,8 @@ import com.ibm.wala.util.io.TemporaryFile;
|
||||
|
||||
public abstract class DynamicCallGraphTestBase extends WalaTestCase {
|
||||
|
||||
protected boolean testPatchCalls = false;
|
||||
|
||||
protected static String getClasspathEntry(String elt) {
|
||||
for (String s : System.getProperty("java.class.path").split(File.pathSeparator)) {
|
||||
if (s.indexOf(elt) >= 0) {
|
||||
@ -80,10 +85,15 @@ public abstract class DynamicCallGraphTestBase extends WalaTestCase {
|
||||
}
|
||||
}
|
||||
|
||||
OfflineDynamicCallGraph.main(
|
||||
rtJar == null?
|
||||
new String[]{testJarLocation, "-o", instrumentedJarLocation}:
|
||||
new String[]{testJarLocation, "-o", instrumentedJarLocation, "--rt-jar", rtJar});
|
||||
List<String> args = new ArrayList<String>();
|
||||
args.addAll(Arrays.asList(testJarLocation, "-o", instrumentedJarLocation));
|
||||
if (rtJar != null) {
|
||||
args.addAll(Arrays.asList("--rt-jar", rtJar));
|
||||
}
|
||||
if (testPatchCalls) {
|
||||
args.add("--patch-calls");
|
||||
}
|
||||
OfflineDynamicCallGraph.main(args.toArray(new String[ args.size() ]));
|
||||
Assert.assertTrue("expected to create /tmp/test.jar", new File(instrumentedJarLocation).exists());
|
||||
instrumentedJarBuilt = true;
|
||||
}
|
||||
|
||||
@ -16,3 +16,5 @@ Bundle-ActivationPolicy: lazy
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ClassPath: .,
|
||||
lib/dx.jar
|
||||
Export-Package: com.ibm.wala.dalvik.test.callGraph,
|
||||
com.ibm.wala.dalvik.test.util
|
||||
|
||||
@ -12,9 +12,15 @@ import com.ibm.wala.dalvik.test.util.Util;
|
||||
import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions;
|
||||
import com.ibm.wala.ipa.callgraph.CGNode;
|
||||
import com.ibm.wala.ipa.callgraph.CallGraph;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
|
||||
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
|
||||
import com.ibm.wala.ipa.slicer.SDG;
|
||||
import com.ibm.wala.ipa.slicer.Slicer.ControlDependenceOptions;
|
||||
import com.ibm.wala.ipa.slicer.Slicer.DataDependenceOptions;
|
||||
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
|
||||
import com.ibm.wala.util.Predicate;
|
||||
import com.ibm.wala.util.collections.HashSetFactory;
|
||||
import com.ibm.wala.util.collections.Pair;
|
||||
import com.ibm.wala.util.functions.VoidFunction;
|
||||
import com.ibm.wala.util.io.FileUtil;
|
||||
|
||||
@ -57,7 +63,7 @@ public class APKCallGraphDriver {
|
||||
System.err.println("Analyzing " + apk + "...");
|
||||
try {
|
||||
long time = System.currentTimeMillis();
|
||||
CallGraph CG;
|
||||
Pair<CallGraph, PointerAnalysis<InstanceKey>> CG;
|
||||
final long startTime = System.currentTimeMillis();
|
||||
IProgressMonitor pm = new IProgressMonitor() {
|
||||
private boolean cancelled = false;
|
||||
@ -100,24 +106,26 @@ public class APKCallGraphDriver {
|
||||
return "timeout";
|
||||
}
|
||||
};
|
||||
CG = DalvikCallGraphTestBase.makeAPKCallGraph(libs(), null, apk.getAbsolutePath(), pm, ReflectionOptions.NONE).fst;
|
||||
CG = DalvikCallGraphTestBase.makeAPKCallGraph(libs(), null, apk.getAbsolutePath(), pm, ReflectionOptions.NONE);
|
||||
System.err.println("Analyzed " + apk + " in " + (System.currentTimeMillis() - time));
|
||||
|
||||
System.err.println(new SDG(CG.fst, CG.snd, DataDependenceOptions.NO_BASE_NO_HEAP_NO_EXCEPTIONS, ControlDependenceOptions.NONE));
|
||||
|
||||
if (dumpIR) {
|
||||
for(CGNode n : CG) {
|
||||
for(CGNode n : CG.fst) {
|
||||
System.err.println(n.getIR());
|
||||
System.err.println();
|
||||
}
|
||||
} else {
|
||||
Set<IMethod> code = HashSetFactory.make();
|
||||
for(CGNode n : CG) {
|
||||
for(CGNode n : CG.fst) {
|
||||
code.add(n.getMethod());
|
||||
}
|
||||
|
||||
if (addAbstract) {
|
||||
for(IClass cls : CG.getClassHierarchy()) {
|
||||
for(IClass cls : CG.fst.getClassHierarchy()) {
|
||||
for(IMethod m : cls.getDeclaredMethods()) {
|
||||
if (m.isAbstract() && !Collections.disjoint(CG.getClassHierarchy().getPossibleTargets(m.getReference()), code)) {
|
||||
if (m.isAbstract() && !Collections.disjoint(CG.fst.getClassHierarchy().getPossibleTargets(m.getReference()), code)) {
|
||||
code.add(m);
|
||||
}
|
||||
}
|
||||
|
||||
@ -131,12 +131,7 @@ public class DalvikCallGraphTestBase extends DynamicCallGraphTestBase {
|
||||
|
||||
AnalysisCache cache = new AnalysisCache(new DexIRFactory());
|
||||
|
||||
Set<LocatorFlags> flags = HashSetFactory.make();
|
||||
flags.add(LocatorFlags.INCLUDE_CALLBACKS);
|
||||
flags.add(LocatorFlags.EP_HEURISTIC);
|
||||
flags.add(LocatorFlags.CB_HEURISTIC);
|
||||
AndroidEntryPointLocator eps = new AndroidEntryPointLocator(flags);
|
||||
List<? extends Entrypoint> es = eps.getEntryPoints(cha);
|
||||
List<? extends Entrypoint> es = getEntrypoints(cha);
|
||||
|
||||
assert ! es.isEmpty();
|
||||
|
||||
@ -152,6 +147,16 @@ public class DalvikCallGraphTestBase extends DynamicCallGraphTestBase {
|
||||
|
||||
return Pair.make(callGraph, ptrAnalysis);
|
||||
}
|
||||
|
||||
public static List<? extends Entrypoint> getEntrypoints(final IClassHierarchy cha) {
|
||||
Set<LocatorFlags> flags = HashSetFactory.make();
|
||||
flags.add(LocatorFlags.INCLUDE_CALLBACKS);
|
||||
flags.add(LocatorFlags.EP_HEURISTIC);
|
||||
flags.add(LocatorFlags.CB_HEURISTIC);
|
||||
AndroidEntryPointLocator eps = new AndroidEntryPointLocator(flags);
|
||||
List<? extends Entrypoint> es = eps.getEntryPoints(cha);
|
||||
return es;
|
||||
}
|
||||
|
||||
public static Pair<CallGraph, PointerAnalysis<InstanceKey>> makeDalvikCallGraph(URI[] androidLibs, File androidAPIJar, String mainClassName, String dexFileName) throws IOException, ClassHierarchyException, IllegalArgumentException, CancelException {
|
||||
AnalysisScope scope = makeDalvikScope(androidLibs, androidAPIJar, dexFileName);
|
||||
|
||||
@ -152,10 +152,20 @@ public final class AndroidEntryPointLocator {
|
||||
int dummy = 0; // for the progress monitor
|
||||
for (IClass cls : cha) {
|
||||
mon.worked(dummy++);
|
||||
if (cls.getName().toString().contains("MainActivity")) {
|
||||
System.err.println("got here");
|
||||
}
|
||||
if (isExcluded(cls)) continue;
|
||||
if (!cls.isInterface() && !cls.isAbstract() && cls.getClassLoader().getName().equals(AnalysisScope.APPLICATION)) {
|
||||
if (!cls.isInterface() &&
|
||||
!cls.isAbstract() &&
|
||||
!( cls.getClassLoader().getName().equals(AnalysisScope.PRIMORDIAL) ||
|
||||
cls.getClassLoader().getName().equals(AnalysisScope.EXTENSION)
|
||||
)) {
|
||||
nextMethod:
|
||||
for (final IMethod m : cls.getDeclaredMethods()) {
|
||||
if (cls.getName().toString().contains("MainActivity")) {
|
||||
System.err.println("got here: " + m);
|
||||
}
|
||||
// If there is a Method signature in the possible entry points use thatone
|
||||
for (AndroidPossibleEntryPoint e: possibleEntryPoints) {
|
||||
if (e.name.equals(m.getName().toString()) ) {
|
||||
@ -399,7 +409,8 @@ nextMethod:
|
||||
}
|
||||
|
||||
private boolean isAPIComponent(final IClass cls) {
|
||||
if (cls.getClassLoader().getReference().equals(ClassLoaderReference.Application)) {
|
||||
ClassLoaderReference clr = cls.getClassLoader().getReference();
|
||||
if (! (clr.equals(ClassLoaderReference.Primordial) || clr.equals(ClassLoaderReference.Extension))) {
|
||||
if (cls.getName().toString().startsWith("Landroid/")) {
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -23,5 +23,6 @@ Require-Bundle: org.eclipse.ui,
|
||||
Bundle-RequiredExecutionEnvironment: JavaSE-1.7
|
||||
Bundle-ActivationPolicy: lazy
|
||||
Export-Package: com.ibm.wala.cast.java.client,
|
||||
com.ibm.wala.cast.java.translator.jdt,
|
||||
com.ibm.wala.ide.jdt,
|
||||
com.ibm.wala.ide.util
|
||||
|
||||
Loading…
Reference in New Issue
Block a user