merge of java 7 changes.

fixes for Dalvik commit.
This commit is contained in:
Julian Dolby 2014-10-06 17:41:58 -04:00
parent 6c47da8091
commit 14c9c96515
78 changed files with 23 additions and 9882 deletions

View File

@ -29,6 +29,14 @@ java_runtime_dir = Your location
#####
#output_dir = Your location
################### Mandatory settings for Android (Dalvik) ####################
# location of runtime jar
#android_rt_jar = .../android-sdk-macosx/platforms/android-20/android.jar
# location of jar-to-dex tool
#android_dx_tool = .../android-sdk-macosx/build-tools/20.0.0/dx
############################ Optional settings ################################
#####
@ -52,4 +60,9 @@ java_runtime_dir = Your location
# Default value: wala_report.txt [Non absolute path are relative to 'output.dir' variable value]
# Info: Can be absolute or relative.
#####
#WALA_report = Your file name
#WALA_report = Your file name
#
# the location of DroidBench for Android tests
#
#droidbench.root = Your location

View File

@ -16,19 +16,19 @@ import com.ibm.wala.shrikeCT.BootstrapMethodsReader.BootstrapMethod;
public class SSAInvokeDynamicInstruction extends SSAInvokeInstruction {
private final BootstrapMethod bootstrap;
public SSAInvokeDynamicInstruction(int result, int[] params, int exception, CallSiteReference site, BootstrapMethod bootstrap) {
super(result, params, exception, site);
public SSAInvokeDynamicInstruction(int iindex, int result, int[] params, int exception, CallSiteReference site, BootstrapMethod bootstrap) {
super(iindex, result, params, exception, site);
this.bootstrap = bootstrap;
}
public SSAInvokeDynamicInstruction(int[] params, int exception, CallSiteReference site, BootstrapMethod bootstrap) {
super(params, exception, site);
public SSAInvokeDynamicInstruction(int iindex, int[] params, int exception, CallSiteReference site, BootstrapMethod bootstrap) {
super(iindex, params, exception, site);
this.bootstrap = bootstrap;
}
@Override
public SSAInstruction copyForSSA(SSAInstructionFactory insts, int[] defs, int[] uses) {
return insts.InvokeInstruction(defs == null || result == -1 ? result : defs[0], uses == null ? params : uses,
return new SSAInvokeDynamicInstruction(iindex, defs == null || result == -1 ? result : defs[0], uses == null ? params : uses,
defs == null ? exception : defs[result == -1 ? 0 : 1], site, bootstrap);
}

View File

@ -33,6 +33,7 @@ import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.properties.WalaProperties;
import com.ibm.wala.shrikeCT.InvalidClassFileException;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.MethodReference;
@ -73,7 +74,7 @@ public class DroidBenchCGTest extends DalvikCallGraphTestBase {
uncalledFunctions.put("Reflection_Reflection1.apk", x);
}
private static final String droidBenchRoot = System.getProperty("droidbench.root");
private static final String droidBenchRoot = walaProperties.getProperty("droidbench.root");
private void assertUserCodeReachable(CallGraph cg) throws InvalidClassFileException {
for(Iterator<IClass> clss = cg.getClassHierarchy().getLoader(ClassLoaderReference.Application).iterateAllClasses();

View File

@ -14,12 +14,6 @@
<property name="compilerArg" value=""/>
<property name="javacSource" value="1.5"/>
<property name="javacTarget" value="1.5"/>
<!-- This property has been updated to correspond to the paths used by the latest Java update
on Mac OS X 10.6 (Java version 1.6.0_22). If you are not using this version of Mac OS X or Java,
try changing the value of the property to "${java.home}/../../../Classes" -->
<condition property="dir_bootclasspath" value="${java.home}/../Classes">
<os family="mac"/>
</condition>
<property name="dir_bootclasspath" value="${java.home}/lib"/>
<path id="path_bootclasspath">
<fileset dir="${dir_bootclasspath}">

View File

@ -1,72 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.domain;
import java.util.HashSet;
import java.util.Set;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
public abstract class CodeElement {
/* For a given value number, and enclosing call graph node, yield
* the set of all CodeElements that that it may refer to (i.e., the
* associated local variable and any instances it may refer to). */
public static Set<CodeElement> valueElements(PointerAnalysis<InstanceKey> pa, CGNode node, int valueNumber) {
//System.out.println("ValueNumber: " + valueNumber + ", Node: " + node.getMethod().getSignature());
Set<CodeElement> elements = new HashSet<CodeElement>();
elements.add(new LocalElement(valueNumber));
// PointerKey pk = new LocalPointerKey(node, valueNumber);
// OrdinalSet<InstanceKey> m = pa.getPointsToSet(pk);
// if(m != null) {
// for(Iterator<InstanceKey> keyIter = m.iterator();keyIter.hasNext();) {
// elements.add(new InstanceKeyElement(keyIter.next()));
// }
// }
return elements;
}
@Override
public abstract boolean equals(Object obj);
@Override
public abstract int hashCode();
}

View File

@ -1,121 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.domain;
import org.scandroid.flow.types.FlowType;
@SuppressWarnings("rawtypes")
public class DomainElement {
// the code element in question
// alternate framing: the /current/ fact about the element
public final CodeElement codeElement;
// the taint (probably from some other point in the code) that affects the
// code element in question
// alternate framing: the /initial/ fact about the element
public final FlowType taintSource;
public DomainElement(CodeElement codeElement, FlowType taintSource) {
this.codeElement = codeElement;
this.taintSource = taintSource;
}
/*
@Override
public boolean equals(Object other) {
if (other == null || !(other instanceof DomainElement))
return false;
DomainElement otherDE = (DomainElement) other;
if (taintSource != null) {
return codeElement.equals(otherDE.codeElement)
&& taintSource.equals(otherDE.taintSource);
}
return codeElement.equals(otherDE.codeElement)
&& otherDE.taintSource == null;
}
@Override
public int hashCode() {
if (taintSource == null)
return codeElement.hashCode();
return codeElement.hashCode() ^ taintSource.hashCode();
}
*/
public String toString() {
return codeElement.toString() + ", " + taintSource;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((codeElement == null) ? 0 : codeElement.hashCode());
result = prime * result
+ ((taintSource == null) ? 0 : taintSource.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
DomainElement other = (DomainElement) obj;
if (codeElement == null) {
if (other.codeElement != null)
return false;
} else if (!codeElement.equals(other.codeElement))
return false;
if (taintSource == null) {
if (other.taintSource != null)
return false;
} else if (!taintSource.equals(other.taintSource))
return false;
return true;
}
}

View File

@ -1,90 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.domain;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.types.FieldReference;
public class FieldElement extends CodeElement {
private FieldReference fieldRef;
private InstanceKey object;
// private TypeReference object;
public FieldElement(InstanceKey object, FieldReference fieldRef)
{
this.fieldRef = fieldRef;
this.object = object;
}
// public FieldElement(TypeReference object, String fieldname)
// {
// this.fieldname = fieldname;
// this.object = object;
// }
public InstanceKey getIK() {
return object;
}
public FieldReference getRef() {
return fieldRef;
}
@Override
public boolean equals(Object other)
{
if(other != null && other instanceof FieldElement)
{
FieldElement otherFE = (FieldElement)other;
return object.equals(otherFE.object) && fieldRef.equals(otherFE.fieldRef);
}
return false;
}
@Override
public int hashCode()
{
return object.hashCode() * fieldRef.hashCode();
}
@Override
public String toString()
{
return "FieldElement("+fieldRef.getSignature()+","+object+")";
}
}

View File

@ -1,138 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.domain;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.HashSet;
import java.util.Iterator;
import java.util.Map;
import java.util.Set;
import com.ibm.wala.dataflow.IFDS.PathEdge;
import com.ibm.wala.dataflow.IFDS.TabulationDomain;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
public class IFDSTaintDomain <E extends ISSABasicBlock>
implements TabulationDomain<DomainElement, BasicBlockInContext<E>> {
private Map<DomainElement, Integer> table = new HashMap<DomainElement, Integer>();
private ArrayList<DomainElement> objects = new ArrayList<DomainElement>();
private Map<CodeElement, Set<DomainElement>> elementIndex = new HashMap<CodeElement, Set<DomainElement>>();
Set<DomainElement> emptySet = new HashSet<DomainElement>();
public Set<DomainElement> getPossibleElements(CodeElement codeElement)
{
Set<DomainElement> elts = elementIndex.get(codeElement);
if(elts != null)
return elts;
return emptySet;
}
private void index(DomainElement e)
{
Set<DomainElement> elements = elementIndex.get(e.codeElement);
if(elements == null)
{
elements = new HashSet<DomainElement>();
elementIndex.put(e.codeElement, elements);
}
elements.add(e);
}
public int add(DomainElement o) {
Integer i = table.get(o);
if(i == null)
{
objects.add(o);
i = table.size() + 1;
table.put(o, i);
//System.out.println("Adding domain element "+i+": "+o);
}
index(o);
return i;
}
public synchronized int getMappedIndex(final Object o) {
if (!(o instanceof DomainElement)) {
throw new IllegalArgumentException(o.getClass().getCanonicalName());
}
final DomainElement de = (DomainElement) o;
final Integer i = table.get(de);
return (i == null ? add(de) : i);
}
public boolean hasPriorityOver(
PathEdge<BasicBlockInContext<E>> p1,
PathEdge<BasicBlockInContext<E>> p2) {
return false;
}
public DomainElement getMappedObject(int n) {
if(n > 0 && n <= objects.size())
return objects.get(n - 1);
return null;
}
public int getMaximumIndex() {
return objects.size();
}
public int getSize() {
return objects.size()+1;
}
public boolean hasMappedIndex(DomainElement o) {
return table.keySet().contains(o);
}
public Iterator<DomainElement> iterator() {
return table.keySet().iterator();
}
public Set<CodeElement> codeElements () {
return elementIndex.keySet();
}
}

View File

@ -1,72 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.domain;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
public class InstanceKeyElement extends CodeElement {
private InstanceKey ik;
public InstanceKeyElement(InstanceKey ik)
{
this.ik = ik;
}
@Override
public boolean equals(Object other)
{
if(other != null && other instanceof InstanceKeyElement)
return ((InstanceKeyElement)other).ik.equals(this.ik);
return false;
}
@Override
public int hashCode()
{
return ik.hashCode();
}
public String toString()
{
return "InstanceKeyElement("+ik+")";
}
public InstanceKey getInstanceKey() {
return ik;
}
}

View File

@ -1,81 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.domain;
public final class LocalElement extends CodeElement {
private final int id;
public LocalElement(int id)
{
this.id = id;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + id;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
LocalElement other = (LocalElement) obj;
if (id != other.id)
return false;
return true;
}
@Override
public String toString()
{
return "LocalElement("+id+")";
}
}

View File

@ -1,60 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.domain;
public class ReturnElement extends CodeElement {
@Override
public boolean equals(Object other)
{
return other != null && other instanceof ReturnElement;
}
@Override
public int hashCode()
{
return 1;
}
@Override
public String toString()
{
return "ReturnElement()";
}
}

View File

@ -1,80 +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.domain;
import com.ibm.wala.types.FieldReference;
public class StaticFieldElement extends CodeElement {
private final FieldReference fieldRef;
public StaticFieldElement(FieldReference fieldRef) {
this.fieldRef = fieldRef;
}
public FieldReference getRef() {
return fieldRef;
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result
+ ((fieldRef == null) ? 0 : fieldRef.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
StaticFieldElement other = (StaticFieldElement) obj;
if (fieldRef == null) {
if (other.fieldRef != null)
return false;
} else if (!fieldRef.equals(other.fieldRef))
return false;
return true;
}
}

View File

@ -1,142 +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.flow.functions;
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.domain.LocalElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
/**
* @author creswick
* @author acfoltzer
*
*/
public class CallFlowFunction<E extends ISSABasicBlock> implements
IUnaryFlowFunction {
private static final Logger logger = LoggerFactory
.getLogger(CallFlowFunction.class);
/**
* A map from the code elements of actual parameters, to the set of code
* elements for formal parameters
*/
private final Map<CodeElement, Set<CodeElement>> paramArgsMap;
private final IFDSTaintDomain<E> domain;
public CallFlowFunction(IFDSTaintDomain<E> domain,
List<CodeElement> actualParams) {
this.domain = domain;
final int numParams = actualParams.size();
this.paramArgsMap = Maps.newHashMapWithExpectedSize(numParams);
for (int i = 0; i < numParams; i++) {
// add a mapping for each parameter
final CodeElement actual = actualParams.get(i);
if (!(actual instanceof LocalElement)) {
logger.warn("non-local code element in actual params list");
}
final CodeElement formal = new LocalElement(i + 1); // +1 for SSA
Set<CodeElement> existingFormals = paramArgsMap.get(actual);
if (null == existingFormals) {
existingFormals = Sets.newHashSetWithExpectedSize(numParams);
}
existingFormals.add(formal);
paramArgsMap.put(actual, existingFormals);
}
}
/*
* (non-Javadoc)
*
* @see com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction#getTargets(int)
*/
@Override
public IntSet getTargets(int d1) {
if (0 == d1) {
return TaintTransferFunctions.ZERO_SET;
}
DomainElement de = domain.getMappedObject(d1);
MutableSparseIntSet set = MutableSparseIntSet.makeEmpty();
/*
* We're in the situation of calling a function:
*
* f(x, y, z)
*
* And determining how taints flow from that call site to the entry of
* the function
*
* ... f(X x, Y y, Z z) { ... }
*
* Our goals are twofold: 1. Propagate taints from the actual parameter
* x to the formal parameter x 2. Exclude any other non-local
* information from propagating to callee
*
* Since we're unioning the result of this with the
* GlobalIdentityFunction, we don't have to worry about 2 for this
* IntSet.
*/
final Set<CodeElement> formals = paramArgsMap.get(de.codeElement);
if (null != formals) {
for (CodeElement formal : formals) {
set.add(domain.getMappedIndex(new DomainElement(formal,
de.taintSource)));
}
}
return set;
}
}

View File

@ -1,85 +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.flow.functions;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.flow.types.FlowType;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
public final class CallNoneToReturnFunction <E extends ISSABasicBlock> implements IUnaryFlowFunction {
private IFDSTaintDomain<E> domain;
public CallNoneToReturnFunction(IFDSTaintDomain<E> domain) {
this.domain = domain;
}
@Override
public IntSet getTargets(int d) {
if (0 == d) {
return TaintTransferFunctions.ZERO_SET;
}
MutableSparseIntSet set = MutableSparseIntSet.makeEmpty();
// TODO: this is questionable
// We don't know anything about the function called,
// so we have to make some assumptions. The safest assumption
// is that everything goes to everything:
// this effectively taints everything in the heap that we've seen before.
DomainElement de = domain.getMappedObject(d);
@SuppressWarnings("unchecked")
FlowType<E> taint = de.taintSource;
for (CodeElement ce : domain.codeElements() ){
int elt = domain.getMappedIndex(new DomainElement(ce, taint));
set.add(elt);
}
return set;
}
}

View File

@ -1,86 +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.flow.functions;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.domain.LocalElement;
import org.scandroid.domain.ReturnElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
public class CallToReturnFunction <E extends ISSABasicBlock>
implements IUnaryFlowFunction {
private static final Logger logger = LoggerFactory.getLogger(CallToReturnFunction.class);
private IFDSTaintDomain<E> domain;
public CallToReturnFunction(IFDSTaintDomain<E> domain) {
this.domain = domain;
}
@Override
public IntSet getTargets(int d) {
MutableSparseIntSet set = MutableSparseIntSet.makeEmpty();
// Local elements (and the 0 element) flow through CallToReturn edges,
// but nothing else does (everything else is subject to whatever
// happened in the invoked function)
if (0 == d) {
set.add(d);
} else {
DomainElement de = domain.getMappedObject(d);
if (de.codeElement instanceof LocalElement || de.codeElement instanceof ReturnElement) {
set.add(d);
} else {
logger.trace("throwing away {}", de);
}
}
return set;
}
}

View File

@ -1,80 +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.flow.functions;
import java.util.Set;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
import com.ibm.wala.util.intset.SparseIntSet;
/**
* A flow function which maps the zero fact to a set of new dataflow facts,
* essentially introducing them from nothing. Identity for all other facts.
*
* @author acfoltzer
*
*/
public class ConstantFlowFunction <E extends ISSABasicBlock> implements IUnaryFlowFunction {
private final MutableSparseIntSet result;
public ConstantFlowFunction(IFDSTaintDomain<E> domain, Set<DomainElement> elts) {
result = MutableSparseIntSet.make(TaintTransferFunctions.ZERO_SET);
for (DomainElement de : elts) {
result.add(domain.getMappedIndex(de));
}
}
/*
* (non-Javadoc)
*
* @see com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction#getTargets(int)
*/
@Override
public IntSet getTargets(int d1) {
return 0 == d1 ? result : SparseIntSet.singleton(d1);
}
}

View File

@ -1,88 +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.flow.functions;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.domain.LocalElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.SparseIntSet;
/**
* Flow function that only permits globals - and the zero element - to flow through
*
* @author creswick
*
*/
public class GlobalIdentityFunction <E extends ISSABasicBlock>
implements IUnaryFlowFunction {
private static final Logger logger = LoggerFactory.getLogger(GlobalIdentityFunction.class);
private final IFDSTaintDomain<E> domain;
public GlobalIdentityFunction(IFDSTaintDomain<E> domain) {
this.domain = domain;
}
/* (non-Javadoc)
* @see com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction#getTargets(int)
*/
@Override
public IntSet getTargets(int d1) {
if (0 == d1) {
return TaintTransferFunctions.ZERO_SET;
}
DomainElement de = domain.getMappedObject(d1);
if( de.codeElement instanceof LocalElement ) {
// if the query domain element is a local, then it is /not/ passed through.
logger.trace("taking {} to emptyset", de);
return TaintTransferFunctions.EMPTY_SET;
} else {
return SparseIntSet.singleton(d1);
}
}
}

View File

@ -1,128 +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.flow.functions;
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.domain.InstanceKeyElement;
import org.scandroid.domain.LocalElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
/**
* Propagates heap information from InstanceKeys to the LocalElements that point
* to those keys
*
* @author acfoltzer
*
* @param <E>
*/
public class GlobalReturnToNodeFunction<E extends ISSABasicBlock> implements
IUnaryFlowFunction {
private static final Logger logger = LoggerFactory
.getLogger(GlobalReturnToNodeFunction.class);
private final IFDSTaintDomain<E> domain;
private final Map<InstanceKey, Set<CodeElement>> ikMap;
public GlobalReturnToNodeFunction(IFDSTaintDomain<E> domain,
PointerAnalysis<InstanceKey> pa, CGNode node) {
this.domain = domain;
this.ikMap = Maps.newHashMap();
for (PointerKey pk : pa.getPointerKeys()) {
if (!(pk instanceof LocalPointerKey)) {
continue;
}
LocalPointerKey lpk = (LocalPointerKey) pk;
if (!lpk.getNode().equals(node)) {
continue;
}
for (InstanceKey ik : pa.getPointsToSet(lpk)) {
Set<CodeElement> elts = ikMap.get(ik);
if (null == elts) {
elts = Sets.newHashSet();
ikMap.put(ik, elts);
}
elts.add(new LocalElement(lpk.getValueNumber()));
}
}
}
@Override
public IntSet getTargets(int d) {
MutableSparseIntSet set = MutableSparseIntSet.makeEmpty();
if (0 == d) {
set.add(d);
} else {
DomainElement de = domain.getMappedObject(d);
if (de.codeElement instanceof InstanceKeyElement) {
InstanceKey ik = ((InstanceKeyElement) de.codeElement)
.getInstanceKey();
Set<CodeElement> elts = ikMap.get(ik);
if (null != elts) {
for (CodeElement elt : elts) {
set.add(domain.getMappedIndex(new DomainElement(elt,
de.taintSource)));
}
}
} else {
logger.debug("throwing away {}", de);
}
}
return set;
}
}

View File

@ -1,106 +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.flow.functions;
import org.scandroid.domain.IFDSTaintDomain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.dataflow.IFDS.IFlowFunction;
import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap;
import com.ibm.wala.dataflow.IFDS.IReversibleFlowFunction;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.dataflow.IFDS.IdentityFlowFunction;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.SparseIntSet;
public class IDTransferFunctions <E extends ISSABasicBlock> implements
IFlowFunctionMap<BasicBlockInContext<E>> {
@SuppressWarnings("unused")
private static final Logger logger =
LoggerFactory.getLogger(IDTransferFunctions.class);
public static final IntSet EMPTY_SET = new SparseIntSet();
public static final IntSet ZERO_SET = SparseIntSet.singleton(0);
private static final IReversibleFlowFunction IDENTITY_FN = new IdentityFlowFunction();
public IDTransferFunctions(IFDSTaintDomain<E> domain,
ISupergraph<BasicBlockInContext<E>, CGNode> graph,
PointerAnalysis<InstanceKey> pa) {
}
@Override
public IUnaryFlowFunction getNormalFlowFunction(BasicBlockInContext<E> src,
BasicBlockInContext<E> dest) {
return IDENTITY_FN;
}
@Override
public IUnaryFlowFunction getCallFlowFunction(BasicBlockInContext<E> src,
BasicBlockInContext<E> dest, BasicBlockInContext<E> ret) {
return IDENTITY_FN;
}
@Override
public IFlowFunction getReturnFlowFunction(BasicBlockInContext<E> call,
BasicBlockInContext<E> src, BasicBlockInContext<E> dest) {
return IDENTITY_FN;
}
@Override
public IUnaryFlowFunction getCallToReturnFlowFunction(
BasicBlockInContext<E> src, BasicBlockInContext<E> dest) {
return IDENTITY_FN;
}
@Override
public IUnaryFlowFunction getCallNoneToReturnFlowFunction(
BasicBlockInContext<E> src, BasicBlockInContext<E> dest) {
return IDENTITY_FN;
}
}

View File

@ -1,597 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.flow.functions;
import java.util.Collection;
import java.util.HashSet;
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.FieldElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.domain.InstanceKeyElement;
import org.scandroid.domain.LocalElement;
import org.scandroid.domain.ReturnElement;
import org.scandroid.flow.types.FlowType;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Sets;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dataflow.IFDS.IFlowFunction;
import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.LocalPointerKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.callgraph.propagation.StaticFieldKey;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.intset.BitVectorIntSet;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableIntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
import com.ibm.wala.util.intset.OrdinalSet;
/**
* @deprecated Replaced by TaintTransferFunctions.
*/
@Deprecated
public class IFDSTaintFlowFunctionProvider<E extends ISSABasicBlock>
implements IFlowFunctionMap<BasicBlockInContext<E>> {
private final IFDSTaintDomain<E> domain;
private final ISupergraph<BasicBlockInContext<E>,CGNode> graph;
private final PointerAnalysis<InstanceKey> pa;
public IFDSTaintFlowFunctionProvider(IFDSTaintDomain<E> domain,
ISupergraph<BasicBlockInContext<E>, CGNode> graph,
PointerAnalysis<InstanceKey> pa)
{
this.domain = domain;
this.graph = graph;
this.pa = pa;
}
// instruction has a valid def set
private static boolean inFlow(SSAInstruction instruction) {
return (instruction instanceof SSAArrayLoadInstruction) ||
(instruction instanceof SSAGetInstruction);
}
// instruction's def is getUse(0)
private static boolean outFlow(SSAInstruction instruction) {
return (instruction instanceof SSAArrayStoreInstruction) ||
(instruction instanceof SSAPutInstruction) ||
(instruction instanceof SSAInvokeInstruction);
}
// instruction is a return instruction
private static boolean returnFlow(SSAInstruction instruction) {
return (instruction instanceof SSAReturnInstruction);
}
private static class UseDefSetPair
{
public Set<CodeElement> uses = Sets.newHashSet();
public Set<CodeElement> defs = Sets.newHashSet();
}
private class DefUse implements IUnaryFlowFunction {
private final List<UseDefSetPair> useToDefList = Lists.newArrayList();
private final BasicBlockInContext<E> bb;
public DefUse(final BasicBlockInContext<E> inBlock) {
this.bb = inBlock;
for (SSAInstruction instruction : bb) {
handleInstruction(instruction);
}
}
private void handleInstruction(SSAInstruction instruction) {
// System.out.println("handle instruction: "+instruction);
UseDefSetPair p = new UseDefSetPair();
boolean thisToResult = false;
if(instruction instanceof SSAInvokeInstruction)
{
thisToResult = handleInvokeInstruction(instruction, p);
}
if (thisToResult) {
useToDefList.add(p);
p = new UseDefSetPair();
}
IClassHierarchy ch = bb.getNode().getClassHierarchy();
if (inFlow(instruction)) {
handleInflowInstruction(instruction, p, ch);
}
else if (outFlow(instruction)) {
handleOutflowInstruction(instruction, p, ch);
}
else if(returnFlow(instruction))
{
handleReturnFlowInstruction(instruction, p);
}
else
{
for (int i = 0; i < instruction.getNumberOfUses(); i++) {
p.uses.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(i)));
}
for (int j = 0; j < instruction.getNumberOfDefs(); j++) {
p.defs.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getDef(j)));
}
}
useToDefList.add(p);
}
private void handleReturnFlowInstruction(SSAInstruction instruction,
UseDefSetPair p) {
SSAReturnInstruction retInst = (SSAReturnInstruction)instruction;
if(retInst.getNumberOfUses() > 0)
{
/* TODO: why not add instance keys, too? */
for(int i = 0; i < instruction.getNumberOfUses(); i++)
{
//p.uses.add(new LocalElement(instruction.getUse(i)));
p.uses.addAll(
CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(i)));
}
p.defs.add(new ReturnElement());
}
}
private boolean handleInvokeInstruction(SSAInstruction instruction,
UseDefSetPair p) {
boolean thisToResult;
SSAInvokeInstruction invInst = (SSAInvokeInstruction)instruction;
if(!invInst.isSpecial() && !invInst.isStatic() && instruction.getNumberOfDefs() > 0)
{
//System.out.println("adding receiver flow in "+this+" for "+invInst);
//System.out.println("\tadding local element "+invInst.getReceiver());
//getReceiver() == getUse(0) == param[0] == this
p.uses.addAll(CodeElement.valueElements(pa, bb.getNode(), invInst.getReceiver()));
for(int i = 0; i < invInst.getNumberOfDefs(); i++)
{
//System.out.println("\tadding def local element "+invInst.getDef(i));
//return valuenumber of invoke instruction
p.defs.addAll(CodeElement.valueElements(pa, bb.getNode(), invInst.getDef(i)));
}
}
thisToResult = true;
return thisToResult;
}
private void handleInflowInstruction(SSAInstruction instruction,
UseDefSetPair p, IClassHierarchy ch) {
if (instruction instanceof SSAGetInstruction) {
handleInflowGetInstruction(instruction, p, ch);
}
else if (instruction instanceof SSAArrayLoadInstruction){
handleInflowArrayLoadInstruction(instruction, p);
}
}
private void handleOutflowInstruction(SSAInstruction instruction,
UseDefSetPair p, IClassHierarchy ch) {
if (instruction instanceof SSAPutInstruction) {
handleOutflowPutInstruction(instruction, p, ch);
}
else if (instruction instanceof SSAArrayStoreInstruction){
handleOutflowArrayStoreInstruction(instruction, p);
}
else if (instruction instanceof SSAInvokeInstruction){
handleOutflowInvokeInstruction(instruction, p);
}
}
private void handleOutflowInvokeInstruction(SSAInstruction instruction,
UseDefSetPair p) {
MethodReference targetMethod = ((SSAInvokeInstruction) instruction).getCallSite().getDeclaredTarget();
if (methodExcluded(targetMethod)) {
// TODO make all parameters flow into all other
// parameters, which could happen in the static case as well.
if (!((SSAInvokeInstruction) instruction).isStatic()) {
// These loops cause all parameters flow into the
// 'this' param (due to instruction.getUse(0))
for (int i = 1; i < instruction.getNumberOfUses(); i++) {
p.uses.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(i)));
}
if (instruction.getNumberOfUses() > 0) {
p.defs.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(0)));
}
}
}
}
private void handleOutflowArrayStoreInstruction(
SSAInstruction instruction, UseDefSetPair p) {
p.uses.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(2)));
p.defs.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(0)));
}
private void handleOutflowPutInstruction(SSAInstruction instruction,
UseDefSetPair p, IClassHierarchy ch) {
SSAPutInstruction pi = (SSAPutInstruction)instruction;
PointerKey pk;
Set<CodeElement> elements = Sets.newHashSet();
if (pi.isStatic()) {
p.uses.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(0)));
FieldReference declaredField = pi.getDeclaredField();
IField staticField = getStaticIField(ch, declaredField);
if (staticField == null) {
pk = null;
} else {
pk = new StaticFieldKey(staticField);
}
} else {
p.uses.addAll(
CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(1)));
// this value number seems to be the object referenced in this instruction (?)
int valueNumber = instruction.getUse(0);
pk = new LocalPointerKey(bb.getNode(), valueNumber);
//MyLogger.log(LogLevel.DEBUG, " instruction: "+instruction);
// add the object that holds the field that was modified
// to the list of things tainted by this flow:
p.defs.addAll(CodeElement.valueElements(pa, bb.getNode(), valueNumber));
}
// now add the field keys to the defs list so that they
// are also tainted:
if (pk!=null) {
OrdinalSet<InstanceKey> m = pa.getPointsToSet(pk);
if (m != null) {
for (InstanceKey instanceKey : m) {
elements.add(new FieldElement(instanceKey, pi.getDeclaredField()));
elements.add(new InstanceKeyElement(instanceKey));
}
}
p.defs.addAll(elements);
}
}
private void handleInflowArrayLoadInstruction(
SSAInstruction instruction, UseDefSetPair p) {
p.uses.addAll(CodeElement.valueElements(pa, bb.getNode(), instruction.getUse(0)));
p.defs.addAll(CodeElement.valueElements(pa, bb.getNode(),instruction.getDef()));
}
private void handleInflowGetInstruction(SSAInstruction instruction,
UseDefSetPair p, IClassHierarchy ch) {
SSAGetInstruction gi = (SSAGetInstruction)instruction;
PointerKey pk;
FieldReference declaredField = gi.getDeclaredField();
if ( gi.isStatic()) {
IField staticField =
getStaticIField(ch, declaredField);
if (staticField == null) {
pk = null;
} else {
pk = new StaticFieldKey(staticField);
}
} else {
int valueNumber = instruction.getUse(0);
pk = new LocalPointerKey(bb.getNode(), valueNumber);
}
if (pk!=null) {
Set<CodeElement> elements = Sets.newHashSet();
OrdinalSet<InstanceKey> m = pa.getPointsToSet(pk);
if(m != null) {
for (InstanceKey instanceKey : m) {
elements.add(new FieldElement(instanceKey, declaredField));
elements.add(new InstanceKeyElement(instanceKey));
}
}
p.uses.addAll(elements);
//getinstruction only has 1 def
p.defs.add(new LocalElement(instruction.getDef(0)));
}
}
/**
* Determines if the provide method is in the exclusions by checking the supergraph.
* @param method
* @return True if the method can not be found in the supergraph.
*/
private boolean methodExcluded(MethodReference method) {
Collection<IMethod> iMethods = pa.getClassHierarchy().getPossibleTargets(method);
return 0 == iMethods.size();
}
private IField getStaticIField(IClassHierarchy ch,
FieldReference declaredField) {
TypeReference staticTypeRef = declaredField.getDeclaringClass();
IClass staticClass = ch.lookupClass(staticTypeRef);
//referring to a static field which we don't have loaded in the class hierarchy
//possibly ignored in the exclusions file or just not included in the scope
if (staticClass == null)
return null;
IField staticField =
staticClass.getField(declaredField.getName());
return staticField;
}
private void addTargets(CodeElement d1, MutableIntSet set, FlowType<E> taintType)
{
//System.out.println(this.toString()+".addTargets("+d1+"...)");
for(UseDefSetPair p: useToDefList)
{
if(p.uses.contains(d1))
{
//System.out.println("\t\tfound pair that uses "+d1);
for(CodeElement i:p.defs)
{
//System.out.println("\t\tadding outflow "+i);
set.add(domain.getMappedIndex(new DomainElement(i,taintType)));
}
}
}
}
@SuppressWarnings("unchecked")
public IntSet getTargets(int d1) {
//System.out.println(this.toString()+".getTargets("+d1+") "+bb);
//BitVectorIntSet set = new BitVectorIntSet();
MutableSparseIntSet set = MutableSparseIntSet.makeEmpty();
set.add(d1);
DomainElement de = domain.getMappedObject(d1);
if (de != null) {
addTargets(de.codeElement, set, de.taintSource);
}
return set;
}
}
public IUnaryFlowFunction getCallFlowFunction(
BasicBlockInContext<E> src,
BasicBlockInContext<E> dest,
BasicBlockInContext<E> ret) {
assert graph.isCall(src);
final SSAInvokeInstruction instruction = (SSAInvokeInstruction) src.getLastInstruction();
// String signature = dest.getMethod().getSignature();
// if ( dest.getMethod().isSynthetic() ) {
// System.out.println("Synthetic: "+signature);
// } else {
// System.err.println(signature);
// }
// if ( LoaderUtils.fromLoader(src.getNode(), ClassLoaderReference.Application)
// && LoaderUtils.fromLoader(dest.getNode(), ClassLoaderReference.Primordial)) {
// System.out.println("Call to system: "+signature);
// }
// if (! dest.getMethod().isSynthetic()
// && LoaderUtils.fromLoader(dest.getNode(), ClassLoaderReference.Primordial)) {
//
// MyLogger.log(DEBUG,"Primordial and No Summary! (getCallFlowFunction) - " + dest.getMethod().getReference());
// }
final Map<CodeElement,CodeElement> parameterMap = Maps.newHashMap();
for (int i = 0; i < instruction.getNumberOfParameters(); i++) {
Set<CodeElement> elements = CodeElement.valueElements(pa, src.getNode(), instruction.getUse(i));
for(CodeElement e: elements) {
parameterMap.put(e, new LocalElement(i+1));
}
}
return new IUnaryFlowFunction() {
public IntSet getTargets(int d1) {
BitVectorIntSet set = new BitVectorIntSet();
if(d1 == 0 || !(domain.getMappedObject(d1).codeElement instanceof LocalElement)) {
set.add(d1);
}
DomainElement de = domain.getMappedObject(d1);
if(de!=null && parameterMap.containsKey(de.codeElement))
set.add(domain.getMappedIndex(new DomainElement(parameterMap.get(de.codeElement),de.taintSource)));
return set;
}
};
}
public IUnaryFlowFunction getCallNoneToReturnFlowFunction(
BasicBlockInContext<E> src,
BasicBlockInContext<E> dest) {
//I Believe this method is called only if there are no callees of src in the supergraph
//if supergraph included all primordials, this method can still be called if it calls a
//method that wasn't included in the scope
//Assertions.UNREACHABLE();
// TODO: Look up summary for this method, or warn if it doesn't exist.
assert (src.getNode().equals(dest.getNode()));
// final SSAInvokeInstruction instruction = (SSAInvokeInstruction) src.getLastInstruction();
// System.out.println("call to return(no callee) method inside call graph: " + src.getNode()+"--" + instruction.getDeclaredTarget());
// System.out.println("call to system: " + instruction.getDeclaredTarget());
return new DefUse(dest);
}
public IUnaryFlowFunction getCallToReturnFlowFunction(
BasicBlockInContext<E> src,
BasicBlockInContext<E> dest) {
assert (src.getNode().equals(dest.getNode()));
//final SSAInvokeInstruction instruction = (SSAInvokeInstruction) src.getLastInstruction();
//System.out.println("call to return method inside call graph: " + instruction.getDeclaredTarget());
return new DefUse(dest);
}
public IUnaryFlowFunction getNormalFlowFunction(
BasicBlockInContext<E> src,
BasicBlockInContext<E> dest) {
assert (src.getNode().equals(dest.getNode()));
//System.out.println("getNormalFlowFuntion");
//System.out.println("\tSrc " + src.getLastInstruction());
//System.out.println("\tDest " + dest.getLastInstruction());
return new DefUse(dest);
}
public class ReturnDefUse extends DefUse
{
CodeElement callSet;
Set<CodeElement> receivers = new HashSet<CodeElement>();
public ReturnDefUse(BasicBlockInContext<E> dest,
BasicBlockInContext<E> call) {
super(dest);
// TODO: look into exception handling through getDef(1)
if(call.getLastInstruction() instanceof SSAInvokeInstruction) {
SSAInvokeInstruction invInst = (SSAInvokeInstruction) call.getLastInstruction();
if(!invInst.isSpecial()) {// && !invInst.isStatic()) {
// for (int i = 0; i < invInst.getNumberOfReturnValues(); i++) {
//
// }
if (invInst.hasDef()) {
callSet = new LocalElement(invInst.getReturnValue(0));
if ( !invInst.isStatic() ) {
//used to be invInst.getReceiver(), but I believe that was incorrect.
receivers.addAll(CodeElement.valueElements(pa, call.getNode(), invInst.getReceiver()));
//receivers.addAll(CodeElement.valueElements(pa, call.getNode(), invInst.getReturnValue(0)));
}
}
}
}
else {
callSet = null;
}
// // TODO: look into exception handling through getDef(1)
// if(call.getLastInstruction().getNumberOfDefs() == 1)
// {
// //System.out.println("\treturn defines something: "+call.getLastInstruction());
// callSet = new LocalElement(call.getLastInstruction().getDef(0));
// if(call.getLastInstruction() instanceof SSAInvokeInstruction)
// {
// SSAInvokeInstruction invInst = (SSAInvokeInstruction) call.getLastInstruction();
// if(!invInst.isSpecial() && !invInst.isStatic()) {
// receivers.addAll(CodeElement.valueElements(pa, call.getNode(), invInst.getReceiver()));
// }
// }
// }
// else
// callSet = null;
}
@Override
public IntSet getTargets(int d1)
{
if(d1 != 0 && domain.getMappedObject(d1).codeElement instanceof ReturnElement)
{
BitVectorIntSet set = new BitVectorIntSet();
if(callSet != null) {
// System.out.println("callset: " + callSet);
set.add(domain.getMappedIndex(new DomainElement(callSet,domain.getMappedObject(d1).taintSource)));
}
return set;
}
else if(d1 != 0 && domain.getMappedObject(d1).codeElement instanceof LocalElement)
{
return new BitVectorIntSet();
}
else if(d1 != 0 && receivers.contains(domain.getMappedObject(d1).codeElement))
{
BitVectorIntSet set = new BitVectorIntSet();
if(callSet != null)
set.add(domain.getMappedIndex(new DomainElement(callSet,domain.getMappedObject(d1).taintSource)));
set.addAll(super.getTargets(d1));
return set;
}
else
{
return super.getTargets(d1);
}
}
}
public IFlowFunction getReturnFlowFunction(BasicBlockInContext<E> call,
BasicBlockInContext<E> src,
BasicBlockInContext<E> dest) {
assert (graph.isCall(call) && graph.isReturn(dest) && call.getNode().equals(dest.getNode()));
//final SSAInvokeInstruction instruction = (SSAInvokeInstruction) call.getLastInstruction();
//System.out.println("Return from call to method inside call graph: " + instruction.getDeclaredTarget());
return new ReturnDefUse(dest,call);
}
}

View File

@ -1,118 +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.flow.functions;
import java.util.List;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.MutableSparseIntSet;
final class PairBasedFlowFunction <E extends ISSABasicBlock> implements IUnaryFlowFunction {
// private static final Logger logger =
// LoggerFactory.getLogger(PairBasedFlowFunction.class);
private final List<UseDefPair> useToDefList;
private final IFDSTaintDomain<E> domain;
public PairBasedFlowFunction(IFDSTaintDomain<E> domain, List<UseDefPair> useToDefList) {
this.domain = domain;
this.useToDefList = useToDefList;
}
@Override
public IntSet getTargets(int d) {
//logger.debug("getTargets("+d+")");
if (0 == d) {
//logger.debug("getTargets("+d+"): {0}");
return TaintTransferFunctions.ZERO_SET;
}
MutableSparseIntSet set = MutableSparseIntSet.makeEmpty();
DomainElement de = domain.getMappedObject(d);
// Here we list what facts we pass through. If a fact was true
// before executing this instruction, it'll be true after,
// unless we created a new definition of its associated
// CodeElement.
// see if D is still true; if so, pass it through:
// (this corresponds to the vertical 'pass through' arrows in the RHS paper)
// we actually assume that D passes through, unless there
// is evidence to the contrary. Because of this, instructions will
// 'default' to propagating taints that were not relevant to that
// instruction, which is what we want.
set.add(d);
for (UseDefPair udPair : useToDefList) {
CodeElement def = udPair.getDef();
if (def.equals(de.codeElement)) {
// this instruction redefined D, so we
// do *not* pass it through - this conditional has
// contradicted our assumption that D should be passed through,
// so remove it from the set:
set.remove(d);
break;
}
}
////////////////////////////////////////////////////////////////
// see if the taints associated with D also flow through to any
// other domain elements:
for (UseDefPair udPair : useToDefList) {
CodeElement use = udPair.getUse();
if (use.equals(de.codeElement)) {
// ok, the d element flows to the def, so we add that def
// and keep looking.
DomainElement newDE =
new DomainElement(udPair.getDef(), de.taintSource);
set.add(domain.getMappedIndex(newDE));
}
}
// logger.debug("getTargets("+d+"): "+set);
return set;
}
}

View File

@ -1,92 +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.flow.functions;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.domain.LocalElement;
import org.scandroid.domain.ReturnElement;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.SparseIntSet;
/**
* @author creswick
*
*/
public class ReturnFlowFunction<E extends ISSABasicBlock> implements
IUnaryFlowFunction {
private final IFDSTaintDomain<E> domain;
private final CodeElement ce;
/**
* @param domain
* @param def
* of the invoke instruction we're returning to
*/
public ReturnFlowFunction(IFDSTaintDomain<E> domain, int def) {
this.domain = domain;
this.ce = new LocalElement(def);
}
/*
* (non-Javadoc)
*
* @see com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction#getTargets(int)
*/
@Override
public IntSet getTargets(int d1) {
if (0 == d1) {
return TaintTransferFunctions.ZERO_SET;
}
DomainElement de = domain.getMappedObject(d1);
// if the domain element is a return element, propagate its taint
if (de.codeElement instanceof ReturnElement) {
return SparseIntSet.singleton(domain
.getMappedIndex(new DomainElement(ce, de.taintSource)));
}
return TaintTransferFunctions.EMPTY_SET;
}
}

View File

@ -1,623 +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.flow.functions;
import java.util.Arrays;
import java.util.List;
import java.util.Set;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.DomainElement;
import org.scandroid.domain.FieldElement;
import org.scandroid.domain.IFDSTaintDomain;
import org.scandroid.domain.InstanceKeyElement;
import org.scandroid.domain.LocalElement;
import org.scandroid.domain.ReturnElement;
import org.scandroid.domain.StaticFieldElement;
import org.scandroid.flow.types.StaticFieldFlow;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.cache.CacheBuilder;
import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;
import com.google.common.collect.Lists;
import com.google.common.collect.Sets;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.dataflow.IFDS.IFlowFunction;
import com.ibm.wala.dataflow.IFDS.IFlowFunctionMap;
import com.ibm.wala.dataflow.IFDS.IReversibleFlowFunction;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.dataflow.IFDS.IdentityFlowFunction;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
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.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayReferenceInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSAFieldAccessInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.types.FieldReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.Pair;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.IntSetAction;
import com.ibm.wala.util.intset.MutableSparseIntSet;
import com.ibm.wala.util.intset.OrdinalSet;
import com.ibm.wala.util.intset.SparseIntSet;
public class TaintTransferFunctions<E extends ISSABasicBlock> implements
IFlowFunctionMap<BasicBlockInContext<E>> {
private static final Logger logger = LoggerFactory
.getLogger(TaintTransferFunctions.class);
// Java, you need type aliases.
private static class BlockPair<E extends ISSABasicBlock> extends
Pair<BasicBlockInContext<E>, BasicBlockInContext<E>> {
protected BlockPair(BasicBlockInContext<E> fst,
BasicBlockInContext<E> snd) {
super(fst, snd);
}
}
private final IFDSTaintDomain<E> domain;
private final PointerAnalysis<InstanceKey> pa;
private final boolean taintStaticFields;
private final IUnaryFlowFunction globalId;
private final IUnaryFlowFunction callToReturn;
private final LoadingCache<BlockPair<E>, IUnaryFlowFunction> callFlowFunctions;
private final LoadingCache<BlockPair<E>, IUnaryFlowFunction> normalFlowFunctions;
public static final IntSet EMPTY_SET = new SparseIntSet();
public static final IntSet ZERO_SET = SparseIntSet.singleton(0);
private static final IReversibleFlowFunction IDENTITY_FN = new IdentityFlowFunction();
public TaintTransferFunctions(IFDSTaintDomain<E> domain,
ISupergraph<BasicBlockInContext<E>, CGNode> graph,
PointerAnalysis<InstanceKey> pa) {
this(domain, graph, pa, false);
}
public TaintTransferFunctions(IFDSTaintDomain<E> domain,
ISupergraph<BasicBlockInContext<E>, CGNode> graph,
PointerAnalysis<InstanceKey> pa, boolean taintStaticFields) {
this.domain = domain;
this.pa = pa;
this.globalId = new GlobalIdentityFunction<E>(domain);
this.callToReturn = new CallToReturnFunction<E>(domain);
this.callFlowFunctions = CacheBuilder.newBuilder().maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<BlockPair<E>, IUnaryFlowFunction>() {
@Override
public IUnaryFlowFunction load(BlockPair<E> key)
throws Exception {
return makeCallFlowFunction(key.fst, key.snd, null);
}
});
this.normalFlowFunctions = CacheBuilder.newBuilder().maximumSize(10000)
.expireAfterWrite(10, TimeUnit.MINUTES)
.build(new CacheLoader<BlockPair<E>, IUnaryFlowFunction>() {
@Override
public IUnaryFlowFunction load(BlockPair<E> key)
throws Exception {
return makeNormalFlowFunction(key.fst, key.snd);
}
});
this.taintStaticFields = taintStaticFields;
}
@Override
public IUnaryFlowFunction getCallFlowFunction(BasicBlockInContext<E> src,
BasicBlockInContext<E> dest, BasicBlockInContext<E> ret) {
try {
return callFlowFunctions.get(new BlockPair<E>(src, dest));
} catch (ExecutionException e) {
logger.error("Exception accessing callFlowFunctions {}", e);
throw new RuntimeException(e);
}
}
private IUnaryFlowFunction makeCallFlowFunction(BasicBlockInContext<E> src,
BasicBlockInContext<E> dest, BasicBlockInContext<E> ret) {
logger.trace("getCallFlowFunction");
SSAInstruction srcInst = src.getLastInstruction();
if (null == srcInst) {
logger.warn("null source for a call");
return IDENTITY_FN;
}
if (srcInst instanceof SSAInvokeInstruction) {
// build list of actual parameter code elements, and return a
// function
final int numParams = ((SSAInvokeInstruction) srcInst)
.getNumberOfParameters();
List<CodeElement> actualParams = Lists
.newArrayListWithCapacity(numParams);
for (int i = 0; i < numParams; i++) {
actualParams.add(i, new LocalElement(srcInst.getUse(i)));
}
logger.trace("actual param list length: {}", actualParams);
// return new TracingFlowFunction<E>(domain, union(new
// GlobalIdentityFunction<E>(domain),
// new CallFlowFunction<E>(domain, actualParams)));
return union(globalId,
new CallFlowFunction<E>(domain, actualParams));
} else {
throw new RuntimeException("src block not an invoke instruction");
}
}
@Override
public IUnaryFlowFunction getCallNoneToReturnFlowFunction(
BasicBlockInContext<E> src, BasicBlockInContext<E> dest) {
if (logger.isTraceEnabled()) {
logger.trace("getNoneToReturnFunction");
logger.trace("callee signature: {}", ((SSAInvokeInstruction) src
.getLastInstruction()).getDeclaredTarget().getSignature());
}
// return callNoneToReturn;
/*
* TODO: is this right?
*
* The original callNoneToReturn impl just adds taints to absolutely
* everything in the domain. This seems like the wrong approach, but
* it's unclear what would be correct...
*
* Switching this to the identity for now improves performance
* drastically.
*/
return IDENTITY_FN;
}
@Override
public IUnaryFlowFunction getCallToReturnFlowFunction(
BasicBlockInContext<E> src, BasicBlockInContext<E> dest) {
if (logger.isTraceEnabled()) {
logger.trace("getCallToReturnFunction\n\t{}\n\t-> {}", src
.getMethod().getSignature(), dest.getMethod()
.getSignature());
}
// return new TracingFlowFunction<E>(domain, new
// CallToReturnFunction<E>(domain));
return callToReturn;
}
@Override
public IUnaryFlowFunction getNormalFlowFunction(BasicBlockInContext<E> src,
BasicBlockInContext<E> dest) {
try {
return normalFlowFunctions.get(new BlockPair<E>(src, dest));
} catch (ExecutionException e) {
logger.error("Exception accessing normalFlowFunctions {}", e);
throw new RuntimeException(e);
}
}
private IUnaryFlowFunction makeNormalFlowFunction(
BasicBlockInContext<E> src, BasicBlockInContext<E> dest) {
List<UseDefPair> pairs = Lists.newArrayList();
if (logger.isTraceEnabled()) {
logger.trace("getNormalFlowFunction {}", dest.getMethod()
.getSignature());
}
// we first try to process the destination instruction
SSAInstruction inst = dest.getLastInstruction();
CGNode node = dest.getNode();
if (null == inst) {
logger.trace("Using identity fn. for normal flow (dest instruction null)");
return IDENTITY_FN;
}
logger.trace("\tinstruction: {}", inst);
Iterable<CodeElement> inCodeElts = getInCodeElts(node, inst);
Iterable<CodeElement> outCodeElts = getOutCodeElts(node, inst);
if (!inCodeElts.iterator().hasNext()) {
logger.trace("no input elements for {}", inst);
}
if (!outCodeElts.iterator().hasNext()) {
logger.trace("no output elements for {}", inst);
}
// for now, take the Cartesian product of the inputs and outputs:
// TODO specialize this on a per-instruction basis to improve precision.
for (CodeElement use : inCodeElts) {
for (CodeElement def : outCodeElts) {
pairs.add(new UseDefPair(use, def));
}
}
// globals may be redefined here, so we can't union with the globals ID
// flow function, as we often do elsewhere.
final PairBasedFlowFunction<E> flowFunction = new PairBasedFlowFunction<E>(
domain, pairs);
// special case for static field gets so we can introduce new taints for
// them
if (taintStaticFields && inst instanceof SSAGetInstruction
&& ((SSAGetInstruction) inst).isStatic()) {
return makeStaticFieldTaints(dest, inst, node, flowFunction);
}
return flowFunction;
}
public IUnaryFlowFunction makeStaticFieldTaints(
BasicBlockInContext<E> dest, SSAInstruction inst, CGNode node,
final PairBasedFlowFunction<E> flowFunction) {
final Set<DomainElement> elts = Sets.newHashSet();
for (CodeElement ce : getStaticFieldAccessCodeElts(node,
(SSAGetInstruction) inst)) {
StaticFieldElement sfe = (StaticFieldElement) ce;
IField field = pa.getClassHierarchy().resolveField(sfe.getRef());
if (field.isFinal()) {
continue;
}
final StaticFieldFlow<E> taintSource = new StaticFieldFlow<E>(dest,
field, true);
elts.add(new DomainElement(ce, taintSource));
}
IUnaryFlowFunction newTaints = new ConstantFlowFunction<E>(domain, elts);
return compose(flowFunction, newTaints);
}
/*
* The usual arguments:
*
* call: the invoke instruction that took us into this method
*
* src: a block that's the postdominator of this method, usually with no
* instructions
*
* dest: whatever instruction followed the invoke instruction in call
*
* What we want to accomplish:
*
* 1. Map taints from the value being returned to a LocalElement in the
* caller's context
*
* 2. Pass through any global information that the callee may have changed
*
* 3. Process ins/outs of dest block as well (it will never be the dest of a
* NormalFlowFunction)
*
* @see
* com.ibm.wala.dataflow.IFDS.IFlowFunctionMap#getReturnFlowFunction(java
* .lang.Object, java.lang.Object, java.lang.Object)
*/
@Override
public IFlowFunction getReturnFlowFunction(BasicBlockInContext<E> call,
BasicBlockInContext<E> src, BasicBlockInContext<E> dest) {
if (logger.isTraceEnabled()) {
logger.trace("getReturnFlowFunction\n\t{}\n\t-> {}\n\t-> {}", call
.getNode().getMethod().getSignature(), src.getNode()
.getMethod().getSignature(), dest.getNode().getMethod()
.getSignature());
logger.trace("\t{} -> {} -> {}", call.getLastInstruction(),
src.getLastInstruction(), dest.getLastInstruction());
}
final SSAInstruction inst = call.getLastInstruction();
if (null == inst || !(inst instanceof SSAInvokeInstruction)) {
// if we don't have an invoke, just punt and hope the necessary
// information is already in global elements
logger.warn("call block null or not an invoke instruction");
return globalId;
}
// we always need to process the destination instruction
final IUnaryFlowFunction flowFromDest = getNormalFlowFunction(null,
dest);
final SSAInvokeInstruction invoke = (SSAInvokeInstruction) inst;
if (invoke.getNumberOfReturnValues() == 0) {
// no return values, just propagate global information
// return new TracingFlowFunction<E>(domain, compose (flowFromDest,
// new GlobalIdentityFunction<E>(domain)));
return compose(flowFromDest, globalId);
}
// we have a return value, so we need to map any return elements onto
// the local element corresponding to the invoke's def
final IUnaryFlowFunction flowToDest = union(globalId,
new ReturnFlowFunction<E>(domain, invoke.getDef()));
// return new TracingFlowFunction<E>(domain, compose(flowFromDest,
// flowToDest));
return compose(flowFromDest, flowToDest);
}
private Iterable<CodeElement> getOutCodeElts(CGNode node,
SSAInstruction inst) {
int defNo = inst.getNumberOfDefs();
Set<CodeElement> elts = Sets.newHashSet();
if (inst instanceof SSAReturnInstruction) {
// only one possible element for returns
if (logger.isTraceEnabled()) {
logger.trace("making a return element for {}", node.getMethod()
.getSignature());
}
elts.add(new ReturnElement());
return elts;
}
if (inst instanceof SSAPutInstruction) {
final Set<CodeElement> fieldAccessCodeElts = getFieldAccessCodeElts(
node, (SSAPutInstruction) inst);
if (logger.isTraceEnabled()) {
logger.trace("put outelts: {}",
Arrays.toString(fieldAccessCodeElts.toArray()));
}
elts.addAll(fieldAccessCodeElts);
}
if (inst instanceof SSAArrayStoreInstruction) {
elts.addAll(getArrayRefCodeElts(node,
(SSAArrayStoreInstruction) inst));
}
for (int i = 0; i < defNo; i++) {
int valNo = inst.getDef(i);
elts.addAll(CodeElement.valueElements(pa, node, valNo));
}
return elts;
}
private Iterable<CodeElement> getInCodeElts(CGNode node, SSAInstruction inst) {
int useNo = inst.getNumberOfUses();
Set<CodeElement> elts = Sets.newHashSet();
if (inst instanceof SSAGetInstruction) {
elts.addAll(getFieldAccessCodeElts(node, (SSAGetInstruction) inst));
}
if (inst instanceof SSAArrayLoadInstruction) {
elts.addAll(getArrayRefCodeElts(node,
(SSAArrayLoadInstruction) inst));
}
for (int i = 0; i < useNo; i++) {
int valNo = inst.getUse(i);
// Constants have valuenumber 0, which is otherwise, illegal.
// these need to be skipped:
if (0 == valNo) {
continue;
}
try {
elts.addAll(CodeElement.valueElements(pa, node, valNo));
} catch (IllegalArgumentException e) {
logger.error("Exception working on node: " + node);
logger.error("Node is in method: " + node.getMethod());
throw e;
}
}
return elts;
}
// private Iterable<CodeElement> getOutCodeElts(final CGNode node, final
// SSAInstruction inst) {
// return new Iterable<CodeElement>() {
// @Override
// public Iterator<CodeElement> iterator() {
// return new DefEltIterator(node, inst);
// }
// };
// }
//
// private Iterable<CodeElement> getInCodeElts(final CGNode node, final
// SSAInstruction inst) {
// return new Iterable<CodeElement>() {
// @Override
// public Iterator<CodeElement> iterator() {
// return new UseEltIterator(node, inst);
// }
// };
// }
private Set<CodeElement> getFieldAccessCodeElts(CGNode node,
SSAFieldAccessInstruction inst) {
if (inst.isStatic()) {
return getStaticFieldAccessCodeElts(node, inst);
}
Set<CodeElement> elts = Sets.newHashSet();
final FieldReference fieldRef = inst.getDeclaredField();
final IField field = node.getClassHierarchy().resolveField(fieldRef);
PointerKey pk = pa.getHeapModel().getPointerKeyForLocal(node,
inst.getRef());
final OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
if (pointsToSet.isEmpty()) {
logger.debug(
"pointsToSet empty for ref of {}, creating InstanceKey manually",
inst);
InstanceKey ik = new ConcreteTypeKey(field.getDeclaringClass());
elts.add(new FieldElement(ik, fieldRef));
elts.add(new InstanceKeyElement(ik));
} else {
for (InstanceKey ik : pointsToSet) {
if (logger.isTraceEnabled()) {
logger.trace("adding elements for field {} on {}",
field.getName(), ik.getConcreteType().getName());
}
elts.add(new FieldElement(ik, fieldRef));
elts.add(new InstanceKeyElement(ik));
}
}
return elts;
}
private Set<CodeElement> getStaticFieldAccessCodeElts(CGNode node,
SSAFieldAccessInstruction inst) {
Set<CodeElement> elts = Sets.newHashSet();
final FieldReference fieldRef = inst.getDeclaredField();
elts.add(new StaticFieldElement(fieldRef));
// TODO: what about tainting the declaring class?
return elts;
}
private Set<CodeElement> getArrayRefCodeElts(CGNode node,
SSAArrayReferenceInstruction inst) {
Set<CodeElement> elts = Sets.newHashSet();
final PointerKey pk = pa.getHeapModel().getPointerKeyForLocal(node,
inst.getArrayRef());
final OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
if (pointsToSet.isEmpty()) {
logger.debug(
"pointsToSet empty for ref of {}, creating InstanceKey manually",
inst);
TypeReference arrayType = TypeReference.findOrCreateArrayOf(inst
.getElementType());
InstanceKey ik = new ConcreteTypeKey(pa.getClassHierarchy()
.lookupClass(arrayType));
elts.add(new InstanceKeyElement(ik));
} else {
for (InstanceKey ik : pointsToSet) {
if (logger.isTraceEnabled()) {
logger.trace("adding element for array store in {}", ik
.getConcreteType().getName());
}
elts.add(new InstanceKeyElement(ik));
}
}
return elts;
}
private IUnaryFlowFunction union(final IUnaryFlowFunction g,
final IUnaryFlowFunction h) {
return new IUnaryFlowFunction() {
@Override
public IntSet getTargets(int d1) {
return g.getTargets(d1).union(h.getTargets(d1));
}
};
}
/**
* Flow function composition
*
* @param f
* @param g
* @return { (x, z) | (x, y) \in g, (y, z) \in f }
*/
private IUnaryFlowFunction compose(final IUnaryFlowFunction f,
final IUnaryFlowFunction g) {
return new IUnaryFlowFunction() {
@Override
public IntSet getTargets(int d1) {
final MutableSparseIntSet set = MutableSparseIntSet.makeEmpty();
g.getTargets(d1).foreach(new IntSetAction() {
@Override
public void act(int x) {
set.addAll(f.getTargets(x));
}
});
return set;
}
};
}
/*
* private class UseEltIterator implements Iterator<CodeElement> { private
* int idx = 0; private Iterator<CodeElement> subIt; private final CGNode
* node; private final SSAInstruction inst; private final int count;
*
* public UseEltIterator(CGNode node, SSAInstruction inst) { this.node =
* node; this.inst = inst; count = inst.getNumberOfUses();
* updateIterator(node, inst); }
*
* private void updateIterator(final CGNode node, final SSAInstruction inst)
* { int valNo = inst.getUse(idx); idx++; Set<CodeElement> elements =
* CodeElement.valueElements(pa, node, valNo); subIt = elements.iterator();
* }
*
* @Override public boolean hasNext() { if (subIt.hasNext()) { return true;
* } else if (idx < count) { updateIterator(node, inst); return hasNext(); }
* else { return false; } }
*
* @Override public CodeElement next() { return subIt.next(); }
*
* @Override public void remove() {} }
*
* private class DefEltIterator implements Iterator<CodeElement> { private
* int idx = 0; private Iterator<CodeElement> subIt; private final CGNode
* node; private final SSAInstruction inst; private final int count;
*
* public DefEltIterator(CGNode node, SSAInstruction inst) { this.node =
* node; this.inst = inst; count = inst.getNumberOfDefs();
* updateIterator(node, inst); }
*
* private void updateIterator(final CGNode node, final SSAInstruction inst)
* { int valNo = inst.getDef(idx); idx++; Set<CodeElement> elements =
* CodeElement.valueElements(pa, node, valNo); subIt = elements.iterator();
* }
*
* @Override public boolean hasNext() { if (subIt.hasNext()) { return true;
* } else if (idx < count) { updateIterator(node, inst); return hasNext(); }
* else { return false; } }
*
* @Override public CodeElement next() { return subIt.next(); }
*
* @Override public void remove() {} }
*/
}

View File

@ -1,76 +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.flow.functions;
import org.scandroid.domain.IFDSTaintDomain;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.dataflow.IFDS.IUnaryFlowFunction;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.util.intset.IntSet;
import com.ibm.wala.util.intset.IntSetAction;
public class TracingFlowFunction<E extends ISSABasicBlock> implements IUnaryFlowFunction {
private final IFDSTaintDomain<E> domain;
private final IUnaryFlowFunction function;
private final Logger logger;
public TracingFlowFunction(IFDSTaintDomain<E> domain, IUnaryFlowFunction function) {
this.domain = domain;
this.function = function;
this.logger = LoggerFactory.getLogger(function.getClass());
}
@Override
public IntSet getTargets(int d1) {
IntSet result = function.getTargets(d1);
logger.debug("TRACING: {}", domain.getMappedObject(d1));
result.foreach(new IntSetAction() {
@Override
public void act(int x) {
logger.debug("\t{}", domain.getMappedObject(x));
}
});
return result;
}
}

View File

@ -1,61 +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.flow.functions;
import org.scandroid.domain.CodeElement;
final class UseDefPair
{
private final CodeElement use;
private final CodeElement def;
public UseDefPair(CodeElement use, CodeElement def) {
this.use = use;
this.def = def;
}
public CodeElement getUse() {
return use;
}
public CodeElement getDef() {
return def;
}
@Override
public String toString() {
return "UseDefPair [use=" + use + ", def=" + def + "]";
}
}

View File

@ -1,113 +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.flow.types;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
/** A flow to or from a field. The associated block represents
* either the location of the get or put instruction, or the
* entry or exit block of a method which is reading or writing
* the field. In the former case, the associate field is redundant,
* but potentially convenient. In the latter case, it's necessary.
*
* @author atomb
*
* @param <E>
*/
public class FieldFlow<E extends ISSABasicBlock> extends FlowType<E> {
private final IField field;
public FieldFlow(BasicBlockInContext<E> block, IField field, boolean source) {
super(block, source);
this.field = field;
}
@Override
public String toString() {
return "FieldFlow( field=" + field + " "+ super.toString() + ")";
}
@Override
public String descString() {
return field.getDeclaringClass().toString() + "." + field.getName().toString();
}
public IField getField() {
return field;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((field == null) ? 0 : field.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
FieldFlow<E> other = (FieldFlow<E>) obj;
if (field == null) {
if (other.field != null)
return false;
} else if (!field.equals(other.field))
return false;
return true;
}
@Override
public <R> R visit(FlowTypeVisitor<E, R> v) {
return v.visitFieldFlow(this);
}
}

View File

@ -1,151 +0,0 @@
/**
*
* 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.
*
*
*/
package org.scandroid.flow.types;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
/**
* Flow types represent specific instances of sources or sinks.
*
* In contrast to the Source/Sink specs, these have ties to specific locations
* in the source.
*
* @author creswick
*/
public abstract class FlowType<E extends ISSABasicBlock> {
private final BasicBlockInContext<E> block;
private final boolean source;
protected FlowType(BasicBlockInContext<E> block, boolean source) {
this.block = block;
this.source = source;
}
public final BasicBlockInContext<E> getBlock() {
return block;
}
public final boolean isSource() {
return source;
}
@Override
public String toString() {
return "block=" + block + ", source=" + source + ", desc=" + descString();
}
public String descString() {
if(source)
return "I";
else
return "O";
}
@Override
public int hashCode() {
final int prime = 31;
int result = 1;
result = prime * result + ((block == null) ? 0 : block.getNumber());
result = prime * result + (source ? 1231 : 1237);
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (obj == null)
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
FlowType<E> other = (FlowType<E>) obj;
if (block == null) {
if (other.block != null)
return false;
} else if (block.getNumber() != other.block.getNumber()) {
return false;
}
if (source != other.source)
return false;
return true;
}
/**
* custom comparison for BasicBlockInContext. The WALA .equals()
* implementation eventually delegates to pointer equality, which is too
* specific for our needs.
*
* @param a
* @param b
* @return
*/
@SuppressWarnings("unused")
private boolean compareBlocks(BasicBlockInContext<E> a,
BasicBlockInContext<E> b) {
// delegate to the defined implementation, but only if it's true.
if (a.equals(b)) {
return true;
}
if (null == a || null == b) {
return false;
}
if (a.getNumber() != b.getNumber()) {
return false;
}
if (!a.getMethod().getSignature().equals(b.getMethod().getSignature())) {
return false;
}
return true;
}
public abstract <R> R visit(FlowTypeVisitor<E, R> v);
public static interface FlowTypeVisitor<E extends ISSABasicBlock, R> {
R visitFieldFlow(FieldFlow<E> flow);
R visitIKFlow(IKFlow<E> flow);
R visitParameterFlow(ParameterFlow<E> flow);
R visitReturnFlow(ReturnFlow<E> flow);
R visitStaticFieldFlow(StaticFieldFlow<E> flow);
}
}

View File

@ -1,92 +0,0 @@
/**
*
* 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.
*
*
*/
package org.scandroid.flow.types;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
public class IKFlow<E extends ISSABasicBlock> extends FlowType<E> {
private final InstanceKey ik;
public IKFlow(InstanceKey ik, BasicBlockInContext<E> block, boolean source) {
super(block, source);
this.ik = ik;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((ik == null) ? 0 : ik.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
IKFlow<E> other = (IKFlow<E>) obj;
if (ik == null) {
if (other.ik != null)
return false;
} else if (!ik.equals(other.ik)) // TODO InstanceKey may not supply equals()
return false;
return true;
}
@Override
public String toString() {
return "IKFlow(ik=" + ik + " " + super.toString() + ")";
}
public InstanceKey getIK() {
return ik;
}
@Override
public <R> R visit(org.scandroid.flow.types.FlowType.FlowTypeVisitor<E, R> v) {
return v.visitIKFlow(this);
}
}

View File

@ -1,111 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* 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.flow.types;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.analysis.IExplodedBasicBlock;
/** A flow to or from the parameter of a method. This can represent formal
* parameters of methods being analyzed, or actual parameters of methods
* being called. In the former case, the associated block is the entry
* block of the method. In the latter case, the block is the block containing
* the invoke instruction.
*
* @author atomb
*
* @param <E>
*/
public class ParameterFlow <E extends ISSABasicBlock> extends FlowType<E> {
private final int argNum;
public ParameterFlow(BasicBlockInContext<E> block,
int argNum, boolean source) {
super(block, source);
this.argNum = argNum;
}
public int getArgNum() {
return argNum;
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + argNum;
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
ParameterFlow<E> other = (ParameterFlow<E>) obj;
if (argNum != other.argNum)
return false;
return true;
}
@Override
public String toString() {
return "ParameterFlow( argNum="+argNum+" "+super.toString()+")";
}
@Override
public String descString() {
String s = "arg(" + argNum + ")";
if(!getBlock().isEntryBlock()) {
SSAInvokeInstruction inv = (SSAInvokeInstruction) ((IExplodedBasicBlock) getBlock().getDelegate()).getInstruction();
s = s + ":" + inv.getDeclaredTarget().getSignature();
}
return s;
}
@Override
public <R> R visit(FlowTypeVisitor<E, R> v) {
return v.visitParameterFlow(this);
}
}

View File

@ -1,77 +0,0 @@
/*
*
* 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.
*
*/
package org.scandroid.flow.types;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
/**
*
* A return flow represents either a flow from a method that was just invoked
* if this points to an invoke instruction (in which case this is a source) or
* a method return, if this points to a return instruction (in which case it is
* a sink).
*
*/
public class ReturnFlow <E extends ISSABasicBlock> extends FlowType<E> {
public ReturnFlow(BasicBlockInContext<E> block, boolean source) {
super(block, source);
}
@Override
public String toString() {
return "ReturnFlow( " + super.toString() + ")";
}
@Override
public String descString() {
if(isSource()) {
SSAInvokeInstruction inv = (SSAInvokeInstruction)getBlock().getLastInstruction();
return "ret:" + inv.getDeclaredTarget().getSignature();
} else {
return "ret";
}
}
@Override
public <R> R visit(FlowTypeVisitor<E, R> v) {
return v.visitReturnFlow(this);
}
}

View File

@ -1,106 +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.flow.types;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
/**
* @author acfoltzer
*
*/
public class StaticFieldFlow <E extends ISSABasicBlock> extends FlowType<E> {
private final IField field;
public StaticFieldFlow(BasicBlockInContext<E> block, IField field, boolean source) {
super(block, source);
this.field = field;
}
@Override
public String toString() {
return "StaticFieldFlow( field=" + field + " "+ super.toString() + ")";
}
@Override
public String descString() {
return field.getDeclaringClass().toString() + "." + field.getName().toString();
}
public IField getField() {
return field;
}
/* (non-Javadoc)
* @see org.scandroid.flow.types.FlowType#visit(org.scandroid.flow.types.FlowType.FlowTypeVisitor)
*/
@Override
public <R> R visit(FlowTypeVisitor<E, R> v) {
return v.visitStaticFieldFlow(this);
}
@Override
public int hashCode() {
final int prime = 31;
int result = super.hashCode();
result = prime * result + ((field == null) ? 0 : field.hashCode());
return result;
}
@Override
public boolean equals(Object obj) {
if (this == obj)
return true;
if (!super.equals(obj))
return false;
if (getClass() != obj.getClass())
return false;
@SuppressWarnings("unchecked")
StaticFieldFlow<E> other = (StaticFieldFlow<E>) obj;
if (field == null) {
if (other.field != null)
return false;
} else if (!field.equals(other.field))
return false;
return true;
}
}

View File

@ -1,453 +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.model;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.HashSet;
import java.util.LinkedList;
import java.util.List;
import java.util.Map;
import java.util.Map.Entry;
import java.util.Set;
import org.scandroid.spec.AndroidSpecs;
import org.scandroid.spec.MethodNamePattern;
import org.scandroid.util.LoaderUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.classLoader.ArrayClass;
import com.ibm.wala.classLoader.CallSiteReference;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.classLoader.Language;
import com.ibm.wala.classLoader.NewSiteReference;
import com.ibm.wala.ipa.callgraph.AnalysisScope;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.summaries.MethodSummary;
import com.ibm.wala.shrikeBT.IInvokeInstruction;
import com.ibm.wala.shrikeBT.IInvokeInstruction.IDispatch;
import com.ibm.wala.ssa.ConstantValue;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSAInstructionFactory;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.Descriptor;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.HashMapFactory;
import com.ibm.wala.util.debug.UnimplementedError;
import com.ibm.wala.util.strings.Atom;
public class AppModelMethod {
private final static Logger logger = LoggerFactory.getLogger(AppModelMethod.class);
int nextLocal;
/**
* A mapping from String (variable name) -> Integer (local number)
*/
private Map<String, Integer> symbolTable = null;
private MethodSummary methodSummary;
private final IClassHierarchy cha;
private final AnalysisScope scope;
private Map<ConstantValue, Integer> constant2ValueNumber = HashMapFactory.make();
SSAInstructionFactory insts;
//Maps a Type to variable name
private Map<TypeReference, Integer> typeToID = new HashMap<TypeReference, Integer> ();
//innerclass dependencies
private Map<TypeReference, LinkedList<TypeReference>> icDependencies = new HashMap<TypeReference, LinkedList<TypeReference>> ();
//all callbacks to consider
private List<MethodParams> callBacks = new ArrayList<MethodParams>();
private Map<TypeReference, TypeReference> aClassToTR = new HashMap<TypeReference, TypeReference> ();
private class MethodParams{
public IMethod im;
public int params[];
private MethodParams(IMethod method) {
im = method;
}
private void setParams(int p[]) {
params = p;
}
private IMethod getIMethod() {
return im;
}
private int[] getParams() {
return params;
}
}
public AppModelMethod(IClassHierarchy cha, AnalysisScope scope, AndroidSpecs specs) {
this.cha = cha;
this.scope = scope;
Language lang = scope.getLanguage(ClassLoaderReference.Application.getLanguage());
insts = lang.instructionFactory();
startMethod();
buildTypeMap(specs);
processTypeMap();
processCallBackParams();
createLoopAndSwitch();
}
private void createLoopAndSwitch() {
int callbackSize = callBacks.size();
//start of while loop
int loopLabel = methodSummary.getNumberOfStatements();
int switchValue = nextLocal++;
//default label, for now same as case1
int defLabel = loopLabel+1;
int[] casesAndLabels = new int[2*callbackSize];
for (int i = 0; i < callbackSize; i++) {
casesAndLabels[i*2] = i+1;
casesAndLabels[i*2+1] = defLabel+i*2;
}
methodSummary.addStatement(
insts.SwitchInstruction(methodSummary.getNumberOfStatements(), switchValue, defLabel, casesAndLabels));
for (int i = 0; i < callbackSize; i++) {
MethodParams mp = callBacks.get(i);
IMethod im = mp.getIMethod();
IDispatch dispatch;
if (im.isInit()) {
dispatch = IInvokeInstruction.Dispatch.SPECIAL;
}
else if (im.isAbstract()) {
dispatch = IInvokeInstruction.Dispatch.INTERFACE;
}
else if (im.isStatic()) {
dispatch = IInvokeInstruction.Dispatch.STATIC;
}
else
dispatch = IInvokeInstruction.Dispatch.VIRTUAL;
addInvocation(mp.getParams(),
CallSiteReference.make(methodSummary.getNumberOfStatements(),
mp.getIMethod().getReference(),
dispatch));
methodSummary.addStatement(insts.GotoInstruction(methodSummary.getNumberOfStatements(), loopLabel));
}
}
private void startMethod() {
String className = "Lcom/SCanDroid/AppModel";
String methodName = "entry";
TypeReference governingClass =
TypeReference.findOrCreate(ClassLoaderReference.Application, TypeName.string2TypeName(className));
Atom mName = Atom.findOrCreateUnicodeAtom(methodName);
Language lang = scope.getLanguage(ClassLoaderReference.Application.getLanguage());
Descriptor D = Descriptor.findOrCreateUTF8(lang, "()V");
MethodReference mref = MethodReference.findOrCreate(governingClass, mName, D);
methodSummary = new MethodSummary(mref);
methodSummary.setStatic(true);
methodSummary.setFactory(false);
int nParams = mref.getNumberOfParameters();
nextLocal = nParams + 1;
symbolTable = HashMapFactory.make(5);
for (int i = 0; i < nParams; i++) {
symbolTable.put("arg" + i, new Integer(i + 1));
}
}
private void buildTypeMap(AndroidSpecs specs) {
//Go through all possible callbacks found in Application code
//Associate their TypeReference with a unique number in typeToID.
//Also keep track of all anonymous classes found.
for (MethodNamePattern mnp:specs.getCallBacks()) {
for (IMethod im: mnp.getPossibleTargets(cha)) {
// limit to functions defined within the application
if(LoaderUtils.fromLoader(im, ClassLoaderReference.Application))
{
callBacks.add(new MethodParams(im));
TypeReference tr = im.getDeclaringClass().getReference();
if (!typeToID.containsKey(tr)) {
logger.debug("AppModel Mapping type "+tr.getName()+" to id " + nextLocal);
typeToID.put(tr, nextLocal++);
//class is an innerclass
if (tr.getName().getClassName().toString().contains("$")) {
addDependencies(tr);
}
}
}
}
}
}
private void addDependencies(TypeReference tr) {
String packageName = "L"+tr.getName().getPackage().toString()+"/";
String outerClassName;
String innerClassName = tr.getName().getClassName().toString();
LinkedList<TypeReference> trLL = new LinkedList<TypeReference> ();
trLL.push(tr);
int index = innerClassName.lastIndexOf("$");
while (index != -1) {
outerClassName = innerClassName.substring(0, index);
TypeReference innerTR = TypeReference.findOrCreate(ClassLoaderReference.Application, packageName+outerClassName);
trLL.push(innerTR);
if (!typeToID.containsKey(innerTR)) {
logger.debug("AppModel Mapping type "+innerTR.getName()+" to id " + nextLocal);
typeToID.put(innerTR, nextLocal++);
aClassToTR.put(innerTR, tr);
}
innerClassName = outerClassName;
index = outerClassName.lastIndexOf("$");
}
icDependencies.put(tr, trLL);
}
private void processTypeMap() {
Set<Integer> createdIDs = new HashSet<Integer> ();
for (Entry<TypeReference, Integer> eSet:typeToID.entrySet()) {
Integer i = eSet.getValue();
if (createdIDs.contains(i))
continue;
TypeReference tr = eSet.getKey();
String className = tr.getName().getClassName().toString();
//Not an anonymous innerclass
if (!className.contains("$")) {
processAllocation(tr, i, false);
createdIDs.add(i);
}
//Is an anonymous innerclass
else {
LinkedList<TypeReference> deps = icDependencies.get(tr);
if (deps == null) {
tr = aClassToTR.get(tr);
}
for (TypeReference trD:icDependencies.get(tr)) {
Integer j = typeToID.get(trD);
if (!createdIDs.contains(j)) {
String depClassName = trD.getName().getClassName().toString();
processAllocation(trD, j, depClassName.contains("$"));
createdIDs.add(j);
}
}
}
}
assert(createdIDs.size() == typeToID.size()):"typeToID and createdID size do not match";
}
private void processCallBackParams() {
for (MethodParams mp:callBacks) {
int params[] = new int[mp.getIMethod().getNumberOfParameters()];
int startPos;
if (mp.getIMethod().isStatic()) {
startPos = 0;
}
else {
params[0] = typeToID.get(mp.getIMethod().getDeclaringClass().getReference());
startPos = 1;
}
for (int i = startPos; i < params.length; i++) {
params[i] = makeArgument(mp.getIMethod().getParameterType(i));
}
mp.setParams(params);
}
}
private int makeArgument(TypeReference tr) {
if (tr.isPrimitiveType())
return addLocal();
else {
SSANewInstruction n = processAllocation(tr, nextLocal++, false);
return (n == null) ? -1 : n.getDef();
}
}
private int addLocal() {
return nextLocal++;
}
private SSANewInstruction processAllocation (TypeReference tr, Integer i, boolean isInner) {
// create the allocation statement and add it to the method summary
NewSiteReference ref = NewSiteReference.make(methodSummary.getNumberOfStatements(), tr);
SSANewInstruction a = null;
if (tr.isArrayType()) {
int[] sizes = new int[((ArrayClass)cha.lookupClass(tr)).getDimensionality()];
Arrays.fill(sizes, getValueNumberForIntConstant(1));
a = insts.NewInstruction(methodSummary.getNumberOfStatements(), i, ref, sizes);
} else {
a = insts.NewInstruction(methodSummary.getNumberOfStatements(), i, ref);
}
methodSummary.addStatement(a);
IClass klass = cha.lookupClass(tr);
if (klass == null) {
return null;
}
if (klass.isArrayClass()) {
int arrayRef = a.getDef();
TypeReference e = klass.getReference().getArrayElementType();
while (e != null && !e.isPrimitiveType()) {
// allocate an instance for the array contents
NewSiteReference n = NewSiteReference.make(methodSummary.getNumberOfStatements(), e);
int alloc = nextLocal++;
SSANewInstruction ni = null;
if (e.isArrayType()) {
int[] sizes = new int[((ArrayClass)cha.lookupClass(tr)).getDimensionality()];
Arrays.fill(sizes, getValueNumberForIntConstant(1));
ni = insts.NewInstruction(methodSummary.getNumberOfStatements(), alloc, n, sizes);
} else {
ni = insts.NewInstruction(methodSummary.getNumberOfStatements(), alloc, n);
}
methodSummary.addStatement(ni);
// emit an astore
SSAArrayStoreInstruction store = insts.ArrayStoreInstruction(methodSummary.getNumberOfStatements(), arrayRef, getValueNumberForIntConstant(0), alloc, e);
methodSummary.addStatement(store);
e = e.isArrayType() ? e.getArrayElementType() : null;
arrayRef = alloc;
}
}
//invoke constructor
IMethod ctor = cha.resolveMethod(klass, MethodReference.initSelector);
if (ctor != null) {
//only check for more constructors when we're looking through the inner classes?
if (isInner && !ctor.getDeclaringClass().getName().toString().equals(klass.getName().toString())) {
boolean foundValidCtor = false;
for (IMethod im: klass.getAllMethods()) {
if (im.getDeclaringClass().getName().toString().equals(klass.getName().toString()) &&
im.getSelector().getName().toString().equals(MethodReference.initAtom.toString())) {
ctor = im;
foundValidCtor = true;
//found a default constructor that takes only the outer class as a parameter
if (im.getDescriptor().getNumberOfParameters() == 1) {
break;
}
}
}
if (!foundValidCtor) {
throw new UnimplementedError("Check for other constructors, or just use default Object constructor");
}
}
int[] params;
if (ctor.getDescriptor().getNumberOfParameters() == 0)
params = new int[] {i};
else {
params = new int[ctor.getNumberOfParameters()];
params[0] = i;
LinkedList<TypeReference> deps = icDependencies.get(tr);
if (deps == null) {
deps = icDependencies.get(aClassToTR.get(tr));
int index = deps.lastIndexOf(tr);
TypeReference otr = deps.get(index-1);
assert(ctor.getParameterType(1).equals(otr)) : "Type Mismatch";
params[1] = typeToID.get(otr);
}
else {
TypeReference otr = deps.get(deps.size()-2);
assert(ctor.getParameterType(1).equals(otr)) : "Type Mismatch";
params[1] = typeToID.get(otr);
}
//Allocate new instances for each of the other parameters
//in the current constructor.
for (int pI = 2; pI < params.length; pI++) {
params[pI] = makeArgument(ctor.getParameterType(pI));
}
}
addInvocation(params, CallSiteReference.make(methodSummary.getNumberOfStatements(), ctor.getReference(),
IInvokeInstruction.Dispatch.SPECIAL));
}
return a;
}
public SSAInvokeInstruction addInvocation(int[] params, CallSiteReference site) {
if (site == null) {
throw new IllegalArgumentException("site is null");
}
CallSiteReference newSite = CallSiteReference.make(methodSummary.getNumberOfStatements(), site.getDeclaredTarget(), site.getInvocationCode());
SSAInvokeInstruction s = null;
if (newSite.getDeclaredTarget().getReturnType().equals(TypeReference.Void)) {
s = insts.InvokeInstruction(methodSummary.getNumberOfStatements(), params, nextLocal++, newSite);
} else {
s = insts.InvokeInstruction(methodSummary.getNumberOfStatements(), nextLocal++, params, nextLocal++, newSite);
}
methodSummary.addStatement(s);
// cache.invalidate(this, Everywhere.EVERYWHERE);
return s;
}
protected int getValueNumberForIntConstant(int c) {
ConstantValue v = new ConstantValue(c);
Integer result = constant2ValueNumber.get(v);
if (result == null) {
result = nextLocal++;
constant2ValueNumber.put(v, result);
}
return result;
}
public MethodSummary getSummary() {
return methodSummary;
}
}

View File

@ -1,73 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.prefixtransfer.modeledAllocations;
import org.scandroid.prefixtransfer.InstanceKeySite;
import org.scandroid.prefixtransfer.PrefixVariable;
public class ConstantString extends InstanceKeySite {
final String constantValue;
final int instanceID;
public ConstantString(int instanceID, String constantValue)
{
this.constantValue = constantValue;
this.instanceID = instanceID;
}
@Override
public PrefixVariable propagate(PrefixVariable input) {
// System.out.println("Propagating at: " + instanceID + " (" + constantValue + ")");
PrefixVariable retVal = new PrefixVariable();
retVal.update(instanceID, constantValue);
retVal.include(instanceID);
return retVal;
}
public String toString() {
return ("ConstantString(instanceID = " + instanceID + "; value = " + constantValue + ")");
}
@Override
public int instanceID() {
return instanceID;
}
}

View File

@ -1,86 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.prefixtransfer.modeledAllocations;
import java.util.Set;
import org.scandroid.prefixtransfer.InstanceKeySite;
import org.scandroid.prefixtransfer.PrefixVariable;
public class StringToLower extends InstanceKeySite {
private final int instanceID;
private final Set<Integer> dependencies;
public StringToLower(int instanceID, Set<Integer> dependencies)
{
this.instanceID = instanceID;
this.dependencies = dependencies;
}
@Override
public PrefixVariable propagate(PrefixVariable input) {
// TODO Auto-generated method stub
PrefixVariable retVal = new PrefixVariable();
String prefix = null;
for(Integer dep:dependencies)
{
String depPrefix = input.getPrefix(dep);
// if any of the dependencies are unknown, then this prefix is also unknown
if(depPrefix == null)
return retVal;
depPrefix = depPrefix.toLowerCase();
if(prefix == null)
prefix = depPrefix;
else
prefix = PrefixVariable.intersect(prefix, depPrefix);
}
retVal.update(instanceID, prefix);
return retVal;
}
@Override
public int instanceID() {
return instanceID;
}
}

View File

@ -1,81 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.prefixtransfer.modeledAllocations;
import org.scandroid.prefixtransfer.InstanceKeySite;
import org.scandroid.prefixtransfer.PrefixVariable;
public class UriAppendString extends InstanceKeySite {
final int uriInstanceID;
final int stringInstanceID;
final int instanceID;
public UriAppendString(int instanceID, int uriInstanceID, int stringInstanceID)
{
this.uriInstanceID = uriInstanceID;
this.stringInstanceID = stringInstanceID;
this.instanceID = instanceID;
}
@Override
public PrefixVariable propagate(PrefixVariable input) {
// System.out.println("Propagating at: " + instanceID + " (" + constantValue + ")");
PrefixVariable retVal = new PrefixVariable();
retVal.copyState(input);
String prefix = input.getPrefix(uriInstanceID);
if (input.fullPrefixKnown.contains(uriInstanceID)) {
retVal.update(instanceID, prefix + "/" + input.getPrefix(stringInstanceID));
if (input.fullPrefixKnown.contains(stringInstanceID))
retVal.include(instanceID);
}
else retVal.update(instanceID, prefix);
return retVal;
}
public String toString() {
return ("UriAppendString(instanceID = " + instanceID + "; uriInstanceID = " + uriInstanceID + "; stringInstanceID = " + stringInstanceID + ")");
}
@Override
public int instanceID() {
return instanceID;
}
}

View File

@ -1,76 +0,0 @@
/*
*
* 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.
*
*
*/
package org.scandroid.prefixtransfer.modeledAllocations;
import org.scandroid.prefixtransfer.InstanceKeySite;
import org.scandroid.prefixtransfer.PrefixVariable;
public class UriParseString extends InstanceKeySite {
final int stringInstanceID;
final int instanceID;
public UriParseString(int instanceID, int stringInstanceID)
{
this.stringInstanceID = stringInstanceID;
this.instanceID = instanceID;
}
@Override
public PrefixVariable propagate(PrefixVariable input) {
// System.out.println("Propagating at: " + instanceID + " (" + constantValue + ")");
PrefixVariable retVal = new PrefixVariable();
retVal.copyState(input);
String prefix = input.getPrefix(stringInstanceID);
retVal.update(instanceID, prefix);
if (input.fullPrefixKnown.contains(stringInstanceID))
retVal.include(instanceID);
return retVal;
}
public String toString() {
return ("UriParseString(instanceID = " + instanceID + "; stringInstanceID = " + stringInstanceID + ")");
}
@Override
public int instanceID() {
return instanceID;
}
}

View File

@ -1,365 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import org.scandroid.util.LoaderUtils;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.types.ClassLoaderReference;
public class AndroidSpecs implements ISpecs {
// private AppModelMethod appEntrySummary;
static String act = "Landroid/app/Activity";
static String svc = "Landroid/app/Service";
static String prv = "Landroid/content/ContentProvider";
static String rslv = "Landroid/content/ContentResolver";
static String ctx = "Landroid/content/Context";
static String http = "Landroid/net/AndroidHttpClient";
static String bnd = "Landroid/os/IBinder";
static String lm = "Landroid/location/LocationManager";
static String tm = "Landroid/telephony/TelephonyManager";
static String sms = "android/telephony/SmsManager";
static String smsGsm = "android/telephony/gsm/SmsManager";
static String ll = "Landroid/location/LocationListener";
static String gl = "Landroid/location/GpsStatus$Listener";
static String nl = "Landroid/location/GpsStatus$NmeaListener";
static MethodNamePattern actCreate =
new MethodNamePattern(act, "onCreate");
static MethodNamePattern actStart =
new MethodNamePattern(act, "onStart");
static MethodNamePattern actResume =
new MethodNamePattern(act, "onResume");
static MethodNamePattern actStop =
new MethodNamePattern(act, "onStop");
static MethodNamePattern actRestart =
new MethodNamePattern(act, "onRestart");
static MethodNamePattern actDestroy =
new MethodNamePattern(act, "onDestroy");
static MethodNamePattern actOnActivityResult =
new MethodNamePattern(act, "onActivityResult");
static MethodNamePattern actOnRestoreInstanceState =
new MethodNamePattern(act, "onRestoreInstanceState");
static MethodNamePattern actOnSaveInstanceState =
new MethodNamePattern(act, "onSaveInstanceState");
static MethodNamePattern actSetResult =
new MethodNamePattern(act, "setResult");
static MethodNamePattern actGetIntent =
new MethodNamePattern(act, "getIntent");
static MethodNamePattern actStartActivityForResult =
new MethodNamePattern(act, "startActivityForResult");
static MethodNamePattern actStartActivityIfNeeded =
new MethodNamePattern(act, "startActivityIfNeeded");
static MethodNamePattern actStartNextMatchingActivity =
new MethodNamePattern(act, "startNextMatchingActivity");
static MethodNamePattern actStartActivityFromChild =
new MethodNamePattern(act, "startActivityFromChild");
static MethodNamePattern svcCreate =
new MethodNamePattern(svc, "onCreate");
static MethodNamePattern svcStart =
new MethodNamePattern(svc, "onStart");
static MethodNamePattern svcStartCommand =
new MethodNamePattern(svc, "onStartCommand");
static MethodNamePattern svcBind =
new MethodNamePattern(svc, "onBind");
static MethodNamePattern rslvQuery =
new MethodNamePattern(rslv, "query");
static MethodNamePattern rslvInsert =
new MethodNamePattern(rslv, "insert");
static MethodNamePattern rslvUpdate =
new MethodNamePattern(rslv, "update");
static MethodNamePattern prvCreate =
new MethodNamePattern(prv, "onCreate");
static MethodNamePattern prvQuery =
new MethodNamePattern(prv, "query");
static MethodNamePattern prvInsert =
new MethodNamePattern(prv, "insert");
static MethodNamePattern prvUpdate =
new MethodNamePattern(prv, "update");
static MethodNamePattern ctxStartActivity =
new MethodNamePattern(ctx, "startActivity");
static MethodNamePattern ctxStartService =
new MethodNamePattern(ctx, "startService");
static MethodNamePattern ctxBindService =
new MethodNamePattern(ctx, "bindService");
static MethodNamePattern bndTransact =
new MethodNamePattern(bnd, "transact");
static MethodNamePattern bndOnTransact =
new MethodNamePattern(bnd, "onTransact");
static MethodNamePattern httpExecute =
new MethodNamePattern(http, "execute");
// private static MethodNamePattern[] callbackModelEntry = {
// new MethodNamePattern("Lcom/SCanDroid/AppModel", "entry")
// };
static MethodNamePattern llLocChanged =
new MethodNamePattern(ll, "onLocationChanged");
static MethodNamePattern llProvDisabled =
new MethodNamePattern(ll, "onProviderDisabled");
static MethodNamePattern llProvEnabled =
new MethodNamePattern(ll, "onProviderEnabled");
static MethodNamePattern llStatusChanged =
new MethodNamePattern(ll, "onStatusChanged");
static MethodNamePattern glStatusChanged =
new MethodNamePattern(gl, "onGpsStatusChanged");
static MethodNamePattern nlNmeaRecvd =
new MethodNamePattern(nl, "onNmeaReceived");
private static MethodNamePattern[] defaultCallbacks = {
actCreate,
actStart,
actResume,
actStop,
actRestart,
actDestroy,
actOnActivityResult,
svcCreate,
svcStart,
svcStartCommand,
svcBind,
//svcTransact,
prvCreate,
prvQuery,
prvInsert,
prvUpdate,
llLocChanged,
llProvDisabled,
llProvEnabled,
llStatusChanged,
glStatusChanged,
nlNmeaRecvd,
};
public MethodNamePattern[] getEntrypointSpecs() { return defaultCallbacks; }
private static SourceSpec[] sourceSpecs = {
// new EntryArgSourceSpec( actCreate, null ),
//doesn't have any parameters
// new EntryArgSourceSpec( actStart, null ),
// new EntryArgSourceSpec( actResume, null ),
// new EntryArgSourceSpec( actStop, null ),
// new EntryArgSourceSpec( actRestart, null ),
// new EntryArgSourceSpec( actDestroy, null ),
//track all parameters? or just the Intent data(3)
new EntryArgSourceSpec( actOnActivityResult, new int[] {3}),
// new EntryArgSourceSpec( actOnRestoreInstanceState, null ),
// new EntryArgSourceSpec( actOnSaveInstanceState, null ),
// new EntryArgSourceSpec( svcCreate, null ),
new EntryArgSourceSpec( svcStart, new int[] { 1 } ),
new EntryArgSourceSpec( svcStartCommand, new int[] { 1 } ),
new EntryArgSourceSpec( svcBind, new int[] {1} ),
new EntryArgSourceSpec(bndOnTransact, new int[] { 2 }),
new EntryArgSourceSpec(llLocChanged, null),
new EntryArgSourceSpec(llProvDisabled, null),
new EntryArgSourceSpec(llProvEnabled, null),
new EntryArgSourceSpec(llStatusChanged, null),
new EntryArgSourceSpec(glStatusChanged, null),
new EntryArgSourceSpec(nlNmeaRecvd, null),
//doesn't exist
// new EntryArgSourceSpec( svcTransact, null ),
//no parameters
//new EntryArgSourceSpec( prvCreate, null ),
// new CallArgSourceSpec( prvQuery, new int[] { 2, 3, 4, 5 }, SourceType.PROVIDER_SOURCE),
// new CallArgSourceSpec( prvInsert, new int[] { 2 }, SourceType.PROVIDER_SOURCE),
// new CallArgSourceSpec( prvUpdate, new int[] { 2, 3, 4 }, SourceType.PROVIDER_SOURCE),
new CallArgSourceSpec(bndTransact, new int[] { 3 }),
new CallRetSourceSpec(rslvQuery, new int[] {}),
// new CallRetSourceSpec(httpExecute, new int[] {}),
new CallRetSourceSpec(actGetIntent, new int[] {}),
// new CallRetSourceSpec(new MethodNamePattern("LTest/Apps/GenericSource", "getIntSource"), new int[]{}),
new CallRetSourceSpec(new MethodNamePattern("LTest/Apps/GenericSource", "getStringSource"), new int[]{}),
new CallRetSourceSpec(new MethodNamePattern(lm, "getProviders"), null),
new CallRetSourceSpec(new MethodNamePattern(lm, "getProvider"), null),
new CallRetSourceSpec(new MethodNamePattern(lm, "getLastKnownLocation"), null),
new CallRetSourceSpec(new MethodNamePattern(lm, "isProviderEnabled"), null),
new CallRetSourceSpec(new MethodNamePattern(lm, "getBestProvider"), null),
new CallRetSourceSpec(new MethodNamePattern(tm, "getNeighboringCellInfo"), null),
new CallRetSourceSpec(new MethodNamePattern(tm, "getCellLocation"), null),
};
public SourceSpec[] getSourceSpecs() { return sourceSpecs; }
/**
* TODO: document!
*/
private static SinkSpec[] sinkSpecs = {
new CallArgSinkSpec(actSetResult, new int[] { 2 }),
// new CallArgSinkSpec(bndTransact, new int[] { 2 }),
new CallArgSinkSpec(rslvQuery, new int[] { 2, 3, 4, 5 }),
new CallArgSinkSpec(rslvInsert, new int[] { 2 }),
// new CallArgSinkSpec(rslvUpdate, new int[] { 2, 3, 4 }),
new CallArgSinkSpec(ctxBindService, new int[] { 1 }),
new CallArgSinkSpec(ctxStartService, new int[] { 1 }),
new CallArgSinkSpec(ctxStartActivity, new int[] { 1 }),
new CallArgSinkSpec(actStartActivityForResult, new int[] { 1 }),
new CallArgSinkSpec(actStartActivityIfNeeded, new int[] { 1 }),
new CallArgSinkSpec(actStartNextMatchingActivity, new int[] { 1 }),
new CallArgSinkSpec(actStartActivityFromChild, new int[] { 2 }),
new EntryArgSinkSpec( bndOnTransact, new int[] { 3 } ),
// new EntryArgSinkSpec( actOnActivityResult, new int[] { 2 } ),
// new EntryArgSinkSpec( actOnSaveInstanceState, new int[] { 0 } ),
//new EntryRetSinkSpec(prvQuery),
new CallArgSinkSpec(new MethodNamePattern("LTest/Apps/GenericSink", "setSink"), new int[]{ 1 }),
new CallArgSinkSpec(new MethodNamePattern(smsGsm, "sendTextMessage"), null),
new CallArgSinkSpec(new MethodNamePattern(sms, "sendMultipartTextMessage"), null),
new CallArgSinkSpec(new MethodNamePattern(smsGsm, "sendDataMessage"), null),
new CallArgSinkSpec(new MethodNamePattern(sms, "sendTextMessage"), null),
new CallArgSinkSpec(new MethodNamePattern(smsGsm, "sendMultipartTextMessage"), null),
new CallArgSinkSpec(new MethodNamePattern(sms, "sendDataMessage"), null),
};
public SinkSpec[] getSinkSpecs() { return sinkSpecs; }
private static MethodNamePattern[] callBacks = new MethodNamePattern[]{};
// public MethodNamePattern[] getCallBacks() {
// if (callBacks == null)
// callBacks = new MethodNamePattern[] {};
// return callBacks;
// }
public void addPossibleListeners(ClassHierarchy cha) {
Set<String> ignoreMethods = new HashSet<String>();
ignoreMethods.add("<init>");
ignoreMethods.add("<clinit>");
ignoreMethods.add("registerNatives");
ignoreMethods.add("getClass");
ignoreMethods.add("hashCode");
ignoreMethods.add("equals");
ignoreMethods.add("clone");
ignoreMethods.add("toString");
ignoreMethods.add("notify");
ignoreMethods.add("notifyAll");
ignoreMethods.add("finalize");
ignoreMethods.add("wait");
List<MethodNamePattern> moreEntryPointSpecs = new ArrayList<MethodNamePattern> ();
//add default entrypoints from AndroidSpecs.entrypointSpecs
//Currently adds methods even if they exist in the ignnoreMethods
//set.
for (MethodNamePattern mnp: defaultCallbacks) {
moreEntryPointSpecs.add(mnp);
}
for (IClass ic:cha) {
if (!LoaderUtils.fromLoader(ic, ClassLoaderReference.Application)) {
continue;
}
//finds all *Listener classes and fetches all methods for the listener
if (ic.getName().getClassName().toString().endsWith("Listener")) {
for (IMethod im: ic.getAllMethods()) {
//TODO: add isAbstract()?
if (!ignoreMethods.contains(im.getName().toString()) && !im.isPrivate()) {
moreEntryPointSpecs.add(
new MethodNamePattern(ic.getName().toString(),
im.getName().toString()));
}
}
}
//not a listener, just find all the methods that start with "on____"
else {
for (IMethod im:ic.getAllMethods()) {
//TODO: add isAbstract()?
if (!ignoreMethods.contains(im.getName().toString()) &&
im.getName().toString().startsWith("on") && !im.isPrivate()) {
moreEntryPointSpecs.add(new MethodNamePattern(ic.getName().toString(),
im.getName().toString()));
}
}
}
}
// entrypointSpecs =
callBacks =
moreEntryPointSpecs.toArray(new MethodNamePattern[moreEntryPointSpecs.size()]);
}
public MethodNamePattern[] getCallBacks() {
return callBacks;
}
// public void setEntrySummary(AppModelMethod amm) {
// this.appEntrySummary = amm;
// }
// public AppModelMethod getEntrySummary() {
// return appEntrySummary;
// }
}

View File

@ -1,82 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.ParameterFlow;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
public class CallArgSinkSpec extends SinkSpec {
public CallArgSinkSpec(MethodNamePattern name, int[] args) {
namePattern = name;
argNums = args;
}
@Override
public <E extends ISSABasicBlock> Collection<FlowType<E>> getFlowType(
BasicBlockInContext<E> block) {
HashSet<FlowType<E>> flowSet = new HashSet<FlowType<E>>();
if (argNums == null) {
SSAInvokeInstruction i = (SSAInvokeInstruction) block
.getLastInstruction();
argNums = new int[i.getDeclaredTarget().getNumberOfParameters()];
for (int p = 0; p < argNums.length; p++)
argNums[p] = p;
}
for (int arg : argNums) {
flowSet.add(new ParameterFlow<E>(block, arg, false));
}
return flowSet;
}
@Override
public String toString() {
return String.format("CallArgSinkSpec(%s,%s)",
namePattern.getDescriptor(), Arrays.toString(argNums));
}
}

View File

@ -1,124 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.InstanceKeyElement;
import org.scandroid.flow.InflowAnalysis;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.ParameterFlow;
import org.scandroid.util.CGAnalysisContext;
import com.google.common.collect.Sets;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.callgraph.propagation.PointerKey;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
/**
* CallArgSourceSpecs represent sources that are arguments to another function.
*
* For example, if code you analyze invokes a function {@code foo(Object obj)}
* and foo <em>writes</em> to the argument, then {@code obj} would be a source.
*
*/
public class CallArgSourceSpec extends SourceSpec {
final String name = "CallArgSource";
public CallArgSourceSpec(MethodNamePattern name, int[] args) {
namePattern = name;
argNums = args;
}
@Override
public <E extends ISSABasicBlock> void addDomainElements(
CGAnalysisContext<E> ctx,
Map<BasicBlockInContext<E>, Map<FlowType<E>, Set<CodeElement>>> taintMap,
IMethod target, BasicBlockInContext<E> block,
SSAInvokeInstruction invInst, int[] newArgNums,
ISupergraph<BasicBlockInContext<E>, CGNode> graph,
PointerAnalysis<InstanceKey> pa, CallGraph cg) {
for (int j = 0; j < newArgNums.length; j++) {
for (FlowType<E> ft : getFlowType(block)) {
// a collection of a LocalElement for this argument's SSA value,
// along with a set of InstanceKeyElements for each instance
// that this SSA value might point to
final int ssaVal = invInst.getUse(newArgNums[j]);
final CGNode node = block.getNode();
Set<CodeElement> valueElements = CodeElement.valueElements(pa,
node, ssaVal);
PointerKey pk = pa.getHeapModel().getPointerKeyForLocal(node, ssaVal);
for (InstanceKey ik : pa.getPointsToSet(pk)) {
valueElements.add(new InstanceKeyElement(ik));
}
InflowAnalysis.addDomainElements(taintMap, block, ft,
valueElements);
}
}
}
public <E extends ISSABasicBlock> Collection<FlowType<E>> getFlowType(
BasicBlockInContext<E> block) {
HashSet<FlowType<E>> flowSet = Sets.newHashSet();
for (int i : argNums) {
flowSet.add(new ParameterFlow<E>(block, i, true));
}
return flowSet;
}
@Override
public String toString() {
return String.format("CallArgSourceSpec(%s, %s)", namePattern, Arrays.toString(argNums));
}
}

View File

@ -1,104 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.Collection;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;
import org.scandroid.domain.CodeElement;
import org.scandroid.flow.InflowAnalysis;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.ReturnFlow;
import org.scandroid.util.CGAnalysisContext;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
/**
* CallRetSourceSpecs represent sources from invocations of other methods
* (eg: API methods).
*
* reading file contents, and returning bytes eg: via {@code int read(...)} is
* an example of a call return source.
*/
public class CallRetSourceSpec extends SourceSpec {
final String sig = "CallRetSource";
public CallRetSourceSpec(MethodNamePattern name, int[] args) {
namePattern = name;
argNums = args;
}
@Override
public<E extends ISSABasicBlock> void addDomainElements(CGAnalysisContext<E> ctx,
Map<BasicBlockInContext<E>, Map<FlowType<E>, Set<CodeElement>>> taintMap, IMethod im,
BasicBlockInContext<E> block, SSAInvokeInstruction invInst, int[] newArgNums,
ISupergraph<BasicBlockInContext<E>, CGNode> graph, PointerAnalysis<InstanceKey> pa, CallGraph cg) {
for (FlowType<E> ft:getFlowType(block, invInst,block.getNode(), im, pa)) {
InflowAnalysis.addDomainElements(taintMap, block, ft,
CodeElement.valueElements(pa, block.getNode(), invInst.getDef(0)));
}
}
private<E extends ISSABasicBlock> Collection<FlowType<E>> getFlowType(
BasicBlockInContext<E> block,
SSAInvokeInstruction invInst,
CGNode node, IMethod im, PointerAnalysis<InstanceKey> pa) {
HashSet<FlowType<E>> flowSet = new HashSet<FlowType<E>>();
flowSet.clear();
flowSet.add(new ReturnFlow<E>(block, true));
return flowSet;
}
@Override
public String toString() {
return String.format("CallRetSourceSpec(%s)", namePattern);
}
}

View File

@ -1,81 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.Arrays;
import java.util.Collection;
import java.util.HashSet;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.ParameterFlow;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
public class EntryArgSinkSpec extends SinkSpec {
/**
* @param name
* of the method
* @param args
* to be tainted. These are zero-based; zero refers to `this` for
* a non-static method, or the first parameter of a static method
*/
public EntryArgSinkSpec(MethodNamePattern name, int[] args) {
namePattern = name;
argNums = args;
}
public <E extends ISSABasicBlock> Collection<FlowType<E>> getFlowType(
BasicBlockInContext<E> block) {
HashSet<FlowType<E>> flowSet = new HashSet<FlowType<E>>();
flowSet.clear();
for (int i : argNums) {
flowSet.add(new ParameterFlow<E>(block, i, false));
}
return flowSet;
}
@Override
public String toString() {
return String.format("EntryArgSinkSpec(%s,%s)",
namePattern.getDescriptor(), Arrays.toString(argNums));
}
}

View File

@ -1,130 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.Arrays;
import java.util.Map;
import java.util.Set;
import org.scandroid.domain.CodeElement;
import org.scandroid.flow.InflowAnalysis;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.ParameterFlow;
import org.scandroid.util.CGAnalysisContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
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.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.intset.OrdinalSet;
/**
* Entry arg source specs represent sources that are arguments to methods
* that are entry points.
*
* For example, the command line arguments to a {@code main(String[] args)}
* are entry arg sources.
*
*/
public class EntryArgSourceSpec extends SourceSpec {
private static final Logger logger = LoggerFactory.getLogger(EntryArgSourceSpec.class);
public EntryArgSourceSpec(MethodNamePattern name, int[] args) {
namePattern = name;
argNums = args;
}
@Override
public<E extends ISSABasicBlock> void addDomainElements(CGAnalysisContext<E> ctx,
Map<BasicBlockInContext<E>, Map<FlowType<E>, Set<CodeElement>>> taintMap,
IMethod im, BasicBlockInContext<E> block, SSAInvokeInstruction invInst,
int[] newArgNums,
ISupergraph<BasicBlockInContext<E>, CGNode> graph, PointerAnalysis<InstanceKey> pa, CallGraph cg) {
for(CGNode node: cg.getNodes(im.getReference())) {
for(int i: newArgNums) {
FlowType<E> flow = new ParameterFlow<E>(block, i, true);
final int ssaVal = node.getIR().getParameter(i);
final Set<CodeElement> valueElements = CodeElement.valueElements(pa, node, ssaVal);
PointerKey pk = pa.getHeapModel().getPointerKeyForLocal(node, ssaVal);
final OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
if (pointsToSet.isEmpty()) {
TypeReference typeRef = node.getMethod().getParameterType(i);
IClass clazz = node.getMethod().getClassHierarchy().lookupClass(typeRef);
if (null == clazz) {
logger.error("couldn't find entry arg class {}", typeRef);
} else if (clazz.isInterface()) {
for (IClass impl : pa.getClassHierarchy().getImplementors(typeRef)) {
logger.debug("creating instance key {} for interface {}", impl, clazz);
InstanceKey ik = new ConcreteTypeKey(impl);
valueElements.addAll(ctx.codeElementsForInstanceKey(ik));
}
} else {
InstanceKey ik = new ConcreteTypeKey(clazz);
valueElements.addAll(ctx.codeElementsForInstanceKey(ik));
}
}
for (InstanceKey ik : pointsToSet) {
valueElements.addAll(ctx.codeElementsForInstanceKey(ik));
}
InflowAnalysis.addDomainElements(taintMap, block, flow, valueElements);
logger.debug("added elements for entry {}: {}", this, valueElements);
}
}
}
@Override
public String toString() {
return String.format("EntryArgSourceSpec(%s, %s)", namePattern, Arrays.toString(argNums));
}
}

View File

@ -1,72 +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.spec;
import java.util.Collection;
import java.util.HashSet;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.ReturnFlow;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
public class EntryRetSinkSpec extends SinkSpec {
public EntryRetSinkSpec(MethodNamePattern name) {
namePattern = name;
}
@Override
public <E extends ISSABasicBlock> Collection<FlowType<E>> getFlowType(
BasicBlockInContext<E> block) {
HashSet<FlowType<E>> flowSet = new HashSet<FlowType<E>>();
flowSet.clear();
flowSet.add(new ReturnFlow<E>(block, false));
return flowSet;
}
@Override
public String toString() {
return String.format("EntryRetSinkSpec(%s)",
namePattern.getDescriptor());
}
}

View File

@ -1,72 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.Collection;
import java.util.LinkedList;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IClassLoader;
import com.ibm.wala.types.TypeName;
import com.ibm.wala.util.strings.Atom;
public class FieldNamePattern {
final String className; // null = match any class
final String memberName; // null = match any method
// * used to match arbitrary substrings
public FieldNamePattern(String c, String m) {
className = c;
memberName = m;
}
Collection<IField> lookupFields(IClassLoader cl) {
Collection<IField> matching = new LinkedList<IField>();
IClass c = cl.lookupClass(TypeName.findOrCreate(className));
if(c == null) return matching;
Atom atom = Atom.findOrCreateUnicodeAtom(memberName);
Collection<IField> allFields = c.getAllFields();
for(IField f: allFields) {
if(f.getName().equals(atom)) {
matching.add(f);
}
}
return matching;
}
}

View File

@ -1,42 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
public interface ISinkSpec {
}

View File

@ -1,42 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
public interface ISourceSpec{
}

View File

@ -1,73 +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.spec;
public interface ISpecs {
/* A list of functions that are entry points. Arguments to these
* functions that are considered sources should be in the
* SourceSpec list. */
public MethodNamePattern[] getEntrypointSpecs();
/* Other methods that source data via their return values or
* modification of their parameters. */
public SourceSpec[] getSourceSpecs();
/* Methods that sink data supplied by some of their parameters. */
public SinkSpec[] getSinkSpecs();
public static ISpecs EMPTY_SPECS = new ISpecs() {
@Override
public SourceSpec[] getSourceSpecs() {
return new SourceSpec[] {};
}
@Override
public SinkSpec[] getSinkSpecs() {
return new SinkSpec[] {};
}
@Override
public MethodNamePattern[] getEntrypointSpecs() {
return new MethodNamePattern[] {};
}
};
}

View File

@ -1,146 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.io.UTFDataFormatException;
import java.util.Collection;
import java.util.LinkedList;
import java.util.Set;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.Descriptor;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.collections.HashSetFactory;
import com.ibm.wala.util.strings.Atom;
public class MethodNamePattern {
final private String className;
final private String memberName;
final private String descriptor; // null = match any types
public MethodNamePattern(String c, String m, String d) {
className = c;
memberName = m;
descriptor = d;
}
public MethodNamePattern(String c, String m) {
className = c;
memberName = m;
descriptor = null;
}
private Collection<IMethod> lookupMethods(IClass c) {
Collection<IMethod> matching = new LinkedList<IMethod>();
Atom atom = Atom.findOrCreateUnicodeAtom(memberName);
Descriptor desc = descriptor == null ? null : Descriptor.findOrCreateUTF8(descriptor);
Collection<IMethod> allMethods = c.getAllMethods();
for(IMethod m: allMethods) {
if(m.getName().equals(atom) && (desc == null || m.getDescriptor().equals(desc))) {
matching.add(m);
}
}
return matching;
}
/**
* Returns a Collection of IMethods which are found in the following
* ClassLoaders: Application, Primordial, Extension
* @param cha
* @return
*/
public Collection<IMethod> getPossibleTargets(IClassHierarchy cha) {
Collection<IMethod> matching = new LinkedList<IMethod>();
IClass c;
c = cha.lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Application, className));
if (c != null)
matching.addAll(lookupMethods(c));
c = cha.lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Primordial, className));
if (c != null)
matching.addAll(lookupMethods(c));
c = cha.lookupClass(TypeReference.findOrCreate(ClassLoaderReference.Extension, className));
if (c != null)
matching.addAll(lookupMethods(c));
Set<IMethod> targets = HashSetFactory.make();
for(IMethod im:matching) {
targets.addAll(cha.getPossibleTargets(im.getReference()));
}
return targets;
}
@Override
public String toString() {
String returnString = "MethodNamePattern (Class: "+className+
" - Method: "+memberName;
if (descriptor == null)
return returnString+")";
return returnString+" - Descriptor: "+descriptor+")";
}
public String getDescriptor() {
return String.format("%s.%s%s", className, memberName, descriptor == null ? "" : descriptor);
}
public String getClassName() {
return className;
}
public String getMemberName() {
return memberName;
}
public static MethodNamePattern patternForReference(MethodReference methodRef)
throws UTFDataFormatException {
String className = methodRef.getDeclaringClass().getName().toUnicodeString();
String methodName = methodRef.getName().toUnicodeString();
String descriptor = methodRef.getDescriptor().toUnicodeString();
MethodNamePattern pattern = new MethodNamePattern(className, methodName, descriptor);
return pattern;
}
}

View File

@ -1,52 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
class ResolvedSpec {
ResolvedSpec() {
// AndroidSpecs spec = new AndroidSpecs();
//
// for(MethodNamePattern m: spec.getEntrypointSpecs()) {
// }
// for(SourceSpec s: spec.getSourceSpecs()) {
// }
// for(ISinkSpec s: spec.getSinkSpecs()) {
// }
}
}

View File

@ -1,79 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@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.spec;
import java.util.Arrays;
import java.util.Collection;
import org.scandroid.flow.types.FlowType;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
public abstract class SinkSpec implements ISinkSpec {
protected MethodNamePattern namePattern;
// Zero-based arguments, but 0 is 'this'
protected int[] argNums; // null = all arguments, empty = no arguments?
public static int[] getNewArgNums(int n) {
int[] newArgNums = new int[n];
for (int i = 0; i < n; i++) {
newArgNums[i] = i + 1;
}
return newArgNums;
}
public MethodNamePattern getNamePattern() {
return namePattern;
}
public int[] getArgNums() {
return argNums;
}
@Override
public String toString() {
return "SinkSpec [namePattern=" + namePattern + ", argNums="
+ Arrays.toString(argNums) + "]";
}
abstract public <E extends ISSABasicBlock> Collection<FlowType<E>> getFlowType(
BasicBlockInContext<E> block);
}

View File

@ -1,92 +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.spec;
import java.util.Map;
import java.util.Set;
import org.scandroid.domain.CodeElement;
import org.scandroid.flow.types.FlowType;
import org.scandroid.util.CGAnalysisContext;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.InstanceKey;
import com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
public abstract class SourceSpec implements ISourceSpec {
protected MethodNamePattern namePattern;
protected int[] argNums; // null = all arguments, empty = no arguments?
public static int[] getNewArgNums(int n) {
int[] newArgNums = new int[n];
for (int i = 0; i < n; i++) {
newArgNums[i] = i+1;
}
return newArgNums;
}
public MethodNamePattern getNamePattern() {
return namePattern;
}
public int[] getArgNums() {
return argNums;
}
@Override
public abstract String toString();
abstract public<E extends ISSABasicBlock> void addDomainElements(CGAnalysisContext<E> ctx,
Map<BasicBlockInContext<E>, Map<FlowType<E>,Set<CodeElement>>> taintMap,
IMethod im, BasicBlockInContext<E> block, SSAInvokeInstruction invInst,
int[] newArgNums, ISupergraph<BasicBlockInContext<E>, CGNode> graph,
PointerAnalysis<InstanceKey> pa, CallGraph cg);
}

View File

@ -1,91 +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.spec;
import java.lang.reflect.Array;
public class SpecUtils {
/**
* Combine two specs objects.
*
* @param s1
* @param s2
* @return
*/
public static ISpecs combine(final ISpecs s1, final ISpecs s2) {
return new ISpecs() {
@Override
public SourceSpec[] getSourceSpecs() {
SourceSpec[] s1Sources = s1.getSourceSpecs();
SourceSpec[] s2Sources = s2.getSourceSpecs();
return concat(s1Sources, s2Sources);
}
@Override
public SinkSpec[] getSinkSpecs() {
return concat(s1.getSinkSpecs(), s2.getSinkSpecs());
}
@Override
public MethodNamePattern[] getEntrypointSpecs() {
return concat(s1.getEntrypointSpecs(), s2.getEntrypointSpecs());
}
@SuppressWarnings("unchecked")
private <T> T[] concat(final T[] a, final T[] b) {
if (null == a) {
return b;
}
if (null == b) {
return a;
}
T[] newArray = (T[]) Array.newInstance(a.getClass().getComponentType(), a.length + b.length);
System.arraycopy(a, 0, newArray, 0, a.length);
System.arraycopy(b, 0, newArray, a.length, b.length);
return newArray;
}
};
}
}

View File

@ -1,94 +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.spec;
import java.util.Collection;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.StaticFieldFlow;
import com.google.common.collect.Sets;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cfg.BasicBlockInContext;
import com.ibm.wala.ssa.ISSABasicBlock;
/**
* @author acfoltzer
*
*/
public class StaticFieldSinkSpec extends SinkSpec {
private final IField field;
private final IMethod method;
/**
* @param field to check for flows
* @param method to check for flow (at method's exit), e.g., main
*/
public StaticFieldSinkSpec(IField field, IMethod method) {
this.field = field;
this.method = method;
}
/* (non-Javadoc)
* @see org.scandroid.spec.SinkSpec#getFlowType(com.ibm.wala.ipa.cfg.BasicBlockInContext)
*/
@Override
public <E extends ISSABasicBlock> Collection<FlowType<E>> getFlowType(
BasicBlockInContext<E> block) {
@SuppressWarnings("unchecked")
Collection<FlowType<E>> flow = Sets.newHashSet((FlowType<E>) new StaticFieldFlow<E>(block, field, false));
return flow;
}
@Override
public String toString() {
return String.format("StaticFieldSinkSpec(%s)", field);
}
public IField getField() {
return field;
}
public IMethod getMethod() {
return method;
}
}

View File

@ -1,151 +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.spec;
import java.util.Map;
import java.util.Set;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.InstanceKeyElement;
import org.scandroid.domain.StaticFieldElement;
import org.scandroid.flow.InflowAnalysis;
import org.scandroid.flow.types.FlowType;
import org.scandroid.flow.types.StaticFieldFlow;
import org.scandroid.util.CGAnalysisContext;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Sets;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.ipa.callgraph.CallGraph;
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
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.cfg.BasicBlockInContext;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.intset.OrdinalSet;
/**
* @author creswick
*
*/
public class StaticFieldSourceSpec extends SourceSpec {
private static final Logger logger = LoggerFactory.getLogger(EntryArgSourceSpec.class);
private final IField field;
public StaticFieldSourceSpec(IField field) {
this.field = field;
argNums = null;
}
/* (non-Javadoc)
* @see org.scandroid.spec.SourceSpec#addDomainElements(java.util.Map, com.ibm.wala.classLoader.IMethod, com.ibm.wala.ipa.cfg.BasicBlockInContext, com.ibm.wala.ssa.SSAInvokeInstruction, int[], com.ibm.wala.dataflow.IFDS.ISupergraph, com.ibm.wala.ipa.callgraph.propagation.PointerAnalysis, com.ibm.wala.ipa.callgraph.CallGraph)
*/
@Override
public <E extends ISSABasicBlock> void addDomainElements(
CGAnalysisContext<E> ctx,
Map<BasicBlockInContext<E>, Map<FlowType<E>, Set<CodeElement>>> taintMap,
IMethod im,
BasicBlockInContext<E> block,
SSAInvokeInstruction invInst,
int[] newArgNums,
ISupergraph<BasicBlockInContext<E>, CGNode> graph,
PointerAnalysis<InstanceKey> pa,
CallGraph cg) {
Set<CodeElement> valueElements = Sets.newHashSet();
valueElements.add(new StaticFieldElement(field.getReference()));
FlowType<E> flow = new StaticFieldFlow<E>(block, field, true);
TypeReference typeRef = field.getFieldTypeReference();
if (typeRef.isPrimitiveType()) {
InflowAnalysis.addDomainElements(taintMap, block, flow, valueElements);
return;
}
// else, handle reference types:
PointerKey pk = pa.getHeapModel().getPointerKeyForStaticField(field);
OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
if (pointsToSet.isEmpty()) {
IClassHierarchy cha = im.getClassHierarchy();
if (null == cha.lookupClass(typeRef)) {
logger.warn("could not resolve class for {}", field);
return;
}
if (cha.isInterface(typeRef)) {
// TODO we could find all implementations of the interface, and add a concrete type key for each.
// we aren't doing that yet.
InflowAnalysis.addDomainElements(taintMap, block, flow, valueElements);
return;
}
IClass clazz = cha.lookupClass(typeRef);
if (null == clazz) {
logger.error("couldn't find entry arg class {}", typeRef);
} else {
InstanceKey ik = new ConcreteTypeKey(clazz);
valueElements.add(new InstanceKeyElement(ik));
}
}
for (InstanceKey ik : pointsToSet) {
valueElements.add(new InstanceKeyElement(ik));
}
InflowAnalysis.addDomainElements(taintMap, block, flow, valueElements);
}
@Override
public String toString() {
return "StaticFieldSourceSpec [field=" + field + "]";
}
}

View File

@ -1,127 +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.spec;
import java.util.Collection;
import java.util.Iterator;
import java.util.List;
import com.google.common.collect.Lists;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.util.strings.StringStuff;
/**
* @author creswick
*
*/
public class StaticSpecs implements ISpecs {
private final ClassHierarchy cha;
private final String methodSignature;
private final Collection<IField> fields;
public StaticSpecs(ClassHierarchy cha, String methodSignature) {
this.cha = cha;
this.methodSignature = methodSignature;
this.fields = collectFields();
}
/* (non-Javadoc)
* @see org.scandroid.spec.ISpecs#getEntrypointSpecs()
*/
@Override
public MethodNamePattern[] getEntrypointSpecs() {
return new MethodNamePattern[0];
}
/* (non-Javadoc)
* @see org.scandroid.spec.ISpecs#getSourceSpecs()
*/
@Override
public SourceSpec[] getSourceSpecs() {
// List<SourceSpec> specs = Lists.newArrayList();
//
// for (IField field : fields) {
// specs.add(new StaticFieldSourceSpec(field));
// }
//
// return specs.toArray(new SourceSpec[] {});
return new SourceSpec[] {};
}
/**
* @return
*/
private List<IField> collectFields() {
List<IField> fields = Lists.newArrayList();
Iterator<IClass> itr = cha.iterator();
while (itr.hasNext()) {
IClass cls = itr.next();
for (IField field : cls.getAllStaticFields()) {
if (field.getFieldTypeReference().isReferenceType()) {
fields.add(field);
}
}
}
return fields;
}
/* (non-Javadoc)
* @see org.scandroid.spec.ISpecs#getSinkSpecs()
*/
@Override
public SinkSpec[] getSinkSpecs() {
List<SinkSpec> specs = Lists.newArrayList();
Collection<IMethod> methods = cha.getPossibleTargets(StringStuff.makeMethodReference(methodSignature));
for (IField field : fields) {
if (!field.isFinal()) {
for (IMethod method : methods) {
specs.add(new StaticFieldSinkSpec(field, method));
}
}
}
return specs.toArray(new SinkSpec[] {});
}
}

View File

@ -1,181 +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.synthmethod;
import java.io.File;
import java.net.URI;
import org.scandroid.util.ISCanDroidOptions;
import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions;
import com.ibm.wala.util.io.FileProvider;
public abstract class DefaultSCanDroidOptions implements ISCanDroidOptions {
@Override
public boolean pdfCG() {
return false;
}
@Override
public boolean pdfPartialCG() {
return false;
}
@Override
public boolean pdfOneLevelCG() {
return false;
}
@Override
public boolean systemToApkCG() {
return false;
}
@Override
public boolean stdoutCG() {
return true;
}
@Override
public boolean includeLibrary() {
// TODO is this right? we haven't summarized with CLI options set, so
// this is what we've been doing...
return true;
}
@Override
public boolean separateEntries() {
return false;
}
@Override
public boolean ifdsExplorer() {
return false;
}
@Override
public boolean addMainEntrypoints() {
return false;
}
@Override
public boolean useThreadRunMain() {
return false;
}
@Override
public boolean stringPrefixAnalysis() {
return false;
}
@Override
public boolean testCGBuilder() {
return false;
}
@Override
public boolean useDefaultPolicy() {
return false;
}
@Override
public abstract URI getClasspath();
@Override
public String getFilename() {
return new File(getClasspath()).getName();
}
@Override
public URI getAndroidLibrary() {
try {
return new FileProvider().getResource("data/android-2.3.7_r1.jar").toURI();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public ReflectionOptions getReflectionOptions() {
return ReflectionOptions.NONE;
}
@Override
public URI getSummariesURI() {
try {
return new FileProvider().getResource("data/MethodSummaries.xml").toURI();
} catch (Exception e) {
throw new RuntimeException(e);
}
}
@Override
public boolean classHierarchyWarnings() {
return false;
}
@Override
public boolean cgBuilderWarnings() {
return false;
}
public static String dumpString(ISCanDroidOptions options) {
return "DefaultSCanDroidOptions [pdfCG()=" + options.pdfCG()
+ ", pdfPartialCG()=" + options.pdfPartialCG() + ", pdfOneLevelCG()="
+ options.pdfOneLevelCG() + ", systemToApkCG()=" + options.systemToApkCG()
+ ", stdoutCG()=" + options.stdoutCG() + ", includeLibrary()="
+ options.includeLibrary() + ", separateEntries()=" + options.separateEntries()
+ ", ifdsExplorer()=" + options.ifdsExplorer()
+ ", addMainEntrypoints()=" + options.addMainEntrypoints()
+ ", useThreadRunMain()=" + options.useThreadRunMain()
+ ", stringPrefixAnalysis()=" + options.stringPrefixAnalysis()
+ ", testCGBuilder()=" + options.testCGBuilder()
+ ", useDefaultPolicy()=" + options.useDefaultPolicy()
+ ", getClasspath()=" + options.getClasspath() + ", getFilename()="
+ options.getFilename() + ", getAndroidLibrary()="
+ options.getAndroidLibrary() + ", getReflectionOptions()="
+ options.getReflectionOptions() + ", getSummariesURI()="
+ options.getSummariesURI() + ", classHierarchyWarnings()="
+ options.classHierarchyWarnings() + ", cgBuilderWarnings()="
+ options.cgBuilderWarnings() + "]";
}
}

View File

@ -1,51 +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.synthmethod;
public class SSASerializationException extends RuntimeException {
private static final long serialVersionUID = 5679383911644331821L;
public SSASerializationException(Exception e) {
super(e);
}
public SSASerializationException(String string) {
super(string);
}
}

View File

@ -1,500 +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.synthmethod;
import java.io.UTFDataFormatException;
import java.util.List;
import java.util.Map;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSABinaryOpInstruction;
import com.ibm.wala.ssa.SSACheckCastInstruction;
import com.ibm.wala.ssa.SSAComparisonInstruction;
import com.ibm.wala.ssa.SSAConditionalBranchInstruction;
import com.ibm.wala.ssa.SSAConversionInstruction;
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAGotoInstruction;
import com.ibm.wala.ssa.SSAInstanceofInstruction;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSALoadMetadataInstruction;
import com.ibm.wala.ssa.SSAMonitorInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAPhiInstruction;
import com.ibm.wala.ssa.SSAPiInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.ssa.SSASwitchInstruction;
import com.ibm.wala.ssa.SSAThrowInstruction;
import com.ibm.wala.ssa.SSAUnaryOpInstruction;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.strings.Atom;
public class SSAtoXMLVisitor implements SSAInstruction.IVisitor {
private static final Logger logger = LoggerFactory.getLogger(SSAtoXMLVisitor.class);
/**
* A counter to use for generating unique local definition names.
*/
private int defCounter = 0;
/**
* Map the known defNum to local def names.
*/
private Map<Integer, String> localDefs = Maps.newHashMap();
/**
* XML document to use for creating elements.
*/
private final Document doc;
/**
* XML elements that represent the ssa instructions
*/
private final List<Element> summary = Lists.newArrayList();
public SSAtoXMLVisitor(Document doc, int argCount) {
this.doc = doc;
for (int i=0; i < argCount; i++) {
localDefs.put(i+1, "arg"+i);
}
}
@Override
public void visitGoto(SSAGotoInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
/**
* Load from an array ref, at specified index, and store in def.
*
* <aaload ref="x" index="0" def="y" />
*/
@Override
public void visitArrayLoad(SSAArrayLoadInstruction instruction) {
try {
Element elt = doc.createElement(XMLSummaryWriter.E_AALOAD);
String refStr = getLocalName(instruction.getArrayRef());
elt.setAttribute(XMLSummaryWriter.A_REF, refStr);
String defStr = getLocalName(instruction.getDef());
elt.setAttribute(XMLSummaryWriter.A_VALUE, defStr);
elt.setAttribute(XMLSummaryWriter.A_INDEX, ""+instruction.getIndex());
summary.add(elt);
} catch (Exception e) {
throw new SSASerializationException(e);
}
}
/**
* <aastore ref="x" value="y" index="0" />
*/
@Override
public void visitArrayStore(SSAArrayStoreInstruction instruction) {
try {
Element elt = doc.createElement(XMLSummaryWriter.E_AASTORE);
String refStr = getLocalName(instruction.getArrayRef());
elt.setAttribute(XMLSummaryWriter.A_REF, refStr);
String valueStr = getLocalName(instruction.getValue());
elt.setAttribute(XMLSummaryWriter.A_VALUE, valueStr);
elt.setAttribute(XMLSummaryWriter.A_INDEX, ""+instruction.getIndex());
summary.add(elt);
} catch (Exception e) {
throw new SSASerializationException(e);
}
}
@Override
public void visitBinaryOp(SSABinaryOpInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitUnaryOp(SSAUnaryOpInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitConversion(SSAConversionInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitComparison(SSAComparisonInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitConditionalBranch(
SSAConditionalBranchInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitSwitch(SSASwitchInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitReturn(SSAReturnInstruction instruction) {
try {
Element elt = doc.createElement(XMLSummaryWriter.E_RETURN);
if (!instruction.returnsVoid()) {
String localName = getLocalName(instruction.getResult());
elt.setAttribute(XMLSummaryWriter.A_VALUE, localName);
}
summary.add(elt);
} catch (Exception e) {
throw new SSASerializationException(e);
}
}
/**
* eg:
*
* <getfield class="Ljava/lang/Thread" field="runnable"
* fieldType="Ljava/lang/Runnable" def="x" ref="arg0" />
*
* I think the get statics look like this:
* 1007g 9.1g 12m S 237.9 0.9 4:27.32 java
* <getstatic class="Ljava/lang/Thread" field="runnable"
* fieldType="Ljava/lang/Runnable" def="x" />
*/
@Override
public void visitGet(SSAGetInstruction instruction) {
try {
String eltName;
if (instruction.isStatic()) {
eltName = XMLSummaryWriter.E_GETSTATIC;
} else {
eltName = XMLSummaryWriter.E_GETFIELD;
}
Element elt = doc.createElement(eltName);
if (!instruction.isStatic()) {
String refName = getLocalName(instruction.getRef());
elt.setAttribute(XMLSummaryWriter.A_REF, refName);
}
String def = newLocalDef(instruction.getDef());
TypeReference fieldType = instruction.getDeclaredFieldType();
TypeReference classType = instruction.getDeclaredField()
.getDeclaringClass();
String fieldName = instruction.getDeclaredField().getName()
.toUnicodeString();
elt.setAttribute(XMLSummaryWriter.A_CLASS, classType.getName().toUnicodeString());
elt.setAttribute(XMLSummaryWriter.A_FIELD, fieldName);
elt.setAttribute(XMLSummaryWriter.A_FIELD_TYPE,
fieldType.getName().toUnicodeString());
elt.setAttribute(XMLSummaryWriter.A_DEF, def);
summary.add(elt);
} catch (Exception e) {
throw new SSASerializationException(e);
}
}
/**
* <putstatic class="Ljava/lang/System" field="security"
* fieldType="Ljava/lang/SecurityManager" value="secure" />
*
* <putfield class="Ljava/lang/Thread" field="runnable"
* fieldType="Ljava/lang/Runnable" ref="arg0" value="arg0" />
*
*/
@Override
public void visitPut(SSAPutInstruction instruction) {
try {
String eltName;
if (instruction.isStatic()) {
eltName = XMLSummaryWriter.E_PUTSTATIC;
} else {
eltName = XMLSummaryWriter.E_PUTFIELD;
}
Element elt = doc.createElement(eltName);
if (!instruction.isStatic()) {
String refName = getLocalName(instruction.getRef());
elt.setAttribute(XMLSummaryWriter.A_REF, refName);
}
String value = getLocalName(instruction.getVal());
TypeReference fieldType = instruction.getDeclaredFieldType();
TypeReference classType = instruction.getDeclaredField()
.getDeclaringClass();
String fieldName = instruction.getDeclaredField().getName()
.toUnicodeString();
elt.setAttribute(XMLSummaryWriter.A_CLASS, classType.getName().toUnicodeString());
elt.setAttribute(XMLSummaryWriter.A_FIELD, fieldName);
elt.setAttribute(XMLSummaryWriter.A_FIELD_TYPE,
fieldType.getName().toUnicodeString());
elt.setAttribute(XMLSummaryWriter.A_VALUE, value);
summary.add(elt);
} catch (Exception e) {
throw new SSASerializationException(e);
}
}
/**
* <call type="virtual" name="put"
* class="Ljava/util/Hashtable"
* descriptor="(Ljava/lang/Object;Ljava/lang/Object;)Ljava/lang/Object;"
* arg0="x" arg1="key" arg2="value" def="local_def" />
*/
@Override
public void visitInvoke(SSAInvokeInstruction instruction) {
try {
Element elt = doc.createElement(XMLSummaryWriter.E_CALL);
MethodReference callee = instruction.getDeclaredTarget();
String descString = callee.getDescriptor().toUnicodeString();
elt.setAttribute(XMLSummaryWriter.A_DESCRIPTOR, descString);
String typeString =
instruction.getCallSite().getInvocationString();
elt.setAttribute(XMLSummaryWriter.A_TYPE, typeString);
String nameString = callee.getName().toUnicodeString();
elt.setAttribute(XMLSummaryWriter.A_NAME, nameString);
String classString = instruction.getDeclaredTarget().getDeclaringClass().getName().toUnicodeString();
elt.setAttribute(XMLSummaryWriter.A_CLASS, classString);
if (! instruction.getDeclaredResultType().equals(TypeReference.Void) ) {
int defNum = instruction.getDef();
String localName = newLocalDef(defNum);
elt.setAttribute(XMLSummaryWriter.A_DEF, localName);
}
int paramCount = instruction.getNumberOfParameters();
for (int i=0; i < paramCount; i++) {
String argName = getLocalName(instruction.getUse(i));
elt.setAttribute(XMLSummaryWriter.A_ARG+i, argName);
}
summary.add(elt);
} catch (Exception e) {
throw new SSASerializationException(e);
}
}
@Override
public void visitNew(SSANewInstruction instruction) {
try {
int defNum = instruction.getDef();
String localName = newLocalDef(defNum);
TypeReference type = instruction.getConcreteType();
String className = type.getName().toUnicodeString();
Element elt = doc.createElement(XMLSummaryWriter.E_NEW);
elt.setAttribute(XMLSummaryWriter.A_DEF, localName);
elt.setAttribute(XMLSummaryWriter.A_CLASS, className);
if (type.isArrayType()) {
// array allocations need a size value
Element sizeElt = doc.createElement(XMLSummaryWriter.E_CONSTANT);
final String sizeName = "sizeOf$allocAt" + instruction.getNewSite().getProgramCounter();
sizeElt.setAttribute(XMLSummaryWriter.A_NAME, sizeName);
sizeElt.setAttribute(XMLSummaryWriter.A_TYPE, "int");
sizeElt.setAttribute(XMLSummaryWriter.A_VALUE, "1");
summary.add(sizeElt);
elt.setAttribute(XMLSummaryWriter.A_SIZE, sizeName);
}
summary.add(elt);
} catch (Exception e) {
throw new SSASerializationException(e);
}
}
@Override
public void visitArrayLength(SSAArrayLengthInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
/**
* Serialiaze a throw to XML.
*
* Something like this?
*
* <throw value="val_localDef" />
*/
@Override
public void visitThrow(SSAThrowInstruction instruction) {
throw new SSASerializationException("Exceptions not currently supported.");
// try {
// int exValNo = instruction.getException();
// String value = getLocalName(exValNo);
//
// Element elt = doc.createElement(XMLSummaryWriter.E_ATHROW);
// elt.setAttribute(XMLSummaryWriter.A_VALUE, value);
// summary.add(elt);
// } catch (Exception e) {
// throw new SSASerializationException(e);
// }
}
@Override
public void visitMonitor(SSAMonitorInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitCheckCast(SSACheckCastInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitInstanceof(SSAInstanceofInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitPhi(SSAPhiInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitPi(SSAPiInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitGetCaughtException(
SSAGetCaughtExceptionInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
@Override
public void visitLoadMetadata(SSALoadMetadataInstruction instruction) {
throw new SSASerializationException("Unsupported.");
}
/**
* Add a new defNum, creating a name for that defnum.
*
* @param defNum
*/
private String newLocalDef(int defNum) {
String newName = "localdef_" + defCounter;
localDefs.put(defNum, newName);
defCounter++;
return newName;
}
/**
* Get a local name for the provided defNum.
*
* If, for some reason, the defNum has not yet been seen (and, thus, has no
* local name associated with it) then this will throw an illegal state
* exception.
*
* TODO needs to return 'arg0' -> 'argN' for those value numbers...
*
* @param defNum
*
* @return
* @throws IllegalStateException
*/
private String getLocalName(int defNum) throws IllegalStateException {
if (0 == defNum) {
return "unknown";
}
if (localDefs.containsKey(defNum)) {
return localDefs.get(defNum);
}
return XMLSummaryWriter.A_ARG + (defNum - 1);
// throw new IllegalStateException("defNum: " + defNum
// + " is not defined.");
}
public List<Element> getInstSummary() {
return summary;
}
@SuppressWarnings("unused")
private String typeRefToStr(TypeReference fieldType)
throws UTFDataFormatException {
Atom className = fieldType.getName().getClassName();
Atom pkgName = fieldType.getName().getPackage();
if ( null == pkgName && null != className ) {
logger.debug("pkg name null for type ref: "+fieldType);
return className.toUnicodeString();
}
if (null == className ) {
logger.debug("className null for type ref: "+fieldType);
}
return pkgName.toUnicodeString() + "/" + className.toUnicodeString();
}
}

View File

@ -1,298 +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.synthmethod;
import java.io.ByteArrayOutputStream;
import java.io.UTFDataFormatException;
import java.util.List;
import java.util.Map;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import javax.xml.parsers.ParserConfigurationException;
import javax.xml.transform.OutputKeys;
import javax.xml.transform.Transformer;
import javax.xml.transform.TransformerConfigurationException;
import javax.xml.transform.TransformerException;
import javax.xml.transform.TransformerFactory;
import javax.xml.transform.dom.DOMSource;
import javax.xml.transform.stream.StreamResult;
import org.w3c.dom.DOMException;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import com.google.common.collect.Maps;
import com.ibm.wala.ipa.summaries.MethodSummary;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.strings.Atom;
public class XMLSummaryWriter {
//
// Define XML element names
//
final static String E_CLASSLOADER = "classloader";
final static String E_METHOD = "method";
final static String E_CLASS = "class";
final static String E_PACKAGE = "package";
final static String E_CALL = "call";
final static String E_NEW = "new";
final static String E_POISON = "poison";
final static String E_SUMMARY_SPEC = "summary-spec";
final static String E_RETURN = "return";
final static String E_PUTSTATIC = "putstatic";
final static String E_GETSTATIC = "getstatic";
final static String E_PUTFIELD = "putfield";
final static String E_AALOAD = "aaload";
final static String E_AASTORE = "aastore";
final static String E_GETFIELD = "getfield";
final static String E_ATHROW = "throw";
final static String E_CONSTANT = "constant";
//
// Define XML attribute names
//
final static String A_NAME = "name";
final static String A_TYPE = "type";
final static String A_CLASS = "class";
final static String A_SIZE = "size";
final static String A_DESCRIPTOR = "descriptor";
final static String A_REASON = "reason";
final static String A_LEVEL = "level";
final static String A_WILDCARD = "*";
final static String A_DEF = "def";
final static String A_STATIC = "static";
final static String A_VALUE = "value";
final static String A_FIELD = "field";
final static String A_FIELD_TYPE = "fieldType";
final static String A_ARG = "arg";
final static String A_ALLOCATABLE = "allocatable";
final static String A_REF = "ref";
final static String A_INDEX = "index";
final static String A_IGNORE = "ignore";
final static String A_FACTORY = "factory";
final static String A_NUM_ARGS = "numArgs";
final static String V_NULL = "null";
final static String V_TRUE = "true";
private final Document doc;
private final Element rootElement;
private Element clrElt = null;
private Element pkgElt = null;
private final Map<Atom, Element> classElts;
public XMLSummaryWriter() throws ParserConfigurationException {
DocumentBuilderFactory docFactory = DocumentBuilderFactory
.newInstance();
DocumentBuilder docBuilder = docFactory.newDocumentBuilder();
doc = docBuilder.newDocument();
rootElement = doc.createElement(E_SUMMARY_SPEC);
doc.appendChild(rootElement);
classElts = Maps.newHashMap();
}
public String serialize() {
ByteArrayOutputStream baos = new ByteArrayOutputStream();
// write the content into xml file
TransformerFactory transformerFactory =
TransformerFactory.newInstance();
// transformerFactory.setAttribute("indent-number", new Integer(4));
try {
Transformer transformer = transformerFactory.newTransformer();
transformer.setOutputProperty(OutputKeys.INDENT, "yes");
transformer.setOutputProperty(
"{http://xml.apache.org/xslt}indent-amount", "2");
DOMSource source = new DOMSource(doc);
StreamResult result = new StreamResult(baos);
transformer.transform(source, result);
} catch (TransformerConfigurationException e) {
e.printStackTrace();
} catch (IllegalArgumentException e) {
e.printStackTrace();
} catch (TransformerException e) {
e.printStackTrace();
}
// using the default encoding here, since the bytes were just written
// with a default encoding...
return baos.toString();
}
/**
* Throws various exceptions if a problem occurred serializing this method.
*
* No guarantees as to the state of the Document if an exception is thrown.
*
* @param summary
* @return
* @throws DOMException
* @throws UTFDataFormatException
* @throws SSASerializationException
*/
public void add(MethodSummary summary) throws UTFDataFormatException {
// create a method element, and populate it's attributes:
Element methElt;
TypeReference methClass = summary.getMethod().getDeclaringClass();
Atom clrName = methClass.getClassLoader().getName();
Atom pkg = methClass.getName().getPackage();
Atom className = methClass.getName().getClassName();
Atom methodName = summary.getMethod().getName();
methElt = doc.createElement(E_METHOD);
methElt.setAttribute(A_NAME, methodName.toUnicodeString());
String descriptor = getMethodDescriptor(summary);
methElt.setAttribute(A_DESCRIPTOR, descriptor);
// default is false:
if (summary.isStatic()) {
methElt.setAttribute(A_STATIC, "true");
}
// default is false:
if (summary.isFactory()) {
methElt.setAttribute(A_FACTORY, "true");
}
// summarize the instructions:
List<Element> instructions = summarizeInstructions(summary);
for (Element elt : instructions) {
methElt.appendChild(elt);
}
// get an element to add this method to:
Element classElt = findOrCreateClassElt(clrName, pkg, className);
classElt.appendChild(methElt);
}
private Element findOrCreateClassElt(Atom classLoaderName, Atom pkg, Atom className)
throws UTFDataFormatException {
Element classElt = classElts.get(className);
if (classElt == null) {
Element pkgElt = findOrCreatePkgElt(classLoaderName, pkg);
classElt = doc.createElement(E_CLASS);
classElt.setAttribute(A_NAME, className.toUnicodeString());
pkgElt.appendChild(classElt);
classElts.put(className, classElt);
}
return classElt;
}
private Element findOrCreateClrElt(Atom classLoaderName) throws DOMException,
UTFDataFormatException {
if (clrElt == null) {
clrElt = doc.createElement(E_CLASSLOADER);
clrElt.setAttribute(A_NAME, classLoaderName.toUnicodeString());
rootElement.appendChild(clrElt);
}
return clrElt;
}
private Element findOrCreatePkgElt(Atom classLoaderName, Atom pkg) throws UTFDataFormatException {
if (pkgElt == null) {
Element clrElt = findOrCreateClrElt(classLoaderName);
pkgElt = doc.createElement(E_PACKAGE);
pkgElt.setAttribute(A_NAME, pkg.toUnicodeString());
clrElt.appendChild(pkgElt);
}
return pkgElt;
}
private List<Element> summarizeInstructions(MethodSummary summary) {
SSAtoXMLVisitor v =
new SSAtoXMLVisitor(doc, summary.getNumberOfParameters());
for (SSAInstruction inst : summary.getStatements()) {
inst.visit(v);
}
return v.getInstSummary();
}
/**
* Generate a method descriptor, such as
* (I[Ljava/lang/String;)[Ljava/lang/String;
*
* @param summary
* @return
*/
private String getMethodDescriptor(MethodSummary summary) {
StringBuilder typeSigs = new StringBuilder("(");
int i=0;
if (!summary.isStatic()) {
i = 1; // if it's not static, start with param 1.
}
for (; i < summary.getNumberOfParameters(); i++) {
TypeReference tr = summary.getParameterType(i);
// unwrap array types
while (tr.isArrayType()) {
typeSigs.append("[");
tr = tr.getArrayElementType();
}
if (tr.isPrimitiveType()) {
typeSigs.append(tr.getName().toUnicodeString());
} else {
typeSigs.append(tr.getName().toUnicodeString()+ ";");
}
}
typeSigs.append(")");
TypeReference returnType = summary.getReturnType();
if (returnType.isPrimitiveType()) {
typeSigs.append(returnType.getName().toUnicodeString());
} else {
typeSigs.append(returnType.getName().toUnicodeString() + ";");
}
String descriptor = typeSigs.toString();
return descriptor;
}
}

View File

@ -1,384 +0,0 @@
/**
*
* Copyright (c) 2009-2012,
*
* Adam Fuchs <afuchs@cs.umd.edu>
* Avik Chaudhuri <avik@cs.umd.edu>
* Steve Suh <suhsteve@gmail.com>
* Galois, Inc. (Adam Foltzer <acfoltzer@galois.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.util;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.net.URISyntaxException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Map;
import java.util.Set;
import org.scandroid.synthmethod.DefaultSCanDroidOptions;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Lists;
import com.google.common.collect.Maps;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
import com.ibm.wala.classLoader.IClass;
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;
import com.ibm.wala.ipa.callgraph.ClassTargetSelector;
import com.ibm.wala.ipa.callgraph.ContextSelector;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.MethodTargetSelector;
import com.ibm.wala.ipa.callgraph.impl.Util;
import com.ibm.wala.ipa.callgraph.propagation.SSAContextInterpreter;
import com.ibm.wala.ipa.callgraph.propagation.SSAPropagationCallGraphBuilder;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXCFABuilder;
import com.ibm.wala.ipa.callgraph.propagation.cfa.ZeroXInstanceKeys;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ipa.cha.ClassHierarchyException;
import com.ibm.wala.ipa.cha.IClassHierarchy;
import com.ibm.wala.ipa.summaries.BypassClassTargetSelector;
import com.ibm.wala.ipa.summaries.BypassMethodTargetSelector;
import com.ibm.wala.ipa.summaries.MethodSummary;
import com.ibm.wala.ipa.summaries.XMLMethodSummaryReader;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.CancelException;
import com.ibm.wala.util.io.FileProvider;
import com.ibm.wala.util.strings.Atom;
import com.ibm.wala.util.warnings.Warning;
import com.ibm.wala.util.warnings.Warnings;
public class AndroidAnalysisContext {
private static final Logger logger = LoggerFactory
.getLogger(AndroidAnalysisContext.class);
static {
// ((ch.qos.logback.classic.Logger) logger).setLevel(Level.TRACE);
}
private static final String methodSpec = "MethodSummaries.xml";
private static final String pathToSpec = "data";
private final ISCanDroidOptions options;
private final AnalysisScope scope;
private final ClassHierarchy cha;
public AndroidAnalysisContext() {
throw new IllegalArgumentException();
}
public AndroidAnalysisContext(ISCanDroidOptions options)
throws IllegalArgumentException, ClassHierarchyException,
IOException, CancelException, URISyntaxException {
this(options, new FileProvider().getFile(/**"conf" + File.separator
+ */"Java60RegressionExclusions.txt"));
}
/**
* @param exclusions
* @param classpath
* @param packagename
* @throws IOException
* @throws IllegalArgumentException
* @throws CancelException
* @throws ClassHierarchyException
* @throws URISyntaxException
*/
public AndroidAnalysisContext(ISCanDroidOptions options, File exclusions)
throws IOException, IllegalArgumentException, CancelException,
ClassHierarchyException, URISyntaxException {
logger.debug(DefaultSCanDroidOptions.dumpString(options));
this.options = options;
scope = AndroidAnalysisScope.setUpAndroidAnalysisScope(options.getAndroidLibrary(), options.getClasspath(), exclusions);
cha = ClassHierarchy.make(scope);
if (options.classHierarchyWarnings()) {
// log ClassHierarchy warnings
for (Iterator<Warning> wi = Warnings.iterator(); wi.hasNext();) {
Warning w = wi.next();
logger.warn(w.getMsg());
}
}
Warnings.clear();
}
// ContextSelector, entry points, reflection options, IR Factory, call graph
// type, include library
public void buildGraphs(List<Entrypoint> localEntries,
InputStream summariesStream) throws CancelException {
}
public static SSAPropagationCallGraphBuilder makeVanillaZeroOneCFABuilder(
AnalysisOptions options, AnalysisCache cache, IClassHierarchy cha,
AnalysisScope scope, ContextSelector customSelector,
SSAContextInterpreter customInterpreter,
InputStream summariesStream, MethodSummary extraSummary) {
if (options == null) {
throw new IllegalArgumentException("options is null");
}
Util.addDefaultSelectors(options, cha);
// addDefaultBypassLogic(options, scope, Util.class.getClassLoader(),
// cha);
// addBypassLogic(options, scope,
// AndroidAppLoader.class.getClassLoader(), methodSpec, cha);
addBypassLogic(options, scope, summariesStream, cha, extraSummary);
return ZeroXCFABuilder.make(cha, options, cache, customSelector,
customInterpreter, ZeroXInstanceKeys.ALLOCATIONS
| ZeroXInstanceKeys.CONSTANT_SPECIFIC);
}
/**
* @param options
* options that govern call graph construction
* @param cha
* governing class hierarchy
* @param scope
* representation of the analysis scope
* @param customSelector
* user-defined context selector, or null if none
* @param customInterpreter
* user-defined context interpreter, or null if none
* @return a 0-CFA Call Graph Builder.
* @throws IllegalArgumentException
* if options is null
*
* TODO: move
*/
public static SSAPropagationCallGraphBuilder makeZeroCFABuilder(
AnalysisOptions options, AnalysisCache cache, IClassHierarchy cha,
AnalysisScope scope, ContextSelector customSelector,
SSAContextInterpreter customInterpreter,
InputStream summariesStream, MethodSummary extraSummary) {
return makeZeroCFABuilder(options, cache, cha, scope,
customSelector, customInterpreter, Lists.newArrayList(summariesStream),
extraSummary);
}
/**
* @param options
* options that govern call graph construction
* @param cha
* governing class hierarchy
* @param scope
* representation of the analysis scope
* @param customSelector
* user-defined context selector, or null if none
* @param customInterpreter
* user-defined context interpreter, or null if none
* @return a 0-CFA Call Graph Builder.
* @throws IllegalArgumentException
* if options is null
*
* TODO: move
*/
public static SSAPropagationCallGraphBuilder makeZeroCFABuilder(
AnalysisOptions options, AnalysisCache cache, IClassHierarchy cha,
AnalysisScope scope, ContextSelector customSelector,
SSAContextInterpreter customInterpreter,
Collection<InputStream> summariesStreams, MethodSummary extraSummary) {
if (options == null) {
throw new IllegalArgumentException("options is null");
}
Util.addDefaultSelectors(options, cha);
for (InputStream stream : summariesStreams) {
addBypassLogic(options, scope, stream, cha, extraSummary);
}
return ZeroXCFABuilder.make(cha, options, cache, customSelector,
customInterpreter, ZeroXInstanceKeys.NONE);
}
// public static void addBypassLogic(AnalysisOptions options, AnalysisScope
// scope, ClassLoader cl, String xmlFile,
// IClassHierarchy cha) throws IllegalArgumentException {
public static void addBypassLogic(AnalysisOptions options,
AnalysisScope scope, InputStream xmlIStream, IClassHierarchy cha,
MethodSummary extraSummary) throws IllegalArgumentException {
if (scope == null) {
throw new IllegalArgumentException("scope is null");
}
if (options == null) {
throw new IllegalArgumentException("options is null");
}
// if (cl == null) {
// throw new IllegalArgumentException("cl is null");
// }
if (cha == null) {
throw new IllegalArgumentException("cha cannot be null");
}
InputStream s = null;
try {
Set<TypeReference> summaryClasses = Sets.newHashSet();
Map<MethodReference, MethodSummary> summaries = Maps.newHashMap();
if (null != xmlIStream) {
XMLMethodSummaryReader newSummaryXML = loadMethodSummaries(
scope, xmlIStream);
summaryClasses.addAll(newSummaryXML.getAllocatableClasses());
for (MethodSummary summary : newSummaryXML.getSummaries().values()) {
logger.trace("SSA instructions for summary of {}:\n{}", summary.getMethod().getSignature().toString(), Arrays.toString(summary.getStatements()));
}
summaries.putAll(newSummaryXML.getSummaries());
}
logger.debug("loaded " + summaries.size() + " new summaries");
// for (MethodReference mr : summaries.keySet()) {
// logger.debug("summary loaded for: "+mr.getSignature());
// }
s = new FileProvider().getInputStreamFromClassLoader(pathToSpec
+ File.separator + methodSpec,
AndroidAnalysisContext.class.getClassLoader());
XMLMethodSummaryReader nativeSummaries = loadMethodSummaries(scope,
s);
logger.debug("loaded " + nativeSummaries.getSummaries().size()
+ " native summaries");
summaries.putAll(nativeSummaries.getSummaries());
summaryClasses.addAll(nativeSummaries.getAllocatableClasses());
if (extraSummary != null) {
summaries.put((MethodReference) extraSummary.getMethod(),
extraSummary);
}
MethodTargetSelector ms = new BypassMethodTargetSelector(
options.getMethodTargetSelector(), summaries,
nativeSummaries.getIgnoredPackages(), cha);
options.setSelector(ms);
ClassTargetSelector cs = new BypassClassTargetSelector(
options.getClassTargetSelector(), summaryClasses, cha,
cha.getLoader(scope.getLoader(Atom
.findOrCreateUnicodeAtom("Synthetic"))));
options.setSelector(cs);
} catch (FileNotFoundException e) {
e.printStackTrace();
} finally {
if (null != s) {
try {
s.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
private static XMLMethodSummaryReader loadMethodSummaries(
AnalysisScope scope, InputStream xmlIStream)
throws FileNotFoundException {
InputStream s = xmlIStream;
XMLMethodSummaryReader summary = null;
try {
if (null == s) {
s = AndroidAnalysisContext.class.getClassLoader()
.getResourceAsStream(
pathToSpec + File.separator + methodSpec);
}
summary = new XMLMethodSummaryReader(s, scope);
} finally {
try {
if (null != s) {
s.close();
}
} catch (IOException e) {
e.printStackTrace();
}
}
return summary;
}
/**
* Returns all concrete classes implementing the given interface or any subinterfaces
* @param iRoot
* @return
*/
public Collection<IClass> concreteClassesForInterface(IClass iRoot) {
Set<IClass> clazzes = Sets.newHashSet();
Set<IClass> done = Sets.newHashSet();
Deque<IClass> todo = Queues.newArrayDeque();
todo.push(iRoot);
while (!todo.isEmpty()) {
IClass i = todo.pop();
for (IClass clazz : cha.getImplementors(i.getReference())) {
if (clazz.isInterface() && !done.contains(clazz)) {
done.add(i);
todo.push(clazz);
} else if (!clazz.isAbstract()) {
clazzes.add(clazz);
}
}
}
return clazzes;
}
public ISCanDroidOptions getOptions() {
return options;
}
public AnalysisScope getScope() {
return scope;
}
public ClassHierarchy getClassHierarchy() {
return cha;
}
}

View File

@ -1,430 +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.util;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import java.io.InputStream;
import java.util.ArrayList;
import java.util.Collection;
import java.util.Deque;
import java.util.Iterator;
import java.util.List;
import java.util.Set;
import org.scandroid.domain.CodeElement;
import org.scandroid.domain.FieldElement;
import org.scandroid.domain.InstanceKeyElement;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.google.common.collect.Queues;
import com.google.common.collect.Sets;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IField;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.dalvik.classLoader.DexIRFactory;
import com.ibm.wala.dataflow.IFDS.ICFGSupergraph;
import com.ibm.wala.dataflow.IFDS.ISupergraph;
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.DefaultContextSelector;
import com.ibm.wala.ipa.callgraph.impl.Everywhere;
import com.ibm.wala.ipa.callgraph.impl.PartialCallGraph;
import com.ibm.wala.ipa.callgraph.propagation.ConcreteTypeKey;
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.cfg.BasicBlockInContext;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.ssa.IRFactory;
import com.ibm.wala.ssa.ISSABasicBlock;
import com.ibm.wala.ssa.SSACFG;
import com.ibm.wala.ssa.SSACFG.BasicBlock;
import com.ibm.wala.ssa.SSAInstruction;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.TypeReference;
import com.ibm.wala.util.Predicate;
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.warnings.Warning;
import com.ibm.wala.util.warnings.Warnings;
/**
* @author acfoltzer
*
* Represents an analysis context after the call graph, pointer
* analysis, and supergraphs have been generated. This is separated from
* AndroidAnalysisContext since these depend on the entrypoints for
* analysis in a way that is not likely reusable across all analyses of
* a particular classpath
*/
public class CGAnalysisContext<E extends ISSABasicBlock> {
private static final Logger logger = LoggerFactory.getLogger(CGAnalysisContext.class);
public final AndroidAnalysisContext analysisContext;
private List<Entrypoint> entrypoints;
public CallGraph cg;
public PointerAnalysis<InstanceKey> pa;
public ISupergraph<BasicBlockInContext<E>, CGNode> graph;
public Graph<CGNode> oneLevelGraph;
public Graph<CGNode> systemToApkGraph;
public Graph<CGNode> partialGraph;
public CGAnalysisContext(AndroidAnalysisContext analysisContext, IEntryPointSpecifier specifier)
throws IOException {
this(analysisContext, specifier, new ArrayList<InputStream>());
}
@SuppressWarnings({ "rawtypes", "unchecked" })
public CGAnalysisContext(AndroidAnalysisContext analysisContext, IEntryPointSpecifier specifier,
Collection<InputStream> extraSummaries) throws IOException {
this.analysisContext = analysisContext;
final AnalysisScope scope = analysisContext.getScope();
final ClassHierarchy cha = analysisContext.getClassHierarchy();
final ISCanDroidOptions options = analysisContext.getOptions();
entrypoints = specifier.specify(analysisContext);
AnalysisOptions analysisOptions = new AnalysisOptions(scope, entrypoints);
for (Entrypoint e : entrypoints) {
logger.debug("Entrypoint: " + e);
}
analysisOptions.setReflectionOptions(options.getReflectionOptions());
AnalysisCache cache = new AnalysisCache((IRFactory<IMethod>) new DexIRFactory());
SSAPropagationCallGraphBuilder cgb;
if (null != options.getSummariesURI()) {
extraSummaries.add(new FileInputStream(new File(options.getSummariesURI())));
}
cgb = AndroidAnalysisContext.makeZeroCFABuilder(analysisOptions, cache, cha, scope,
new DefaultContextSelector(analysisOptions, cha), null, extraSummaries, null);
if (analysisContext.getOptions().cgBuilderWarnings()) {
// CallGraphBuilder construction warnings
for (Iterator<Warning> wi = Warnings.iterator(); wi.hasNext();) {
Warning w = wi.next();
logger.warn(w.getMsg());
}
}
Warnings.clear();
logger.info("*************************");
logger.info("* Building Call Graph *");
logger.info("*************************");
boolean graphBuilt = true;
try {
cg = cgb.makeCallGraph(cgb.getOptions());
} catch (Exception e) {
graphBuilt = false;
if (!options.testCGBuilder()) {
throw new RuntimeException(e);
} else {
e.printStackTrace();
}
}
if (options.testCGBuilder()) {
// TODO: this is too specialized for cmd-line apps
int status = graphBuilt ? 0 : 1;
System.exit(status);
}
// makeCallGraph warnings
for (Iterator<Warning> wi = Warnings.iterator(); wi.hasNext();) {
Warning w = wi.next();
logger.warn(w.getMsg());
}
Warnings.clear();
pa = cgb.getPointerAnalysis();
partialGraph = GraphSlicer.prune(cg, new Predicate<CGNode>() {
@Override
// CallGraph composed of APK nodes
public boolean test(CGNode node) {
return LoaderUtils.fromLoader(node, ClassLoaderReference.Application) || node.getMethod().isSynthetic();
}
});
if (options.includeLibrary()) {
graph = (ISupergraph) ICFGSupergraph.make(cg, cache);
} else {
Collection<CGNode> nodes = Sets.newHashSet();
for (Iterator<CGNode> nIter = partialGraph.iterator(); nIter.hasNext();) {
nodes.add(nIter.next());
}
CallGraph pcg = PartialCallGraph.make(cg, cg.getEntrypointNodes(), nodes);
graph = (ISupergraph) ICFGSupergraph.make(pcg, cache);
}
oneLevelGraph = GraphSlicer.prune(cg, new Predicate<CGNode>() {
@Override
public boolean test(CGNode node) {
// Node in APK
if (LoaderUtils.fromLoader(node, ClassLoaderReference.Application)) {
return true;
} else {
Iterator<CGNode> n = cg.getPredNodes(node);
while (n.hasNext()) {
// Primordial node has a successor in APK
if (LoaderUtils.fromLoader(n.next(), ClassLoaderReference.Application))
return true;
}
n = cg.getSuccNodes(node);
while (n.hasNext()) {
// Primordial node has a predecessor in APK
if (LoaderUtils.fromLoader(n.next(), ClassLoaderReference.Application))
return true;
}
// Primordial node with no direct successors or predecessors
// to APK code
return false;
}
}
});
systemToApkGraph = GraphSlicer.prune(cg, new Predicate<CGNode>() {
@Override
public boolean test(CGNode node) {
if (LoaderUtils.fromLoader(node, ClassLoaderReference.Primordial)) {
Iterator<CGNode> succs = cg.getSuccNodes(node);
while (succs.hasNext()) {
CGNode n = succs.next();
if (LoaderUtils.fromLoader(n, ClassLoaderReference.Application)) {
return true;
}
}
// Primordial method, with no link to APK code:
return false;
} else if (LoaderUtils.fromLoader(node, ClassLoaderReference.Application)) {
// see if this is an APK method that was
// invoked by a Primordial method:
Iterator<CGNode> preds = cg.getPredNodes(node);
while (preds.hasNext()) {
CGNode n = preds.next();
if (LoaderUtils.fromLoader(n, ClassLoaderReference.Primordial)) {
return true;
}
}
// APK code, no link to Primordial:
return false;
}
// who knows, not interesting:
return false;
}
});
if (options.stdoutCG()) {
for (Iterator<CGNode> nodeI = cg.iterator(); nodeI.hasNext();) {
CGNode node = nodeI.next();
logger.debug("CGNode: " + node);
for (Iterator<CGNode> succI = cg.getSuccNodes(node); succI.hasNext();) {
logger.debug("\tSuccCGNode: " + succI.next().getMethod().getSignature());
}
}
}
for (Iterator<CGNode> nodeI = cg.iterator(); nodeI.hasNext();) {
CGNode node = nodeI.next();
if (node.getMethod().isSynthetic()) {
logger.trace("Synthetic Method: {}", node.getMethod().getSignature());
logger.trace("{}", node.getIR().getControlFlowGraph().toString());
SSACFG ssaCFG = node.getIR().getControlFlowGraph();
int totalBlocks = ssaCFG.getNumberOfNodes();
for (int i = 0; i < totalBlocks; i++) {
logger.trace("BLOCK #{}", i);
BasicBlock bb = ssaCFG.getBasicBlock(i);
for (SSAInstruction ssaI : bb.getAllInstructions()) {
logger.trace("\tInstruction: {}", ssaI);
}
}
}
}
}
/**
* @param rootIK
* @return a set of all code elements that might refer to this object or one
* of its fields (recursively)
*/
public Set<CodeElement> codeElementsForInstanceKey(InstanceKey rootIK) {
Set<CodeElement> elts = Sets.newHashSet();
Deque<InstanceKey> iks = Queues.newArrayDeque();
iks.push(rootIK);
while (!iks.isEmpty()) {
InstanceKey ik = iks.pop();
logger.debug("getting code elements for {}", ik);
elts.add(new InstanceKeyElement(ik));
final IClass clazz = ik.getConcreteType();
final TypeReference typeRef = clazz.getReference();
// If an array, recur down into the structure
if (typeRef.isArrayType()) {
if (typeRef.getArrayElementType().isPrimitiveType()) {
// don't do anything for primitive contents
continue;
}
OrdinalSet<InstanceKey> pointsToSet =
pa.getPointsToSet(pa.getHeapModel().getPointerKeyForArrayContents(ik));
if (pointsToSet.isEmpty()) {
logger.debug("pointsToSet empty for array contents, creating InstanceKey manually");
final IClass contentsClass = pa.getClassHierarchy().lookupClass(typeRef.getArrayElementType());
if (contentsClass.isInterface()) {
for (IClass implementor : analysisContext.concreteClassesForInterface(contentsClass)) {
final InstanceKey contentsIK = new ConcreteTypeKey(implementor);
final InstanceKeyElement elt = new InstanceKeyElement(contentsIK);
if (!elts.contains(elt)) {
elts.add(elt);
iks.push(contentsIK);
}
}
} else {
InstanceKey contentsIK = new ConcreteTypeKey(contentsClass);
final InstanceKeyElement elt = new InstanceKeyElement(contentsIK);
if (!elts.contains(elt)) {
elts.add(elt);
iks.push(contentsIK);
}
}
} else {
for (InstanceKey contentsIK : pointsToSet) {
final InstanceKeyElement elt = new InstanceKeyElement(contentsIK);
if (!elts.contains(elt)) {
elts.add(elt);
iks.push(contentsIK);
}
}
}
continue;
}
for (IField field : clazz.getAllInstanceFields()) {
logger.debug("adding elements for field {}", field);
final TypeReference fieldTypeRef = field.getFieldTypeReference();
elts.add(new FieldElement(ik, field.getReference()));
final IClass fieldClass = analysisContext.getClassHierarchy().lookupClass(fieldTypeRef);
if (fieldTypeRef.isPrimitiveType() || fieldClass == null) {
continue;
} else if (fieldTypeRef.isArrayType()) {
PointerKey pk = pa.getHeapModel().getPointerKeyForInstanceField(ik, field);
final OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
if (pointsToSet.isEmpty()) {
logger.debug("pointsToSet empty for array field, creating InstanceKey manually");
InstanceKey fieldIK = new ConcreteTypeKey(pa.getClassHierarchy().lookupClass(fieldTypeRef));
final InstanceKeyElement elt = new InstanceKeyElement(fieldIK);
if (!elts.contains(elt)) {
elts.add(elt);
iks.push(fieldIK);
}
} else {
for (InstanceKey fieldIK : pointsToSet) {
final InstanceKeyElement elt = new InstanceKeyElement(fieldIK);
if (!elts.contains(elt)) {
elts.add(elt);
iks.push(fieldIK);
}
}
}
} else if (fieldTypeRef.isReferenceType()) {
PointerKey pk = pa.getHeapModel().getPointerKeyForInstanceField(ik, field);
final OrdinalSet<InstanceKey> pointsToSet = pa.getPointsToSet(pk);
if (pointsToSet.isEmpty() && !analysisContext.getClassHierarchy().isInterface(fieldTypeRef)) {
logger.debug("pointsToSet empty for reference field, creating InstanceKey manually");
InstanceKey fieldIK = new ConcreteTypeKey(fieldClass);
final InstanceKeyElement elt = new InstanceKeyElement(fieldIK);
if (!elts.contains(elt)) {
elts.add(elt);
iks.push(fieldIK);
}
} else {
for (InstanceKey fieldIK : pointsToSet) {
final InstanceKeyElement elt = new InstanceKeyElement(fieldIK);
if (!elts.contains(elt)) {
elts.add(elt);
iks.push(fieldIK);
}
}
}
} else {
logger.warn("unknown field type {}", field);
}
}
}
return elts;
}
public ISCanDroidOptions getOptions() {
return analysisContext.getOptions();
}
public ClassHierarchy getClassHierarchy() {
return analysisContext.getClassHierarchy();
}
public AnalysisScope getScope() {
return analysisContext.getScope();
}
public List<Entrypoint> getEntrypoints() {
return entrypoints;
}
public CGNode nodeForMethod(IMethod method) {
return cg.getNode(method, Everywhere.EVERYWHERE);
}
}

View File

@ -1,321 +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.util;
import java.io.File;
import java.net.URI;
import org.apache.commons.cli.CommandLine;
import org.apache.commons.cli.CommandLineParser;
import org.apache.commons.cli.HelpFormatter;
import org.apache.commons.cli.OptionBuilder;
import org.apache.commons.cli.Options;
import org.apache.commons.cli.ParseException;
import org.apache.commons.cli.PosixParser;
import org.slf4j.LoggerFactory;
import ch.qos.logback.classic.Level;
import ch.qos.logback.classic.Logger;
import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions;
@SuppressWarnings("static-access")
public class CLISCanDroidOptions implements ISCanDroidOptions {
private static final String VERBOSE = "verbose";
private static final String REFLECTION = "reflection";
private static final String ANDROID_LIB = "android-lib";
private static final String CHECK_POLICY = "check-policy";
private static final String TEST_CGB = "test-cgb";
private static final String SUMMARIES_FILE = "summaries-file";
private static final String PREFIX_ANALYSIS = "prefix-analysis";
private static final String THREAD_RUN_MAIN = "thread-run-main";
private static final String STDOUT_CALL_GRAPH = "stdout-call-graph";
private static final String MAIN_ENTRYPOINT = "main-entrypoint";
private static final String IFDS_EXPLORER = "IFDS-Explorer";
private static final String SEPARATE_ENTRIES = "separate-entries";
private static final String INCLUDE_LIBRARY = "include-library";
private static final String SYSTEM_TO_APK_CALL_GRAPH = "system-to-apk-call-graph";
private static final String ONE_LEVEL_CALL_GRAPH = "one-level-call-graph";
private static final String PARTIAL_CALL_GRAPH = "partial-call-graph";
private static final String CALL_GRAPH = "call-graph";
private CommandLineParser parser = new PosixParser();
private CommandLine line;
private URI classpath;
private String filename;
private URI androidLib;
private URI summariesFile;
private ReflectionOptions reflectionOptions;
private static final String USAGE = "[options] <.apk or .jar>";
private final Options options = new Options();
{
options.addOption("h", "help", false, "print this message");
options.addOption(OptionBuilder
.withLongOpt(VERBOSE)
.withDescription(
"logging level (default INFO) [OFF, ERROR, WARN, INFO, DEBUG, TRACE, ALL]")
.hasArg().withArgName("level").create());
options.addOption("c", CALL_GRAPH, false, "create full call graph pdf");
options.addOption("p", PARTIAL_CALL_GRAPH, false,
"create partial call graph pdf (Application only)");
options.addOption("o", ONE_LEVEL_CALL_GRAPH, false,
"create one level call graph pdf (Application + 1 level of System calls)");
options.addOption("s", SYSTEM_TO_APK_CALL_GRAPH, false,
"create system to apk callgraph (System + 1 level of Application calls)");
options.addOption("l", INCLUDE_LIBRARY, false,
"analyze library in flow analysis");
options.addOption("e", SEPARATE_ENTRIES, false,
"analyze each entry point separately");
options.addOption("i", IFDS_EXPLORER, false,
"bring up a gui to analyze domainelements for flow analysis");
options.addOption("m", MAIN_ENTRYPOINT, false,
"look for main methods and add them as entrypoints");
options.addOption("a", STDOUT_CALL_GRAPH, false,
"output full call graph to stdout");
options.addOption("t", THREAD_RUN_MAIN, false,
"use ServerThread.run as the entry point for analysis");
options.addOption("x", PREFIX_ANALYSIS, false,
"run string prefix analysis");
options.addOption("f", SUMMARIES_FILE, true,
"Use the specified summaries xml file");
options.addOption(OptionBuilder
.withLongOpt(TEST_CGB)
.withDescription(
"Only load the call graph, exit status indicates success")
.create());
options.addOption("y", CHECK_POLICY, false,
"Check conformance with built-in policy");
options.addOption(OptionBuilder.withLongOpt(ANDROID_LIB)
.withDescription("include ALIB in scope of analysis").hasArg()
.withArgName("ALIB").create());
options.addOption(OptionBuilder
.withLongOpt(REFLECTION)
.withDescription(
"FULL, NO_FLOW_TO_CASTS, NO_METHOD_INVOKE, NO_FLOW_TO_CASTS_NO_METHOD_INVOKE, ONE_FLOW_TO_CASTS_NO_METHOD_INVOKE, NO_STRING_CONSTANTS, NONE (Default)")
.hasArg().withArgName("option").create());
}
public CLISCanDroidOptions(String[] args, boolean reqArgs) {
try {
line = parser.parse(options, args);
} catch (ParseException exp) {
System.err.println("Unexpected exception: " + exp.getMessage());
System.err.println("Usage: " + USAGE);
System.exit(0);
}
if (hasOption("help")) {
HelpFormatter formatter = new HelpFormatter();
formatter.printHelp(USAGE, options);
System.exit(0);
}
// handle verbosity
// parse this arg as a Logback level, then set the root logger level
// appropriately
Level level = Level.toLevel(getOption(VERBOSE), Level.INFO);
Logger root = (Logger) LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);
root.setLevel(level);
if (!hasOption(ANDROID_LIB)) {
System.err.println("Please specify an android library");
System.exit(0);
}
classpath = processClasspath(reqArgs);
filename = processFilename();
androidLib = processURIArg(getOption(ANDROID_LIB));
summariesFile = processURIArg(getOption(SUMMARIES_FILE));
reflectionOptions = processReflectionOptions();
if (reqArgs
&& !(filename.endsWith(".apk") || filename.endsWith(".jar"))) {
System.err.println("Usage: " + USAGE);
System.exit(0);
}
}
private URI processURIArg(String arg) {
if (arg == null) {
return null;
} else {
return new File(arg).toURI();
}
}
private URI processClasspath(boolean reqArgs) {
// getArgs() returns all args that are not recognized;
String[] myargs = line.getArgs();
if ((myargs.length != 1 || !(myargs[0].endsWith(".apk") || myargs[0]
.endsWith(".jar"))) && reqArgs) {
System.err.println("Usage: " + USAGE);
System.exit(0);
}
return processURIArg(myargs[0]);
}
private String processFilename() {
if (classpath == null)
return null;
return new File(classpath).getName();
}
private ReflectionOptions processReflectionOptions() {
final String reflection = getOption(REFLECTION);
if (reflection == null) {
return ReflectionOptions.NONE;
} else {
return ReflectionOptions.valueOf(reflection);
}
}
private boolean hasOption(String s) {
return line != null && line.hasOption(s);
}
private String getOption(String s) {
return line.getOptionValue(s);
}
@Override
public boolean pdfCG() {
return hasOption(CALL_GRAPH);
}
@Override
public boolean pdfPartialCG() {
return hasOption(PARTIAL_CALL_GRAPH);
}
@Override
public boolean pdfOneLevelCG() {
return hasOption(ONE_LEVEL_CALL_GRAPH);
}
@Override
public boolean systemToApkCG() {
return hasOption(SYSTEM_TO_APK_CALL_GRAPH);
}
@Override
public boolean stdoutCG() {
return hasOption(STDOUT_CALL_GRAPH);
}
@Override
public boolean includeLibrary() {
return hasOption(INCLUDE_LIBRARY);
}
@Override
public boolean separateEntries() {
return hasOption(SEPARATE_ENTRIES);
}
@Override
public boolean ifdsExplorer() {
return hasOption(IFDS_EXPLORER);
}
@Override
public boolean addMainEntrypoints() {
return hasOption(MAIN_ENTRYPOINT);
}
@Override
public boolean useThreadRunMain() {
return hasOption(THREAD_RUN_MAIN);
}
@Override
public boolean stringPrefixAnalysis() {
return hasOption(PREFIX_ANALYSIS);
}
@Override
public boolean testCGBuilder() {
return hasOption(TEST_CGB);
}
@Override
public boolean useDefaultPolicy() {
return hasOption(CHECK_POLICY);
}
@Override
public URI getClasspath() {
return classpath;
}
@Override
public String getFilename() {
return filename;
}
@Override
public URI getAndroidLibrary() {
return androidLib;
}
@Override
public ReflectionOptions getReflectionOptions() {
return reflectionOptions;
}
@Override
public URI getSummariesURI() {
return summariesFile;
}
@Override
public boolean classHierarchyWarnings() {
// TODO Auto-generated method stub
return true;
}
@Override
public boolean cgBuilderWarnings() {
// TODO Auto-generated method stub
return true;
}
}

View File

@ -1,311 +0,0 @@
/*******************************************************************************
* Copyright (c) 2002 - 2006, 2011 IBM Corporation and others.
* All rights reserved. This program and the accompanying materials
* are made available under the terms of the Eclipse Public License v1.0
* which accompanies this distribution, and is available at
* http://www.eclipse.org/legal/epl-v10.html
*
* Contributors:
* IBM Corporation - initial API and implementation
* Steve Suh <suhsteve@gmail.com> - added cleanUpString
*******************************************************************************/
package org.scandroid.util;
import java.io.BufferedInputStream;
import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.util.Arrays;
import java.util.Collection;
import java.util.Iterator;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import com.ibm.wala.util.WalaException;
import com.ibm.wala.util.collections.Iterator2Collection;
import com.ibm.wala.util.debug.Assertions;
import com.ibm.wala.util.graph.Graph;
import com.ibm.wala.viz.DotUtil;
import com.ibm.wala.viz.NodeDecorator;
public class DexDotUtil extends DotUtil {
private static final Logger logger = LoggerFactory.getLogger(DexDotUtil.class);
/**
* possible output formats for dot
*
*/
// public static enum DotOutputType {
// PS, SVG, PDF, EPS
// }
private static DotOutputType outputType = DotOutputType.PDF;
private static int fontSize = 6;
private static String fontColor = "black";
private static String fontName = "Arial";
// public static void setOutputType(DotOutputType outType) {
// outputType = outType;
// }
// public static DotOutputType getOutputType() {
// return outputType;
// }
private static String outputTypeCmdLineParam() {
switch (outputType) {
case PS:
return "-Tps";
case EPS:
return "-Teps";
case SVG:
return "-Tsvg";
case PDF:
return "-Tpdf";
default:
Assertions.UNREACHABLE();
return null;
}
}
/**
* Some versions of dot appear to croak on long labels. Reduce this if so.
*/
private final static int MAX_LABEL_LENGTH = Integer.MAX_VALUE;
/**
*/
public static <T> void dotify(Graph<T> g, NodeDecorator<T> labels, String dotFile, String outputFile, String dotExe)
throws WalaException {
dotify(g, labels, null, dotFile, outputFile, dotExe);
}
public static <T> void dotify(Graph<T> g, NodeDecorator<T> labels, String title, String dotFile, String outputFile, String dotExe)
throws WalaException {
if (g == null) {
throw new IllegalArgumentException("g is null");
}
File f = DexDotUtil.writeDotFile(g, labels, title, dotFile);
spawnDot(dotExe, outputFile, f);
}
public static void spawnDot(String dotExe, String outputFile, File dotFile) throws WalaException {
if (dotFile == null) {
throw new IllegalArgumentException("dotFile is null");
}
String[] cmdarray = { dotExe, outputTypeCmdLineParam(), "-o", outputFile, "-v", dotFile.getAbsolutePath() };
logger.debug("spawning process " + Arrays.toString(cmdarray));
BufferedInputStream output = null;
BufferedInputStream error = null;
try {
Process p = Runtime.getRuntime().exec(cmdarray);
output = new BufferedInputStream(p.getInputStream());
error = new BufferedInputStream(p.getErrorStream());
boolean repeat = true;
while (repeat) {
try {
Thread.sleep(500);
} catch (InterruptedException e1) {
e1.printStackTrace();
// just ignore and continue
}
if (output.available() > 0) {
byte[] data = new byte[output.available()];
int nRead = output.read(data);
logger.error("read " + nRead + " bytes from output stream");
}
if (error.available() > 0) {
byte[] data = new byte[error.available()];
int nRead = error.read(data);
logger.error("read " + nRead + " bytes from error stream");
}
try {
p.exitValue();
// if we get here, the process has terminated
repeat = false;
logger.debug("process terminated with exit code " + p.exitValue());
} catch (IllegalThreadStateException e) {
// this means the process has not yet terminated.
repeat = true;
}
}
} catch (IOException e) {
e.printStackTrace();
throw new WalaException("IOException in " + DotUtil.class);
} finally {
if (output != null) {
try {
output.close();
} catch (IOException e) {
e.printStackTrace();
}
}
if (error != null) {
try {
error.close();
} catch (IOException e) {
e.printStackTrace();
}
}
}
}
public static <T> File writeDotFile(Graph<T> g, NodeDecorator<T> labels, String title, String dotfile) throws WalaException {
if (g == null) {
throw new IllegalArgumentException("g is null");
}
StringBuffer dotStringBuffer = dotOutput(g, labels, title);
// retrieve the filename parameter to this component, a String
if (dotfile == null) {
throw new WalaException("internal error: null filename parameter");
}
try {
File f = new File(dotfile);
FileWriter fw = new FileWriter(f);
fw.write(dotStringBuffer.toString());
fw.close();
return f;
} catch (Exception e) {
throw new WalaException("Error writing dot file " + dotfile);
}
}
/**
* @return StringBuffer holding dot output representing G
* @throws WalaException
*/
private static <T> StringBuffer dotOutput(Graph<T> g, NodeDecorator<T> labels, String title) throws WalaException {
StringBuffer result = new StringBuffer("digraph \"DirectedGraph\" {\n");
if (title != null) {
result.append("graph [label = \""+title+"\", labelloc=t, concentrate = true];");
} else {
result.append("graph [concentrate = true];");
}
String rankdir = getRankDir();
if (rankdir != null) {
result.append("rankdir=" + rankdir + ";");
}
String fontsizeStr = "fontsize=" + fontSize;
String fontcolorStr = (fontColor != null) ? ",fontcolor="+fontColor : "";
String fontnameStr = (fontName != null) ? ",fontname="+fontName : "";
result.append("center=true;");
result.append(fontsizeStr);
result.append(";node [ color=blue,shape=\"box\"");
result.append(fontsizeStr);
result.append(fontcolorStr);
result.append(fontnameStr);
result.append("];edge [ color=black,");
result.append(fontsizeStr);
result.append(fontcolorStr);
result.append(fontnameStr);
result.append("]; \n");
Collection<T> dotNodes = computeDotNodes(g);
outputNodes(labels, result, dotNodes);
for (Iterator<? extends T> it = g.iterator(); it.hasNext();) {
T n = it.next();
for (Iterator<? extends T> it2 = g.getSuccNodes(n); it2.hasNext();) {
T s = it2.next();
result.append(" ");
result.append(getPort(n, labels));
result.append(" -> ");
result.append(getPort(s, labels));
result.append(" \n");
}
}
result.append("\n}");
return result;
}
private static <T> void outputNodes(NodeDecorator<T> labels, StringBuffer result, Collection<T> dotNodes) throws WalaException {
for (Iterator<T> it = dotNodes.iterator(); it.hasNext();) {
outputNode(labels, result, it.next());
}
}
private static <T> void outputNode(NodeDecorator<T> labels, StringBuffer result, T n) throws WalaException {
result.append(" ");
result.append("\"");
result.append(getLabel(n, labels));
result.append("\"");
result.append(decorateNode(n, labels));
}
/**
* Compute the nodes to visualize
*/
private static <T> Collection<T> computeDotNodes(Graph<T> g) throws WalaException {
return Iterator2Collection.toSet(g.iterator());
}
private static String getRankDir() throws WalaException {
return null;
}
/**
* @param n node to decorate
* @param d decorating master
*/
private static <T> String decorateNode(T n, NodeDecorator<T> d) throws WalaException {
StringBuffer result = new StringBuffer();
result.append(" [ ]\n");
return result.toString();
}
private static <T> String getLabel(T o, NodeDecorator<T> d) throws WalaException {
String result = null;
if (d == null) {
//result = o.toString();
result = cleanUpString(o.toString());
} else {
result = d.getLabel(o);
result = result == null ? cleanUpString(o.toString()) : cleanUpString(result);
}
if (result.length() >= MAX_LABEL_LENGTH) {
result = result.substring(0, MAX_LABEL_LENGTH - 3) + "...";
}
return result;
}
private static <T> String getPort(T o, NodeDecorator<T> d) throws WalaException {
return "\"" + getLabel(o, d) + "\"";
}
public static int getFontSize() {
return fontSize;
}
public static void setFontSize(int fontSize) {
DexDotUtil.fontSize = fontSize;
}
private static String cleanUpString(String s) {
if (!s.isEmpty() && s.startsWith("Node: ")) {
String[] nodeString = s.split(",");
if (nodeString.length >= 3) {
String className = nodeString[1];
String methodName = nodeString[2];
return className.trim() + "\\n" + methodName.substring(0,methodName.indexOf(" > ")).trim();
}
}
return s;
}
}

View File

@ -1,60 +0,0 @@
/*
*
* Copyright (c) 2009-2012,
*
* Galois, Inc. (Aaron Tomb <atomb@galois.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.util;
import com.ibm.wala.util.MonitorUtil.IProgressMonitor;
public final class EmptyProgressMonitor implements IProgressMonitor {
public void beginTask(String task, int totalWork) { }
public boolean isCanceled() { return false; }
public void done() { }
public void worked(int units) { }
@Override
public void subTask(String subTask) {
}
@Override
public void cancel() {
}
@Override
public String getCancelMessage() {
return "EmptyProgressMonitor canceled.";
}
}

View File

@ -1,404 +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.util;
import java.io.BufferedReader;
import java.io.File;
import java.io.IOException;
import java.io.InputStreamReader;
import java.util.ArrayList;
import java.util.LinkedList;
import java.util.List;
import java.util.StringTokenizer;
import javax.xml.parsers.DocumentBuilder;
import javax.xml.parsers.DocumentBuilderFactory;
import org.scandroid.spec.AndroidSpecs;
import org.scandroid.spec.MethodNamePattern;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.w3c.dom.Document;
import org.w3c.dom.Element;
import org.w3c.dom.Node;
import org.w3c.dom.NodeList;
import com.google.common.collect.Lists;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.Entrypoint;
import com.ibm.wala.ipa.callgraph.impl.DefaultEntrypoint;
import com.ibm.wala.ipa.cha.ClassHierarchy;
import com.ibm.wala.types.ClassLoaderReference;
import com.ibm.wala.types.MethodReference;
import com.ibm.wala.util.strings.StringStuff;
public class EntryPoints {
private static final Logger logger = LoggerFactory.getLogger(EntryPoints.class);
private String pathToApkFile;
private String pathToApkTool;
private String pathToJava;
private String tempFolder;
private ArrayList<String[]> ActivityIntentList;
private ArrayList<String[]> ReceiverIntentList;
private ArrayList<String[]> ServiceIntentList;
private LinkedList<Entrypoint> entries;
public void listenerEntryPoints(ClassHierarchy cha, AndroidAnalysisContext loader) {
ArrayList<MethodReference> entryPointMRs = new ArrayList<MethodReference>();
// onLocation
entryPointMRs.add(StringStuff.makeMethodReference("android.location.LocationListener.onLocationChanged(Landroid/location/Location;)V"));
for(MethodReference mr:entryPointMRs)
for(IMethod im:cha.getPossibleTargets(mr))
{
logger.debug("Considering target "+im.getSignature());
// limit to functions defined within the application
if(im.getReference().getDeclaringClass().getClassLoader().
equals(ClassLoaderReference.Application)) {
logger.debug("Adding entry point: "+im.getSignature());
entries.add(new DefaultEntrypoint(im, cha));
}
}
}
public static List<Entrypoint> defaultEntryPoints(ClassHierarchy cha) {
List<Entrypoint> entries = Lists.newArrayList();
for (MethodNamePattern mnp:new AndroidSpecs().getEntrypointSpecs()) {
for (IMethod im: mnp.getPossibleTargets(cha)) {
logger.debug("Considering target "+im.getSignature());
// limit to functions defined within the application
if(LoaderUtils.fromLoader(im, ClassLoaderReference.Application))
{
logger.debug("Adding entry point: "+im.getSignature());
entries.add(new DefaultEntrypoint(im, cha));
}
}
}
return entries;
}
public void activityModelEntry(ClassHierarchy cha, AndroidAnalysisContext loader) {
String[] methodReferences = {
"android.app.Activity.ActivityModel()V",
// find all onActivityResult functions and add them as entry points
// "android.app.Activity.onActivityResult(IILandroid/content/Intent;)V",
//
// // SERVICE ENTRY POINTS
// "android.app.Service.onCreate()V",
// "android.app.Service.onStart(Landroid/content/Intent;I)V",
// "android.app.Service.onBind(Landroid/content/Intent;)Landroid/os/IBinder;",
// "android.app.Service.onTransact(ILandroid/os/Parcel;Landroid/os/Parcel;I)B"
};
for (int i = 0; i < methodReferences.length; i++) {
MethodReference mr =
StringStuff.makeMethodReference(methodReferences[i]);
for (IMethod im : cha.getPossibleTargets(mr)) {
logger.debug("Considering target " + im.getSignature());
// limit to functions defined within the application
if (im.getReference().getDeclaringClass().getClassLoader()
.equals(ClassLoaderReference.Application)) {
logger.debug("Adding entry point: " + im.getSignature());
entries.add(new DefaultEntrypoint(im, cha));
}
}
}
}
@SuppressWarnings("unused")
private void systemEntry(ClassHierarchy cha, AndroidAnalysisContext loader) {
String[] systemEntyPoints = {
// "android.app.ActivityThread.main([Ljava/lang/String;)V"
// , "com.android.server.ServerThread.run()V"
//"android.location.LocationManager$ListenerTransport._handleMessage(Landroid/os/Message;)V"
// "android.location.LocationManager$ListenerTransport$1.handleMessage(Landroid/os/Message;)V"
// "android.os.Handler.handleMessage(Landroid/os/Message;)V",
// "android.os.Handler$Callback.handleMessage(Landroid/os/Message;)Z",
// "com.android.internal.os.HandlerCaller$Callback.executeMessage(Landroid/os/Message;)V"
// "android.os.Handler.dispatchMessage(Landroid/os/Message;)V",
// "android.view.View.dispatchTouchEvent(Landroid/view/MotionEvent;)Z",
// "android.view.View.onTouchEvent(Landroid/view/MotionEvent;)Z",
// "android.view.View.setOnClickListener(Landroid/view/View$OnClickListener;)V",
"com.android.server.ServerThread.run()V"
//"android.app.ActivityThread.main([Ljava/lang/String;)V"
};
for (int i = 0; i < systemEntyPoints.length; i++) {
MethodReference methodRef =
StringStuff.makeMethodReference(systemEntyPoints[i]);
for (IMethod im : cha.getPossibleTargets(methodRef)) {
logger.debug("Adding entry point: " + im.getSignature());
entries.add(new DefaultEntrypoint(im, cha));
}
}
}
public void addTestEntry(ClassHierarchy cha, AndroidAnalysisContext loader) {
String[] methodReferences = {
// "Test.Apps.Outer$PrivateInnerClass.printNum()V",
//"Test.Apps.Outer$PublicInnerClass.printNum()V"
//"Test.Apps.Outer.<init>()V"
//"Test.Apps.Outer.getNum()I"
//"Test.Apps.FixpointSolver.someMethod(LTest/Apps/GenericSink;LTest/Apps/GenericSource;)V"
//"Test.Apps.Outer$PrivateInnerClass.testParameters(LTest/Apps/GenericSink;LTest/Apps/GenericSource;)V"
"android.view.View.setOnClickListener(Landroid/view/View$OnClickListener;)V",
};
for (int i = 0; i < methodReferences.length; i++) {
MethodReference mr =
StringStuff.makeMethodReference(methodReferences[i]);
for (IMethod im : cha.getPossibleTargets(mr)) {
logger.debug("Adding entry point: " + im.getSignature());
entries.add(new DefaultEntrypoint(im, cha));
}
}
}
public void unpackApk(String classpath){
StringTokenizer st = new StringTokenizer(classpath, File.pathSeparator);
pathToApkFile = st.nextToken();
//String pathToApkTool = new String(System.getProperty("user.dir").replace(" ", "\\ ") + File.separator + "apktool" +File.separator);
pathToApkTool = System.getProperty("user.dir") + File.separator + "apktool" +File.separator;
//String pathToJava = new String(System.getProperty("java.home").replace(" ", "\\ ") + File.separator + "bin" + File.separator);
pathToJava = System.getProperty("java.home") + File.separator + "bin" + File.separator;
String s = null;
//String command = new String(pathToJava + "java -jar " + pathToApkTool + "apktool.jar d -f " + pathToApkFile + " " + pathToApkTool + tempFolder);
//System.out.println("command: " + command);
ProcessBuilder pb = new ProcessBuilder(pathToJava + "java", "-jar", pathToApkTool + "apktool.jar", "d", "-f", pathToApkFile, pathToApkTool+tempFolder);
try {
//Process p = Runtime.getRuntime().exec(command);
Process p = pb.start();
BufferedReader stdInput = new BufferedReader(new
InputStreamReader(p.getInputStream()));
BufferedReader stdError = new BufferedReader(new
InputStreamReader(p.getErrorStream()));
// read the output from the command
logger.debug("Here is the standard output of the command:\n");
while ((s = stdInput.readLine()) != null) {
logger.debug(s);
}
// read any errors from the attempted command
logger.debug("Here is the standard error of the command (if any):\n");
while ((s = stdError.readLine()) != null) {
logger.debug(s);
}
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//System.out.println( System.getProperty("user.dir") );
//System.out.println("classpath: " + st.nextToken());
}
public void readXMLFile() {
try {
File fXmlFile = new File(pathToApkTool + tempFolder + File.separator + "AndroidManifest.xml");
DocumentBuilderFactory dbFactory = DocumentBuilderFactory.newInstance();
DocumentBuilder dBuilder = dbFactory.newDocumentBuilder();
Document doc = dBuilder.parse(fXmlFile);
doc.getDocumentElement().normalize();
//System.out.println("Root element :" + doc.getDocumentElement().getNodeName());
String basePackage = doc.getDocumentElement().getAttribute("package");
NodeList iList = doc.getElementsByTagName("intent-filter");
System.out.println("-----------------------");
for (int i = 0; i < iList.getLength(); i++) {
Node nNode = iList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
Element eElement = (Element) nNode;
// System.out.println(eElement.getNodeName());
populateIntentList(basePackage, eElement);
}
}
} catch (Exception e) {
e.printStackTrace();
}
}
@SuppressWarnings("unused")
private static String getTagValue(String sTag, Element eElement) {
NodeList nlList = eElement.getElementsByTagName(sTag).item(0).getChildNodes();
Node nValue = (Node) nlList.item(0);
return nValue.getNodeValue();
}
private void populateIntentList(String basePackage, Element eElement) {
ArrayList<String[]> IntentList;
NodeList actionList = eElement.getElementsByTagName("action");
Node parent = eElement.getParentNode();
IntentList = chooseIntentList(parent.getNodeName());
String IntentClass = parent.getAttributes().getNamedItem("android:name").getTextContent();
for (int i = 0; i < actionList.getLength(); i++)
{
Node nNode = actionList.item(i);
if (nNode.getNodeType() == Node.ELEMENT_NODE) {
IntentList.add(new String[2]);
IntentList.get(IntentList.size()-1)[0] = actionList.item(i).getAttributes().getNamedItem("android:name").getTextContent();
if (IntentClass.startsWith(basePackage))
IntentList.get(IntentList.size()-1)[1] = IntentClass;
else {
if (IntentClass.startsWith("."))
IntentList.get(IntentList.size()-1)[1] = basePackage + IntentClass;
else {
IntentList.get(IntentList.size()-1)[1] = basePackage + "." + IntentClass;
IntentList.add(new String[2]);
IntentList.get(IntentList.size()-1)[0] = actionList.item(i).getAttributes().getNamedItem("android:name").getTextContent();
IntentList.get(IntentList.size()-1)[1] = IntentClass;
}
//IntentList.get(IntentList.size()-1)[1] = basePackage + (IntentClass.startsWith(".") ? IntentClass : "." + IntentClass);
}
//System.out.println(IntentList.get(IntentList.size()-1)[0] + " ~> " + IntentList.get(IntentList.size()-1)[1]);
}
}
}
@SuppressWarnings("unused")
private void populateEntryPoints(ClassHierarchy cha) {
String method = null;
IMethod im = null;
for (String[] intent: ActivityIntentList) {
//method = IntentToMethod(intent[0]);
method = "onCreate(Landroid/os/Bundle;)V";
logger.debug("activity intent method: "+intent[1]+"."+method);
if (method != null)
im = cha.resolveMethod(StringStuff.makeMethodReference(intent[1]+"."+method));
if (im!=null)
entries.add(new DefaultEntrypoint(im,cha));
}
for (String[] intent: ReceiverIntentList) {
//Seems that every broadcast receiver can be an entrypoints?
// method = IntentToMethod(intent[0]);
method = "onReceive(Landroid/content/Context;Landroid/content/Intent;)V";
logger.debug("receiver intent method: "+intent[1]+"."+method);
if (method != null)
im = cha.resolveMethod(StringStuff.makeMethodReference(intent[1]+"."+method));
if (im!=null)
entries.add(new DefaultEntrypoint(im,cha));
}
//IMethod im = cha.resolveMethod(StringStuff.makeMethodReference("android.app.Activity.onCreate(Landroid/os/Bundle;)V"));
//entries.add(new DefaultEntrypoint(im, cha));
}
@SuppressWarnings("unused")
private String IntentToMethod(String intent) {
if (intent.contentEquals("android.intent.action.MAIN") ||
intent.contentEquals("android.media.action.IMAGE_CAPTURE") ||
intent.contentEquals("android.media.action.VIDEO_CAPTURE") ||
intent.contentEquals("android.media.action.STILL_IMAGE_CAMERA") ||
intent.contentEquals("android.intent.action.MUSIC_PLAYER") ||
intent.contentEquals("android.media.action.VIDEO_CAMERA"))
return "onCreate(Landroid/os/Bundle;)V";
// else if (intent.contentEquals("android.intent.action.BOOT_COMPLETED") ||
// intent.contentEquals("android.appwidget.action.APPWIDGET_UPDATE") ||
// intent.contentEquals("android.provider.Telephony.SECRET_CODE") )
// return "onReceive(Landroid/content/Context;Landroid/content/Intent;)V";
else return null;
}
private ArrayList<String[]> chooseIntentList(String name) {
if (name.equals("activity"))
return ActivityIntentList;
else if (name.equals("receiver"))
return ReceiverIntentList;
else if (name.equals("service"))
return ServiceIntentList;
else {
return ActivityIntentList;
// throw new UnimplementedError("EntryPoints intent category not yet covered: " + name);
}
}
@SuppressWarnings("unused")
private void outputIntentList() {
if (ActivityIntentList != null)
for (int i = 0; i < ActivityIntentList.size(); i++)
logger.debug("Activity Intent: " + ActivityIntentList.get(i)[0] + " ~> " + ActivityIntentList.get(i)[1]);
if (ReceiverIntentList != null)
for (int i = 0; i < ReceiverIntentList.size(); i++)
logger.debug("Receiver Intent: " + ReceiverIntentList.get(i)[0] + " ~> " + ReceiverIntentList.get(i)[1]);
if (ServiceIntentList != null)
for (int i = 0; i < ServiceIntentList.size(); i++)
logger.debug("Service Intent: " + ServiceIntentList.get(i)[0] + " ~> " + ServiceIntentList.get(i)[1]);
}
public LinkedList<Entrypoint> getEntries() {
return entries;
}
}

View File

@ -1,54 +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.util;
import java.util.List;
import com.ibm.wala.ipa.callgraph.Entrypoint;
public interface IEntryPointSpecifier {
/**
* @param analysisContext
* @return a list of entrypoints for the given analysis context
*/
public List<Entrypoint> specify(AndroidAnalysisContext analysisContext);
}

View File

@ -1,155 +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.util;
import java.net.URI;
import com.ibm.wala.ipa.callgraph.AnalysisOptions.ReflectionOptions;
/**
* @author acfoltzer
*
* An abstraction of the options for a SCanDroid execution
*/
public interface ISCanDroidOptions {
/**
* @return whether to create a full call graph pdf
*/
public boolean pdfCG();
/**
* @return whether to create an application-only call graph pdf
*/
public boolean pdfPartialCG();
/**
* @return whether to create a call graph of application + 1 level of system
* calls
*/
public boolean pdfOneLevelCG();
/**
* @return whether to create a system + 1 level of application call graph
*/
public boolean systemToApkCG();
/**
* @return whether to print a full call graph to stdout
*/
public boolean stdoutCG();
/**
* @return whether to include the Android library in flow analysis
*/
public boolean includeLibrary();
/**
* @return whether to analyze each entry point separately
*/
public boolean separateEntries();
/**
* @return whether to bring up a GUI to analyze domain elements for flow
* analysis
*/
public boolean ifdsExplorer();
/**
* @return whether to look for main methods and add them as entry points
*/
public boolean addMainEntrypoints();
/**
* @return whether to use ServerThread.run as the entry point for analysis
*/
public boolean useThreadRunMain();
/**
* @return whether to run string prefix analysis
*/
public boolean stringPrefixAnalysis();
/**
* @return whether to stop after generating the call graph
*/
public boolean testCGBuilder();
/**
* @return whether to log class hierarchy warnings
*/
public boolean classHierarchyWarnings();
/**
* @return whether to log call graph builder warnings
*/
public boolean cgBuilderWarnings();
/**
* @return whether to check conformance to built-in policy
*/
public boolean useDefaultPolicy();
/**
* @return the URI pointing to the jar or apk to analyze
*/
public URI getClasspath();
/**
* @return the filename portion of the classpath to analyze
*/
public String getFilename();
/**
* @return a URI to the Android library jar
*/
public URI getAndroidLibrary();
/**
* @return the ReflectionOptions for this run
*/
public ReflectionOptions getReflectionOptions();
/**
* @return a URI to the XML method summaries file
*/
public URI getSummariesURI();
}

View File

@ -1,71 +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.util;
import com.ibm.wala.classLoader.IClass;
import com.ibm.wala.classLoader.IMethod;
import com.ibm.wala.ipa.callgraph.CGNode;
import com.ibm.wala.types.ClassLoaderReference;
public class LoaderUtils {
public static boolean fromLoader(CGNode node, ClassLoaderReference clr) {
IClass declClass = node.getMethod().getDeclaringClass();
ClassLoaderReference nodeClRef =
declClass.getClassLoader().getReference();
return nodeClRef.equals(clr);
}
public static boolean fromLoader(IMethod method, ClassLoaderReference clr) {
IClass declClass = method.getDeclaringClass();
ClassLoaderReference nodeClRef =
declClass.getClassLoader().getReference();
return nodeClRef.equals(clr);
}
public static boolean fromLoader(IClass declClass, ClassLoaderReference clr) {
ClassLoaderReference nodeClRef =
declClass.getClassLoader().getReference();
return nodeClRef.equals(clr);
}
}

View File

@ -1,213 +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.util;
import com.ibm.wala.ssa.SSAArrayLengthInstruction;
import com.ibm.wala.ssa.SSAArrayLoadInstruction;
import com.ibm.wala.ssa.SSAArrayStoreInstruction;
import com.ibm.wala.ssa.SSABinaryOpInstruction;
import com.ibm.wala.ssa.SSACheckCastInstruction;
import com.ibm.wala.ssa.SSAComparisonInstruction;
import com.ibm.wala.ssa.SSAConditionalBranchInstruction;
import com.ibm.wala.ssa.SSAConversionInstruction;
import com.ibm.wala.ssa.SSAGetCaughtExceptionInstruction;
import com.ibm.wala.ssa.SSAGetInstruction;
import com.ibm.wala.ssa.SSAGotoInstruction;
import com.ibm.wala.ssa.SSAInstanceofInstruction;
import com.ibm.wala.ssa.SSAInstruction.IVisitor;
import com.ibm.wala.ssa.SSAInvokeInstruction;
import com.ibm.wala.ssa.SSALoadMetadataInstruction;
import com.ibm.wala.ssa.SSAMonitorInstruction;
import com.ibm.wala.ssa.SSANewInstruction;
import com.ibm.wala.ssa.SSAPhiInstruction;
import com.ibm.wala.ssa.SSAPiInstruction;
import com.ibm.wala.ssa.SSAPutInstruction;
import com.ibm.wala.ssa.SSAReturnInstruction;
import com.ibm.wala.ssa.SSASwitchInstruction;
import com.ibm.wala.ssa.SSAThrowInstruction;
import com.ibm.wala.ssa.SSAUnaryOpInstruction;
public class ThrowingSSAInstructionVisitor implements IVisitor {
private final RuntimeException e;
public ThrowingSSAInstructionVisitor(RuntimeException e) {
this.e = e;
}
@Override
public void visitGoto(SSAGotoInstruction instruction) {
throw e;
}
@Override
public void visitArrayLoad(SSAArrayLoadInstruction instruction) {
throw e;
}
@Override
public void visitArrayStore(SSAArrayStoreInstruction instruction) {
throw e;
}
@Override
public void visitBinaryOp(SSABinaryOpInstruction instruction) {
throw e;
}
@Override
public void visitUnaryOp(SSAUnaryOpInstruction instruction) {
throw e;
}
@Override
public void visitConversion(SSAConversionInstruction instruction) {
throw e;
}
@Override
public void visitComparison(SSAComparisonInstruction instruction) {
throw e;
}
@Override
public void visitConditionalBranch(
SSAConditionalBranchInstruction instruction) {
throw e;
}
@Override
public void visitSwitch(SSASwitchInstruction instruction) {
throw e;
}
@Override
public void visitReturn(SSAReturnInstruction instruction) {
throw e;
}
@Override
public void visitGet(SSAGetInstruction instruction) {
throw e;
}
@Override
public void visitPut(SSAPutInstruction instruction) {
throw e;
}
@Override
public void visitInvoke(SSAInvokeInstruction instruction) {
throw e;
}
@Override
public void visitNew(SSANewInstruction instruction) {
throw e;
}
@Override
public void visitArrayLength(SSAArrayLengthInstruction instruction) {
throw e;
}
@Override
public void visitThrow(SSAThrowInstruction instruction) {
throw e;
}
@Override
public void visitMonitor(SSAMonitorInstruction instruction) {
throw e;
}
@Override
public void visitCheckCast(SSACheckCastInstruction instruction) {
throw e;
}
@Override
public void visitInstanceof(SSAInstanceofInstruction instruction) {
throw e;
}
@Override
public void visitPhi(SSAPhiInstruction instruction) {
throw e;
}
@Override
public void visitPi(SSAPiInstruction instruction) {
throw e;
}
@Override
public void visitGetCaughtException(
SSAGetCaughtExceptionInstruction instruction) {
throw e;
}
@Override
public void visitLoadMetadata(SSALoadMetadataInstruction instruction) {
throw e;
}
}

View File

@ -2,6 +2,6 @@
<classpath>
<classpathentry kind="src" path="src"/>
<classpathentry kind="con" path="org.eclipse.pde.core.requiredPlugins"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.launching.macosx.MacOSXType/Java SE 6"/>
<classpathentry kind="con" path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<classpathentry kind="output" path="bin"/>
</classpath>

View File

@ -10,5 +10,5 @@
<repository location="http://download.eclipse.org/releases/juno"/>
</location>
</locations>
<targetJRE path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.6"/>
<targetJRE path="org.eclipse.jdt.launching.JRE_CONTAINER/org.eclipse.jdt.internal.debug.ui.launcher.StandardVMType/JavaSE-1.7"/>
</target>