soot.jimple.infoflow.data.SootMethodAndClass Java Examples

The following examples show how to use soot.jimple.infoflow.data.SootMethodAndClass. You can vote up the ones you like or vote down the ones you don't like, and go to the original project or source file by following the links above each example. You may check out the related API usage on the sidebar.
Example #1
Source File: AnalyzeJimpleClass.java    From JAADAS with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Incrementally collects the callback methods for all Android default
 * handlers implemented in the source code. This just processes the contents
 * of the worklist.
 * Note that this operation runs inside Soot, so this method only registers
 * a new phase that will be executed when Soot is next run
 */
public void collectCallbackMethodsIncremental() {
	Transform transform = new Transform("wjtp.ajc", new SceneTransformer() {
		protected void internalTransform(String phaseName, @SuppressWarnings("rawtypes") Map options) {
			// Process the worklist from last time
			System.out.println("Running incremental callback analysis for " + callbackWorklist.size()
					+ " components...");
			MultiMap<String, SootMethodAndClass> workListCopy =
					new HashMultiMap<String, SootMethodAndClass>(callbackWorklist);
			for (String className : workListCopy.keySet()) {
				List<MethodOrMethodContext> entryClasses = new LinkedList<MethodOrMethodContext>();
				for (SootMethodAndClass am : workListCopy.get(className))
					entryClasses.add(Scene.v().getMethod(am.getSignature()));
				analyzeRechableMethods(Scene.v().getSootClass(className), entryClasses);
				callbackWorklist.remove(className);
			}
			System.out.println("Incremental callback analysis done.");
		}
	});
	PackManager.v().getPack("wjtp").add(transform);
}
 
Example #2
Source File: SetupApplication.java    From ic3 with Apache License 2.0 5 votes vote down vote up
public AndroidEntryPointCreator createEntryPointCreator() {
  AndroidEntryPointCreator entryPointCreator =
      new AndroidEntryPointCreator(new ArrayList<String>(this.entrypoints));
  Map<String, List<String>> callbackMethodSigs = new HashMap<String, List<String>>();
  for (String className : this.callbackMethods.keySet()) {
    List<String> methodSigs = new ArrayList<String>();
    callbackMethodSigs.put(className, methodSigs);
    for (SootMethodAndClass am : this.callbackMethods.get(className)) {
      methodSigs.add(am.getSignature());
    }
  }
  entryPointCreator.setCallbackFunctions(callbackMethodSigs);
  return entryPointCreator;
}
 
Example #3
Source File: AndroidMethod.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
/***
 * Static method to create AndroidMethod from Soot method signature
 * 
 * @param signature The Soot method signature
 * @return The new AndroidMethod object
 */
public static AndroidMethod createFromSignature(String signature) {
	if (!signature.startsWith("<"))
		signature = "<" + signature;
	if (!signature.endsWith(">"))
		signature = signature + ">";
	
	SootMethodAndClass smac = SootMethodRepresentationParser.v()
			.parseSootMethodString(signature);
	return new AndroidMethod(smac.getMethodName(), smac.getParameters(),
			smac.getReturnType(), smac.getClassName());
}
 
Example #4
Source File: SetupApplication.java    From ic3 with Apache License 2.0 5 votes vote down vote up
/**
 * Adds a method to the set of callback method
 * 
 * @param layoutClass The layout class for which to register the callback
 * @param callbackMethod The callback method to register
 */
private void addCallbackMethod(String layoutClass, AndroidMethod callbackMethod) {
  Set<SootMethodAndClass> methods = this.callbackMethods.get(layoutClass);
  if (methods == null) {
    methods = new HashSet<SootMethodAndClass>();
    this.callbackMethods.put(layoutClass, methods);
  }
  methods.add(new AndroidMethod(callbackMethod));
}
 
Example #5
Source File: SourceSinkDefinition.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Creates a new instance of the MethodSourceSinkDefinition class
 * @param am The method for which this object defines sources and sinks
 * @param baseObjects The source and sink definitions for the base object on
 * which a method of this class is invoked
 * @param parameters The source and sink definitions for parameters of
 * the current method
 * @param returnValues The source definitions for the return value of the
 * current method
 */
public SourceSinkDefinition(SootMethodAndClass am,
		Set<AccessPathTuple> baseObjects,
		Set<AccessPathTuple>[] parameters,
		Set<AccessPathTuple> returnValues) {
	this.method = am;
	this.baseObjects = baseObjects == null || baseObjects.isEmpty()
			? null : baseObjects;
	this.parameters = parameters;
	this.returnValues = returnValues == null || returnValues.isEmpty()
			? null : returnValues;
}
 
Example #6
Source File: MethodRepresentationTests.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
@Test(timeout=300000)
public void testParser(){
	String s = "<soot.jimple.infoflow.test.TestNoMain: java.lang.String function1()>";
	
	SootMethodRepresentationParser parser = SootMethodRepresentationParser.v();
	SootMethodAndClass result = parser.parseSootMethodString(s);
	
	assertEquals("soot.jimple.infoflow.test.TestNoMain", result.getClassName());
	assertEquals("function1", result.getMethodName());
	assertEquals("java.lang.String", result.getReturnType());
}
 
Example #7
Source File: SootMethodRepresentationParser.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
/**
 * parses a string in soot representation, for example:
 * <soot.jimple.infoflow.test.TestNoMain: java.lang.String function1()>
 * <soot.jimple.infoflow.test.TestNoMain: void functionCallOnObject()>
 * <soot.jimple.infoflow.test.TestNoMain: java.lang.String function2(java.lang.String,java.lang.String)>
 * @param parseString The method signature to parse
 */
public SootMethodAndClass parseSootMethodString(String parseString){
	if(!parseString.startsWith("<") || !parseString.endsWith(">")){
		throw new IllegalArgumentException("Illegal format of " +parseString +" (should use soot method representation)");
	}
	String name = "";
	String className = "";
	String returnType = "";
	Pattern pattern = Pattern.compile("<(.*?):");
       Matcher matcher = pattern.matcher(parseString);
       if(matcher.find()){
       	className = matcher.group(1);
       }
       pattern = Pattern.compile(": (.*?) ");
       matcher = pattern.matcher(parseString);
       if(matcher.find()){
       	returnType =  matcher.group(1);
       	//remove the string contents that are already found so easier regex is possible
       	parseString = parseString.substring(matcher.end(1));        	
       }
       pattern = Pattern.compile(" (.*?)\\(");
       matcher = pattern.matcher(parseString);
       if(matcher.find()){
       	name = matcher.group(1);
       }
       List<String> paramList = new ArrayList<String>();
       pattern = Pattern.compile("\\((.*?)\\)");
       matcher = pattern.matcher(parseString);
       if(matcher.find()){
       	String params = matcher.group(1);
       	for (String param : params.split(","))
      			paramList.add(param.trim());
       }
       return new SootMethodAndClass(name, className, returnType, paramList);
      
}
 
Example #8
Source File: SetupApplication.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
/**
 * Adds a method to the set of callback method
 * 
 * @param layoutClass
 *            The layout class for which to register the callback
 * @param callbackMethod
 *            The callback method to register
 */
private void addCallbackMethod(String layoutClass, AndroidMethod callbackMethod) {
	Set<SootMethodAndClass> methods = this.callbackMethods.get(layoutClass);
	if (methods == null) {
		methods = new HashSet<SootMethodAndClass>();
		this.callbackMethods.put(layoutClass, methods);
	}
	methods.add(new AndroidMethod(callbackMethod));
}
 
Example #9
Source File: SetupApplication.java    From JAADAS with GNU General Public License v3.0 5 votes vote down vote up
private AndroidEntryPointCreator createEntryPointCreator() {
	AndroidEntryPointCreator entryPointCreator = new AndroidEntryPointCreator(new ArrayList<String>(
			this.entrypoints));
	Map<String, List<String>> callbackMethodSigs = new HashMap<String, List<String>>();
	for (String className : this.callbackMethods.keySet()) {
		List<String> methodSigs = new ArrayList<String>();
		callbackMethodSigs.put(className, methodSigs);
		for (SootMethodAndClass am : this.callbackMethods.get(className))
			methodSigs.add(am.getSignature());
	}
	entryPointCreator.setCallbackFunctions(callbackMethodSigs);
	return entryPointCreator;
}
 
Example #10
Source File: SetupApplication.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Calculates the sets of sources, sinks, entry points, and callbacks methods for the given APK file.
 * 
 * @param sourcesAndSinks
 *            A provider from which the analysis can obtain the list of
 *            sources and sinks
 * @throws IOException
 *             Thrown if the given source/sink file could not be read.
 * @throws XmlPullParserException
 *             Thrown if the Android manifest file could not be read.
 */
public void calculateSourcesSinksEntrypoints(ISourceSinkDefinitionProvider sourcesAndSinks)
		throws IOException, XmlPullParserException {
	// To look for callbacks, we need to start somewhere. We use the Android
	// lifecycle methods for this purpose.
	this.sourceSinkProvider = sourcesAndSinks;
	ProcessManifest processMan = new ProcessManifest(apkFileLocation);
	this.appPackageName = processMan.getPackageName();
	this.entrypoints = processMan.getEntryPointClasses();

	// Parse the resource file
	long beforeARSC = System.nanoTime();
	ARSCFileParser resParser = new ARSCFileParser();
	resParser.parse(apkFileLocation);
	logger.info("ARSC file parsing took " + (System.nanoTime() - beforeARSC) / 1E9 + " seconds");
	this.resourcePackages = resParser.getPackages();

	// Add the callback methods
	LayoutFileParser lfp = null;
	if (enableCallbacks) {
		lfp = new LayoutFileParser(this.appPackageName, resParser);
		calculateCallbackMethods(resParser, lfp);

		// Some informational output
		System.out.println("Found " + lfp.getUserControls() + " layout controls");
	}
	
	System.out.println("Entry point calculation done.");

	// Clean up everything we no longer need
	soot.G.reset();

	// Create the SourceSinkManager
	{
		Set<SootMethodAndClass> callbacks = new HashSet<>();
		for (Set<SootMethodAndClass> methods : this.callbackMethods.values())
			callbacks.addAll(methods);

		sourceSinkManager = new AccessPathBasedSourceSinkManager(
				this.sourceSinkProvider.getSources(),
				this.sourceSinkProvider.getSinks(),
				callbacks,
				layoutMatchingMode,
				lfp == null ? null : lfp.getUserControlsByID());

		sourceSinkManager.setAppPackageName(this.appPackageName);
		sourceSinkManager.setResourcePackages(this.resourcePackages);
		sourceSinkManager.setEnableCallbackSources(this.enableCallbackSources);
	}

	entryPointCreator = createEntryPointCreator();
}
 
Example #11
Source File: SequentialEntryPointCreator.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
@Override
protected SootMethod createDummyMainInternal(SootMethod mainMethod) {
	Map<String, Set<String>> classMap =
			SootMethodRepresentationParser.v().parseClassNames(methodsToCall, false);
	
	// create new class:
	Body body = mainMethod.getActiveBody();
		LocalGenerator generator = new LocalGenerator(body);
	
	// Create the classes
	for (String className : classMap.keySet()) {
		SootClass createdClass = Scene.v().forceResolve(className, SootClass.BODIES);
		createdClass.setApplicationClass();
		Local localVal = generateClassConstructor(createdClass, body);
		if (localVal == null) {
			logger.warn("Cannot generate constructor for class: {}", createdClass);
			continue;
		}
		
		// Create the method calls
		for (String method : classMap.get(className)) {
			SootMethodAndClass methodAndClass =
					SootMethodRepresentationParser.v().parseSootMethodString(method);
			SootMethod methodToInvoke = findMethod(Scene.v().getSootClass(
					methodAndClass.getClassName()), methodAndClass.getSubSignature());
			
			if (methodToInvoke == null)
				System.err.println("Method " + methodAndClass + " not found, skipping");
			else if (methodToInvoke.isConcrete()) {
				// Load the method
				methodToInvoke.retrieveActiveBody();
				buildMethodCall(methodToInvoke, body, localVal, generator);
			}
		}
	}
	
	// Jimple needs an explicit return statement
	body.getUnits().add(Jimple.v().newReturnVoidStmt());
	
	return mainMethod;
}
 
Example #12
Source File: DefaultEntryPointCreator.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
@Override
protected SootMethod createDummyMainInternal(SootMethod mainMethod) {
	Map<String, Set<String>> classMap =
			SootMethodRepresentationParser.v().parseClassNames(methodsToCall, false);
	
	// create new class:
	Body body = mainMethod.getActiveBody();
		LocalGenerator generator = new LocalGenerator(body);
	HashMap<String, Local> localVarsForClasses = new HashMap<String, Local>();
	
	// create constructors:
	for(String className : classMap.keySet()){
		SootClass createdClass = Scene.v().forceResolve(className, SootClass.BODIES);
		createdClass.setApplicationClass();
		
		Local localVal = generateClassConstructor(createdClass, body);
		if (localVal == null) {
			logger.warn("Cannot generate constructor for class: {}", createdClass);
			continue;
		}
		localVarsForClasses.put(className, localVal);
	}
	
	// add entrypoint calls
	int conditionCounter = 0;
	JNopStmt startStmt = new JNopStmt();
	JNopStmt endStmt = new JNopStmt();
	Value intCounter = generator.generateLocal(IntType.v());
	body.getUnits().add(startStmt);
	for (Entry<String, Set<String>> entry : classMap.entrySet()){
		Local classLocal = localVarsForClasses.get(entry.getKey());
		for (String method : entry.getValue()){
			SootMethodAndClass methodAndClass =
					SootMethodRepresentationParser.v().parseSootMethodString(method);
			SootMethod currentMethod = findMethod(Scene.v().getSootClass(methodAndClass.getClassName()),
					methodAndClass.getSubSignature());
			if (currentMethod == null) {
				logger.warn("Entry point not found: {}", method);
				continue;
			}
			
			JEqExpr cond = new JEqExpr(intCounter, IntConstant.v(conditionCounter));
			conditionCounter++;
			JNopStmt thenStmt = new JNopStmt();
			JIfStmt ifStmt = new JIfStmt(cond, thenStmt);
			body.getUnits().add(ifStmt);
			buildMethodCall(currentMethod, body, classLocal, generator);
			body.getUnits().add(thenStmt);
		}
	}
	body.getUnits().add(endStmt);
	JGotoStmt gotoStart = new JGotoStmt(startStmt);
	body.getUnits().add(gotoStart);
	
	body.getUnits().add(Jimple.v().newReturnVoidStmt());
	NopEliminator.v().transform(body);
	eliminateSelfLoops(body);
	return mainMethod;
}
 
Example #13
Source File: AndroidEntryPointCreator.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Adds calls to the callback methods defined in the application class
 * @param applicationClass The class in which the user-defined application
 * is implemented
 * @param applicationLocal The local containing the instance of the
 * user-defined application
 */
private void addApplicationCallbackMethods() {
	if (!this.callbackFunctions.containsKey(applicationClass.getName()))
		return;
	
	// Do not try to generate calls to methods in non-concrete classes
	if (applicationClass.isAbstract())
		return;
	if (applicationClass.isPhantom()) {
		System.err.println("Skipping possible application callbacks in "
				+ "phantom class " + applicationClass);
		return;
	}

	for (String methodSig : this.callbackFunctions.get(applicationClass.getName())) {
		SootMethodAndClass methodAndClass = SootMethodRepresentationParser.v().parseSootMethodString(methodSig);
	
		// We do not consider lifecycle methods which are directly inserted
		// at their respective positions
		if (AndroidEntryPointConstants.getApplicationLifecycleMethods().contains
				(methodAndClass.getSubSignature()))
			continue;
				
		SootMethod method = findMethod(Scene.v().getSootClass(methodAndClass.getClassName()),
				methodAndClass.getSubSignature());
		// If we found no implementation or if the implementation we found
		// is in a system class, we skip it. Note that null methods may
		// happen since all callback interfaces for application callbacks
		// are registered under the name of the application class.
		if (method == null)
			continue;
		if (method.getDeclaringClass().getName().startsWith("android.")
				|| method.getDeclaringClass().getName().startsWith("java."))
			continue;
		
		// Get the local instance of the target class
		Local local = this.localVarsForClasses.get(methodAndClass.getClassName());
		if (local == null) {
			System.err.println("Could not create call to application callback "
					+ method.getSignature() + ". Local was null.");
			continue;
		}

		// Add a conditional call to the method
		JNopStmt thenStmt = new JNopStmt();
		createIfStmt(thenStmt);
		buildMethodCall(method, body, local, generator);	
		body.getUnits().add(thenStmt);
	}
}
 
Example #14
Source File: CustomEntryPointCreator.java    From steady with Apache License 2.0 4 votes vote down vote up
/**
 * <p>generateAppropriateDummyClasses.</p>
 *
 * @param methodsToCall a {@link java.util.Collection} object.
 */
public void generateAppropriateDummyClasses(Collection<String> methodsToCall) {

    Map<String, Set<String>> classMap = SootMethodRepresentationParser.v().parseClassNames(methodsToCall, false);
    for (String className : classMap.keySet()) {
        SootClass createdClass = Scene.v().getSootClass(className);
        if (createdClass.isConcrete() && !createdClass.isPhantom() && !createdClass.isPhantomClass()) {
            for (String method : classMap.get(className)) {
                SootMethodAndClass methodAndClass = SootMethodRepresentationParser.v().parseSootMethodString(method);
                SootMethod methodToInvoke = findMethod(Scene.v().getSootClass(methodAndClass.getClassName()),
                        methodAndClass.getSubSignature());

                List<Type> parameterTypes = methodToInvoke.getParameterTypes();
                //check if we actually have concrete parameters for these classes, otherwise generate dummyclasses
                for (Type parameterType : parameterTypes) {
                    if (super.isSimpleType(parameterType.getEscapedName())) {
                        continue;
                    }
                    if (!(parameterType instanceof RefType)) {
                        continue;
                    }
                    SootClass class2Search = ((RefType) parameterType).getSootClass();
                    //check if a concrete subclass exists
                    boolean compatibleTypeExists = concreteSubClassExists(class2Search);

                    if (!compatibleTypeExists) {

                        if (Scene.v().isExcluded(class2Search)) {
                            SootClass dummyClass = getDummyClass(class2Search);
                            this.dummyClasses.add(dummyClass);
                        }
                    }


                }


            }
        }
    }


}
 
Example #15
Source File: AnalyzeJimpleClass.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
public Map<String, Set<SootMethodAndClass>> getCallbackMethods() {
	return this.callbackMethods;
}
 
Example #16
Source File: SourceSinkDefinition.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Creates a new instance of the MethodSourceSinkDefinition class 
 */
public SourceSinkDefinition(SootMethodAndClass am) {
	this(am, null, null, null);
}
 
Example #17
Source File: AndroidMethod.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
public AndroidMethod(SootMethodAndClass methodAndClass) {
	super(methodAndClass);
	this.permissions = Collections.emptySet();
}
 
Example #18
Source File: AccessPathBasedSourceSinkManager.java    From JAADAS with GNU General Public License v3.0 3 votes vote down vote up
/**
 * Creates a new instance of the {@link AndroidSourceSinkManager} class with strong matching, i.e. the methods in
 * the code must exactly match those in the list.
 * 
 * @param sources
 *            The list of source methods
 * @param sinks
 *            The list of sink methods
 * @param callbackMethods
 *            The list of callback methods whose parameters are sources through which the application receives data
 *            from the operating system
 * @param weakMatching
 *            True for weak matching: If an entry in the list has no return type, it matches arbitrary return types
 *            if the rest of the method signature is compatible. False for strong matching: The method signature in
 *            the code exactly match the one in the list.
 * @param layoutMatching
 *            Specifies whether and how to use Android layout components as sources for the information flow
 *            analysis
 * @param layoutControls
 *            A map from reference identifiers to the respective Android layout controls
 */
public AccessPathBasedSourceSinkManager(Set<SourceSinkDefinition> sources,
		Set<SourceSinkDefinition> sinks,
		Set<SootMethodAndClass> callbackMethods,
		LayoutMatchingMode layoutMatching,
		Map<Integer, LayoutControl> layoutControls) {
	super(sources, sinks, callbackMethods, layoutMatching, layoutControls);
}
 
Example #19
Source File: AndroidSourceSinkManager.java    From JAADAS with GNU General Public License v3.0 2 votes vote down vote up
/**
 * Creates a new instance of the {@link AndroidSourceSinkManager} class with
 * either strong or weak matching.
 * 
 * @param sources
 *            The list of source methods
 * @param sinks
 *            The list of sink methods
 */
public AndroidSourceSinkManager(Set<SourceSinkDefinition> sources,
		Set<SourceSinkDefinition> sinks) {
	this(sources, sinks, Collections.<SootMethodAndClass>emptySet(),
			LayoutMatchingMode.NoMatch, null);
}
 
Example #20
Source File: SourceSinkDefinition.java    From JAADAS with GNU General Public License v3.0 2 votes vote down vote up
/**
 * Gets the method for which this object defines sources and sinks
 * @return The method for which this object defines sources and sinks
 */
public SootMethodAndClass getMethod() {
	return this.method;
}