All Downloads are FREE. Search and download functionalities are using the official Maven repository.

soot.jimple.infoflow.methodSummary.source.SummarySourceSinkManager Maven / Gradle / Ivy

package soot.jimple.infoflow.methodSummary.source;

import java.util.Collection;
import java.util.Collections;
import java.util.LinkedList;
import java.util.List;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import com.google.common.cache.CacheLoader;
import com.google.common.cache.LoadingCache;

import heros.solver.IDESolver;
import soot.Scene;
import soot.SootClass;
import soot.SootField;
import soot.SootMethod;
import soot.Value;
import soot.jimple.DefinitionStmt;
import soot.jimple.ParameterRef;
import soot.jimple.ReturnStmt;
import soot.jimple.ReturnVoidStmt;
import soot.jimple.Stmt;
import soot.jimple.ThisRef;
import soot.jimple.infoflow.InfoflowManager;
import soot.jimple.infoflow.data.AccessPath;
import soot.jimple.infoflow.methodSummary.data.factory.SourceSinkFactory;
import soot.jimple.infoflow.sourcesSinks.manager.ISourceSinkManager;
import soot.jimple.infoflow.sourcesSinks.manager.SinkInfo;
import soot.jimple.infoflow.sourcesSinks.manager.SourceInfo;

/**
 * SourceSinkManager for computing library summaries
 * 
 * @author Malte Viering
 * @author Steven Arzt
 */
public class SummarySourceSinkManager implements ISourceSinkManager {

	protected final LoadingCache> classToFields = IDESolver.DEFAULT_CACHE_BUILDER
			.build(new CacheLoader>() {
				@Override
				public Collection load(SootClass sc) throws Exception {
					List res = new LinkedList();
					List impler = Scene.v().getActiveHierarchy()
							.getSuperclassesOfIncluding(method.getDeclaringClass());
					for (SootClass c : impler)
						res.addAll(c.getFields());
					return res;
				}
			});

	private boolean debug = false;

	private final Logger logger = LoggerFactory.getLogger(SummarySourceSinkManager.class);
	private final String methodSig;
	private final String parentClass;
	private final SourceSinkFactory sourceSinkFactory;

	private SootMethod method = null;

	/**
	 * Creates a new instance of the {@link SummarySourceSinkManager} class
	 * 
	 * @param mSig              The signature of the method for which summaries
	 *                          shall be created
	 * @param parentClass       The parent class containing the method for which
	 *                          summaries shall be created. If mSig is the signature
	 *                          of a method inherited from a base class, this
	 *                          parameter receives the class on which the method
	 *                          denoted by mSig is called.
	 * @param sourceSinkFactory The {@link SourceSinkFactory} to create source and
	 *                          sink data objects
	 */
	public SummarySourceSinkManager(String mSig, String parentClass, SourceSinkFactory sourceSinkFactory) {
		this.methodSig = mSig;
		this.parentClass = parentClass;
		this.sourceSinkFactory = sourceSinkFactory;
	}

	/**
	 * Creates a new instance of the {@link SummarySourceSinkManager} class
	 * 
	 * @param method            The method for which summaries shall be created
	 * @param sourceSinkFactory The {@link SourceSinkFactory} to create source and
	 *                          sink data objects
	 */
	public SummarySourceSinkManager(SootMethod method, SourceSinkFactory sourceSinkFactory) {
		this.method = method;
		this.methodSig = null;
		this.parentClass = null;
		this.sourceSinkFactory = sourceSinkFactory;
	}

	@Override
	public SourceInfo getSourceInfo(Stmt sCallSite, InfoflowManager manager) {
		// If this is not the method we are looking for, we skip it
		SootMethod currentMethod = manager.getICFG().getMethodOf(sCallSite);
		if (!isMethodToSummarize(currentMethod))
			return null;

		if (sCallSite instanceof DefinitionStmt) {
			DefinitionStmt jstmt = (DefinitionStmt) sCallSite;
			Value leftOp = jstmt.getLeftOp();
			Value rightOp = jstmt.getRightOp();

			// check if we have a source with apl = 0 (this or parameter source)
			if (rightOp instanceof ParameterRef) {
				ParameterRef pref = (ParameterRef) rightOp;
				logger.debug("source: " + sCallSite + " " + currentMethod.getSignature());
				if (debug)
					System.out.println("source: " + sCallSite + " " + currentMethod.getSignature());
				return new SourceInfo(null, manager.getAccessPathFactory().createAccessPath(leftOp, true),
						Collections.singletonList(
								sourceSinkFactory.createParameterSource(pref.getIndex(), pref.getType().toString())));
			} else if (rightOp instanceof ThisRef) {
				ThisRef tref = (ThisRef) rightOp;
				if (debug)
					System.out.println("source: (this)" + sCallSite + " " + currentMethod.getSignature());
				return new SourceInfo(null, manager.getAccessPathFactory().createAccessPath(leftOp, true),
						Collections.singletonList(sourceSinkFactory.createThisSource(tref.getType().toString())));
			}
		}
		return null;
	}

	private boolean isMethodToSummarize(SootMethod currentMethod) {
		// Initialize the method we are interested in
		if (method == null)
			method = Scene.v().getMethod(methodSig);

		// This must either be the method defined by signature or the
		// corresponding one in the parent class
		if (currentMethod == method)
			return true;

		return parentClass != null && currentMethod.getDeclaringClass().getName().equals(parentClass)
				&& currentMethod.getSubSignature().equals(method.getSubSignature());
	}

	@Override
	public SinkInfo getSinkInfo(Stmt sCallSite, InfoflowManager manager, AccessPath sourceAP) {
		// We only fake the sources during the initial collection pass. During
		// the actual taint propagation, the TaintPropagationHandler will take
		// care of recording the outbound abstractions
		if (sourceAP != null)
			return null;

		// If this is not the method we are looking for, we skip it
		SootMethod currentMethod = manager.getICFG().getMethodOf(sCallSite);
		if (!isMethodToSummarize(currentMethod))
			return null;

		return sCallSite instanceof ReturnStmt || sCallSite instanceof ReturnVoidStmt ? new SinkInfo() : null;
	}

	@Override
	public void initialize() {
		// nothing to do here
	}

	/**
	 * Gets the factory that creates the sources and sinks
	 * 
	 * @return The factory that creates the sources and sinks
	 */
	public SourceSinkFactory getSourceSinkFactory() {
		return sourceSinkFactory;
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy