parent
6c47da8091
commit
14c9c96515
|
@ -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
|
||||
|
|
|
@ -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);
|
||||
}
|
||||
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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}">
|
||||
|
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -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();
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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+")";
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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+")";
|
||||
}
|
||||
|
||||
}
|
|
@ -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()";
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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() {} }
|
||||
*/
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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 + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
// }
|
||||
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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));
|
||||
}
|
||||
}
|
|
@ -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());
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 {
|
||||
}
|
|
@ -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{
|
||||
}
|
|
@ -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[] {};
|
||||
}
|
||||
};
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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()) {
|
||||
// }
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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);
|
||||
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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 + "]";
|
||||
}
|
||||
}
|
|
@ -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[] {});
|
||||
}
|
||||
|
||||
}
|
|
@ -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() + "]";
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
}
|
||||
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
}
|
|
@ -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.";
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
}
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
|
@ -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();
|
||||
|
||||
}
|
|
@ -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);
|
||||
}
|
||||
}
|
|
@ -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;
|
||||
|
||||
}
|
||||
|
||||
}
|
|
@ -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>
|
||||
|
|
|
@ -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>
|
||||
|
|
Loading…
Reference in New Issue