Tool Support
Artifact Elements
The provided archive contains the following elements:
- PATDroid.py: The main scripts that integrates and runs different phases of the approach (i.e., static and dynamic components described in the paper)
- Libs: Contains the following elements:
- seal_key_store.jks: A temporary key store used for signing the apks.
- sample_apps: sample apps accompanied by their GUI tests, provided for evaluation.
Requirements (not included in the archive):
- Python 2.7
- Java 8
- Android SDK (Path to SDK root should be set in environment variable $ANDROID_HOME)
- Running Android emulator or a rooted device with Android 6.0 (API level 23) or above
How to run
PATDroid could be run in two modes: 1) Developers mode (where app source code and GUI tests are available), and 2) Tester mode (where only apk file is available). Here we describe using PATDroid in each mode:
Developers Mode
To run PATDroid in developers mode, you need to generate and provide two APK files, one apk for the main app (called app under test or AUT in the paper), and the other apk for the GUI or instrumented test (called test harness app or THA in the paper). You can find those two apk files under $YOUR_PROJECT$/app/build/outputs/apk
, if the app is developed using Android Studio.
Note: Currently PATDroid supports the two major Android GUI testing framework, namely Espresso and Robotium.
Preparing the apps under test:
To enable dynamic analysis process, your main apk file (AUT) should be also instrumed. For this purpose, you need to perform two more steps:
1. Enabling aspectj in your app by adding the following code to the app/build.gradle:
buildscript {
repositories {
jcenter()
maven { url "https://jitpack.io" }
}
dependencies {
classpath 'com.github.Archinamon:GradleAspectJ-Android:2.2.2'
}
}
apply plugin: 'com.android.application'
apply plugin: 'com.archinamon.aspectj'
2. Adding the following aspect file (logger.aj) to the project under: $YOUR_PROJECT$/app/src/main/aspectj:
import android.util.Log;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
aspect Logger {
String INSTRUMENTATION_TAG = "edu.uci.seal.cactus_instrumentation";
pointcut entryPoint(): within(android..*.*+) && execution(* edu.uci.ics.seal..*.on*(..));
before(): entryPoint() {
String className = thisJoinPoint.getThis().getClass().getName();
final Matcher matcher = Pattern.compile("execution\\((.* )*(.*) " + className.replaceAll("\\$", ".") + "\\.(.*)\\((.*)\\)\\)").matcher(thisJoinPoint.toLongString());
if (matcher.matches()) {
String returnType = matcher.group(2);
String methodName = matcher.group(3);
String params = matcher.group(4).replaceAll(" ", "");
String signature = String.format("<%s: %s %s(%s)>", className, returnType, methodName, params);
String message = String.format("App_Entry_Point ### %s", signature);
Log.i(INSTRUMENTATION_TAG, message);
}
}
}
For the evaluation:
Instead of performing the above steps to prepare APKs, you can use any of the sample apps provided in the app directory.
Running PATDroid in Developers mode:
Having two apk files (i.e., AUT that prepared as above and THA), you can run PATDroid to identify the required permissions for each test.
./PATDroid.py a $AUT_PATH$ $THA_PATH$
Testers Mode
If you don't have the app source code and/or GUI tests, you can run PATDroid in this mode. However, since the generated tests in this mode are random (i.e., Monkey tests), PATDroid is less effective compared to those generated in Developers mode.
Installing Xposed module
To run PATDroid in this mode, you first need to install the Xposed framework as described here:
Running PATDroid in Testers mode:
./PATDroid.py a $APP_PATH$ -t m
Note: One (and only one) Android emulator or device should be running before the execution of PATDroid in both modes.
PATDroid output
For a given apk file named, for instance, myApp.apk, PATDroid generates a JSON output file, named myApp.json, with the structure similar to the example shown in the following:
The output file describes all permissions of the app ("perms" tag) as well as the relevant permission for each test. Consider test04_addExpenseReceipt, for example, where CAMERA permission is identified as relevant. Thanks to PATDroid results, instead of executing this test 2^3=8 times (since the app has 3 permissions), we can run it twice, once with CAMERA permission granted and once revoked. The saved time would be more significant for larger apps with more permissions and tests.
All Options
usage: PATDroid.py [-h] [-s ANDROID_SDK] [-o OUTPUT] [-r RESULT]
[-e EMULATOR_ID] [-v] [-i] [-p] [-t Test Framework]
{a,e,all} [apk_address] [apk_test_address]
Run PATDroid
positional arguments:
{a,e,all} PATDroid running mode (a=single app analysis, all=analyze all apps in a directory)
apk_address the path to the apk file or the directory containing apk files
apk_test_address the path to the test apk file
optional arguments:
-h, --help show this help message and exit
-s ANDROID_SDK the path to the Android' SDK home directory (by default read from $ANDROID_HOME)
-o OUTPUT the path to the output file
-r RESULT the path to the analysis output json file
-e EMULATOR_ID the emulator/device id
-v, --verbose increase output verbosity
-i, --interactive run interactively
-p, --performance measure analysis time
-t Test Framework test framework for running tests (e= Espresso, r=Robotium, m=Monkey)