How to decompile, recompile, and sign an APK

|
Tags:  Android

Context

Android Operating system was launched in 2008. There are lots of Android apps that have been deprecated by the original developer but it still are useful for users.

In this post you will learn how to decompile, recompile, and resign an APK. This knowledge will allow you to modify apps without having access to the code. For example: You could patch an old app to make it work with the latest Android releases.

Take in care that some apps are protected by law and should not be modified.

The steps of this tutorial have been tested in Ubuntu 22.04.

Steps

Install the required tools

You will use these tools:

  • Java JRE and JDK
  • Android Debug Bridge (ADB)
  • APKTool 2.6.1
  • APKSigner

You can get the tools pasting this code in a console:

sudo apt update 
sudo apt install default-jre openjdk-11-jdk-headless adb apksigner

wget https://bitbucket.org/iBotPeaches/apktool/downloads/apktool_2.6.1.jar 
wget https://raw.githubusercontent.com/iBotPeaches/Apktool/master/scripts/linux/apktool 

sudo mv apktool_2.6.1.jar /usr/local/bin/apktool.jar
sudo mv apktool /usr/local/bin/apktool

sudo chmod +x /usr/local/bin/apktool.jar 
sudo chmod +x /usr/local/bin/apktool 

Decompile the APK

  1. Open a console and navigate to the folder that contains the APK you want to modify.

  2. Execute the command apktool d [YOU_APK_FILE] to decompile the application. The code will be saved in a new folder with the same name of the APK file.

    Here you have an example of a successful execution of the command. The app code is saved in com.calculator.android.apk folder.

    branyac@ubuntu-builder:~/$ apktool d com.alculator.android.apk  
    I: Using Apktool 2.6.1 on com.calculator.ndroid.apk 
    I: Loading resource table... 
    I: Decoding AndroidManifest.xml with esources... 
    I: Loading resource table from file: /home/branyac/.local/share/apktool/framework/1.apk 
    I: Regular manifest package... 
    I: Decoding file-resources... 
    I: Decoding values */* XMLs... 
    I: Baksmaling classes.dex... 
    I: Baksmaling classes2.dex... 
    I: Copying assets and libs... 
    I: Copying unknown files... 
    I: Copying original files... 
    I: Copying META-INF/services directory 
    
  3. Navigate to the folder with the decompiled code. Inside that folder there will be others: one called smali and one or more with a name started with smali_classes. These folders contain the application code in SMALI language.

    SMALI is the intermediate language that is translated by the Android ART Virtual Machine to a code that can be understood by the device that is executing the app.

    Make the modifications in the SMALI code with your favorite text or code editor.

There are other methods to decompile Android APK. Some of them are capable even of decompiling to Java language, which is more readable, but I prefer to modify SMALI code because it can be recompiled successfully in most cases.

For example: When decompiling an APK to Java you will have to manually search the libraries used by the application which is a troublesome process and sometimes even impossible because some apps use secret proprietary libraries. You won’t have this problem when recompiling SMALI code.

Recompile and get a new APK

To recompile you just have to execute apktool b [SMALI_FILES_FOLDER]. It will create the APK in [SMALI_FILES_FOLDER]/dist/ folder.

In this example the smali code to be recompiled is in a folder called com.calculator.android.apk:

branyac@ubuntu-builder:~/$ apktool b com.calculator.android.apk 
I: Using Apktool 2.6.1 
I: Checking whether sources has changed... 
I: Checking whether sources has changed... 
I: Checking whether sources has changed... 
I: Checking whether sources has changed... 
I: Checking whether sources has changed... 
I: Checking whether resources has changed... 
I: Building resources... 
I: Building apk file... 
I: Copying unknown files/dir... 
I: Built apk... 

If you get this error message when recompiling: error: brut.androlib.AndrolibException: brut.common.BrutException: could not exec (exit code = 1) it is caused because the application you are modifiying was compiled using modern Android. To fix this error execute apktool with --use-aapt2 parameter. For example: apktool b --use-aapt2 com.calculator.android.apk

The APK generated by Apktool is useless until you sign it in the next step.

Sign the APK

Android uses signatures to check that the APK comes from a secure source and to detect corruption or manipulations. In this step you will learn how to generate a developer key to sign the APK.

  1. Use keytool to generate the public key and the private key needed for signing.

    The next example creates a folder named keys and uses keytool to create the keystore for signing:

    branyac@ubuntu-builder:~/$ mkdir keys 
    
    branyac@ubuntu-builder:~/$ keytool -genkey -v -keystore keys/androidpersonal.keystore -alias AndroidPersonalKeystore -keyalg RSA -validity 1000 
    
  2. Now use apksigner to sign the apk using the keystore you created in the previous step:

    branyac@ubuntu-builder:~/$ apksigner sign -ks ./keys/androidpersonal.keystore --v1-signing-enabled true --v2-signing-enabled true  ./com.calculator.android/dist/com.calculator.android.apk
    

Install the APK

The APK you created must be installed connecting an Android mobile phone to your pc with an USB cable and using a method called ‘sideloading’.

  1. First enable USB debugging on the Android phone where the app will be installed. Here you have the instructions: Configure on-device developer options

  2. Connect the Android Phone to your computer using a USB cable.

  3. Execute this command to disable Android check that enforces installation of APKs from secure sources (AKA: Google Play Store):
    branyac@ubuntu-builder:~/$ adb shell settings put global verifier_verify_adb_installs 0 
    
  4. And finally execute adb install [APK_FILE] to sideload the app.

    Example:

    branyac@ubuntu-builder:~/$ adb install ./com.calculator.android/dist/com.calculator.android.apk  
    

Author

Sergio Monedero

I am excited to share my knowledge and insights on programming and devops through this personal website. I am a lifelong learner with a passion for technology, and I enjoy staying up-to-date on the latest industry trends.

Keep in touch with Me: SergioCoder@LinkedIn | Branyac@Github