soot.jimple.infoflow.android.manifest.ProcessManifest Java Examples

The following examples show how to use soot.jimple.infoflow.android.manifest.ProcessManifest. 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: UtilApk.java    From FuzzDroid with Apache License 2.0 7 votes vote down vote up
@SuppressWarnings("unchecked")
private static void addMaxPrioForSMSReceiver(ProcessManifest manifest) {
	for(AXmlNode receiver : manifest.getReceivers()) {
		for(AXmlNode receiverChild : receiver.getChildren()) {
			if(receiverChild.getTag().equals("intent-filter")) {
				//search for SMS receiver
				for(AXmlNode childChild : receiverChild.getChildren()) {
					if(childChild.getTag().equals("action")) {
						if(childChild.hasAttribute("name") && ((String)childChild.getAttribute("name").getValue()).equalsIgnoreCase("android.provider.Telephony.SMS_RECEIVED")){
							//prepare the priority filter
							if(receiverChild.hasAttribute("priority")) 
								((AXmlAttribute<Integer>)receiverChild.getAttribute("priority")).setValue(Integer.MAX_VALUE);
							else {
								AXmlAttribute<Integer> attr = new AXmlAttribute<Integer>("priority", Integer.MAX_VALUE, ANDROID_NAMESPACE);
								receiverChild.addAttribute(attr);
							}
						}
					}
				}
			}
		}
	}
}
 
Example #2
Source File: Instrumenter.java    From FuzzDroid with Apache License 2.0 6 votes vote down vote up
private void addTemporalManifestChanges(ProcessManifest androidManifest) {
	File manifestFile = null;
	try{
		//temporarily save the modified AndroidManifest
		manifestFile = File.createTempFile("AndroidManifest.xml", null);		
		FileOutputStream fos = new FileOutputStream(manifestFile.getPath());
		byte[] output = androidManifest.getOutput();
		fos.write(output);
		fos.close();
		
		ArrayList<File> files = new ArrayList<File>();
		files.add(manifestFile);
		HashMap<String, String> paths = new HashMap<String, String>();
		paths.put(manifestFile.getAbsolutePath(), "AndroidManifest.xml");
		//add the modified AndroidManifest into the original APK
		androidManifest.getApk().addFilesToApk(files, paths);
	}catch(Exception ex) {
		LoggerHelper.logEvent(MyLevel.EXCEPTION_ANALYSIS, ex.getMessage());
		ex.printStackTrace();
		System.exit(-1);
	}
	finally {
		if (manifestFile != null && manifestFile.exists())
			manifestFile.delete();
	}
}
 
Example #3
Source File: Util.java    From DroidForce with GNU Lesser General Public License v2.1 6 votes vote down vote up
/**
 * This is a kind of hack and includes much more instrumentation which is necessary;
 * But it is still sound ;-).
 * @param apkFileLocation: apk file path
 */
public static void initializePePInAllPossibleClasses(String apkFileLocation){
	try {
		ProcessManifest manifest = new ProcessManifest(apkFileLocation);		
		Set<String> entryClasses = manifest.getEntryPointClasses();
		 
		for(String entryClass : entryClasses){
			SootClass sc = Scene.v().getSootClass(entryClass);
			
			List<SootClass> allSuperClasses = Scene.v().getActiveHierarchy().getSuperclassesOf(sc);
		 	for(SootClass subclass : allSuperClasses)
		 		if(subclass.getName().equals("android.content.Context")){
		 			initializePeP(sc);
		 			break;
		 		}
		}
	}
	catch (IOException | XmlPullParserException ex) {
		System.err.println("Could not read Android manifest file: " + ex.getMessage());
		throw new RuntimeException(ex);
	}
}
 
Example #4
Source File: ICCLinker.java    From soot-infoflow-android-iccta with GNU Lesser General Public License v2.1 6 votes vote down vote up
public static void main(String[] args) 
{
	DB.setJdbcPath("res/jdbc.xml");

	String apkPath = args[0];
	
	try 
	{
		ProcessManifest processMan = new ProcessManifest(apkPath);
		String pkgName = processMan.getPackageName();
		
		buildLinks(pkgName);
	} 
	catch (Exception e) 
	{
		e.printStackTrace();
	}
	
}
 
Example #5
Source File: DummyMainGenerator.java    From DroidRA with GNU Lesser General Public License v2.1 6 votes vote down vote up
public static SootMethod generateDummyMain(String apkFileLocation)
{
	SootMethod mainMethod = null;
	
	try
	{	
		ProcessManifest processMan = new ProcessManifest(apkFileLocation);
		Set<String> entrypoints = processMan.getEntryPointClasses();
		
		DummyMainGenerator dmGenerator = new DummyMainGenerator(apkFileLocation);
		
		mainMethod = dmGenerator.generateMain(entrypoints);
		
		System.out.println(mainMethod.retrieveActiveBody());
	}
	catch (Exception ex)
	{
		ex.printStackTrace();
	}
	
	return mainMethod;
}
 
Example #6
Source File: DummyMainGenerator.java    From DroidRA with GNU Lesser General Public License v2.1 6 votes vote down vote up
@Override
protected void internalTransform(String phaseName, Map<String, String> options) 
{
	try
	{	
		ProcessManifest processMan = new ProcessManifest(apkFileLocation);
		Set<String> entrypoints = processMan.getEntryPointClasses();
		
		SootMethod mainMethod = generateMain(entrypoints);
		
		System.out.println(mainMethod.retrieveActiveBody());
	}
	catch (Exception ex)
	{
		ex.printStackTrace();
	}
}
 
Example #7
Source File: DroidRAUtils.java    From DroidRA with GNU Lesser General Public License v2.1 6 votes vote down vote up
public static void extractApkInfo(String apkPath)
{
	GlobalRef.apkPath = apkPath;
	
	try 
	{
		ProcessManifest manifest = new ProcessManifest(apkPath);
		
		GlobalRef.pkgName = manifest.getPackageName();
		GlobalRef.apkVersionCode = manifest.getVersionCode();
		GlobalRef.apkVersionName = manifest.getVersionName();
		GlobalRef.apkMinSdkVersion = manifest.getMinSdkVersion();
		GlobalRef.apkPermissions = manifest.getPermissions();
	} 
	catch (Exception e) 
	{
		e.printStackTrace();
	}
}
 
Example #8
Source File: UtilApk.java    From FuzzDroid with Apache License 2.0 5 votes vote down vote up
private static void addInternetPermissionIfNecessary(ProcessManifest androidManifest) {
	String internetPerm = "android.permission.INTERNET";
	Set<String> allPermissions = androidManifest.getPermissions();
	for(String perm : allPermissions) {
		if(perm.equals(internetPerm))
			//do nothing in case the internet-permission already exists
			return;
	}
	
	androidManifest.addPermission(internetPerm);
}
 
Example #9
Source File: UpdateManifestAndCodeForWaitPDP.java    From DroidForce with GNU Lesser General Public License v2.1 5 votes vote down vote up
/**
 * Get the package name of the application
 * @param apkFileLocation
 * @return
 */
public static String getApplicationPackageName(String apkFileLocation) {
	String packageName = null;
	try {
		ProcessManifest pm = new ProcessManifest(apkFileLocation);
		AXmlHandler axmlh = pm.getAXml(); 
		
		// Find main activity and remove main intent-filter
		List<AXmlNode> anodes = axmlh.getNodesWithTag("manifest");
		for (AXmlNode an: anodes) {
			boolean hasMain = false;
			boolean hasLauncher = false;
			AXmlNode filter = null;
			
			AXmlAttribute aname = an.getAttribute("package");
			String aval = (String)aname.getValue();
			packageName = aval;
			System.out.println("package: "+ packageName);
			break;
			
		}
	} catch (IOException | XmlPullParserException ex) {
		System.err.println("Could not read Android manifest file: " + ex.getMessage());
		throw new RuntimeException(ex);
	}

	return packageName;
}
 
Example #10
Source File: DummyMainGenerator.java    From DroidRA with GNU Lesser General Public License v2.1 5 votes vote down vote up
public static Set<String> getComponents(String apkFileLocation)
{
	Set<String> entrypoints = null;
	try
	{	
		ProcessManifest processMan = new ProcessManifest(apkFileLocation);
		entrypoints = processMan.getEntryPointClasses();
	}
	catch (Exception ex)
	{
		ex.printStackTrace();
	}
	
	return entrypoints;
}
 
Example #11
Source File: UtilApk.java    From FuzzDroid with Apache License 2.0 5 votes vote down vote up
private static void addTracingService(ProcessManifest androidManifest) {
	AXmlNode tracingService = new AXmlNode("service", null, androidManifest.getApplication());
	AXmlAttribute<String> nameAttribute = new AXmlAttribute<String>("name", UtilInstrumenter.HELPER_SERVICE_FOR_PATH_TRACKING,  ANDROID_NAMESPACE);
	AXmlAttribute<String> exportedAttribute = new AXmlAttribute<String>("exported", "false",  ANDROID_NAMESPACE);
	tracingService.addAttribute(nameAttribute);
	tracingService.addAttribute(exportedAttribute);
	
	androidManifest.addService(tracingService);
}
 
Example #12
Source File: UtilApk.java    From FuzzDroid with Apache License 2.0 5 votes vote down vote up
private static void addHookinHelperAsApplicationIfNecessary(ProcessManifest androidManifest){
	AXmlNode application = androidManifest.getApplication();
	if(!application.hasAttribute("name")) {
		AXmlAttribute<String> nameAttribute = new AXmlAttribute<String>("name", UtilInstrumenter.HELPER_APPLICATION_FOR_HOOKING,  ANDROID_NAMESPACE);
		application.addAttribute(nameAttribute);
	}
}
 
Example #13
Source File: UtilApk.java    From FuzzDroid with Apache License 2.0 5 votes vote down vote up
private static void addComponentCallerService(ProcessManifest androidManifest) {
	AXmlNode componentCallerService = new AXmlNode("service", null, androidManifest.getApplication());
	AXmlAttribute<String> nameAttribute = new AXmlAttribute<String>("name", UtilInstrumenter.COMPONENT_CALLER_SERVICE_HELPER,  ANDROID_NAMESPACE);
	AXmlAttribute<String> exportedAttribute = new AXmlAttribute<String>("exported", "false",  ANDROID_NAMESPACE);
	componentCallerService.addAttribute(nameAttribute);
	componentCallerService.addAttribute(exportedAttribute);
	
	androidManifest.addService(componentCallerService);
}
 
Example #14
Source File: UtilApk.java    From FuzzDroid with Apache License 2.0 5 votes vote down vote up
private static void addPermissionIfNecessary(String permission, ProcessManifest androidManifest) {
	Set<String> allPermissions = androidManifest.getPermissions();
	for(String perm : allPermissions) {
		if(perm.equals(permission))
			//do nothing in case the sdcard-permission already exists
			return;
	}
	
	androidManifest.addPermission(permission);
}
 
Example #15
Source File: UtilApk.java    From FuzzDroid with Apache License 2.0 5 votes vote down vote up
public static void manipulateAndroidManifest(ProcessManifest androidManifest) {
	// process old manifest
	addHookinHelperAsApplicationIfNecessary(androidManifest);
	addInternetPermissionIfNecessary(androidManifest);
	addTracingService(androidManifest);
	addComponentCallerService(androidManifest);
	addMaxPrioForSMSReceiver(androidManifest);
	addPermissionIfNecessary("android.permission.READ_EXTERNAL_STORAGE", androidManifest);
	addPermissionIfNecessary("android.permission.WRITE_EXTERNAL_STORAGE", androidManifest);
	addPermissionIfNecessary("android.permission.WRITE_CONTACT", androidManifest);
}
 
Example #16
Source File: FrameworkEventManager.java    From FuzzDroid with Apache License 2.0 5 votes vote down vote up
private boolean isLaunchableAcitivity(SootClass sc, ProcessManifest manifest) {
	Set<AXmlNode> launchableActivities = manifest.getLaunchableActivities();
	for(AXmlNode node : launchableActivities) {
		if(node.hasAttribute("name")) {
			String activityName = (String)node.getAttribute("name").getValue();
			activityName = getFullyQualifiedName(manifest, activityName);
			
			if(activityName.equals(sc.getName()))
				return true;
		}
	}
	return false;
}
 
Example #17
Source File: Instrumenter.java    From FuzzDroid with Apache License 2.0 4 votes vote down vote up
private void executeTransformers(ProcessManifest manifest) {
		// We first need to retrieve some information from the manifest
		Set<String> constructors = new HashSet<>();
		for (String className : manifest.getEntryPointClasses())
			constructors.add("<" + className + ": void <init>()>");
				
		ConditionTracking conditionTracking = new ConditionTracking();
		CodePositionTracking codePositionTracking = new CodePositionTracking(codePositionManager);
		DynamicCallGraphTracking dynamicCallGraphTracking = new DynamicCallGraphTracking(codePositionManager);
		PathExecutionTransformer pathExecutionTransformer = new PathExecutionTransformer();
		GoalReachedTracking goalReachedTracking = new GoalReachedTracking(config.getAllTargetLocations());
		TimingBombTransformer timingBombs = new TimingBombTransformer();
		DummyMethodHookTransformer dummyMethods = new DummyMethodHookTransformer();
		DynamicValueTransformer dynamicValues = new DynamicValueTransformer(true);
		ClassLoaderTransformer classLoaders = new ClassLoaderTransformer();
		
		for (SootClass sc : Scene.v().getApplicationClasses())
			for (SootMethod sm : sc.getMethods())
				if (sm.isConcrete()) {
					Body body = sm.getActiveBody();
					//todo PAPER-EVAL ONLY
					codePositionTracking.transform(body);					
					if(!FrameworkOptions.evaluationOnly){
//						conditionTracking.transform(body);
//						dynamicCallGraphTracking.transform(body);
					}
//					if (FrameworkOptions.recordPathExecution)
//						pathExecutionTransformer.transform(body);
					goalReachedTracking.transform(body);
					//todo PAPER-EVAL ONLY
					if(!FrameworkOptions.evaluationOnly){
						timingBombs.transform(body);
						dummyMethods.transform(body);
						dynamicValues.transform(body);
					}
					classLoaders.transform(body);
				}
		//todo PAPER-EVAL ONLY
		if(!FrameworkOptions.evaluationOnly)
			new CrashReporterInjection(constructors).transform();
		new GlobalInstanceTransformer().transform();
	}
 
Example #18
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 #19
Source File: FrameworkEventManager.java    From FuzzDroid with Apache License 2.0 4 votes vote down vote up
public Set<FrameworkEvent> extractInitalEventsForReachingTarget(Unit targetLocation, BackwardsInfoflowCFG backwardsCFG, ProcessManifest manifest) {
	Set<Unit> headUnits = getAllInitalMethodCalls(targetLocation, backwardsCFG);
	Set<FrameworkEvent> androidEvents = getAndroidEventsFromManifest(backwardsCFG, headUnits, manifest);
	return androidEvents;
}
 
Example #20
Source File: Test.java    From soot-infoflow-android-iccta with GNU Lesser General Public License v2.1 4 votes vote down vote up
public static void main(final String[] args)
{
	apkPath = args[0];
	androidJars =args[1];
	System.out.println("[IccTA]" + apkPath + ", " + androidJars);
	
	parseConfig();
	
	try
	{
		DB.setJdbcPath("res/jdbc.xml");
		
		ProcessManifest processMan = new ProcessManifest(apkPath);
		Test.appPackageName = processMan.getPackageName();
		
		System.out.println("[IccTA]" + "ICC Provider is " + iccProviderStr);
		
		if (iccProviderStr.equals("ic3"))
		{
			ICCLinker.buildLinks(Test.appPackageName);
		}
		
		if (apkPath.contains(APK_COMBINER))
		{
			if (apkPath.contains("/"))
			{
				int startPos = apkPath.lastIndexOf('/');
				String filename = apkPath.substring(startPos+1);
				
				filename = filename.replace(".apk", "");
				
				Test.appPackageNames = filename.split(Test.APK_COMBINER);
			}
		}
		
		AndroidIPCManager ipcManager = new AndroidIPCManager("res/IPCMethods.txt", Test.appPackageName);
		if (Test.appPackageNames != null)
		{
			ipcManager = new AndroidIPCManager("res/IPCMethods.txt", Test.appPackageNames);
		}
		
		ipcManager.setIccProvider(iccProviderStr);
		
		InfoStatistic mostBeginning = new InfoStatistic("Beginning");
		ipcManager.addJimpleUpdater(mostBeginning);
		
		InfoStatistic mostEnding = new InfoStatistic("Ending");
		ipcManager.addPostJimpleUpdater(mostEnding);
		
		SharedPreferencesUpdater sharedPreferencesUpdater = new SharedPreferencesUpdater();
		ipcManager.addJimpleUpdater(sharedPreferencesUpdater);
		
		//JimpleReduceStaticFieldsTransformer jrsf = new JimpleReduceStaticFieldsTransformer();
		//ipcManager.addJimpleUpdater(jrsf);
		
		JimpleIndexNumberTransformer jinTransformer = new JimpleIndexNumberTransformer();
		ipcManager.addJimpleUpdater(jinTransformer);
		
		ApplicationClassSet acs = new ApplicationClassSet();
		ipcManager.addJimpleUpdater(acs);
		
		//ExtraMapping extraMapping = new ExtraMapping(ApplicationClassSet.applicationClasses);
		//ipcManager.addJimpleUpdater(extraMapping);
		
		ExtraExtractor extraExtractor = new ExtraExtractor();
		ipcManager.addJimpleUpdater(extraExtractor);
		
		FlowDroidLauncher.setIPCManager(ipcManager);
		FlowDroidLauncher.main(args);
	}
	catch (Exception ex)
	{
		ex.printStackTrace();
	}
}
 
Example #21
Source File: Main.java    From FuzzDroid with Apache License 2.0 4 votes vote down vote up
private Set<FrameworkEvent> getFrameworkEvents(Unit targetLocation, BackwardsInfoflowCFG cfg) {
	FrameworkEventManager eventManager =  FrameworkEventManager.getEventManager();
	ProcessManifest manifest = UtilApk.getManifest();									
	Set<FrameworkEvent> targetAndroidEvents = eventManager.extractInitalEventsForReachingTarget(targetLocation, cfg, manifest);			
	return targetAndroidEvents;
}
 
Example #22
Source File: UpdateManifestAndCodeForWaitPDP.java    From DroidForce with GNU Lesser General Public License v2.1 4 votes vote down vote up
/**
 * Get the name of the main activity in the AndroidManifest.xml file
 * @param apkFileLocation
 * @return
 */
public static String getMainActivityName(String apkFileLocation) {
	String mainActivityName = null;
	try {
		ProcessManifest pm = new ProcessManifest(apkFileLocation);
		AXmlHandler axmlh = pm.getAXml(); 
		
		// Find main activity and remove main intent-filter
		List<AXmlNode> anodes = axmlh.getNodesWithTag("activity");
		for (AXmlNode an: anodes) {
			boolean hasMain = false;
			boolean hasLauncher = false;
			AXmlNode filter = null;
			
			AXmlAttribute aname = an.getAttribute("name");
			String aval = (String)aname.getValue();
			System.out.println("activity: "+ aval);
			for (AXmlNode ch : an.getChildren()) {
				System.out.println("children: "+ ch);
			}
			List<AXmlNode> fnodes = an.getChildrenWithTag("intent-filter");
			for (AXmlNode fn: fnodes) {
				
				hasMain = false;
				hasLauncher = false;
				
				// check action
				List<AXmlNode> acnodes = fn.getChildrenWithTag("action");
				for (AXmlNode acn: acnodes) {
					AXmlAttribute acname = acn.getAttribute("name");
					String acval = (String)acname.getValue();
					System.out.println("action: "+ acval);
					if (acval.equals("android.intent.action.MAIN")) {
						hasMain = true;
					}
				}
				// check category
				List<AXmlNode> catnodes = fn.getChildrenWithTag("category");
				for (AXmlNode catn: catnodes) {
					AXmlAttribute catname = catn.getAttribute("name");
					String catval = (String)catname.getValue();
					System.out.println("category: "+ catval);
					if (catval.equals("android.intent.category.LAUNCHER")) {
						hasLauncher = true;
						filter = fn;
					}
				}
				if (hasLauncher && hasMain) {
					break;
				}
			}
			
			if (hasLauncher && hasMain) {
				// replace name with the activity waiting for the connection to the PDP
				System.out.println("main activity is: "+ aval);
				System.out.println("excluding filter: "+ filter);
				filter.exclude();
				mainActivityName = aval;
				break;
			}
			
		}
	} catch (IOException | XmlPullParserException ex) {
		System.err.println("Could not read Android manifest file: " + ex.getMessage());
		throw new RuntimeException(ex);
	}

	return mainActivityName;
}
 
Example #23
Source File: Instrumenter.java    From FuzzDroid with Apache License 2.0 4 votes vote down vote up
private void initializeHooking(ProcessManifest manifest) {						
	String applicationName = manifest.getApplicationName();
	//case 1
	if(applicationName != null) {
		if(applicationName.startsWith(".")) {
			String packageName = manifest.getPackageName();
			if(packageName == null)
				throw new RuntimeException("There is a problem with the package name");
			applicationName = packageName + applicationName;
		}
		SootClass applicationSootClass = Scene.v().getSootClass(applicationName);
		if(applicationSootClass != null) {				
			String attachMethodName = String.format("<%s: void attachBaseContext(android.content.Context)>", applicationName);
			SootMethod attachMethod = Scene.v().grabMethod(attachMethodName);	
			//case 1
			if(attachMethod != null) {
				Body body = attachMethod.getActiveBody();
				Local contextParam = body.getParameterLocal(0);
				
				List<Unit> unitsToInstrument = new ArrayList<Unit>();										
				String hookingHelperApplicationClassAttachMethodName = String.format("<%s: void initializeHooking(android.content.Context)>", UtilInstrumenter.HOOKER_CLASS);
				SootMethod hookingHelperApplicationClassAttachMethod = Scene.v().getMethod(hookingHelperApplicationClassAttachMethodName);
				if(hookingHelperApplicationClassAttachMethod == null)
					throw new RuntimeException("this should not happen");					
				SootMethodRef ref = hookingHelperApplicationClassAttachMethod.makeRef();					
				InvokeExpr invExpr = Jimple.v().newStaticInvokeExpr(ref, contextParam);
				unitsToInstrument.add(Jimple.v().newInvokeStmt(invExpr));
				
				
				Unit instrumentAfterUnit = null;
				for(Unit unit : body.getUnits()) {
					if(unit instanceof InvokeStmt) {
						InvokeStmt invStmt = (InvokeStmt)unit;
						if(invStmt.getInvokeExpr().getMethod().getSubSignature().equals("void attachBaseContext(android.content.Context)")) {
							instrumentAfterUnit = unit;
							break;
						}
					}
				}
				
				if(instrumentAfterUnit == null)
					throw new RuntimeException("this should not happen");
				body.getUnits().insertAfter(unitsToInstrument, instrumentAfterUnit);								
			}
			//case 2
			else {
				attachMethodName = String.format("<%s: void attachBaseContext(android.content.Context)>", UtilInstrumenter.HELPER_APPLICATION_FOR_HOOKING);	
				attachMethod = Scene.v().grabMethod(attachMethodName);
				if(attachMethod == null)
					throw new RuntimeException("this should not happen");
				
				List<Type> params = new ArrayList<Type>();
				SootClass contextClass = Scene.v().getSootClass("android.content.Context");
				params.add(contextClass.getType());
				SootMethod newAttachMethod = new SootMethod("attachBaseContext", params, VoidType.v());
				newAttachMethod.setModifiers(soot.Modifier.PROTECTED);
				newAttachMethod.setActiveBody(attachMethod.getActiveBody());
				applicationSootClass.addMethod(newAttachMethod);
			}
			
			//there is no need for our Application class
			Scene.v().getSootClass(UtilInstrumenter.HELPER_APPLICATION_FOR_HOOKING).setLibraryClass();
		}
		else {
			throw new RuntimeException("There is a problem with the Application class!");
		}
	}
	//case 3
	else{
		//there is no need for any instrumentation since the Application class is set to application-class.
	}
}