make Android entrypoint locator work for source code

This commit is contained in:
Julian Dolby 2016-06-10 21:21:08 -04:00
parent 21340b44cf
commit 76286a330c
15 changed files with 128 additions and 35 deletions

View File

@ -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

View File

@ -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;
}

View File

@ -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;
}
};
}

View File

@ -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) {

View File

@ -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);

View File

@ -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);

View File

@ -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);
}

View File

@ -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;

View File

@ -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);

View File

@ -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;
}

View File

@ -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

View File

@ -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);
}
}

View File

@ -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);

View File

@ -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;
}

View File

@ -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