A black-box obfuscation tool for Android apps.
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).
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).
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.7
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
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
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
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 commands in the previously created Obfuscapk/src/
directory (the folder containing the Dockerfile
) in order 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.7 -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.
Make sure to have apktool
,
jarsigner
and
zipalign
installed and available from command line:
$ apktool
Apktool v2.4.0 - 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.7
installation (along with
its package manager pip
).
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.7 venv
$ source venv/bin/activate
$ # Install Obfuscapk's requirements.
$ python3.7 -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.7 -m obfuscapk.cli --help
usage: python3.7 -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 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:
- Docker image: a local directory containing the application to obfuscate has to be mounted to
/workdir
in the container (e.g., the current directory"${PWD}"
), so the command:
$ obfuscapk [params...]
becomes:
$ docker run --rm -it -u $(id -u):$(id -g) -v "${PWD}":"/workdir" obfuscapk [params...]
- From source: every instruction has to be executed from the
Obfuscapk/src/
directory (or by addingObfuscapk/src/
directory toPYTHONPATH
environment variable) and the command:
$ obfuscapk [params...]
becomes:
$ python3.7 -m obfuscapk.cli [params...]
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] <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 the -o
option, e.g.,
-o Rebuild -o NewSignature -o NewAlignment
). The other optional arguments are as follows:
-
-w DIR
is used to set the working directory where to save the intermediate files (generated byapktool
). If not specified, a directory namedobfuscation_working_dir
is created in the same directory as the input application. This can be useful for debugging purposes, but if it's not needed it can be set to a temporary directory (e.g.,-w /tmp/
). -
-d OUT_APK
is used to set the path of the destination file: the apk file generated by the obfuscation process (e.g.,-d /home/user/Desktop/obfuscated.apk
). If not specified, the final obfuscated file will be saved inside the working directory. Note: existing files will be overwritten without any warning. -
-i
is a flag for ignoring known third party libraries during the obfuscation, in order to use less resources, to increase performances and to reduce the risk of errors. The list of libraries to ignore is adapted from LiteRadar project. -
-p
is a flag for showing progress bars during the obfuscation operations. When using the tool in batch operations/automatic builds it's convenient to have progress bars disabled, otherwise this flag should be enabled to see the obfuscation progress. -
-k VT_API_KEY
is needed only when usingVirusTotal
obfuscator, to set the API key(s) to be used when communicating with Virus Total. Can be set multiple times to cycle through the API keys during the requests (e.g.,-k VALID_VT_KEY_1 -k VALID_VT_KEY_2
).
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:
-
since no working directory was specified, a new working directory (
obfuscation_working_dir
) is created in the same location asoriginal.apk
(this can be useful to inspect thesmali
files/manifest/resources in case of errors) -
some checks are performed in order to make sure that all the needed files/executables are available
-
the actual obfuscation process begins: the specified obfuscators are executed (in order) one by one until there's no obfuscator left or until an error is encountered
-
when running the first obfuscator,
original.apk
is decompiled withapktool
and the results are stored into the working directory -
since the first obfuscator is
RandomManifest
, the entries in the decompiled Android manifest are reordered randomly (without breaking thexml
structures) -
Rebuild
obfuscator simply rebuilds the application (now with the modified manifest) usingapktool
, and since no output file was specified, the resulting apk file is saved in the working directory created before -
NewSignature
obfuscator signs the newly created apk file with a custom certificate contained in this keystore -
NewAlignment
obfuscator useszipalign
tool to align the resulting apk file
-
-
when all the obfuscators have been executed without errors, the resulting obfuscated apk file can be found in
obfuscation_working_dir/original_obfuscated.apk
, signed, aligned and ready to be installed into a device/emulator
As seen in the previous example, Rebuild
, NewSignature
and NewAlignment
obfuscators are always needed to complete
an obfuscation operation, in order 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.
The obfuscators included in Obfuscapk can be divided into different categories, depending on the operations they perform:
-
Trivial: as the name suggests, this category includes simple operations (that do not modify much the original application), like signing the apk file with a new signature
-
Rename: operations that change the names of the used identifiers (classes, fields, methods)
-
Encryption: packaging encrypted code/resources and decrypting them during the app execution
-
Code: all the operations that involve the modification of the decompiled source code
-
Resources: operations on the resource files (like modifying the manifest)
-
Other
The obfuscators currently bundled with Obfuscapk are briefly presented below (in alphabetical order).
NOTE:
not all the obfuscators below correspond to real obfuscation techniques (e.g., Rebuild
, NewSignature
,
NewAlignment
and VirusTotal
), but they are implemented as obfuscators in order to keep the architecture modular
and easy to extend with new functionality.
AdvancedReflection [Code]
Apply reflection only to dangerous APIs.
ArithmeticBranch [Code]
Insert junk code (arithmetic computations).
AssetEncryption [Encryption]
Encrypt asset files.
CallIndirection [Code]
Modify the call graph of the application.
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]
Reorder code using goto instructions.
LibEncryption [Encryption]
Encrypt native libs.
MethodOverload [Code]
Overload methods.
MethodRename [Rename]
Rename methods.
NewAlignment [Trivial]
Realign the application.
NewSignature [Trivial]
Re-sign the application with a new custom signature.
Nop [Code]
Add multiple nop sequences between instructions.
RandomManifest [Resource]
Randomly reorder entries in the manifest file.
Rebuild [Trivial]
Rebuild the application.
Reflection [Code]
Apply reflection.
Reorder [Code]
Reorder code by shuffling code blocks.
ResStringEncryption [Encryption]
Encrypt strings in resources (only those called inside code).
VirusTotal [Other]
Send the original and the obfuscated application to Virus Total.
Questions, bug reports and pull requests are welcome on GitHub at https://github.com/ClaudiuGeorgiu/Obfuscapk.
You are free to use this code under the MIT License.
This software was developed for research purposes at the Computer Security Lab (CSecLab), hosted at DIBRIS, University of Genoa.
- Gabriel Claudiu Georgiu -- Core Developer
- Simone Aonzo -- Research assistant
- Alessio Merlo -- Faculty Member