cleanup in com.ibm.wala.dalvik project
This commit is contained in:
parent
77275aad73
commit
d0d2609bf3
|
@ -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",
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -1,4 +1,4 @@
|
|||
package org.scandroid.util;
|
||||
package com.ibm.wala.dalvik.util;
|
||||
|
||||
import java.io.File;
|
||||
import java.io.IOException;
|
|
@ -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));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
|
||||
}
|
|
@ -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
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
|
|
Loading…
Reference in New Issue