soot.jimple.infoflow.android.resources.ARSCFileParser Java Examples

The following examples show how to use soot.jimple.infoflow.android.resources.ARSCFileParser. 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: AndroidSourceSinkManager.java    From JAADAS with GNU General Public License v3.0 6 votes vote down vote up
/**
 * Finds the given resource in the given package
 * 
 * @param resName
 *            The name of the resource to retrieve
 * @param resID
 * @param packageName
 *            The name of the package in which to look for the resource
 * @return The specified resource if available, otherwise null
 */
private AbstractResource findResource(String resName, String resID, String packageName) {
	// Find the correct package
	for (ARSCFileParser.ResPackage pkg : this.resourcePackages) {
		// If we don't have any package specification, we pick the app's
		// default package
		boolean matches = (packageName == null || packageName.isEmpty()) && pkg.getPackageName().equals(this.appPackageName);
		matches |= pkg.getPackageName().equals(packageName);
		if (!matches)
			continue;

		// We have found a suitable package, now look for the resource
		for (ARSCFileParser.ResType type : pkg.getDeclaredTypes())
			if (type.getTypeName().equals(resID)) {
				AbstractResource res = type.getFirstResource(resName);
				return res;
			}
	}
	return null;
}
 
Example #2
Source File: LayoutFileParser.java    From LibScout with Apache License 2.0 4 votes vote down vote up
public LayoutFileParser(String packageName, ARSCFileParser resParser) {
	this.packageName = packageName;
	this.resParser = resParser;
}
 
Example #3
Source File: AndroidSourceSinkManager.java    From JAADAS with GNU General Public License v3.0 4 votes vote down vote up
/**
 * Finds the last assignment to the given local representing a resource ID
 * by searching upwards from the given statement
 * 
 * @param stmt
 *            The statement from which to look backwards
 * @param local
 *            The variable for which to look for assignments
 * @return The last value assigned to the given variable
 */
private Integer findLastResIDAssignment(Stmt stmt, Local local, BiDiInterproceduralCFG<Unit, SootMethod> cfg, Set<Stmt> doneSet) {
	if (!doneSet.add(stmt))
		return null;

	// If this is an assign statement, we need to check whether it changes
	// the variable we're looking for
	if (stmt instanceof AssignStmt) {
		AssignStmt assign = (AssignStmt) stmt;
		if (assign.getLeftOp() == local) {
			// ok, now find the new value from the right side
			if (assign.getRightOp() instanceof IntConstant)
				return ((IntConstant) assign.getRightOp()).value;
			else if (assign.getRightOp() instanceof FieldRef) {
				SootField field = ((FieldRef) assign.getRightOp()).getField();
				for (Tag tag : field.getTags())
					if (tag instanceof IntegerConstantValueTag)
						return ((IntegerConstantValueTag) tag).getIntValue();
					else
						System.err.println("Constant " + field + " was of unexpected type");
			} else if (assign.getRightOp() instanceof InvokeExpr) {
				InvokeExpr inv = (InvokeExpr) assign.getRightOp();
				if (inv.getMethod().getName().equals("getIdentifier") && inv.getMethod().getDeclaringClass().getName().equals("android.content.res.Resources") && this.resourcePackages != null) {
					// The right side of the assignment is a call into the
					// well-known
					// Android API method for resource handling
					if (inv.getArgCount() != 3) {
						System.err.println("Invalid parameter count for call to getIdentifier");
						return null;
					}

					// Find the parameter values
					String resName = "";
					String resID = "";
					String packageName = "";

					// In the trivial case, these values are constants
					if (inv.getArg(0) instanceof StringConstant)
						resName = ((StringConstant) inv.getArg(0)).value;
					if (inv.getArg(1) instanceof StringConstant)
						resID = ((StringConstant) inv.getArg(1)).value;
					if (inv.getArg(2) instanceof StringConstant)
						packageName = ((StringConstant) inv.getArg(2)).value;
					else if (inv.getArg(2) instanceof Local)
						packageName = findLastStringAssignment(stmt, (Local) inv.getArg(2), cfg);
					else {
						System.err.println("Unknown parameter type in call to getIdentifier");
						return null;
					}

					// Find the resource
					ARSCFileParser.AbstractResource res = findResource(resName, resID, packageName);
					if (res != null)
						return res.getResourceID();
				}
			}
		}
	}

	// Continue the search upwards
	for (Unit pred : cfg.getPredsOf(stmt)) {
		if (!(pred instanceof Stmt))
			continue;
		Integer lastAssignment = findLastResIDAssignment((Stmt) pred, local, cfg, doneSet);
		if (lastAssignment != null)
			return lastAssignment;
	}
	return null;
}
 
Example #4
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();
}