Reverse Engineering Android APKs

If you have an Android device, you might have heard the term APK and wondered what it means. Let’s quickly discuss what an APK is and why it’s important to Android.

 

What Is an APK File?

APK stands for Android Package Kit (also Android Application Package) and is the file format that Android uses to distribute and install apps. It contains all the elements that an app needs to install correctly on your device.

Just like EXE files on Windows, you can place an APK file on your Android device to install an app. Manually installing apps using APKs is called sideloading.

Normally when you visit Google Play to download an app, it automatically downloads and installs the APK for you. While you can extract APKs from the Play Store, they’re also available to download from alternative app stores.

What Is Reverse Engineering?

Software Reverse Engineering is a process of recovering the design, requirement specifications and functions of a product from an analysis of its code. It builds a program database and generates information from this.

The purpose of reverse engineering is to facilitate the maintenance work by improving the understandability of a system and to produce the necessary documents for a legacy system.

Reverse Engineering Goals:

  • Cope with Complexity.
  • Recover lost information.
  • Detect side effects.
  • Synthesise higher abstraction.
  • Facilitate Reuse.
  • In case of APKs, we might want to modify the application by injecting our own code.

How to Decompile APKs in order to Modify?

When we compile an  Application/Program, BYTECODE is generated.In Java, the BYTE CODE are SMALI codes here and the executor is Dalvik (recently ART) in Android (not JVM). Here, I will describe shortly how to reverse and inject code in SMALI. Here’s a SMALI equivalent code for Sample Java Code:

Example.java

if (flagx == 1)
    flagx = 2;
else
    flagx = 3;

Example.smali (flagx variable is referenced as v0)
const/4 v1, 0x1
if-ne v0, v1, :cond_0
const/4 v2, 0x2
move v0,v2
goto :goto_0
:cond_0
const/4 v2, 0x3
move v0,v2
:goto_0


 

We can see how much complex the so simple java code became in smali! At this rate how the hell can one figure out the smali for complex java code? Well the easiest way to do it would be starting from the opposite end. We can use JADX to to get the Java equivalent of the Smali files, compare them and edit the Smali files according to our needs. Then a question might arise, Why can’t we simple edit the Java files generated by JADX? –We can’t do that as the Java Source code Generated by JADX is not 100% correct and might be missing some information, which might break the application, so all modifications needs to be done at SMALI level.

 

The main steps for code injection are:

  1. Decompile APK to Smali Code
  2. Find the right place to inject the code
  3. Use safe (or unsafe) local variables to inject
  4. Recompile the Smali Code to APK
  5. Generate Signature Key
  6. Sign the Recompiled APK

Decompile APK to Smali Code

Using the tool named APKTool you can easily decompile APK to its elements. Actually APK is a ZIP compressed file. Which contains Manifest (permissions, activities, services, etc.), all source codes compiled inside DEX (classes.dex), resources (all images, xml elements of UI, sounds, etc.), Libraries (generally native ones), META-INF (public key of the signature).

You can download apk tool from this link. Using the following command you can get the APK decompiled.

java -jar apktool.jar d YOUR_APK.apk

Find right place to inject the code

After successful decompilation, a folder will be generated beside the APK. There is a folder named smali there which contains all the classes inside the main DEX file. All of the classes are in Smali format over there. You can use each of them for injecting the code. Smali is the code like here:

In the above example, A simple Toast message is put after the setContentView() method of an Activity.

For making the smali code you can use two methods:

  1. Use smali code instructions. You can use this link for more details.
  2. TRICK: Write your code in a separate Android project and make its APK. Then use apktool for finding out the smali code of your {injection} code!

Use safe (or unsafe) local variables to inject

As you see in the above example, v1,v2,v3, … are used for smali code injection. v_i \;\;\;\;\; i \in {1,2, ... , 16} are the local variables. Android has 16 registers for this purpose which contains the inside the class variables (v) and the parameters (p) of the method we are injecting inside. for example onCreate has two parameters (p0 for this, p1 for Bundle) and some variables (vs). You should use vs for your purpose while do not compromise other vs. If you can add extra locals to your file, then you can use safe variables, if not you should use the defined local variables without compromise other variables.

Tips: Local Variables can be often modified to get required results, For Example: if a variable v_i \;\;\;\;\; i \in {1,2, ... , 16} stores information such as :if the application is premium,whether to show ads,etc, one can modify them according to their needs .

Example: If the application checks whether to show Ads like this (Well, Ads are really annoying for me and I guess for everyone 😛):

boolean toShowAds=check(param... args); //One can simple modify the check method to return false always.

This same method can be used for other purposes like converting non-premium application to premium, or even hack in-App Billing, but i don’t recommend doing this and I am not responsible if you land in any trouble :P.

Recompile the Smali Code to APK

If the injection is correct, you can use the following command to recompile the injected code.

java -jar apktool.jar b THE_DECOMPILED_FOLDER

This will generate an APK inside THE_DECOMPILED_FOLDER/dist folder.

Generate Signature Key

Sign the Recompiled APK

You have to sign the generated APK using any of the APK-Signer like this, or any other of your choice.

Note:After you install APK after modification with your custom signature, you won’t be receiving any updates for the application from Play Store,as it checks if the signature matches the original developer’s signature.

Enjoy your modded APK!

The same method is used by websites that distribute,cracked applications.I don’t recommend downloading such applications from random websites,as they might have injected codes that might steal your information.There’s one more method of injecting code, which requires root and you don’t even need to decompile the App.It’s called Xposed Framework . What it does is, it lets you write an App using which you can hook the methods present in an application.

 

References:

Decompile and Modify APKs on the go with APKTool for Android [XDA Spotlight]

http://pallergabor.uw.hu/androidblog/dalvik_opcodes.html

https://ibotpeaches.github.io/Apktool/

 

Comments

Leave a Reply

Your email address will not be published. Required fields are marked *