Notes

Decompiling APKs

Daniel Weibel
Created 15 Apr 2017

Explanation of the different ways to decompile an APK. Decompiling an APK means to recover the Java code (or another intelligible code) from an APK file.

This can be useful to analyse third-party apps, or to modify them (by compiling the decompiled code to an APK again).

What Is An APK?

APK stands for an Application Package, and it is the file format in which an app can be installed on an Android device.

An APK file is a ZIP file that contains a file called classes.dex.

The classes.dex file contains the entire code of an app in DEX bytecode.

DEX stands for Dalvik Executable, and DEX bytecode is the machine code of the Dalvik Virtual Machine running on Android devices.

How To Get The APK Of An App?

The Google Play Store does not provide the APKs of the apps that are distributed there.

In order to nevertheless get the APK of an app, you can use one of the following ways:

  • APKMirror: a website providing the APKs of many common apps
  • Apk Extractor: an app that allows to extract the APK of any app installed on your device

How To Decompile An APK?

There are two ways to decompile an APK.

1. d2j-dex2jar

The d2j-dex2jar tool allows to view the decompiled Java code, but not to edit the Java code, or recompile the app.

Usage

  1. Change extension of APK from .apk to .zip and unzip the file
  2. Find classes.dex in the unzipped folder
  3. Decompile classes.dex to classes.jar with the following command:
     d2j-dex2jar -f -o classes.jar classes.dex
    
  4. Now you can browse the Java code in classes.jar with the JD-GUI tool

Apktool

Apktool allows to decompile everything of the app (including Manifest and resources), to edit the decompiled code, and to recompile the app.

However the target language of the decompilation is not to Java but smali.

Usage

  1. Decompile the APK with the following command:
     apktool d app.apk -o out/ -f
    
  2. Now you can view and edit the smali code with any text editor
  3. For recompiling the app, use the following command:
     apktool b out/
    

Code Obfuscation

There is a caveat to APK decompilation: code obfuscation.

Code obfuscation replaces all the identifers chosen by the developer (class names, method names, variable names, etc.) with short meaningless strings.

With both of the above decompilation methods, if the app has been obfuscated (for example with ProGuard), then the decompiled code contains only these obfuscated identifiers, and not the original ones.

This makes it much more difficult make sense of the decompiled code (however, not impossible).

On the other hand, if the app hasn’t been obsucated, then both of the above decompilation method can recover the original identifiers.

Levels of Obfuscation

Obfuscation can occur either on the Java-level or on the DEX-level.

Java-level means that the identifiers of the Java code are obfuscated before it is compiled to Java bytecode (and then to DEX bytecode).

DEX-level means that the obfuscation occurs on the DEX bytecode (that is, after the Java $\rightarrow$ Java bytecode $\rightarrow$ DEX bytecode compilation steps)

The common tools for Android code obfuscation are ProGuard for Java-level obfuscation and DexGuard for DEX-level obfuscation.

Notes

Supporting tools for editing and understanding smali code:

  • Xposed: framework for modules that modify an existing app by decompiling its APK and recompiling it; to use these modules, a rooted device is necessary
  • BurpSuite - intercept HTTPS requests
  • SmaliEx - recombine multi-dexed files to a single DEX file
  • Frida - for quick prototyping
  • AndroidEagleEye - based on Xposed
  • IDA - Interactive Disassembler
  • smalidea - smali plugin for IntelliJ

Xposed modules: