Lab 5: Android Development Environment The goal is to download the kernel sources, a cross compiler, some tools for accessing an Android OS, and an emu- lator. A new kernel for the ARM architecture will be built from the kernel sources and ARM kernel modules will be built and loaded into the running kernel. The kernel under test will be run from an emulator before it is pushed to an android phone. The following directories will be created - a description of their contents is given. Directory Description .android-studio location of the Studio IDE .android-sdk-linux location of the SDK, platform-tools and tools .android/avd location of android virtual devices Install and set up build tools Official guide: http://developer.android.com Host OS: 64 bits, instructions below assume Ubuntu Linux OS utilities: use apt-get install, one at a time git, gnupg, flex, bison, gperf, build-essential, zip, wget, libc6-dev, libncurses5-dev:i386, x11proto-core-dev, libx11-dev:i386, g++-multilib, libgl1-mesa-glx:i386, libgl1-mesa-dev, libreadline6-dev:i386, mingw32, python-markdown, tofrodos, libxml2-utils, xsltproc, zlib1g-dev:i386 Packages: Java 1.8 from Oracle (if not already installed) Visit http://java.oracle.com/, click Java SE 8 Update, click JDK download Accept license, get jdk-8uXX-linux-x64.tar.gz prompt> sudo tar xf jdk-8uXX-linux-x64.tar.gz prompt> sudo mkdir /usr/java (if it’s not there) prompt> sudo mv jdk1.8.0 XX /usr/java prompt> cd /usr/local prompt> sudo ln -s /usr/java/jdk1.8.0 XX java make the following change to ~/.bash profile: export PATH=".:/usr/local/java/bin:$PATH" then prompt> source ~/.bash profile Android SDK, emulator Visit http://developer.android.com/sdk/index.html#Other and download from Section “All Android Studio Packages” Assume downloads go to directory Downloads prompt> cd ~/Downloads prompt> unzip android-studio-ide-141.2456560-linux.zip prompt> mv android-studio ~/.android-studio prompt> ~/.android-studio/bin/studio.sh No sdk will be found - click ’Next’, in the Android SDK Location field type this: ˜/.android-sdk-linux/Sdk Click ’Next’, then ’Finish’ prompt> ~/.android-studio/bin/studio.sh Click ’Configure’ then ’SDK Manager’ Update or install a platform, sdk build tools, sdk tools Click the ’Launch Standalone SDK Manager’ link at the bottom of the SDK manager and install ’ARM EABI v7a System Image’ Also check out various configurations, settings, etc. make the following change to .bash profile: export PATH=".:~/.android-sdk-linux/Sdk/platform-tools: ~/.android-sdk-linux/Sdk/tools:/usr/local/java/bin:$PATH" (all on one line), then prompt> source ~/.bash profile Create a virtual device for the emulator Find a target to tie a virtual device to prompt> android list targets id: 1 or "android-23" Name: Android 6.0 Type: Platform API level: 23 Revision: 2 Skins: ... ABIs : armeabi-v7a Make the virtual device, with name avd1 tied to id 1 from above The device information will be created in ~/.android/avd/avd1.avd prompt> android create avd -n avd1 -t 1 Run the emulator on the virtual device prompt> emulator -avd avd1 This takes a really long time to start the first time Check to see what is running prompt> adb devices emulator-5554 offline After a while prompt> adb devices emulator-5554 device Identify the kernel that will be downloaded prompt> adb shell root@generic:/ # cat /proc/version Linux version 3.4.67-00992-gb1dfee2 (ghackmann@ghackmann.mtv.corp.google.com) (gcc version 4.8 (GCC) ) #39 PREEMPT Mon Jul 13 11:06:17 PDT 2015 Leave the emulator running and open another shell Download, set up the kernel sources and cross compiler In the new shell, get the sources using the above information prompt> mkdir ~/.android-os prompt> cd ~/.android-os/ prompt> git clone https://android.googlesource.com/kernel/goldfish.git prompt> cd goldfish prompt> git checkout -b local-goldfish-3.4 -t origin/android-goldfish-3.4 prompt> ls Get a configuration file from the running emulator prompt> adb pull /proc/config.gz prompt> gunzip config.gz prompt> mv config .config in .config change ’#CONFIG MODULES is not set’ to ’CONFIG MODULES=y’ prompt> cd ~/.android-os prompt> ln -s ../android-sdk-linux/ndk-bundle/toolchains prompt> ls toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86 64/bin arm-linux-androideabi-addr2line* arm-linux-androideabi-gcov-tool* ... arm-linux-androideabi-gcov* arm-linux-androideabi-ld.gold* prompt> sudo apt-get install binutils-arm-linux-gnueabi cpp-4.7-arm-linux-gnueabi \ gcc-4.7-arm-linux-gnueabi gcc-4.7-arm-linux-gnueabi-base gcc-arm-linux-gnueabi Compile the kernel prompt> cd ~/.android os/goldfish prompt> export ARCH=arm prompt> export CROSS COMPILE=~/.android os/toolchains/arm-linux-androideabi-4.9/ \ prebuilt/linux-x86 64/arm-linux-androideabi/bin/arm-linux-androideabi- prompt> make Note in future compiles some kernel pieces will be compiled as modules as indicated in edits to .config. In that case this should be followed up with: prompt> make modules ; make modules install Check that the compiled image is present prompt> ls arch/arm/boot zImage* ... Kill the running emulator and run the emulator on the new kernel root@generic:/ # exit prompt> emulator -kernel ~/.android-os/goldfish/arch/arm/boot/zImage -avd avd1 Leave the emulator running Make, load, test, and unload a kernel module Open a new shell and create a module prompt> cd ~/.android-os prompt> mkdir modules prompt> cd modules Edit tester.c to have the following content: #includeint init module(void) { printk(KERN INFO "tester: Module loaded successfully\n"); return 0; } void cleanup module(void) { printk(KERN INFO "tester: Module unloaded successfully\n"); } MODULE LICENSE("GPL"); Edit Makefile to have the following content: obj-m := tester.o DIR=/home/username/.android-os/goldfish PWD=‘pwd‘ CCOMP=~/.android-os/toolchains/arm-linux-androideabi-4.9/prebuilt/linux-x86 64/bin/ \ arm-linux-androideabi- FLGS=CFLAGS MODULE=-fno-pic all: make $(FLGS) -C $(DIR) M=$(PWD) ARCH=arm CROSS COMPILE=$(CCOMP) modules clean: make -C $(DIR) M=$(PWD) clean Compile the module prompt> make Push the module to the running emulator; load and test it prompt> adb push tester.ko /data/ prompt> adb shell root@generic:/ # insmod /data/tester.ko root@generic:/ # dmesg tester 1: module loaded successfully Unload the module root@generic:/ # rmmod tester root@generic:/ # dmesg tester 1: module unloaded successfully Get busybox utilities to augment the toolbox The pre-packaged toolbox is pitiful. At the cost of about 1MB you can have a much better toolbox to work with. Get it like this: prompt> cd ~/.android os prompt> wget http://git.busybox.net/busybox/snapshot/busybox-1 24 2.tar.bz2 Compile: prompt> tar xf busybox-1 24 2.tar.bz2 prompt> cd busybox-1 24 2 prompt> ARCH=arm prompt> CROSS COMPILE=arm-linux-gnueabi- prompt> make menuconfig de-select Networking Utilities -> Support RPC services save and exit menuconfig prompt> make ARCH=arm CROSS COMPILE=arm-linux-gnueabi- Push and run: prompt> adb push busybox /data/ prompt> adb shell root@generic:/ # /data/busybox (lists all commands) root@generic:/ # /data/busybox ls I will send a working busybox to you if the above does not work One way to make the commands easier to use: root@generic:/ # /data/busybox vi /data/aliases Edit the file to look like this: alias ls=’/data/busybox ls’ alias df=’/data/busybox df’ alias ifconfig=’/data/busybox ifconfig’ alias chown=’/data/busybox chown’ ... Save using : then wq Source the file and run commands: root@generic:/ # source /data/aliases root@generic:/ # ifconfig Connect the Android Phone The emulator is used for testing to prevent screwing up the Android phone. But ultimately it is necessary to push compiled products to the phone. This section shows the basics of how to do that. For details and troubleshooting see instructions in http://www.howtogeek.com/125769/how-to-install-and-use-abd-the-android-debug-bridge-utility/ Turn on the phone Plug the phone into a USB port on the computer Open the phone’s app drawer Tap the Settings icon Scroll down looking for “Developer Options” Do the following if this is not found: Scroll down and select “About Phone” Scroll down to “Build Number” and tap seven times Hit return and look for “Developer Options” Select “Developer Options” and enable “USB Debugging” From the computer run prompt> adb devices This returns something like List of devices attached 3001e1b device The easiest way to root the android phone is via Windows: https://www.kingoapp.com/android-root.htm After the phone is rooted, click on the Superuser app icon Then download and use qtadb for the interface http://bernaerts.dyndns.org/linux/74-ubuntu/328-ubuntu-trusty-android-adb-fastboot-qtadb Build an Android project in Android Studio Launch Android Studio prompt> ~/.android-studio/bin/studio.sh Set up a (default hello world) project Click ’Start a New Android Project’ In the ’Application Name’ field, name the project ’First’ In the ’Company Domain’ field, change xxxxx.example.com to silly.app.first In the ’Project Location’ field, replace ’AndroidStudioProject’ with ’.android-studio-projects’ Click on Next Click on Next Choose ’Blank Activity’ Click on Next Click on Finish Note: it will be quite a while before the project is created Explore the result Look at First -> app -> java -> first.app.silly.name -> MainActivity.java Look at First -> app -> res -> layout -> activity main.xml Edit String Navigate to the content main.xml tab Click and drag the ”Hello, world!” to the center of the screen Double-click the ”Hello, world!” to open an edit box Append “hi there folks” to “Hello world!” Add a Button Click and drag ’Button’ under ’Widgets’ to below the text Double click the ’Button’ and change text to ’Next Page’ Add a Second Page Right click on ’app’ at the top left Navigate to New -> Activity -> Blank Activity Change the activity name to ’Second’ Click ’Finish’ Wait for activity second.xml to appear Drag a large text object to the screen Double click the text object Change the ’id’ field to @string/second page, the text to ’Second Page’ Open strings.xml Insert the line: Second Page Edit the Button’s onClick method Display MainActivity.java Add the following at the end of the onCreate method: Button button = (Button) findViewById(R.id.button); button.setOnClickListener(new View.OnClickListener() { @Override public void onClick(View v) { goToSecond(); } }); Add the following method to the bottom of the MainActivity class: private void goToSecond() { Intent intent = new Intent(this, Second.class); startActivity(intent); } Add the following to the list of import statements: import android.content.Intent; import android.widget.Button; Try it Connection to the phone should be established as above Hit the green arrow in Android Studio Choose the phone - takes a while to compile and load Export the signed app as a .apk file (see key making instructions on the next page) Drop the ’Build’ menu in Android Studio Choose Generate Signed APK Enter the path to your keystore (e.g. /home/franco/.keystore) Enter the password for the keystore Enter the password for the key to use Enter the key alias Click ’Next’, observe the destination of the apk file Click ’Finish’ Install the app prompt> mv ~/.android-studio-projects/First/app/app-release.apk ~/first.apk prompt> adb install ~/first.apk There may be a harmless error message - use adb shell then su to search in /data/local/tmp Find the app on the phone and run it On the left is a screenshot showing the app icon labeled ’First’ On the right is a screenshot showing the app on the second page Make a key prompt> keytool -genkeypair -keystore ~/.keystore -keyalg "RSA" -keysize 2048 -alias franco Enter keystore password:Re-enter new password: What is your first and last name? [Unknown]: John F What is the name of your organizational unit? [Unknown]: EECS What is the name of your organization? [Unknown]: U. Cinci What is the name of your City or Locality? [Unknown]: Cinci What is the name of your State or Province? [Unknown]: Ohio What is the two-letter country code for this unit? [Unknown]: US Is CN=John F, OU=EECS, O=U. Cinci, L=Cinci, ST=Ohio, C=US correct? [no]: yes Enter key password for (RETURN if same as keystore password): Make a certificate prompt> keytool -selfcert -keystore ~/.keystore -alias franco Enter keystore password: See what you did prompt> keytool -list -keystore ~/.keystore Enter keystore password: Keystore type: JKS Keystore provider: SUN Your keystore contains 1 entry franco, Mar 23, 2014, PrivateKeyEntry, Certificate fingerprint (SHA1): 4D:A6:71:ED:A9:C1:AA:D1:73:52:AA:7A:4C:... Export the certificate prompt> keytool -exportcert -keystore ~/.keystore -alias franco -file franco.cer Enter keystore password: Certificate stored in file Print the certificate prompt> keytool -printcert -file franco.cer Get and use the apktool and aapt tools Download and install the package (decompiler and apk manager) prompt> cd ~/.android-os prompt> mkdir apktool prompt> cd apktool prompt> wget https://bitbucket.org/iBotPeaches/apktool/downloads/apktool 2.0.3.jar prompt> wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool prompt> chmod a+x apktool prompt> ln -s apktool 2.0.3.jar apktool.jar Edit the PATH value in ~/.bash profile and source it export PATH="~/.android-os/apktool:$PATH" prompt> source ~/.bash profile Download a large apk file prompt> cd ~/.android-os prompt> mkdir apk prompt> cd apk prompt> wget http://gauss.ececs.uc.edu/Courses/c6053/homework/Browser.apk Decompile the file prompt> apktool decode Browser.apk Look at some files prompt> cd Browser prompt> ls prompt> more AndroidManifest.xml prompt> ls res prompt> ls smali/com/google/common/base Use aapt to examime the apk file To /etc/apt/sources.list add deb http://mirrors.kernel.org/ubuntu vivid main universe prompt> sudo apt-get update prompt> sudo apt-get install aapt prompt> cd ~/.android-os/apk prompt> aapt l Browser.apk prompt> aapt d badging Browser.apk prompt> aapt d permissions Browser.apk prompt> aapt d xmltree Browser.apk AndroidManifest.xml Get and use dex2jar and jd-gui tools Download and try dex2jar (decompiles apk or dex to a jar file) prompt> cd /.android os Download dex2jar from https://sourceforge.net/projects/dex2jar/?source=typ redirect prompt> mv ~/Downloads/dex2jar-2.0.zip . prompt> unzip dex2jar-2.0.zip prompt> cd dex2jar-2.0 prompt> chmod a+x *.sh prompt> d2j-dex2jar.sh ../apk/Browser.apk prompt> jar tf Browser-dex2jar.jar Download and try jd-gui on First-dex2jar.jar (view class files as java source) prompt> cd ~/.android-os prompt> wget http://gauss.ececs.uc.edu/Courses/c6053/homework/jd-gui.tar prompt> tar xf jd-gui.tar prompt> jd-gui/jd-gui dex2jar-2.0/Browser-dex2jar.jar Click on any file, for example as shown below