Realtime Privacy Monitoring on Smartphones

TaintDroid Build Instructions

Disclaimer: Use the TaintDroid and TaintDroid UI research prototypes at your own risk.

TaintDroid is a research prototype and is provided "as is" without warranty or support of any kind, whether expressed or implied. The creators of TaintDroid make no guarantee and hold no responsibility for any damage, injury, loss of property, loss of data, loss of any and all resources, or any negative influence what-so-ever that may result from any and all use of TaintDroid and associated materials. This includes but is not limited to the downloadable software and documentation available from this website. Negative consequences of your usage of TaintDroid and any associated materials are solely your problem and your responsibility.

Before you start:

We created a TaintDroid discussion group for those who are interested in building, installing and running TaintDroid. You may want to post related questions there if answers are not found on this webpage.

This guide assumes that you have:

It is strongly recommended that you use the nandroid tool provided in a custom recovery firmware such as Amon_RA to backup your current Nexus One system before flashing new images to your device.

Step 1: Get the Android source code

TaintDroid uses the "android-2.1_r2.1p" tag of the Android source code. This is a snapshot of the Android 2.1 code for the Google Nexus One (HTC Passion). Follow the instructions on source.android.com for obtaining and building Android. Use the "-b android-2.1_r2.1p" branch option for repo when checking out the source code.

If you are already familiar with getting and building the Android source code, the following commands summarize the steps:

% mkdir -p ~/tdroid/tdroid-2.1_r2.1p
% cd ~/tdroid/tdroid-2.1_r2.1p
% repo init -u git://android.git.kernel.org/platform/manifest.git -b android-2.1_r2.1p
% repo sync
... wait

Note: At this point, it is recommend that you build Android without any modifications. This will ensure that any build errors for your environment are resolved and are not confused with TaintDroid build errors. For example:

% . ./build/envsetup.sh
% lunch 1
% make -j4
... wait
% emulator
... ensure the build works

Step 2: Get the TaintDroid source code

Download the TaintDroid local_manifest.xml and place it in ~/tdroid/tdroid-2.1_r2.1p/.repo or copy and paste the following content into .repo/local_manifest.xml.

<manifest>
  <remote  name="github"
           fetch="git://github.com" />
  <remove-project name="platform/dalvik"/>
  <project path="dalvik" remote="github" name="TaintDroid/android_platform_dalvik" revision="taintdroid-2.1_r2.1p" />
  <remove-project name="platform/frameworks/base"/>
  <project path="frameworks/base" remote="github" name="TaintDroid/android_platform_frameworks_base" revision="taintdroid-2.1_r2.1p" />
</manifest>

Next, pull the source code and make sure we are working with the right version.

% cd ~/tdroid/tdroid-2.1_r2.1p
% repo sync
% cd dalvik
% git branch --track taintdroid-2.1_r2.1p github/taintdroid-2.1_r2.1p
% git checkout taintdroid-2.1_r2.1p
% git pull # (just to be safe)
% cd ..
% cd frameworks/base
% git branch --track taintdroid-2.1_r2.1p github/taintdroid-2.1_r2.1p
% git checkout taintdroid-2.1_r2.1p
% git pull # (just to be safe)

Step 2.1: Enable ext2 SDcard support

ext2 support is not currently enabled for the SDcard; however the code exists in android-2.1_r2.1p The following simple patch to the system/core directory enable ext2/ext3 support for the SDcard and ensures it is mounted with user_xattr. It is probably easiest to make the changes by hand as opposed to applying the change as a patch.

diff --git a/vold/volmgr.c b/vold/volmgr.c
index deb680e..a5f5789 100644
--- a/vold/volmgr.c
+++ b/vold/volmgr.c
@@ -43,7 +43,7 @@ static volume_t *vol_root = NULL;
 static boolean safe_mode = true;
 
 static struct volmgr_fstable_entry fs_table[] = {
-//    { "ext3", ext_identify, ext_check, ext_mount , true },
+    { "ext3", ext_identify, ext_check, ext_mount , true },
     { "vfat", vfat_identify, vfat_check, vfat_mount , false },
     { NULL, NULL, NULL, NULL , false}
 };
diff --git a/vold/volmgr_ext3.c b/vold/volmgr_ext3.c
index fe3b2bb..8979c70 100644
--- a/vold/volmgr_ext3.c
+++ b/vold/volmgr_ext3.c
@@ -157,7 +157,8 @@ int ext_mount(blkdev_t *dev, volume_t *vol, boolean safe_mode)
  
     char **f;
     for (f = fs; *f != NULL; f++) {
-        rc = mount(devpath, vol->mount_point, *f, flags, NULL);
+        //rc = mount(devpath, vol->mount_point, *f, flags, NULL);
+        rc = mount(devpath, vol->mount_point, *f, flags, "user_xattr");
         if (rc && errno == EROFS) {
             LOGE("ext_mount(%s, %s): Read only filesystem - retrying mount RO",
		  devpath, vol->mount_point);

The patch can be applied manually, or by copying the diff into a file and running the command "git apply -v <diff-file>" from the system/core directory of the Android source code.

Step 3: Obtain a kernel with YAFFS2 XATTR support

We added XATTR support for the YAFFS2 filesystem used by Android. You can either download the kernel with YAFFS2 XATTR support we built for the Nexus One, or build your own kernel with our YAFFS2 XATTR patch.

For the Nexus One, there are two files of interest:

arch/arm/boot/zImage
drivers/net/wireless/bcm4329/bcm4329.ko

Step 3a (easier option): Get a prebuilt kernel

% cd ~
% wget http://www.appanalysis.org/files/nexusone-xattr-kernel-2.6.29.zip

Step 3b (harder option): Build a kernel with YAFFS2 XATTR support

The following instructions assume you are building a kernel for the Nexus One. If you are building a kernel for an emulator, use "kernel/common.git". You may also want to select different kernel version. The new Google Nexus One phones with SLCD screens need at least kernel version 2.6.32.

% cd ~
% wget http://www.appanalysis.org/files/yaffs_xattr.patch
...
% cd ~/tdroid/tdroid-2.1_r2.1p
% git clone git://android.git.kernel.org/kernel/msm.git
% cd msm
% git branch --track android-msm-2.6.29-nexusone origin/android-msm-2.6.29-nexusone
% git checkout android-msm-2.6.29-nexusone
% git pull # (just to be safe)
...
% patch -p1 < ~/yaffs_xattr.patch
...
% cd ~/tdroid/tdroid-2.1_r2.1p
% . ./build/envsetup.sh
% lunch 1 # (lunch 1 is fine for now)
...
% cd msm
% export ARCH=arm
% export SUBARCH=arm
% export CROSS_COMPILE=arm-eabi-

Next, you need a kernel config file. The easiest way is to pull the config.gz file off of a Nexus One with a stock image. Alternatively, you can download the nexusone-2.1update1-config.gz file we extracted from one of our devices.

% adb pull /proc/config.gz # from a Nexus One with a stock image
% gunzip config.gz
% cp config .config
% make oldconfig
... say "Y" to YAFFS_XATTR and YAFFS_SECURITY

Finally, build the kernel

% make menuconfig
... verify YAFFS and EXT2 with XATTR and SECURITY support
% make -j4

Copy the following files aside for later use.

arch/arm/boot/zImage
drivers/net/wireless/bcm4329/bcm4329.ko

Step 4: Setup the vendor build scripts

The AOSP 2.1 release does not provide the vendor setup needed to build for Nexus One, so we borrow the unofficial vendor setup put together by CyanogenMod. To complete this step, you will need a Nexus One with a stock installation of Android 2.1 to provide the proprietary libraries which we cannot distribute due to license restrictions. It is important that these files are copied from a system running Android 2.1; files taken from other versions of Android will be incompatible with the TaintDroid build. First, download and unzip the vendor setup:

% cd ~/tdroid/tdroid-2.1_r2.1p
% wget http://www.appanalysis.org/files/nexusone_vendor_setup.zip
% unzip nexusone_vendor_setup.zip

Next, use the extract-files.sh script to pull the proprietary libraries from the stock installation. With a Nexus One running Android 2.1 connected via USB, do:

% cd vendor/google/passion
% ./extract-files.sh

Finally, copy the kernel image (kernel, or zImage if compiled via Step 3b) and wireless driver (bcm4329.ko) from Step 3 to the vendor setup directory:

Step 4a (if you used Step 3a):

% cd ~
% unzip nexusone-xattr-kernel-2.6.29.zip
% cp kernel ~/tdroid/tdroid-2.1_r2.1p/vendor/google/passion/kernel
% cp bcm4329.ko ~/tdroid/tdroid-2.1_r2.1p/vendor/google/passion/bcm4329.ko

Step 4b (if you used Step 3b):

% cd ~/tdroid/tdroid-2.1_r2.1p
% cp msm/arch/arm/boot/zImage vendor/google/passion/kernel
% cp msm/drivers/net/wireless/bcm4329/bcm4329.ko vendor/google/passion/bcm4329.ko

Step 5: Build TaintDroid

First, we need to create a buildspec.mk file and define some variables so that TaintDroid will build properly. There are various options that control different optimizations and logging inside of TaintDroid. The following contents should be sufficient unless you care to begin developing TaintDroid. Note that in the below configuration.

% cd ~/tdroid/tdroid-2.1_r2.1p
% edit/create buildspec.mk 
# Enable core taint tracking logic (always add this)
WITH_TAINT_TRACKING := true

# Enable taint tracking for ODEX files (always add this)
WITH_TAINT_ODEX := true

# Enable taint tracking in the "fast" (aka ASM) interpreter (recommended)
WITH_TAINT_FAST := true

# Enable addition output for tracking JNI usage (not recommended)
#TAINT_JNI_LOG := true

Now we can build TaintDroid.

% . ./build/envsetup.sh
% lunch aosp_passion_us-eng
% make clean
% make -j4

Step 6: Flash the device

In order to flash new images, the phone must be connected to the development PC via USB and booted in fastboot mode. Start with the phone powered down, then hold down the trackball while pressing the power button to turn on the phone. If you have problems using fastboot to flash your device, please refer to the documentation at source.android.com.

If you have not already unlocked your bootloader, first issue the following command to unlock the bootloader:

% fastboot oem unlock

Then, follow the on-screen instructions on the phone to unlock the bootloader. Please note that this will void your warranty.

Before flashing images to your device, we reiterate our previous recommendation: It is strongly recommended that you use the nandroid tool provided in a custom recovery firmware such as Amon_RA to backup your current Nexus One system before flashing new images to your device.

Next, flash the images that we have built:

% cd out/target/product/passion
% fastboot flash boot boot.img
% fastboot flash system system.img
% fastboot flash userdata userdata.img

Additionally, if you want to test a kernel without flashing, you can do:

% fastboot boot boot.img

Step 7 (optional): Install Google apps

Due to licensing restrictions, we cannot distribute proprietary Google applications such as Gmail, the Android Market, and Maps, with the TaintDroid build. If you want to use these apps, you must install them separately from another web site. Installing these apps is optional; they are not required to use TaintDroid.

First, download the Google apps installer from a site such as CyanogenMod and save it on your SDcard.

http://cyanogenmod-mirror.local.host.name/gapps/gapps-passion-EPE54B-signed.zip

Next, flash your Nexus One with a custom recovery firmware which provides the ability to install .zip updates from an SDcard, for example Amon_RA.

% cd ~
% wget http://alternate-coding.com/recovery-RA-nexus-v1.8.0.1-aw.img
% fastboot flash recovery recovery-RA-nexus-v1.8.0.1-aw.img

Then boot the recovery firmware on the device by selecting "BOOTLOADER" and then "RECOVERY" from the boot menu, and install the Google apps by selecting "Flash zip from sdcard" and then gapps-passion-EPE54B-signed.zip.

Step 8: Format the SDcard as ext2

The SDcard needs to be formatted as either ext2 or ext3 for TaintDroid to track information across files stored to it. Connect the phone to a Linux computer and mount the SDcard by clicking the USB storage notification. Determine the /dev entry for the SDcard (/dev/sdb in our example, but may be different in your case). Use mke2fs command to make the file system. The TaintDroid phone will automatically recognize the SDcard formatted as ext2/ext3. However, a Windows or Mac computer will not be able to read the SDcard contents.

For example, if the SDcard is attached as /dev/sdb:

% sudo umount /dev/sdb1
% sudo mke2fs /dev/sdb1

Step 9: Install the TaintDroid UI

The TaintDroidNotify application enables TaintDroid to post notifications to the status bar. To install: boot the device, download the apk, then install using adb.

... boot device
% wget http://www.appanalysis.org/files/TaintDroidNotify.apk
% adb install TaintDroidNotify.apk

To enable notifications: on the device, tap the "TaintDroid Notify Controller" icon, and then tap the button labeled "Start".