Logo

A black-box obfuscation tool for Android apps.

Codacy Ubuntu Build Status Windows Build Status MacOS Build Status Docker Hub Python Version License

Obfuscapk is a modular Python tool for obfuscating Android apps without needing their source code, since apktool is used to decompile the original apk file and to build a new application, after applying some obfuscation techniques on the decompiled smali code, resources and manifest. The obfuscated app retains the same functionality as the original one, but the differences under the hood sometimes make the new application very different from the original (e.g., to signature-based antivirus software).

❱ Publication

More details about Obfuscapk can be found in the paper "Obfuscapk: An open-source black-box obfuscation tool for Android apps". You can cite the paper as follows:

@article{aonzo2020obfuscapk,
    title = "Obfuscapk: An open-source black-box obfuscation tool for Android apps",
    journal = "SoftwareX",
    volume = "11",
    pages = "100403",
    year = "2020",
    issn = "2352-7110",
    doi = "https://doi.org/10.1016/j.softx.2020.100403",
    url = "http://www.sciencedirect.com/science/article/pii/S2352711019302791",
    author = "Simone Aonzo and Gabriel Claudiu Georgiu and Luca Verderame and Alessio Merlo",
    keywords = "Android, Obfuscation, Program analysis"
}

❱ Demo

Demo

❱ Architecture

Architecture

Obfuscapk is designed to be modular and easy to extend, so it's built using a plugin system. Consequently, every obfuscator is a plugin that inherits from an abstract base class and needs to implement the method obfuscate. When the tool starts processing a new Android application file, it creates an obfuscation object to store all the needed information (e.g., the location of the decompiled smali code) and the internal state of the operations (e.g., the list of already used obfuscators). Then the obfuscation object is passed, as a parameter to the obfuscate method, to all the active plugins/obfuscators (in sequence) to be processed and modified. The list and the order of the active plugins is specified through command line options.

The tool is easily extensible with new obfuscators: it's enough to add the source code implementing the obfuscation technique and the plugin metadata (a <obfuscator-name>.obfuscator file) in the src/obfuscapk/obfuscators directory (take a simple existing obfuscator like Nop as a starting example). The tool will detect automatically the new plugin, so no further configuration is needed (the new plugin will be treated like all the other plugins bundled with the tool).

❱ Installation

There are two ways of getting a working copy of Obfuscapk on your own computer: either by using Docker or by using directly the source code in a Python 3 environment. In both cases, the first thing to do is to get a local copy of this repository, so open up a terminal in the directory where you want to save the project and clone the repository:

$ git clone https://github.com/ClaudiuGeorgiu/Obfuscapk.git

Docker image


Prerequisites

This is the suggested way of installing Obfuscapk, since the only requirement is to have a recent version of Docker installed:

$ docker --version             
Docker version 19.03.0, build aeac949

Official Docker Hub image

The official Obfuscapk Docker image is available on Docker Hub (automatically built from this repository):

$ # Download the Docker image.
$ docker pull claudiugeorgiu/obfuscapk
$ # Give it a shorter name.
$ docker tag claudiugeorgiu/obfuscapk obfuscapk

Install

If you downloaded the official image from Docker Hub, you are ready to use the tool so go ahead and check the usage instructions, otherwise execute the following command in the previously created Obfuscapk/src/ directory (the folder containing the Dockerfile) to build the Docker image:

$ # Make sure to run the command in Obfuscapk/src/ directory.
$ # It will take some time to download and install all the dependencies.
$ docker build -t obfuscapk .

When the Docker image is ready, make a quick test to check that everything was installed correctly:

$ docker run --rm -it obfuscapk --help
usage: python3 -m obfuscapk.cli [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK]
...

Obfuscapk is now ready to be used, see the usage instructions for more information.

From source


Prerequisites

Make sure to have a recent version of apktool, jarsigner and zipalign installed and available from the command line:

$ apktool
Apktool v2.4.1 - a tool for reengineering Android apk files
...
$ jarsigner
Usage: jarsigner [options] jar-file alias
       jarsigner -verify [options] jar-file [alias...]
...
$ zipalign
Zip alignment utility
Copyright (C) 2009 The Android Open Source Project
...

To install and use apktool you need a recent version of Java, which should also have jarsigner bundled. zipalign is included in the Android SDK. The location of the executables can also be specified through the following environment variables: APKTOOL_PATH, JARSIGNER_PATH and ZIPALIGN_PATH (e.g., in Ubuntu, run export APKTOOL_PATH=/custom/location/apktool before running Obfuscapk in the same terminal).

Apart from the above tools, the only requirement of this project is a working Python 3 (at least 3.6) installation (along with its package manager pip).

Install

Run the following commands in the main directory of the project (Obfuscapk/) to install the needed dependencies:

$ # Make sure to run the commands in Obfuscapk/ directory.

$ # The usage of a virtual environment is highly recommended, e.g., virtualenv.
$ # If not using virtualenv (https://virtualenv.pypa.io/), skip the next 2 lines.
$ virtualenv -p python3 venv
$ source venv/bin/activate

$ # Install Obfuscapk's requirements.
$ python3 -m pip install -r src/requirements.txt

After the requirements are installed, make a quick test to check that everything works correctly:

$ cd src/
$ # The following command has to be executed always from Obfuscapk/src/ directory
$ # or by adding Obfuscapk/src/ directory to PYTHONPATH environment variable.
$ python3 -m obfuscapk.cli --help
usage: python3 -m obfuscapk.cli [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK]
...

Obfuscapk is now ready to be used, see the usage instructions for more information.

❱ Usage

From now on, Obfuscapk will be considered as an executable available as obfuscapk, so you need to adapt the commands according to how you installed the tool:

Let's start by looking at the help message:

$ obfuscapk --help
obfuscapk [-h] -o OBFUSCATOR [-w DIR] [-d OUT_APK] [-i] [-p] [-k VT_API_KEY]
          [--keystore-file KEYSTORE_FILE] [--keystore-password KEYSTORE_PASSWORD]
          [--key-alias KEY_ALIAS] [--key-password KEY_PASSWORD]
          <APK_FILE>

There are two mandatory parameters: <APK_FILE>, the path (relative or absolute) to the apk file to obfuscate and the list with the names of the obfuscation techniques to apply (specified with a -o option that can be used multiple times, e.g., -o Rebuild -o NewSignature -o NewAlignment). The other optional arguments are as follows:

Let's consider now a simple working example to see how Obfuscapk works:

$ # original.apk is a valid Android apk file.
$ obfuscapk -o RandomManifest -o Rebuild -o NewSignature -o NewAlignment original.apk

When running the above command, this is what happens behind the scenes:

As seen in the previous example, Rebuild, NewSignature and NewAlignment obfuscators are always needed to complete an obfuscation operation, to build the final obfuscated apk. They are not actual obfuscation techniques, but they are needed in the build process and so they are included in the list of obfuscators to keep the overall architecture modular.

Not working as expected? See FAQ and troubleshooting.

❱ Obfuscators

The obfuscators included in Obfuscapk can be divided into different categories, depending on the operations they perform:

The obfuscators currently bundled with Obfuscapk are briefly presented below (in alphabetical order). Please refer to the source code of the project for more details.

NOTE: not all the obfuscators below correspond to real obfuscation techniques (e.g., Rebuild, NewSignature, NewAlignment and VirusTotal), but they are implemented as obfuscators to keep the architecture modular and easy to extend with new functionality.

AdvancedReflection [Code]

Uses reflection to invoke dangerous APIs of the Android Framework. To find out if a method belongs to the Android Framework, Obfuscapk refers to the mapping discovered by Backes et al.

ArithmeticBranch [Code]

Insert junk code. In this case, the junk code is composed by arithmetic computations and a branch instruction depending on the result of these computations, crafted in such a way that the branch is never taken.

AssetEncryption [Encryption]

Encrypt asset files.

CallIndirection [Code]

This technique modifies the control-flow graph without impacting the code semantics: it adds new methods that invoke the original ones. For example, an invocation to the method m1 will be substituted by a new wrapper method m2, that, when invoked, it calls the original method m1.

ClassRename [Rename]

Change the package name and rename classes (even in the manifest file).

ConstStringEncryption [Encryption]

Encrypt constant strings in code.

DebugRemoval [Code]

Remove debug information.

FieldRename [Rename]

Rename fields.

Goto [Code]

Given a method, it inserts a goto instruction pointing to the end of the method and another goto pointing to the instruction after the first goto; it modifies the control-flow graph by adding two new nodes.

LibEncryption [Encryption]

Encrypt native libs.

MethodOverload [Code]

It exploits the overloading feature of the Java programming language to assign the same name to different methods but using different arguments. Given an already existing method, this technique creates a new void method with the same name and arguments, but it also adds new random arguments. Then, the body of the new method is filled with random arithmetic instructions.

MethodRename [Rename]

Rename methods.

NewAlignment [Trivial]

Realign the application.

NewSignature [Trivial]

Re-sign the application with a new custom signature.

Nop [Code]

Insert junk code. Nop, short for no-operation, is a dedicated instruction that does nothing. This technique just inserts random nop instructions within every method implementation.

RandomManifest [Resource]

Randomly reorder entries in the manifest file.

Rebuild [Trivial]

Rebuild the application.

Reflection [Code]

This technique analyzes the existing code looking for method invocations of the app, ignoring the calls to the Android framework (see AdvancedReflection). If it finds an instruction with a suitable method invocation (i.e., no constructor methods, public visibility, enough free registers, etc.) such invocation is redirected to a custom method that will invoke the original method using the Reflection APIs.

Reorder [Code]

This technique consists of changing the order of basic blocks in the code. When a branch instruction is found, the condition is inverted (e.g., branch if lower than, becomes branch if greater or equal than) and the target basic blocks are reordered accordingly. Furthermore, it also randomly re-arranges the code abusing goto instructions.

ResStringEncryption [Encryption]

Encrypt strings in resources (only those called inside code).

VirusTotal [Other]

Send the original and the obfuscated application to Virus Total. You must provide the VT API key (see -k option).

❱ Contributing

Questions, bug reports and pull requests are welcome on GitHub at https://github.com/ClaudiuGeorgiu/Obfuscapk. Make sure to also check FAQ and troubleshooting, since some of the most common questions are already answered there.

❱ License

You are free to use this code under the MIT License.

❱ Credits

Unige Dibris

This software was developed for research purposes at the Computer Security Lab (CSecLab), hosted at DIBRIS, University of Genoa.

❱ Team