I prefer using the Android emulator to a real phone for some application
assessments for many reasons. Unfortunately, not all apps run properly
on the emulator. This series of posts will focus on modifications
we can make to our emulators to allow more control and flexibility
during application assessments. This first post will focus on controlling device identifiers and numbers.
Sometimes an application will obtain the device phone number and device identifiers and submit these to a remote server, maybe for authentication or authorization (such as white-listing phone numbers per provider). The easiest way to obtain this information in an application is the use the TelephonyManager class. We will focus on the following methods of the TelephonyManager class:
- getDeviceId()
- getLine1Number()
- getVoiceMailNumber()
- getSubscriberId()
- getSimSerialNumber()
We have two options for performing the modifications: 1) Download the Android source code from the AOSP page, make the modifications in the Java source, and then build a custom version of Android, or 2) we can make the modifications to the compiled system libraries that are present on our Android emulator. I chose to take option two because of the hardware requirements and testing speed of options one (building Android can take awhile). So the first step was to find the TelephonyManager files in the Android source. Note: For the remainder of this post, I will be using Android API 10.
Not hard to find, they're in the "/frameworks/base/telephony/java/android/telephony/" directory.
Being in the "framework" directory gives us some hints as to where the files exist on the device. When we build Android, all of these sources will eventually make their way into Dalvik DEX byte-code, and are zipped (but with JAR extension + META-INF directory) along with any other necessary files. They are placed in the "/system/framework/" directory on the device.
When the system boots, the Android system will take the "classes.dex" from each of these system library JARs, verify and optimize them, then store them on the "data" partition in the directory "/data/dalvik-cache/". We'll need to modify the JARs if we want to make any system library changes. The JAR that contains our compiled TelephonyManager DEX code is "/system/framework/framework.jar".
We first need to pull this file off the device. We can then unzip the "framework.jar", and use "baksmali" to disassemble the "classes.dex" file. Now we can do a simple grep to find our class of interest.
Now lets switch gears quick and get the replacement code ready. I decided to replace our methods of interest with code that opened a file on the SD card and read the values from there. The following code can be used as replacement code for the getDeviceId() method.
To get the Smali equivalent code, I used "ant" to build the app, them used "apktool" to decode the APK file. From here, it was just a direct replacement into the getDeviceId() method of the "TelephonyManager.smali" file.
With the modifications complete we can reverse the process: convert the Smali code back to DEX with "smali", zip the files back up as "framework.jar", and push the new archive to the "/system/framework/" directory.
The final step is to create a new system partition, and we can use the method posted here. Restarting the emulator with the new system partition will result in our custom library being loaded.
And there we go! The return of any of these methods is now controlled by the contents of the "/mnt/sdcard/device_ids.txt" file. For those who want to just make the changes and go, I've included a working version of the "framework.jar" for API 10 if people would like to grab it, push it to your emulator, then build a new system image. If at any point you no longer want to control these values, you can just remove the "/mnt/sdcard/device_ids.txt" file, and the "real" getXX() method will be called. If anyone observes any unusual instability or errors, please contact me! Note: Use this library at your own risk. I do not suggest using this library on a real device!
To make things even easier, I wrote an application to help manage the "/mnt/sdcard/device_ids.txt" file, so you can make changes instantly. You can grab the app source or APK file from my Github repositories, as well as the "framework.jar" and a sample "device_ids.txt".
I'll continue to post more changes to help with application assessments over the next few months. :)
-jakev