Wednesday, November 21, 2012

Extending Existing Android Applications - Part One

There are a couple tutorials out there that show you how to reverse engineer Android applications.  Usually these leave you with smali files which you can modify and recompile or they leave you with a .jar file that you can browse with a Java decompiler.  Both of these methods leave something to be desired, namely; a good environment for writing new code.

Smali files are a reliable representation of the code, but they're hard to use and they don't integrate with Eclipse and the typical development environment an Android developer is used to.  Generating a jar file is more desirable.  Of course, we need more than just the jar to compile the app; we also need its resources and the android manifest.

Most tutorials focus on either apktool to get the smali files and the resources or dex2jar to get a jar file which can then be decompiled.  Here I'm going to demonstrate how to use both apktool and dex2jar together with Eclipse to reverse and then extend an Android app.  The end result will be a development environment that is easy to use and should allow major changes to be made to the app without any significant hardship.

Prerequisites:

Step One: Get the application's APK

The APK file is how Android apps are stored on your device.  Before we can do anything else we need to have the application's APK.  There are a couple ways to get this file, but we're not going to get in to them here.

For the purposes of this article I'll be using an APK from a simple app of my own, GasMileage.apk.

Step Two: Deconstruct the APK with apktool

To deconstruct the APK with apktool, run the following command:

apktool.bat d <path to apk> <destination directory name>

Note that the destination directory shouldn't exist until you run this command.

Example:
C:\play\inyourbits>apktool\apktool.bat d c:\play\inyourbits\GasMileage.apk GasMileage
I: Baksmaling...
testI: Loading resource table...
I: Loaded.
I: Loading resource table from file: C:\Users\Tom\apktool\framework\1.apk
I: Loaded.
I: Decoding file-resources...
I: Decoding values*/* XMLs...
I: Done.
I: Copying assets and libs...
In the destination folder we now have:
  • AndroidManifest.xml
  • apktool.yml
  • res
  • smali

Step Three: Generate a jar file from the APK

To create the jar file, use the following command:

d2j-dex2jar.bat <path to apk>

Example:
C:\play\inyourbits>dex2jar-0.0.9.9\d2j-dex2jar.bat GasMileage.apk
dex2jar GasMileage.apk -> GasMileage-dex2jar.jar
In the working directory we now have 'GasMileage-dex2jar.jar.'

Step Four:  Move the jar file

Move the jar file in to the destination directory created by apktool.

The directory should now contain:
  • AndroidManifest.xml
  • apktool.yml
  • res
  • smali
  • GasMileage-dex2jar.jar 

Step Five: Import the directory in to Eclipse 

Import the directory in eclipse as an Android project.
  • Click File->Import
  • Select 'Android->Existing Android Code Into Workspace'

  • Enter the path to your destination directory, in this case 'C:\play\inyourbits\GasMileage'

  • Click 'Finish'

Step Six: Import the Jar as a library

  • Right click on the project name
  • Click 'Properties'
  • Click 'Java Build Path'
  • Select 'Libraries'

  • Click 'Add JARs'
  • Select the dex2jar jar file

  • Click 'OK'
  • Click 'Order and Export'
  • Check the box next to the dex2jar
    • If we didn't do this then when we built our app the .jar file wouldn't be included with it


Step Seven: Remove the resources from the jar

The jar file created with dex2jar contains the resources classes, however Eclipse is going to build those resources fresh when it compiles the project.  So, we need to remove the resource files from the jar file so that the compilation works.
  • Open the dex2jar jar file with 7zip (or another zip utility)
  • Navigate through the hierarchy until you find the resource class files
    • There will be a number of R$ classes as well as one R.class

  • Delete all of the resource class files

  • Close the jar file

Step Eight: Run the app in the emulator

Now we're going to run the app in the Android emulator to make sure everything is working properly.
  • Select the project in Package Explorer
  • Click 'Run->Run'
  • When asked choose 'Android Application'

  • Click 'OK'
  • Wait until the application starts and make sure it works

Note: there are some APKs that this method does not work for due to flaws in the dex2jar process.

Next Time

Now that we've taken the application apart and put it back together again we can begin the process of actually modifying the behavior of the program.  We'll cover that in the next post.