Tags

, , , , , , ,

As a part of my research project, fortunately (or unfortunately :P) I had to reverse engineer ~25GB of android code to implement prototypes of my ideas in providing flexibility in user security policies (will upload the kernel image sometime soon !)

This article outlines the steps used for modifications, debugging and building modified kernel I picked up in the process. It is gained mainly from android documentation and google groups on android building (JBQ , if you are reading this, thanks a ton for your comments for all the times I was stuck up.) :
Required tools and software :
1. Eclipse – version 4.2
2. Android source code – version 4.1.2_r1
3. Approximately 75 GB disk space for the source code and builds
4. Ubuntu 12.04 LTS for 64-bit systems
5. Android Software Development Kit (SDK) for 64 bit machine
6. Java Development Kit (JDK) version 1.6.0
7. Python version 2.7
8. Git version 1.7
9. GNU Make version 3.81
10. Sample apps for testing

Once we have the required software with their specific versions, development can be categorized under the following major phases:
1. Download the entire android source code (while you go have game of foosball as it takes a while).
2. Build an emulator from the source code (optional if you want to make sure it is working before your changes).
3. Modify/Debug at required points in the process flow of source code depending on your prototype.
4. Re-build the emulator with modified source code.
5. Create a device flash-able image from the source code.
6. Test the device for modifications incorporated (I strongly suggest this, as nothing is complete unless tested for basic functionalities)

Phase 1:  Download the entire android source code
1. After SDK, JDK, Python and Git are installed, we require some more specific
packages for compiling our Android source code. So before we go around downloading the code, we need to install the following packages and then link the libGL image with gnu’s libGL
$: apt-get install git-core gnupg flex bison gperf build-essential \
zip curl libc6-dev libncurses5-dev:i386 x11proto-core-dev \
libx11-dev:i386 libreadline6-dev:i386 libgl1-mesa-glx:i386 \
libgl1-mesa-dev g++-multilib mingw32 openjdk-6-jdk tofrodos \
python-markdown libxml2-utils xsltproc zlib1g-dev:i386

$: ln -s /usr/lib/i386-linux-gnu/mesa/libGL.so.1 /usr/lib/i386-linux-gnu/libGL.so

2. Configure our system to recognize android devices through USB for debugging by modifying the /etc/udev/rules.d/51-android.rules file. Since our test device is Google Nexus , we need to add the following lines , save it and then make it executable:

# adb protocol on grouper (Nexus 7)
SUBSYSTEM==”usb”, ATTR{idVendor}==”18d1″, ATTR{idProduct}==”4e42″,
MODE=”0600″, OWNER=”arpita”
# fastboot protocol on grouper (Nexus 7)
SUBSYSTEM==”usb”, ATTR{idVendor}==”18d1″, ATTR{idProduct}==”4e40″,
MODE=”0600″, OWNER=”arpita”

To make it executable : chmod a+rx /etc/udev/rules.d/51-android.rules

[ Updated after Bhuvi noticed the discrepancy. Thanks 🙂 ]

(You can find a list of other vendor IDs here)

4. Once the environment is created, download the source code (this step takes a
while since the source code is approx 25GB large)
$ mkdir ~/bin
$ PATH=~/bin:$PATH
$ curl https://dl-ssl.google.com/dl/googlesource/git-repo/repo > ~/bin/repo
$ chmod a+x ~/bin/repo
$ mkdir WORKING_DIRECTORY
$ repo init -u https://android.googlesource.com/platform/manifest
$ repo init -u https://android.googlesource.com/platform/manifest -b android-
4.1.2_r1
$ repo sync

5. Apart from google’s source code, to make a device working, we also require
proprietary drivers for Wi-Fi, Bluetooth, GPS, Touch Panel, Orientation Sensor,
Graphics, NFC, DRM. Download them to the WORKING_DRIECTORY, extract
them and accept the terms and conditions. For each of the binaries, run $ sh nameofthebinarytoextract.sh
6. After the binaries of proprietary drivers have been extracted, update the
timestamps of /vendor, so that they are included in our build. Run $ touch /vendor/*
Phase 2:  Build an emulator from the source code
1. Initialize the build environment.
$ source build/envsetup.sh
$ lunch full-eng
2. Make the build by $ make -jn, where n is the number of threads that can be
allocated.
3. Once the build is complete, $ emulator should bring up the emulator.
Phase 3: Modify/Debug at required points in the process flow of source code depending on your prototype.

It essentially deals with reverse engineering and tracing the process flow. We can do it either via DDMS by running $ ddms, or use eclipse to debug via DDMS. The steps taken to set up eclipse for tracing are :
1. Make a new Android Project from existing source code.
2. Locate the module in which we want to debug (Whole Android source code is
not required & recommended) eg. <source>/framework/base/services/java
(ignore the errors as they will not affect the emulator)
3. Open the AndroidManifest.xml file of that project and rename the package
name to any process name on which you want to debug (eg. system_process)
4. Insert breakpoint in the linked source code as required.
5. Go to DDMS perspective select the device/emulator, and under that select the
process name listed in step 3 and debug.
Phase 4: Re-build the emulator with modified source code.

Coming to phase 4 of rebuilding the emulator with modified source code, since we made changes to the API, we need to update it and then reinitialize the build environment to rebuild it. After API is updated, initializing and the build steps are essentially the same as those listed in phase 2.
$ make update-api

Phase 5: Create a device flash-able image from the source code.

It involves building a device flash-able image from the modified source code. Similar to steps in phase 2, remove the previous build folders and follow it up by initializing the build environment:
$ make clobber
$ build/envsetup.sh
$ lunch full_grouper-userdebug
$ make -j#n (n being the max number of cores on your system)

Since the last make step takes a while, meanwhile on the test device, do the following steps :
1. Connect a charged Nexus device via USB to the laptop.
2. Enable USB debugging option to interact via system
3. From system, run adb reboot bootloader to set it up in fastboot mode. Fastboot
mode allows new kernel images to be flashed.
$ fastboot flashall-w
4. After make completes, the fastboot command should flash image and reboot the system.

Phase 6: Test the device for modifications incorporated

Once you have the working kernel flashed onto your device, go ahead and explore. It includes installing sample user apps and checking for functionalities of
modified source. Now, to what extent you test, depends on your tenacity after doing all the previous steps 😀 .

Hope this helps in attempts to tinker with the well written and documented android code. 🙂