How To Reverse Engineer Android APK 1


Have you ever experienced a strong sense of curiosity about something? Perhaps a recent app you used have the greatest functionalities you have experienced. It made you ask in your mind, “How was it done?”. In this post, I am going to show you how to reverse engineer an Android app to answer that question.

Before starting, the content of this post is entirely for educational purpose only.


Compiling signed APK

For this exercise, I will be using a new Basic Activity project from Android Studio 2.2. In order to create the project, just start a new project on Android Studio. When asked which type of template to use, select the Basic Activity template.

Once Android Studio finishes setting up the project, compile it as a signed APK. Go to Build > Generate Signed APK to do this. You will see a prompt asking for a keystore, which you can either provide one if you already have one or create one. If you have never created a keystore before you can follow the Android Studio User Guide. The signed APK is located at the path “app/build/outputs/apk/” within your project directory and the default name of the APK is “app-release”.

For the reverse engineering process, I will be using the signed APK from the Basic Activity project.

Decompiling signed APK

To decompile a signed APK you will using the following tools:

  • apktool
  • dex2jar (optional)
  • JD-GUI (optional)

To decompile a signed APK with the apktool, you will need to provide the decompile option and path to the APK. Here is an example of the output from apktool when decompiling:

output from apktool when decompiling

Afterward, there will be a new directory with the same name as the apk in current working directory. Within the directory, you can find the AndroidManifest.xml and the assembly code (dalvik), which the Android’s Java VM implementation uses.

the content of a decompiled APK

The “smali” directory contains the source code in dalvik. If you want to make any modifications, the dalvik code is where to add them.

Recompiling APK

To recompile the APK, you will need to provide the build option and path to the decompiled APK directory. Apktool will rebuild the app from all the files within the decompiled APK directory and place the rebuilt APK in the “dist” directory.

output of apktool rebuilding an APK

the content after rebuilding APK

Readable smali files

Reading assembly level code is not something most software developers do nowadays. It would be difficult to understand all the dalvik code even if you have an opcode table right next to you. You can actually make those smali files friendlier to read. The tools you will need are dex2jar and JD-GUI.

There are 4 steps to convert an APK to readable java source code. The steps are:

1. Extract the “classes.dex” file from the APK

command line to extract classes.dex from APK

2. Use dex2jar tool to convert the classes.dex file to Java class files. This will result in a jar file.

command line to convert from dalvik to java

3. Use the java decompiler JD-GUI to extract the source code from the jar file.

use JD-GUI to extract from the jar file

4. View the source files or save them by going to File > Save all sources.

reverse engineered java code from signed APK

The java code is not perfect, but it gives you a much better idea than the dalvik code. It is much easier to follow and to read even though all the comments and meaningful variables names are gone.


 

I hope you found this helpful. If so, share it with others so they can benefit as well.

 

Was there something I missed that you believe I should include? Have the information I provided help you out recently? If so, feel free to leave a comment.

 

Also, to stay in touch you can follow me on twitter.

  • Aditya Nand

    If you could please guide me How to construct a Static-Function Call Graph from the dalvik code. In my work, I need to decompile the apk file and get the dalvik code. And after you get the java code, how do you form a static function call graph with nodes being the sensitive APIs and the edges showing the call between the 2 APIs. Guide me please