Android Obfuscation Tools Comparison

Android Obfuscation Tools Comparison

Mar 7, 2016

As you may or may not know, Android apps can be decompiled back into something very close to the original Java code. It’s a simple process. You don’t even need a phone. Download the target APK using the Apkpure website and then use Jadx to decompile the code back into Java.

One easy way to make it harder for hackers to attack an Android app is to use obfuscation to remove strings and variable names and in some cases prevent decompilation. While it’s not a silver bullet – see caveats below – it’s very easy to enable in an Android project and it does remove a lot of useful information.

Original Code:

Figure 1 – Original WalkieTalkie Google Example Code

Figure 1 shows a code snippet from an old Google example SIP client app. It’s a basic app that connects to a SIP server. Once connected, your mobile phone can make and receive calls as if it was your desktop phone. Unfortunately it’s writing the username (namePref), password (passPref) and the address of the SIP server (domainPref) to shared preferences which isn’t a good idea. But it’s very useful for our purposes to see if obfuscation will hide anything.

Decompiled Code w/o Obfuscation

Figure 2 – Decompiled Code without any obfuscation

Figure 2 shows the code after the APK has been compiled without any obfuscation and then decompiled using Jadx. As you can see we can still see where the code saves the user’s credentials.

Enabling ProGuard

To turn on ProGuard, simply set the minifyEnabled flag to true in your build.gradle file

android {
  ...
  buildTypes {
        release {
            minifyEnabled true
            proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
        }
    }
  ...
}

Decompiled Code w/Obfuscation

Figure 3 – Decompile code when using ProGuard

Figure 3 shows the obfuscated code after it’s been compiled with ProGuard enabled and then decompiled once again using Jadx. The variables have been renamed but we can still see where the code saves the user’s credentials. So far obfuscation hasn’t done a lot to protect our username and password.

ProGuard’s obfuscation transformations are all recorded in a mapping.txt file. Be careful to save this file. Use it for debugging with any stacktraces you receive to find your way back to the original method and variable names.

Enabling DexGuard

DexGuard is the commercial version of ProGuard and is available from http://guardsquare.com It doesn’t just rename variables it performs much stronger control and preventative obfuscations.

See Christian Collberg’s Taxonomy of Obfuscation Transformations fora great explanation of the different type of obfuscations.Enable DexGuard in your top level build.gradle file as follows

buildscript {
    repositories {
     	flatDir { dirs '../lib' }
     	jcenter()
    }

    dependencies {
     	classpath 'com.android.tools.build:gradle:1.3.0'
     	classpath ':dexguard:'
    }
}

Enable DexGuard in your app’s build.gradle file as follows

apply plugin: 'com.android.application'
apply plugin: 'dexguard'
...
android {
  ...
  buildTypes {
   debug {
        minifyEnabled true
        proguardFile getDefaultDexGuardFile('dexguard-release.pro')
        proguardFile 'dexguard-project.txt'
    }
    release {
        minifyEnabled true
        proguardFile getDefaultDexGuardFile('dexguard-release.pro')
        proguardFile 'dexguard-project.txt'
    }
  }
  ...
}

Decompiled Code w/DexGuard

Figure 4 – Decompiled code when using DexGuard

Figure 4 shows the decompiled code after it has been compiled with DexGuard enabled. Good news, the initializeLocalProfile() method didn’t decompile. DexGuard has worked and we can’t see the credentials.

Caveats

Before we get too excited there are some major caveats with obfuscation. It raises the bar, but most seasoned hackers will disassemble an APK into smali rather than decompile it into Java. Obfuscation won’t necessarily protect you from a smali attack. It also wouldn’t take someone too long to find the shared preferences file so better to save password information on the server and not on the phone where is easy to access.

Other Android Obfuscation Options

It’s important to do something to protect your app. Android apps are in most cases debuggable – whether you like it or not – so don’t make it any easy for hackers to follow your code. If you don’t feel that obfuscation is secure enough then you do have the option of writing the Android code in C++ and using the NDK to compile the app. It can still be disassembled so it’s not perfect but it is harder to debug and follow the flow of the code.

For more information, pick up the Bulletproof Android written by RIIS founder and president, Godfrey Nolan on Amazon or send us a message on our contact form if you have any questions. Code and configuration files are available on github