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

soot.jimple.infoflow.aliasing.ImplicitFlowAliasStrategy Maven / Gradle / Ivy

There is a newer version: 2.9.0
Show newest version
package soot.jimple.infoflow.aliasing;

import java.util.HashMap;
import java.util.HashSet;
import java.util.Map;
import java.util.Set;

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

import heros.solver.IDESolver;
import soot.Local;
import soot.SootMethod;
import soot.Unit;
import soot.Value;
import soot.jimple.AssignStmt;
import soot.jimple.FieldRef;
import soot.jimple.InstanceFieldRef;
import soot.jimple.Jimple;
import soot.jimple.Stmt;
import soot.jimple.infoflow.InfoflowManager;
import soot.jimple.infoflow.data.Abstraction;
import soot.jimple.infoflow.data.AccessPath;
import soot.jimple.infoflow.solver.IInfoflowSolver;

/**
 * Aliasing strategy to be used for conditionally-called methods when analyzing
 * implicit flows
 * 
 * @author Steven Arzt
 */
public class ImplicitFlowAliasStrategy extends AbstractBulkAliasStrategy {

	protected final LoadingCache>> methodToAliases = IDESolver.DEFAULT_CACHE_BUILDER
			.build(new CacheLoader>>() {
				@Override
				public Map> load(SootMethod method) throws Exception {
					return computeGlobalAliases(method);
				}
			});

	public ImplicitFlowAliasStrategy(InfoflowManager manager) {
		super(manager);
	}

	/**
	 * Computes the global non-flow-sensitive alias information for the given method
	 * 
	 * @param method The method for which to compute the alias information
	 */
	private Map> computeGlobalAliases(SootMethod method) {
		Map> res = new HashMap>();

		// Find the aliases
		for (Unit u : method.getActiveBody().getUnits()) {
			if (!(u instanceof AssignStmt))
				continue;
			final AssignStmt assign = (AssignStmt) u;

			// Aliases can only be generated on the heap
			if (!(assign.getLeftOp() instanceof FieldRef
					&& (assign.getRightOp() instanceof FieldRef || assign.getRightOp() instanceof Local)))
				if (!(assign.getRightOp() instanceof FieldRef
						&& (assign.getLeftOp() instanceof FieldRef || assign.getLeftOp() instanceof Local)))
					continue;

			final AccessPath apLeft = manager.getAccessPathFactory().createAccessPath(assign.getLeftOp(), true);
			final AccessPath apRight = manager.getAccessPathFactory().createAccessPath(assign.getRightOp(), true);

			Set mapLeft = res.get(apLeft);
			if (mapLeft == null) {
				mapLeft = new HashSet();
				res.put(apLeft, mapLeft);
			}
			mapLeft.add(apRight);

			Set mapRight = res.get(apRight);
			if (mapRight == null) {
				mapRight = new HashSet();
				res.put(apRight, mapRight);
			}
			mapRight.add(apLeft);
		}
		return res;
	}

	@Override
	public void computeAliasTaints(Abstraction d1, Stmt src, Value targetValue, Set taintSet,
			SootMethod method, Abstraction newAbs) {
		// Use global aliasing
		Value baseValue = ((InstanceFieldRef) targetValue).getBase();
		Set aliases = methodToAliases.getUnchecked(method)
				.get(manager.getAccessPathFactory().createAccessPath(baseValue, true));
		if (aliases != null)
			for (AccessPath ap : aliases) {
				AccessPath newAP = manager.getAccessPathFactory().merge(ap, newAbs.getAccessPath());
				Abstraction aliasAbs = newAbs.deriveNewAbstraction(newAP, null);
				if (taintSet.add(aliasAbs))
					// We have found a new alias. This new base object may however yet
					// again alias with something, so we need to check again
					if (ap.isInstanceFieldRef()) {
						InstanceFieldRef aliasBaseVal = Jimple.v().newInstanceFieldRef(ap.getPlainValue(),
								ap.getFirstField().makeRef());
						computeAliasTaints(d1, src, aliasBaseVal, taintSet, method, aliasAbs);
					}
			}
	}

	@Override
	public void injectCallingContext(Abstraction abs, IInfoflowSolver fSolver, SootMethod callee, Unit callSite,
			Abstraction source, Abstraction d1) {
	}

	@Override
	public boolean isFlowSensitive() {
		return false;
	}

	@Override
	public boolean requiresAnalysisOnReturn() {
		return true;
	}

	@Override
	public boolean hasProcessedMethod(SootMethod method) {
		return methodToAliases.getIfPresent(method) != null;
	}

	@Override
	public IInfoflowSolver getSolver() {
		return null;
	}

	@Override
	public void cleanup() {
		methodToAliases.invalidateAll();
		methodToAliases.cleanUp();
	}

}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy