Android: How to Decompile and Recompile APKs

Objective: Decompile Android APK files to enable making changes to resource files, smali files, AndroidManifest.xml files, etc. After making changes, recompile the modified code into a signed APK and install the modified APK file to phone.

For this tutorial, you will need the following tools to be installed:

  • Java JDK – for keytool and jarsigner
  • Android SDK – for adb and zipalign
  • Apktool – to decompile ad recompile APKs
  • Android mobile phone with USB debugging enabled

This article will not cover the installation of the tools mentioned above. Installing the tools are quite straight forward, except maybe for Apktool. To install Apktool, refer to the Apktool install guide.

Before proceeding further, make sure that the PATH environment variable includes the Java SDK, Android SDK and Apktool binaries. All our work will be done within a directory called work within your home directory.

$ mkdir ~/work
$ cd ~/work

Decompile APK

Before we decompile an APK file, we need to extract the file from the phone. To extract the APK file, we need to know the package name. For example, WhatsApp package name is “com.whatsapp“. We can get the package name from the app’s Google Play Store web URL. For WhatsApp, the URL is https://play.google.com/store/apps/details?id=com.whatsapp and the package name can be found after the “id=” field.

Once you have determined the package name for the APK, get the path to the APK on your phone using Android ADB. Connect your Android mobile phone to your computer’s USB and run the following ADB command and specify the package of the APK.

$ adb shell pm path com.whatsapp
package:/data/app/com.whatsapp-1.apk

The package path is “/data/app/com.whatsapp-1.apk”. Now, copy the package to your computer.

$ adb pull /data/app/com.whatsapp-1.apk
3001 KB/s (20121758 bytes in 6.546s)

Now, decompile the APK using Apktool with the following syntax.

$ apktool d -o out com.whatsapp-1.apk

Apktool will decompile the APK file and write the output to a sub directory called out.

You are now free to edit the AndroidManifest.xml file, resource files or the smali files based on your requirements.

Generate Keys for App Signing

Now, we will need to generate keys to sign the APK. Run keytool using the following syntax. This will only need to be done once and the key can be reused in the future. To update an app, the new version of the app must be signed using the same key. Android will not allow an app to be updated if the keys are different.

$ keytool -genkey -v -keystore testkey.keystore -alias testkey -keyalg RSA -keysize 1024 -validity 10000
Enter keystore password:  password
Re-enter new password: password
What is your first and last name?
  [Unknown]:  Android
What is the name of your organizational unit?
  [Unknown]:  Android
What is the name of your organization?
  [Unknown]:  Android
What is the name of your City or Locality?
  [Unknown]:  Mountain View
What is the name of your State or Province?
  [Unknown]:  California
What is the two-letter country code for this unit?
  [Unknown]:  US
Is CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US correct?
  [no]:  yes

Generating 1,024 bit RSA key pair and self-signed certificate (SHA256withRSA) with a validity of 10,000 days
        for: CN=Android, OU=Android, O=Android, L=Mountain View, ST=California, C=US
Enter key password for <testkey>
        (RETURN if same as keystore password):
[Storing testkey.keystore]

Once the key has been generated, save the key file “testkey.keystore” so that it can be reused in future. Always try to use the same key to sign apps to minimise any key related issues cropping up.

Recompile and Sign APK

Recompile the decompiled APK using Apktool by specifying the app path, which is the out directory.

$ apktool b out

Apktool will write the output APK file to out/dist directory. Copy the new APK to the root of the work directory. Note that the file has been renamed from “com.whatsapp-1.apk” to “com.whatsapp-1-new.apk” after copying.

$ ls -l ~/work/out/dist
total 19320
-rw-r----- 1 ibrahim staff 19780982 Apr  4 21:11 com.whatsapp-1.apk
$ cp ~/work/out/dist/com.whatsapp-1.apk com.whatsapp-1-new.apk

If you are reusing the keys used for signing, copy the key to the work directory. If you have just generated the key, ignore this step.

$ cp /path/to/testkey.keystore ~/work

Sign the APK with the generated private key using jarsigner.

$ jarsigner -verbose -sigalg SHA1withRSA -digestalg SHA1 -keystore testkey.keystore com.whatsapp-1-new.apk testkey
Enter Passphrase for keystore: password

Next, align the final APK package using zipalign.

$ zipalign -v 4 com.whatsapp-1-new.apk com.whatsapp-1-zipaligned.apk

The APK package is now ready to be installed onto your phone. Before installing, the original package on your phone has to be uninstalled. Once the original APK package been uninstalled, install the new package to your phone using ADB. Your phone has to be connected to your computer via USB for this to work.

$ adb install com.whatsapp-1-zipaligned.apk
        pkg: /data/local/tmp/com.whatsapp-1-zipaligned.apk
Success
4245 KB/s (20121352 bytes in 4.628s)

The modified APK should now be installed on your phone and is ready for use.

ibrahim = { interested_in(unix, linux, android, open_source, reverse_engineering); coding(c, shell, perl, php, python, java, javascript, nodejs, angular, react); plays_on(xbox, ps4); linux_desktop_user(true); }