cleanup in com.ibm.wala.dalvik project

This commit is contained in:
Martin Mohr 2013-02-06 14:29:28 +01:00 committed by Juergen Graf
parent 77275aad73
commit d0d2609bf3
15 changed files with 24 additions and 1714 deletions

View File

@ -20,17 +20,7 @@ Export-Package: com.ibm.wala.dalvik.classLoader,
com.ibm.wala.dalvik.ipa.callgraph.impl,
com.ibm.wala.dalvik.ipa.callgraph.propagation.cfa,
com.ibm.wala.dalvik.ssa,
org.scandroid,
org.scandroid.domain,
org.scandroid.flow,
org.scandroid.flow.functions,
org.scandroid.flow.types,
org.scandroid.model,
org.scandroid.prefixtransfer,
org.scandroid.prefixtransfer.modeledAllocations,
org.scandroid.spec,
org.scandroid.synthmethod,
org.scandroid.util
com.ibm.wala.dalvik.util
Require-Bundle: com.ibm.wala.cast;bundle-version="1.0.0",
com.ibm.wala.cast.java;bundle-version="1.0.0",
com.ibm.wala.core;bundle-version="1.1.3",

View File

@ -44,6 +44,7 @@ import static org.jf.dexlib.Util.AccessFlags.PRIVATE;
import static org.jf.dexlib.Util.AccessFlags.PUBLIC;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
import org.jf.dexlib.ClassDataItem;
@ -62,6 +63,7 @@ import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.util.strings.ImmutableByteArray;
public class DexIClass extends BytecodeClass<IClassLoader> {
@ -334,4 +336,9 @@ public class DexIClass extends BytecodeClass<IClassLoader> {
// return construcorId!=-1?methods[construcorId]:null;
return clinitId!=-1?methods[clinitId]:null;
}
@Override
public Collection<Annotation> getAnnotations() {
throw new UnsupportedOperationException();
}
}

View File

@ -46,6 +46,8 @@ import static org.jf.dexlib.Util.AccessFlags.PUBLIC;
import static org.jf.dexlib.Util.AccessFlags.STATIC;
import static org.jf.dexlib.Util.AccessFlags.VOLATILE;
import java.util.Collection;
import org.jf.dexlib.ClassDataItem.EncodedField;
import com.ibm.wala.classLoader.IClass;
@ -54,6 +56,7 @@ import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.util.strings.Atom;
import com.ibm.wala.util.strings.ImmutableByteArray;
@ -162,4 +165,9 @@ public class DexIField implements IField {
return myClass.getClassHierarchy();
}
@Override
public Collection<Annotation> getAnnotations() {
throw new UnsupportedOperationException();
}
}

View File

@ -136,6 +136,7 @@ import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.Selector;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.types.annotations.Annotation;
import com.ibm.wala.util.strings.Atom;
import com.ibm.wala.util.strings.ImmutableByteArray;
@ -3271,4 +3272,9 @@ public class DexIMethod implements IBytecodeMethod {
return null;
}
@Override
public Collection<Annotation> getAnnotations() {
throw new UnsupportedOperationException();
}
}

View File

@ -1,4 +1,4 @@
package org.scandroid.util;
package com.ibm.wala.dalvik.util;
import java.io.File;
import java.io.IOException;

View File

@ -1,258 +0,0 @@
package org.scandroid;
/*
*
* Copyright (c) 2009-2012,
*
* Adam Fuchs <afuchs@cs.umd.edu>
* Avik Chaudhuri <avik@cs.umd.edu>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.IKFlow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.NormalAllocationInNode;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
public class Checker {
private static final Logger logger = LoggerFactory.getLogger(Checker.class);
private static boolean addFlow(IKFlow source, IKFlow dest, Map<IKFlow, Set<IKFlow>> flow)
{
Set<IKFlow> dests = flow.get(source);
if(dests == null)
{
dests = new HashSet<IKFlow>();
flow.put(source, dests);
}
return dests.add(dest);
}
private static boolean addFlow(FlowType source, FlowType dest, Map<FlowType, Set<FlowType>> flow)
{
Set<FlowType> dests = flow.get(source);
if(dests == null)
{
dests = new HashSet<FlowType>();
flow.put(source, dests);
}
return dests.add(dest);
}
private static Map<IKFlow, Set<IKFlow>> computeClosure(Map<FlowType, Set<FlowType>> permissionFlow)
{
Map<IKFlow, Set<IKFlow>> uriFlow = new HashMap<IKFlow, Set<IKFlow>>();
boolean changed = true;
Map<FlowType, Set<FlowType>> growingFlow = new HashMap<FlowType,Set<FlowType>>(permissionFlow);
Map<FlowType, Set<FlowType>> newFlow = new HashMap<FlowType,Set<FlowType>>();
while(changed)
{
changed = false;
newFlow.clear();
for(Entry<FlowType, Set<FlowType>> e: growingFlow.entrySet())
{
if(e.getKey() instanceof IKFlow)
{
for(FlowType v:e.getValue())
{
/*
if(v instanceof IKFlow)
addFlow((IKFlow)e.getKey(),(IKFlow)v,uriFlow);
else
{
// find all of the possible targets
if(v instanceof ActivityCallFlow || v instanceof ServiceCallFlow)
{
// find all instances of InputFlow
for(Entry<FlowType, Set<FlowType>> e2:permissionFlow.entrySet())
{
if(e2.getKey() instanceof InputFlow)
{
for(FlowType v2: e2.getValue())
{
addFlow(e.getKey(),v2,newFlow);
}
}
}
}
else if(v instanceof ReturnFlow)
{
for(Entry<FlowType, Set<FlowType>> e2:permissionFlow.entrySet())
{
if(e2.getKey() instanceof ReturnFlow)
{
for(FlowType v2: e2.getValue())
{
addFlow(e.getKey(),v2,newFlow);
}
}
}
}
else if(v instanceof BinderFlow)
{
for(Entry<FlowType, Set<FlowType>> e2:permissionFlow.entrySet())
{
if(e2.getKey() instanceof BinderFlow)
{
for(FlowType v2: e2.getValue())
{
addFlow(e.getKey(),v2,newFlow);
}
}
}
}
}
*/
}
}
}
for(Entry<FlowType,Set<FlowType>> e: newFlow.entrySet())
{
for(FlowType v:e.getValue())
{
changed = addFlow(e.getKey(),v,growingFlow) || changed;
}
}
}
return uriFlow;
}
public static void check(
Map<FlowType, Set<FlowType>> permissionOutflow,
Permissions perms, Map<InstanceKey, String> prefixes) {
// compute the transitive closure of permissionOutflow
Map<IKFlow,Set<IKFlow>> uriFlow = computeClosure(permissionOutflow);
HashMap<InstanceKey, HashSet<String>> readPerms = new HashMap<InstanceKey, HashSet<String>>();
HashMap<InstanceKey, HashSet<String>> writePerms = new HashMap<InstanceKey, HashSet<String>>();
for (Entry<InstanceKey, String> prefix: prefixes.entrySet()) {
if (prefix.getKey() instanceof NormalAllocationInNode) {
NormalAllocationInNode ik = (NormalAllocationInNode) prefix.getKey();
if (ik.getConcreteType().getName().toString().contains("Landroid/net/Uri")) {
// logger.debug(pa.getInstanceKeyMapping().getMappedIndex(ik) + " << " + perms.readPerms(prefix.getValue()));
readPerms.put(ik, perms.readPerms(prefix.getValue()));
// logger.debug(pa.getInstanceKeyMapping().getMappedIndex(ik) + " >> " + perms.writePerms(prefix.getValue()));
writePerms.put(ik, perms.writePerms(prefix.getValue()));
}
}
}
logger.debug("*********************");
logger.debug("* Constraints *");
logger.debug("*********************");
/*
for (Entry<IKFlow, Set<IKFlow>> e: uriFlow.entrySet()) {
if(e.getKey() instanceof IKFlow)
{
InstanceKey sourceIK = ((IKFlow)e.getKey()).ik;
if (readPerms.containsKey(sourceIK)) {
for (FlowType f: e.getValue()) {
if(f instanceof IKFlow)
{
if (readPerms.containsKey(((IKFlow)f).ik))
logger.debug(readPerms.get(((IKFlow)f).ik) + " can read " + readPerms.get(sourceIK));
}
}
}
if (writePerms.containsKey(sourceIK)) {
for (FlowType f: e.getValue()) {
if(f instanceof IKFlow)
if (writePerms.containsKey(((IKFlow)f).ik)) logger.debug(writePerms.get(sourceIK) + " can write " + writePerms.get(((IKFlow)f).ik));
}
}
}
}
*/
}
private static Map<InstanceKey, Set<InstanceKey>> fake(PointerAnalysis pa) {
Map<InstanceKey, Set<InstanceKey>> permissionOutflow = new HashMap<InstanceKey, Set<InstanceKey>>();
HashSet<InstanceKey> iks = new HashSet<InstanceKey>();
iks.add(pa.getInstanceKeyMapping().getMappedObject(25));
permissionOutflow.put(pa.getInstanceKeyMapping().getMappedObject(29), iks);
return permissionOutflow;
}
public static void fakeCheck(PointerAnalysis pa,
Map<InstanceKey, Set<InstanceKey>> permissionOutflow,
Permissions perms, Map<InstanceKey, String> prefixes) {
permissionOutflow = fake(pa);
HashMap<InstanceKey, HashSet<String>> readPerms = new HashMap<InstanceKey, HashSet<String>>();
HashMap<InstanceKey, HashSet<String>> writePerms = new HashMap<InstanceKey, HashSet<String>>();
for (Entry<InstanceKey, String> prefix: prefixes.entrySet()) {
if (prefix.getKey() instanceof NormalAllocationInNode) {
NormalAllocationInNode ik = (NormalAllocationInNode) prefix.getKey();
if (ik.getConcreteType().getName().toString().equals("Landroid/net/Uri")) {
logger.debug(pa.getInstanceKeyMapping().getMappedIndex(ik) + " << " + perms.readPerms(prefix.getValue()));
readPerms.put(ik, perms.readPerms(prefix.getValue()));
logger.debug(pa.getInstanceKeyMapping().getMappedIndex(ik) + " >> " + perms.writePerms(prefix.getValue()));
writePerms.put(ik, perms.writePerms(prefix.getValue()));
}
}
}
logger.debug("*********************");
logger.debug("* Constraints *");
logger.debug("*********************");
for (Entry<InstanceKey, Set<InstanceKey>> e: permissionOutflow.entrySet()) {
if (readPerms.containsKey(e.getKey())) {
for (InstanceKey k: e.getValue()) {
if (readPerms.containsKey(k)) logger.debug(readPerms.get(k) + " can read " + readPerms.get(e.getKey()));
}
}
if (writePerms.containsKey(e.getKey())) {
for (InstanceKey k: e.getValue()) {
if (writePerms.containsKey(k)) logger.debug(writePerms.get(e.getKey()) + " can write " + writePerms.get(k));
}
}
}
}
}

View File

@ -1,221 +0,0 @@
/**
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@galois.com>, Rogan Creswick <creswick@galois.com>)
* Steve Suh <suhsteve@gmail.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
package org.scandroid;
import java.io.IOException;
import java.lang.reflect.Method;
import java.lang.reflect.Modifier;
import java.util.Enumeration;
import java.util.List;
import java.util.Map;
import java.util.jar.JarEntry;
import java.util.jar.JarFile;
import com.google.common.collect.HashMultimap;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Multimap;
/**
* @author creswick
*
*/
public class JarInspector {
private static String OUTPUT_DIR = "results";
/**
* @param args
* @throws IOException
* @throws ClassNotFoundException
*/
public static void main(String[] args) throws IOException, ClassNotFoundException {
final String appJar = args[0];
final Multimap<String, String> pkgMethods = getMethodsByPackage(appJar);
int count = 0;
for (final String pkg : pkgMethods.keySet()) {
System.out.println(pkg+": "+pkgMethods.get(pkg).size());
count += pkgMethods.get(pkg).size();
}
System.out.println("Methods: "+count);
}
/**
* Calculate a map of package name to method descriptor for all interesting
* methods in the supplied jar file (which must also be on the classpath)
*
* @param jarFile
* @return
* @throws ClassNotFoundException
* @throws IOException
*/
public static Multimap<String, String> getMethodsByPackage(String jarFile)
throws ClassNotFoundException, IOException {
Multimap<String, String> pkgMap = HashMultimap.create();
List<String> classes = getClasses(jarFile);
for (String c : classes ) {
//System.out.println(c);
Method[] methods;
Class<?> clazz;
try {
clazz = Class.forName(c);
// skip a bunch of class types that don't really have code:
if (clazz.isEnum()
|| clazz.isInterface()
|| clazz.isAnnotation()
|| clazz.isAnonymousClass()
|| clazz.isPrimitive()
|| clazz.isSynthetic()
) {
continue;
}
methods = clazz.getMethods();
} catch (Throwable e) {
System.err.println("Could not load class: "+c);
e.printStackTrace();
continue;
}
for (Method m : methods) {
// skip methods that are declared on other classes (eg: java/lang/Object)
if ( !m.getDeclaringClass().equals(clazz)
// skip bridge methods (what /are/ these?)
|| m.isBridge()
// skip synthetic methods (native?)
|| m.isSynthetic()
// skip varargs -- not sure summaries can support that.
|| m.isVarArgs()) {
continue;
}
// only look at public methods:
if (! Modifier.isPublic(m.getModifiers()) ){
continue;
}
StringBuilder desc = new StringBuilder(c);
desc.append("."+m.getName());
desc.append("(");
for( Class<?> pType : m.getParameterTypes() ) {
desc.append(toDescStr(pType));
}
desc.append(")");
desc.append(toDescStr(m.getReturnType()));
String packageName = clazz.getPackage().getName();
pkgMap.put(packageName, desc.toString());
}
}
return pkgMap;
}
private static String toDescStr(Class<?> pType) {
Map<Class<?>, String> primitives = Maps.newHashMap();
primitives.put(Void.TYPE, "V");
primitives.put(float.class, "F");
primitives.put(double.class, "D");
primitives.put(byte.class, "B");
primitives.put(short.class, "S");
primitives.put(int.class, "I");
primitives.put(long.class, "J");
primitives.put(boolean.class, "Z");
primitives.put(char.class, "C");
if (primitives.containsKey(pType)) {
return (String)primitives.get(pType);
}
StringBuilder typeName = new StringBuilder();
if (pType.isArray()){
typeName.append(pType.getName().replace('.', '/'));
} else {
typeName.append("L");
typeName.append(pType.getName().replace('.', '/'));
typeName.append(";");
}
return typeName.toString();
}
private static List<String> getClasses(String jarFile) throws IOException {
List<String> classes = Lists.newArrayList();
Multimap<String, String> packages = getPackages(jarFile);
for(String pkg : packages.keySet() ){
//System.out.println(pkg);
for (String c : packages.get(pkg)) {
classes.add(pkg+"."+c);
}
}
return classes;
}
private static Multimap<String, String> getPackages(String appJar) throws IOException {
Multimap<String, String> packages = HashMultimap.create();
JarFile jf = new JarFile(appJar);
Enumeration<JarEntry> entries = jf.entries();
while (entries.hasMoreElements()) {
JarEntry je = entries.nextElement();
String name = je.getName();
// skip everything but class files:
if ( !name.endsWith(".class") ) {
continue;
}
int slashIdx = name.lastIndexOf("/");
String className = name.substring(slashIdx + 1, name.lastIndexOf('.'));
String pkgName = name.substring(0, slashIdx);
String dottedPkg = pkgName.replace('/', '.');
packages.put(dottedPkg, className);
}
return packages;
}
}

View File

@ -1,158 +0,0 @@
/**
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@galois.com>, Rogan Creswick <creswick@galois.com>)
* Steve Suh <suhsteve@gmail.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
package org.scandroid;
import java.io.UTFDataFormatException;
import java.util.List;
import org.scandroid.spec.EntryArgSinkSpec;
import org.scandroid.spec.EntryArgSourceSpec;
import org.scandroid.spec.EntryRetSinkSpec;
import org.scandroid.spec.ISpecs;
import org.scandroid.spec.MethodNamePattern;
import org.scandroid.spec.SinkSpec;
import org.scandroid.spec.SourceSpec;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.ibm.wala.ipa.summaries.MethodSummary;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
/**
* @author creswick
*
*/
public class MethodSummarySpecs implements ISpecs {
private static final Logger logger = LoggerFactory.getLogger(MethodSummarySpecs.class);
private final MethodSummary methodRef;
public MethodSummarySpecs(MethodSummary methodRef) {
this.methodRef = methodRef;
}
/* (non-Javadoc)
* @see spec.ISpecs#getEntrypointSpecs()
*/
@Override
public MethodNamePattern[] getEntrypointSpecs() {
return new MethodNamePattern[0];
}
/* (non-Javadoc)
* @see spec.ISpecs#getSourceSpecs()
*/
@Override
public SourceSpec[] getSourceSpecs() {
try {
return getSources(methodRef).toArray(new SourceSpec[] {});
} catch (UTFDataFormatException e) {
e.printStackTrace();
}
return new SourceSpec[] {};
}
/* (non-Javadoc)
* @see spec.ISpecs#getSinkSpecs()
*/
@Override
public SinkSpec[] getSinkSpecs() {
try {
return getSinks(methodRef).toArray(new SinkSpec[] {});
} catch (UTFDataFormatException e) {
e.printStackTrace();
}
return new SinkSpec[] {};
}
private List<SinkSpec> getSinks(MethodSummary mSummary) throws UTFDataFormatException {
List<SinkSpec> sinks = Lists.newArrayList();
MethodReference mRef = (MethodReference) mSummary.getMethod();
//
// Add the args as EntryArgSinkSpecs:
//
String className = mRef.getDeclaringClass().getName().toUnicodeString();
String methodName = mRef.getName().toUnicodeString();
String descriptor = mRef.getDescriptor().toUnicodeString();
MethodNamePattern pattern = new MethodNamePattern(className, methodName, descriptor);
int[] argNums = new int[mSummary.getNumberOfParameters()];
for (int i = 0; i < argNums.length; i++) {
argNums[i] = i;
}
sinks.add(new EntryArgSinkSpec(pattern, argNums));
TypeReference typeRef = mRef.getReturnType();
if (! typeRef.equals(TypeReference.Void)) {
//
// Add the return value as a EntryRetSinkSpec
//
sinks.add(new EntryRetSinkSpec(pattern));
}
logger.debug("found sinks: " + sinks.toString());
return sinks;
}
private List<SourceSpec> getSources(MethodSummary mSummary) throws UTFDataFormatException {
List<SourceSpec> sources = Lists.newArrayList();
MethodReference mRef = (MethodReference) mSummary.getMethod();
//
// Add the args as EntryArgSourceSpecs:
//
String className = mRef.getDeclaringClass().getName().toUnicodeString();
String methodName = mRef.getName().toUnicodeString();
String descriptor = mRef.getDescriptor().toUnicodeString();
MethodNamePattern pattern = new MethodNamePattern(className, methodName, descriptor);
int[] argNums = new int[mSummary.getNumberOfParameters()];
for (int i = 0; i < argNums.length; i++) {
argNums[i] = i;
}
sources.add(new EntryArgSourceSpec(pattern, argNums));
logger.debug("found sources: " + sources.toString());
return sources;
}
}

View File

@ -1,218 +0,0 @@
/**
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@galois.com>,
* Rogan Creswick <creswick@galois.com>,
* Adam Foltzer <acfoltzer@galois.com>)
* Steve Suh <suhsteve@gmail.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
package org.scandroid;
import java.io.IOException;
import java.io.InputStream;
import java.io.ObjectInputStream;
import java.io.UTFDataFormatException;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.scandroid.spec.CallArgSinkSpec;
import org.scandroid.spec.CallArgSourceSpec;
import org.scandroid.spec.CallRetSourceSpec;
import org.scandroid.spec.ISpecs;
import org.scandroid.spec.MethodNamePattern;
import org.scandroid.spec.SinkSpec;
import org.scandroid.spec.SourceSpec;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.strings.StringStuff;
/**
* An ISpecs implementation generated from the PScout permission mappings. The
* inputstream these constructors expect is *not* the raw PScout file, but
* rather a parsed version of that file that has been serialized as a
* java.util.Map from permission names to sets of method signatures.
*
* @author acfoltzer
*
*/
public class PermissionMappingSpecs implements ISpecs {
private final Map<String, Set<String>> mappings;
private final SourceSpec[] sources;
private final SinkSpec[] sinks;
/**
* Generate sources and sinks for all permissions in the given mappings
*
* @param mappings
* file generated by pscoutParser
* @throws IOException
* @throws ClassNotFoundException
*/
@SuppressWarnings("unchecked")
public PermissionMappingSpecs(InputStream mappingStream)
throws ClassNotFoundException, IOException {
this.mappings = (Map<String, Set<String>>) new ObjectInputStream(
mappingStream).readObject();
Set<SourceSpec> sourceSet = Sets.newHashSet();
Set<SinkSpec> sinkSet = Sets.newHashSet();
for (Entry<String, Set<String>> entry : mappings.entrySet()) {
sourceSet.addAll(sourcesForSet(entry.getValue()));
sinkSet.addAll(sinksForSet(entry.getValue()));
}
this.sources = (SourceSpec[]) sourceSet.toArray(new SourceSpec[sourceSet.size()]);
this.sinks = (SinkSpec[]) sinkSet.toArray(new SinkSpec[sinkSet.size()]);
}
/**
* Generate sources and sinks only for those permissions specified.
*
* @param mappingStream
* file generated by pscoutParser
* @param sourcePermissions
* for which to make sources
* @param sinkPermissions
* for which to make sinks
* @throws IOException
* @throws ClassNotFoundException
*/
public PermissionMappingSpecs(InputStream mappingStream,
Set<String> sourcePermissions, Set<String> sinkPermissions)
throws ClassNotFoundException, IOException {
this.mappings = (Map<String, Set<String>>) new ObjectInputStream(
mappingStream).readObject();
Set<SourceSpec> sourceSet = Sets.newHashSet();
Set<SinkSpec> sinkSet = Sets.newHashSet();
for (String sourcePermission : sourcePermissions) {
sourceSet.addAll(sourcesForSet(mappings.get(sourcePermission)));
}
for (String sinkPermission : sinkPermissions) {
sinkSet.addAll(sinksForSet(mappings.get(sinkPermission)));
}
this.sources = (SourceSpec[]) sourceSet.toArray();
this.sinks = (SinkSpec[]) sinkSet.toArray();
}
private List<SourceSpec> sourcesForSet(Set<String> set)
throws UTFDataFormatException {
List<SourceSpec> result = Lists.newLinkedList();
for (String methodString : set) {
MethodReference methodRef = StringStuff
.makeMethodReference(methodString);
MethodNamePattern pattern = MethodNamePattern
.patternForReference(methodRef);
// the pscout results don't record static vs. non-static, so we
// assume it could be either
int[] staticArgs = new int[methodRef.getNumberOfParameters()];
for (int i = 0; i < staticArgs.length; i++) {
staticArgs[i] = i;
}
int[] virtualArgs = new int[methodRef.getNumberOfParameters() + 1];
for (int i = 0; i < virtualArgs.length; i++) {
virtualArgs[i] = i;
}
result.add(new CallArgSourceSpec(pattern, staticArgs));
result.add(new CallArgSourceSpec(pattern, virtualArgs));
result.add(new CallRetSourceSpec(pattern, new int[] {}));
}
return result;
}
private List<SinkSpec> sinksForSet(Set<String> set)
throws UTFDataFormatException {
List<SinkSpec> result = Lists.newLinkedList();
for (String methodString : set) {
MethodReference methodRef = StringStuff
.makeMethodReference(methodString);
MethodNamePattern pattern = MethodNamePattern
.patternForReference(methodRef);
// the pscout results don't record static vs. non-static, so we
// assume it could be either
int[] staticArgs = new int[methodRef.getNumberOfParameters()];
for (int i = 0; i < staticArgs.length; i++) {
staticArgs[i] = i;
}
int[] virtualArgs = new int[methodRef.getNumberOfParameters() + 1];
for (int i = 0; i < virtualArgs.length; i++) {
virtualArgs[i] = i;
}
result.add(new CallArgSinkSpec(pattern, staticArgs));
result.add(new CallArgSinkSpec(pattern, virtualArgs));
}
return result;
}
/*
* (non-Javadoc)
*
* @see org.scandroid.spec.ISpecs#getEntrypointSpecs()
*/
@Override
public MethodNamePattern[] getEntrypointSpecs() {
return new MethodNamePattern[] {};
}
/*
* (non-Javadoc)
*
* @see org.scandroid.spec.ISpecs#getSourceSpecs()
*/
@Override
public SourceSpec[] getSourceSpecs() {
return sources;
}
/*
* (non-Javadoc)
*
* @see org.scandroid.spec.ISpecs#getSinkSpecs()
*/
@Override
public SinkSpec[] getSinkSpecs() {
return sinks;
}
}

View File

@ -1,86 +0,0 @@
package org.scandroid;
/*
*
* Copyright (c) 2009-2012,
*
* Adam Fuchs <afuchs@cs.umd.edu>
* Avik Chaudhuri <avik@cs.umd.edu>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import java.util.HashMap;
import java.util.HashSet;
import java.util.Set;
import java.util.Map.Entry;
public class Permissions {
private HashMap<String, String> readPerms = new HashMap<String, String>();
private HashMap<String, String> writePerms = new HashMap<String, String>();
public Permissions() {
readPerms.put("content://some.authority1", "READ1");
writePerms.put("content://some.authority1", "WRITE1");
readPerms.put("content://some.other.authority1", "READ2");
writePerms.put("content://some.other.authority1", "WRITE2");
readPerms.put("content://some.authority2", "READ3");
writePerms.put("content://some.authority2", "WRITE3");
readPerms.put("content://some.other.authority2", "READ4");
writePerms.put("content://some.other.authority2", "WRITE4");
readPerms.put("content://some.authority3", "READ5");
writePerms.put("content://some.authority3", "WRITE5");
readPerms.put("content://some.other.authority3", "READ6");
writePerms.put("content://some.other.authority3", "WRITE6");
}
public static Permissions load(Set<String> manifestFilenames)
{
return new Permissions();
}
public HashSet<String> readPerms(String uri) {
HashSet<String> perms = new HashSet<String>();
for (Entry<String,String> e: readPerms.entrySet()) {
if (uri.startsWith(e.getKey())) perms.add(e.getValue());
}
return perms;
}
public HashSet<String> writePerms(String uri) {
HashSet<String> perms = new HashSet<String>();
for (Entry<String,String> e: writePerms.entrySet()) {
if (uri.startsWith(e.getKey())) perms.add(e.getValue());
}
return perms;
}
}

View File

@ -1,250 +0,0 @@
/**
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@galois.com>,
* Rogan Creswick <creswick@galois.com>,
* Adam Foltzer <acfoltzer@galois.com>)
* Steve Suh <suhsteve@gmail.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
package org.scandroid;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.net.URI;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.flow.FlowAnalysis;
import org.scandroid.flow.InflowAnalysis;
import org.scandroid.flow.OutflowAnalysis;
import org.scandroid.flow.types.FlowType;
import org.scandroid.spec.AndroidSpecs;
import org.scandroid.spec.ISpecs;
import org.scandroid.util.AndroidAnalysisContext;
import org.scandroid.util.CGAnalysisContext;
import org.scandroid.util.CLISCanDroidOptions;
import org.scandroid.util.EntryPoints;
import org.scandroid.util.IEntryPointSpecifier;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.dataflow.IFDS.TabulationResult;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.analysis.IExplodedBasicBlock;
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
public class SeparateEntryAnalysis {
private static final Logger logger = LoggerFactory
.getLogger(SeparateEntryAnalysis.class);
public static void main(String[] args) throws Exception {
CLISCanDroidOptions options = new CLISCanDroidOptions(args, true);
logger.info("Loading app.");
AndroidAnalysisContext analysisContext = new AndroidAnalysisContext(
options);
URI summariesURI = options.getSummariesURI();
InputStream summaryStream = null;
if (null != summariesURI) {
File summariesFile = new File(summariesURI);
if (!summariesFile.exists()) {
logger.error("Could not find summaries file: " + summariesFile);
System.exit(1);
}
summaryStream = new FileInputStream(summariesFile);
}
// for (IClass c : analysisContext.getClassHierarchy()) {
// logger.error(" class loaded: {}", c);
// }
//
final List<Entrypoint> entrypoints = EntryPoints
.defaultEntryPoints(analysisContext.getClassHierarchy());
if (entrypoints == null || entrypoints.size() == 0) {
throw new IOException("No Entrypoints Detected!");
}
for (Entrypoint entry : entrypoints) {
logger.info("Entry point: " + entry);
}
if (options.separateEntries()) {
int i = 1;
for (final Entrypoint entry : entrypoints) {
CGAnalysisContext<IExplodedBasicBlock> cgContext = new CGAnalysisContext<IExplodedBasicBlock>(
analysisContext, new IEntryPointSpecifier() {
@Override
public List<Entrypoint> specify(
AndroidAnalysisContext analysisContext) {
return Lists.newArrayList(entry);
}
});
logger.info("** Processing entry point " + i + "/"
+ entrypoints.size() + ": " + entry);
analyze(cgContext, summaryStream, null);
i++;
}
} else {
CGAnalysisContext<IExplodedBasicBlock> cgContext = new CGAnalysisContext<IExplodedBasicBlock>(
analysisContext, new IEntryPointSpecifier() {
@Override
public List<Entrypoint> specify(
AndroidAnalysisContext analysisContext) {
return entrypoints;
}
});
analyze(cgContext, summaryStream, null);
}
}
/**
* @param analysisContext
* @param localEntries
* @param methodAnalysis
* @param monitor
* @return the number of permission outflows detected
* @throws IOException
*/
public static int analyze(
CGAnalysisContext<IExplodedBasicBlock> analysisContext,
InputStream summariesStream, IProgressMonitor monitor)
throws IOException {
try {
logger.info("Supergraph size = "
+ analysisContext.graph.getNumberOfNodes());
Map<InstanceKey, String> prefixes;
if (analysisContext.getOptions().stringPrefixAnalysis()) {
logger.info("Running prefix analysis.");
prefixes = UriPrefixAnalysis.runAnalysisHelper(
analysisContext.cg, analysisContext.pa);
logger.info("Number of prefixes = " + prefixes.values().size());
} else {
prefixes = new HashMap<InstanceKey, String>();
}
ISpecs specs = new AndroidSpecs();
logger.info("Running inflow analysis.");
Map<BasicBlockInContext<IExplodedBasicBlock>, Map<FlowType<IExplodedBasicBlock>, Set<CodeElement>>> initialTaints = InflowAnalysis
.analyze(analysisContext, prefixes, specs);
logger.info(" Initial taint size = " + initialTaints.size());
logger.info("Running flow analysis.");
IFDSTaintDomain<IExplodedBasicBlock> domain = new IFDSTaintDomain<IExplodedBasicBlock>();
TabulationResult<BasicBlockInContext<IExplodedBasicBlock>, CGNode, DomainElement> flowResult = FlowAnalysis
.analyze(analysisContext, initialTaints, domain, monitor);
logger.info("Running outflow analysis.");
Map<FlowType<IExplodedBasicBlock>, Set<FlowType<IExplodedBasicBlock>>> permissionOutflow = new OutflowAnalysis(
analysisContext, specs).analyze(flowResult, domain);
logger.info(" Permission outflow size = "
+ permissionOutflow.size());
// logger.info("Running Checker.");
// Checker.check(permissionOutflow, perms, prefixes);
logger.info("");
logger.info("================================================================");
logger.info("");
for (Map.Entry<BasicBlockInContext<IExplodedBasicBlock>, Map<FlowType<IExplodedBasicBlock>, Set<CodeElement>>> e : initialTaints
.entrySet()) {
logger.info(e.getKey().toString());
for (Map.Entry<FlowType<IExplodedBasicBlock>, Set<CodeElement>> e2 : e
.getValue().entrySet()) {
logger.info(e2.getKey() + " <- " + e2.getValue());
}
}
for (Map.Entry<FlowType<IExplodedBasicBlock>, Set<FlowType<IExplodedBasicBlock>>> e : permissionOutflow
.entrySet()) {
logger.info(e.getKey().toString());
for (FlowType t : e.getValue()) {
logger.info(" --> " + t);
}
}
// System.out.println("DOMAIN ELEMENTS");
// for (int i = 1; i < domain.getSize(); i++) {
// System.out.println("#"+i+" - "+domain.getMappedObject(i));
// }
// System.out.println("------");
// for (CGNode n:loader.cg.getEntrypointNodes()) {
// for (int i = 0; i < 6; i++)
// {
// try {
// System.out.println(i+": ");
// String[] s =
// n.getIR().getLocalNames(n.getIR().getInstructions().length-1, i);
//
// for (String ss:s)
// System.out.println("\t"+ss);
// }
// catch (Exception e) {
// System.out.println("exception at " + i);
// }
// }
// }
//
// System.out.println("------");
// for (CGNode n:loader.cg.getEntrypointNodes()) {
// for (SSAInstruction ssa: n.getIR().getInstructions()) {
// // System.out.println("Definition " + ssa.getDef() + ":"+ssa);
// System.out.println("Definition "+ssa);
// }
// }
return permissionOutflow.size();
} catch (com.ibm.wala.util.debug.UnimplementedError e) {
logger.error("exception during analysis", e);
}
return 0;
}
}

View File

@ -1,257 +0,0 @@
package org.scandroid;
/*
*
* Copyright (c) 2009-2012,
*
* Adam Fuchs <afuchs@cs.umd.edu>
* Avik Chaudhuri <avik@cs.umd.edu>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import java.io.IOException;
import java.util.Collection;
import java.util.HashSet;
import java.util.Iterator;
import java.util.LinkedList;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.domain.LocalElement;
import org.scandroid.flow.functions.IFDSTaintFlowFunctionProvider;
import org.scandroid.flow.functions.TaintTransferFunctions;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dataflow.IFDS.ICFGSupergraph;
import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap;
import com.ibm.wala.dataflow.IFDS.IMergeFunction;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.dataflow.IFDS.PathEdge;
import com.ibm.wala.dataflow.IFDS.TabulationDomain;
import com.ibm.wala.dataflow.IFDS.TabulationProblem;
import com.ibm.wala.dataflow.IFDS.TabulationResult;
import com.ibm.wala.dataflow.IFDS.TabulationSolver;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint;
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
import com.ibm.wala.ipa.callgraph.impl.PartialCallGraph;
import com.ibm.wala.ipa.callgraph.impl.Util;
import com.ibm.wala.ipa.callgraph.propagation.AllocationSiteInNode;
import com.ibm.wala.ipa.callgraph.propagation.InstanceFieldKey;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ipa.cfg.InterproceduralCFG;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.IR;
import com.ibm.wala.ssa.SSAOptions;
import com.ibm.wala.ssa.analysis.IExplodedBasicBlock;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.WalaException;
import com.ibm.wala.util.collections.Filter;
import com.ibm.wala.util.config.AnalysisScopeReader;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.util.graph.GraphSlicer;
import com.ibm.wala.util.intset.OrdinalSet;
import com.ibm.wala.util.intset.OrdinalSetMapping;
import com.ibm.wala.util.io.FileProvider;
import com.ibm.wala.util.strings.Atom;
import com.ibm.wala.util.strings.StringStuff;
public class StringPrefixAnalysis {
/**
* @param args
* @throws IOException
* @throws CancelException
* @throws IllegalArgumentException
* @throws WalaException
* @throws CloneNotSupportedException
*/
public static void main(String[] args) throws IOException, IllegalArgumentException, CancelException, WalaException, CloneNotSupportedException {
// AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope(args[0], new FileProvider().getFile(""));
final AnalysisScope scope = AnalysisScopeReader.makeJavaBinaryAnalysisScope("/Users/scubafuchs/Documents/wala_workspace/HelloAndroid/simple_program.jar:/Users/scubafuchs/working/android-sdk-mac_x86-1.5_r1/platforms/android-1.1/android.jar", new FileProvider().getFile("bin/Java60RegressionExclusions.txt"));
ClassHierarchy cha = ClassHierarchy.make(scope);
AnalysisCache cache = new AnalysisCache();
IMethod m = cha.resolveMethod(StringStuff.makeMethodReference("adam.HelloWorld.main([Ljava/lang/String;)V"));
IMethod mfoo = cha.resolveMethod(StringStuff.makeMethodReference("adam.HelloWorld.foo(Ljava/util/LinkedList;)V"));
if (m == null) {
Assertions.UNREACHABLE();
}
SSAOptions optionsIR = new AnalysisOptions().getSSAOptions();
IR ir = cache.getSSACache().findOrCreateIR(m, Everywhere.EVERYWHERE, optionsIR);
if (ir == null) {
Assertions.UNREACHABLE();
}
Iterable<Entrypoint> entrypoints = Util.makeMainEntrypoints(scope, cha);
AnalysisOptions optionsCFG = new AnalysisOptions(scope, entrypoints);
LinkedList<Entrypoint> entries = new LinkedList<Entrypoint>();
for (Entrypoint entry: entrypoints) {
entries.add(entry);
}
entries.add(new DefaultEntrypoint(mfoo, cha));
optionsCFG.setEntrypoints(entries);
SSAPropagationCallGraphBuilder cgb = Util.makeVanillaZeroOneCFABuilder(optionsCFG, cache, cha, scope);
CallGraph cg = cgb.makeCallGraph(optionsCFG);
PointerAnalysis pa = cgb.getPointerAnalysis();
OrdinalSetMapping<InstanceKey> keyMapping = pa.getInstanceKeyMapping();
for (int i = 0; i < keyMapping.getSize(); i++) {
InstanceKey ik = keyMapping.getMappedObject(i);
if (ik instanceof AllocationSiteInNode) {
System.out.println(i + " -> " + ik);
}
}
InstanceKey newInMain = keyMapping.getMappedObject(13);
System.out.println("=======================");
System.out.println("Fields: " + newInMain.getConcreteType().getAllFields());
PointerKey pkNewInMain = new InstanceFieldKey(newInMain, newInMain.getConcreteType().getField(Atom.findOrCreateAsciiAtom("s")));
PointerKey pkBar = new StaticFieldKey(newInMain.getConcreteType().getField(Atom.findOrCreateAsciiAtom("bar")));
System.out.println("PK: " + pkNewInMain);
OrdinalSet<InstanceKey> keys = pa.getPointsToSet(pkNewInMain);
for (Iterator<InstanceKey> i = keys.iterator(); i.hasNext();) {
System.out.println("\t\t" + i.next());
}
System.out.println("PK: " + pkBar);
keys = pa.getPointsToSet(pkBar);
for (Iterator<InstanceKey> i = keys.iterator(); i.hasNext();) {
System.out.println("\t\t" + i.next());
}
play(cg, pa, cache);
}
private static void play(CallGraph cg, PointerAnalysis pa, AnalysisCache cache) throws WalaException, CancelException, CloneNotSupportedException {
Graph<CGNode> partialGraph = GraphSlicer.prune(cg, new Filter<CGNode>() {
public boolean accepts(CGNode o) {
return o.getMethod().getDeclaringClass().getClassLoader().getReference().equals(ClassLoaderReference.Application);
}
});
Collection<CGNode> nodes = new HashSet<CGNode>();
for(Iterator<CGNode> nIter = partialGraph.iterator(); nIter.hasNext();)
{
nodes.add(nIter.next());
}
PartialCallGraph pcg = PartialCallGraph.make(cg, cg.getEntrypointNodes(), nodes);
InterproceduralCFG ipcfg = new InterproceduralCFG(pcg);
runAnalysisCG(pcg, ipcfg, pa, cache);
}
private static void runAnalysisCG(PartialCallGraph pcg, InterproceduralCFG x, PointerAnalysis pa, AnalysisCache cache) throws CancelException, WalaException, CloneNotSupportedException {
final InterproceduralCFG cfg = x;
// final Hashtable<CGNode, Vector<Integer>> varMaps = new Hashtable<CGNode, Vector<Integer>>();
// final Vector<String> mapInv = new Vector<String>();
// int count = 0;
// for (Iterator<CGNode> i = cfg.getCallGraph().iterator(); i.hasNext();) {
// CGNode proc = i.next();
// varMaps.put(proc, new Vector<Integer>());
// for (int j = 1; j <= proc.getIR().getSymbolTable().getMaxValueNumber(); j++) {
// varMaps.get(proc).add(count++);
// mapInv.add(proc.getMethod() + " :v" + j);
// }
// }
// for (int k = 0; k < mapInv.size(); k++) {
// System.out.println(k + " => " + mapInv.get(k));
// }
final IFDSTaintDomain domain = new IFDSTaintDomain();
final ISupergraph<BasicBlockInContext<IExplodedBasicBlock>,CGNode> graph =
(ISupergraph) ICFGSupergraph.make(pcg, cache);
// pdfGraph(graph, "supergraph");
final IFlowFunctionMap<BasicBlockInContext<IExplodedBasicBlock>> functionMap =
new TaintTransferFunctions<IExplodedBasicBlock>(domain, graph, pa);
//new IFDSTaintFlowFunctionProvider(domain, graph, pa);
TabulationProblem<BasicBlockInContext<IExplodedBasicBlock>,CGNode,DomainElement> problem = new TabulationProblem<BasicBlockInContext<IExplodedBasicBlock>,CGNode,DomainElement>() {
public TabulationDomain<DomainElement, BasicBlockInContext<IExplodedBasicBlock>> getDomain() {
return domain;
}
public IFlowFunctionMap<BasicBlockInContext<IExplodedBasicBlock>> getFunctionMap() {
return functionMap;
}
public IMergeFunction getMergeFunction() {
return null;
}
public ISupergraph<BasicBlockInContext<IExplodedBasicBlock>, CGNode> getSupergraph() {
return graph;
}
public Collection<PathEdge<BasicBlockInContext<IExplodedBasicBlock>>> initialSeeds() {
LinkedList<PathEdge<BasicBlockInContext<IExplodedBasicBlock>>> list = new LinkedList<PathEdge<BasicBlockInContext<IExplodedBasicBlock>>>();
CGNode entryProc = cfg.getCallGraph().getEntrypointNodes().iterator().next();
BasicBlockInContext<IExplodedBasicBlock>[] entryBlocks = graph.getEntriesForProcedure(entryProc);
for(BasicBlockInContext<IExplodedBasicBlock> entryBlock: entryBlocks) {
for (int i = 0; i < entryProc.getIR().getNumberOfParameters(); i++) {
list.add(PathEdge.createPathEdge(entryBlock, 0, entryBlock, domain.getMappedIndex(new DomainElement(new LocalElement(i+1),null))));
}
}
return list;
}
};
TabulationSolver<BasicBlockInContext<IExplodedBasicBlock>,CGNode,DomainElement> solver = TabulationSolver.make(problem);
TabulationResult<BasicBlockInContext<IExplodedBasicBlock>,CGNode,DomainElement> result = solver.solve();
System.out.println("Result:\n" + result.toString());
System.out.println("Seeds: " + result.getSeeds());
}
}

View File

@ -1,82 +0,0 @@
/**
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@galois.com>, Rogan Creswick <creswick@galois.com>)
* Steve Suh <suhsteve@gmail.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
package org.scandroid;
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
public class TimedMonitor implements IProgressMonitor {
private final long deadline;
/**
* @param seconds The time limit, in seconds.
*/
public TimedMonitor(long seconds) {
deadline = System.currentTimeMillis() + (seconds * 1000L);
}
@Override
public void beginTask(String task, int totalWork) {
}
@Override
public boolean isCanceled() {
return (System.currentTimeMillis() > deadline);
}
@Override
public void done() {
}
@Override
public void worked(int units) {
}
@Override
public void subTask(String subTask) {
// TODO Auto-generated method stub
}
@Override
public void cancel() {
// TODO Auto-generated method stub
}
}

View File

@ -1,172 +0,0 @@
package org.scandroid;
/*
*
* Copyright (c) 2009-2012,
*
* Adam Fuchs <afuchs@cs.umd.edu>
* Avik Chaudhuri <avik@cs.umd.edu>
* Steve Suh <suhsteve@gmail.com>
*
* All rights reserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
*
* 1. Redistributions of source code must retain the above copyright notice,
* this list of conditions and the following disclaimer.
*
* 2. Redistributions in binary form must reproduce the above copyright notice,
* this list of conditions and the following disclaimer in the documentation
* and/or other materials provided with the distribution.
*
* 3. The names of the contributors may not be used to endorse or promote
* products derived from this software without specific prior written
* permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT OWNER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*
*
*/
import java.util.ArrayList;
import java.util.HashMap;
import java.util.Iterator;
import java.util.Map;
import java.util.Map.Entry;
import org.scandroid.prefixtransfer.InstanceKeySite;
import org.scandroid.prefixtransfer.PrefixTransferFunctionProvider;
import org.scandroid.prefixtransfer.PrefixVariable;
import org.scandroid.prefixtransfer.UriPrefixTransferGraph;
import org.scandroid.util.CGAnalysisContext;
import org.scandroid.util.EmptyProgressMonitor;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.dataflow.graph.DataflowSolver;
import com.ibm.wala.dataflow.graph.IKilldallFramework;
import com.ibm.wala.dataflow.graph.ITransferFunctionProvider;
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.ssa.analysis.IExplodedBasicBlock;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.CancelRuntimeException;
import com.ibm.wala.util.graph.Graph;
public class UriPrefixAnalysis {
private static final Logger logger = LoggerFactory.getLogger(UriPrefixAnalysis.class);
public static Map<InstanceKey,String> runAnalysis(CGAnalysisContext<IExplodedBasicBlock> analysisContext) throws CancelRuntimeException
{
return runAnalysisHelper(analysisContext.cg, analysisContext.pa);
}
public static ArrayList<InstanceKey> locateKeys(Map<InstanceKey,String> prefixes, String s) {
ArrayList<InstanceKey> keylist = new ArrayList<InstanceKey>();
for (Entry<InstanceKey,String> e : prefixes.entrySet()) {
if (e.getValue().contains(s))
keylist.add(e.getKey());//pa.getInstanceKeyMapping().getMappedIndex(e.getKey())
}
return keylist;
}
public static Map<InstanceKey,String> runAnalysisHelper(CallGraph cg, PointerAnalysis pa) throws CancelRuntimeException
{
logger.debug("*******************************************************");
logger.debug("* Prefix Analysis: Constructing Prefix Transfer Graph *");
final Graph<InstanceKeySite> g = new UriPrefixTransferGraph(pa);
logger.debug("* The Graph: *");
logger.debug("*******************************************************");
Iterator<InstanceKeySite> iksI = g.iterator();
while (iksI.hasNext()) {
InstanceKeySite iks = iksI.next();
logger.debug("# " + iks);
Iterator<InstanceKeySite> edgesI = g.getSuccNodes(iks);
while (edgesI.hasNext()) {
logger.debug("? \t -->" + edgesI.next());
}
}
final PrefixTransferFunctionProvider tfp = new PrefixTransferFunctionProvider();
IKilldallFramework<InstanceKeySite, PrefixVariable> framework = new IKilldallFramework<InstanceKeySite, PrefixVariable>()
{
public Graph<InstanceKeySite> getFlowGraph() {
return g;
}
public ITransferFunctionProvider<InstanceKeySite, PrefixVariable> getTransferFunctionProvider() {
return tfp;
}
};
DataflowSolver<InstanceKeySite, PrefixVariable> dfs = new DataflowSolver<InstanceKeySite, PrefixVariable>(framework){
@Override
protected PrefixVariable makeEdgeVariable(InstanceKeySite src,
InstanceKeySite dst) {
return new PrefixVariable(){};
}
@Override
protected PrefixVariable makeNodeVariable(InstanceKeySite n,
boolean IN) {
// TODO Auto-generated method stub
PrefixVariable var = new PrefixVariable(){};
// if (n instanceof StringBuilderToStringInstanceKeySite) var.setOrderNumber(0);
// else var.setOrderNumber(10);
// var.add(3);
return var;
}
@Override
protected PrefixVariable[] makeStmtRHS(int size) {
return new PrefixVariable[size];
}
};
logger.debug("\n**************************************************");
logger.debug("* Running Analysis");
try {
dfs.solve(new EmptyProgressMonitor());
} catch (CancelException e) {
throw new CancelRuntimeException(e);
}
Map<InstanceKey,String> prefixes = new HashMap<InstanceKey,String>();
iksI = g.iterator();
while (iksI.hasNext()) {
InstanceKeySite iks = iksI.next();
prefixes.put(pa.getInstanceKeyMapping().getMappedObject(iks.instanceID()), dfs.getOut(iks).knownPrefixes.get(iks.instanceID()));
// logger.debug(iks + " ~> " + dfs.getOut(iks));
}
// logger.debug("\nLocalPointerKeys that point to String constants: \n" + stringConstants);
for (Entry<InstanceKey,String> e : prefixes.entrySet()) {
logger.debug(pa.getInstanceKeyMapping().getMappedIndex(e.getKey()) + "\t~> " + e.getValue());
}
// TODO: populate prefixes
return prefixes;
}
}

View File

@ -67,6 +67,7 @@ import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.Module;
import com.ibm.wala.dalvik.classLoader.DexFileModule;
import com.ibm.wala.dalvik.dex.util.config.DexAnalysisScopeReader;
import com.ibm.wala.dalvik.util.AndroidAnalysisScope;
import com.ibm.wala.ipa.callgraph.AnalysisCache;
import com.ibm.wala.ipa.callgraph.AnalysisOptions;
import com.ibm.wala.ipa.callgraph.AnalysisScope;