DexProtector User Manual

Description

DexProtector is designed for comprehensive protection of Android-applications (APKs, including Platform signed applications) and Android Libraries (AARs) against reverse engineering and modification. It has integration with all the popular build tools such as Gradle, Ant, and Maven. As DexProtector works with Dalvik Bytecode in case of the protection of Android applications, and with Java bytecode in case of the protection of Android Libraries, it can protect applications not only written in Java programming language. Besides that, it can protect purely native applications, games that use various game engines (Cocos2d, Unity, etc.), applications that are based on HTML/JS, for example Cordova/PhoneGap, and also apps written with use of Mono (Xamarin, Titanium).

Features

  • Encryption of strings
  • Encryption of classes
  • Support for multidex applications
  • Hiding method calls, field types and field access with use of the DexProtector's native invokedynamic engine
  • Integrity control: certificate checks, APK's content checks
  • Tamper notifications
  • Native code obfuscation
  • Native code encryption
  • Native code anti-debugging (gdb)
  • Encryption of resources and assets
  • Resource name obfuscation (resources.arsc)
  • Obfuscation of AndroidManifest: Applications/ActivityNames/ContentProviders/Receivers class names mangling
  • Transparent SSL Pinning / HTTP Public Key Pinning (HPKP)
  • Environment checks: Emulator/Root/Debug/Hooks detection, custom firmware detection, wireless status monitoring

Note: Some of the features are available in the Enterprise version only. Please see the feature matrix here.

Note: DexProtector automatically detects which kind of application (Android Wear/Android TV) is being protected and applies available protection features to them.

String Encryption

Encryption of strings is used to hide the contents of string constants in Android applications. It is based on a strong cryptographic algorithm with the dynamic keys. These keys are calculated during the work of the protected application based on many parameters, and they can't be extracted from the application's code. As a result, if the code is decompiled, the contents of strings will be hidden and will be inaccessible for static analysis and decryption.

Note: We recommend to encrypt strings that contain sensitive data (logins, passwords, API credentials, keys, and so on), it’s also useful to encrypt some more strings in order to knock a malicious person out of the way, and to make the reverse engineering task much more complicated. A good approach is to have as many strings encrypted as possible until it's ok for the performance of the application. We do not recommend to use String Encryption for strings in open source libraries and for insensitive strings, because it may lead to a negative performance impact.

Class Encryption

DexProtector allows you to encrypt entire classes.dex including Application, Activities, ContentProviders, Receivers. It also supports multidex configurations (Enterprise version only). Classes protected by this function are encrypted and moved from all original classes.dex files (common storage of all classes of an application in the APK-file). Thus they become "invisible" to APK-file decompiling tools, for example: apktool, dex2jar.

Note: Decryption of classes is an expensive operation. We recommend to use this feature for all your critical classes where you have valuable logic, and other sensitive things you want to hide from third eyes. As the decryption operation takes time, having all the classes encrypted may lead to significant performance impact. But you can easily avoid it by adding only critical classes to the filter, or excluding insensitive. For example, it is not necessary to have open source, or uncritical classes encrypted.

Hide Access

Hiding of method calls allows protecting the critical places of an application from the analysis and modification. This mechanism masks the calls of library methods and application methods with the dynamic functions constructed in a special way. It also hides field types and accesses to fields.

Note: It is recommended using this function only for classes which logic must be protected from analysis and modification, for example, work with the license, mechanism of In-App purchases, etc.

Note: This technique allows you to hide Google API calls or third-party API calls you use in your project, it hides calls to methods with use of our native 'invokedynamic' engine, so that it is almost impossible to decompile protected code, and to figure out which method is going to be called in a certain place. It is also a part of our anti-decompiler technique.

Native Library Protection

DexProtector Enterprise allows you to protect native libraries of all kinds: libraries with JNI functions and regular native libraries. The following protection methods are available:

  • Encryption of native libraries
  • Obfuscation of JNI-method names inside of the libraries and in Dalvik bytecode
  • Protection against debugging of native libraries

Content Protection

Our solution allows protecting the content of APK files and AAR libraries to prevent malicious copying and modification:

  • Encryption of res folder contents
  • Encryption of assets folder contents
  • Resource name obfuscation for resources.arsc
  • Applications/ActivityNames/ContentProviders/Receivers class names mangling in AndroidManifest.xml (DexProtector Enterprise only)

Note: With the use of this function you can easily encrypt an application's internal resources, WebView resources (html, js, css), Cordova/PhoneGap resources (html, js, css). DexProtector Enterprise also supports encryption of game engines resources, video and audio resources, and allows you to access the encrypted resources from external applications.

Integrity Control

Integrity control, or tamper resistance is a mandatory part of the protection DexProtector provides and it is turned on automatically; it prevents the protected APK-file from modification. DexProtector Enterprise allows you to manually configure the integrity control function: enable/disable the certificate check. It also allows you to fire a notification of any kind if the application has been tampered with. Still, the low-level integrity checks are performed first. If they are bypassed, which is barely possible, a notification will be fired.

Tamper Notifications

DexProtector Enterprise allows you to set actions that will be performed when there have been attempts to modify applications' content and/or the signature.

Every single integrity check consists of two phases:

Probe - at this phase, the integrity of the apk file is being checked

Callback - processing of the check's results

For each check, it is needed to set its own Probe and Callback methods and DexProtector will automatically handle them.

The Probe setting requires a method that has android.content.Context as a parameter. The function that checks the integrity of the apk will be automatically embedded in the beginning of the method.

Note: This method must be called in your application prior to using the checks' results.

In order to configure the Callback, it is needed to set two methods: the first one will be called when the application has been tampered with. The second one will be called when the integrity checks have passed successfully. These methods should have public static modifier and (Object data) signature.

For example:

    public static positiveIntegrityCheckCallbackApkTampered(Object o){
        // report the fact of tampering to corporate servers
    }

    public static negativeIntegrityCheckCallbackApkOk(Object o){
        // everything is fine
    }

Please see details of how to configure Tamper Notifications in the Configuration File Format section.

Note: We recommend to process the results of the check function both on the client side (device) and on the server side. Sample: GitHub

Transparent SSL Pinning / HTTP Public Key Pinning (HPKP)

DexProtector Enterprise allows you to securely and transparently protect your Android applications that use HTTPS communication against MITM attacks (Man-in-the-middle). It is not needed to modify the source code and implement SSL Pinning / HPKP (HTTP Public Key Pinning) manually. The following components and frameworks are supported: WebView, Cordova/PhoneGap, Http/sURLConnection.

In order to perform all the checks, DexProtector Enterprise uses a clean room implementation of getting a server SSL certificate chain and performing its validation. It is important to highlight that OpenSSL and Android Security API are not used in these processes, thus your application will be resistive to attacks aimed to bypass HTTPS certificate validation: modification of OpenSSL, replacing/adding forged CA certificates into TrustStore, replacing TrustManager in Android Security API, imposition of a forget certificate chain when Android Security API is used.

DexProtector Enterprise supports the standard approach of configuring SSL Pinning/HTTP Public Key Pinning - Network Security Configuration, which is available for Android N (see details here) What is crucial, DexProtector Enterprise works with a standard configuration and it works for all the Android versions that are supported by DexProtector, not only for Android N.

An important measure of fighting against MITM-attacks is monitoring of checks that are being executed on HTTPS certificates and HTTPS connections. For that purpose the Reporting Pin Validation Failure mechanism was implemented in DexProtector Enterprise - RFC7469 - Public Key Pinning Extension for HTTP (see details here). If an anomaly is detected the module that is injected into your application could send reports in JSON format to a server that is set in your configuration.

Please see configuration details here.

Environment checks and device attestation

DexProtector Enterprise allows using different environment and device checks in protected applications. The following checks are supported:

  • Emulator Detection
  • Root Detection
  • Root Cloaking Detection
  • Debug Detection
  • Hooks Detection (xposed, luckypatcher)
  • Custom Firmware Detection
  • Wireless Secure Status Monitoring

Every single check consists of two phases:

Probe - at this phase the device/environment data is being collected

Callback - processing of the check's results

For each check it is needed to set its own Probe and Callback methods and DexProtector will automatically handle them.

The Probe setting requires a method that has android.content.Context as a parameter. The function that collects and processes environment/device data will be automatically embedded in the beginning of the method.

Note: This method must be called in your application prior to using the checks' results.

In order to configure the Callback it is needed to set two methods: the first one will be called when the check has been successful, for example the Root Detection detected that the device was rooted. The second one will be called when the check was unsuccessful, i.e. the Root Detection did not find that the device was rooted. These methods should have public static modifier and (Object data) signature. Depending on the types of checks the required data will be passed as data parameter.

For example:

    public static positiveCheckCallback(Object o){
        // store information or call network service
    }

    public static negativeCheckCallback(Object o){
        // store information or call network service
    }

Please see details of how to configure these checks in the Configuration File Format section.

Note: We recommend to process the results of the check functions both on the client side (device) and on the server side.

Sample: GitHub

Performance Tuning

In order to eliminate the negative performance impact, it is needed to consider which classes/strings and resources should be protected. The set of classes/resources that should be protected can be specified with the help of a filter (filter format). If you need more detailed adjustment, for example, protection of class methods or individual fields, you can use the annotations mechanism (annotations). We recommend to set filters for classes where you have sensitive strings for String Encryption, classes where you have valuable logic - Class Encryption and Hide Access, and add filters for valuable resources in the assets folder. And we would also recommend to exclude all the open source libraries.

If no filters specified, DexProtector protects all the strings in all the classes (String Encryption), all the classes and method calls, fields (removes types) and field accesses in all the classes (Class Encryption, Hide Access), encrypts resources (Resource Encryption).

There is a reference configuration file dexprotector.xml in the root folder of the distribution kit. It has exclusions for widespread open source libraries. String Encryption, Class Encryption and Hide Access are enabled in this configuration. If you do not have your own configuration yet, we recommend to start with the reference configuration and then add settings that are relevant to your Android applications.

General information

As an input, DexProtector receives the application APK-file or Android Library AAR-file. An output is the protected APK-file, and protected AAR-file respectively. The output APK can be signed in the Debug mode (it is intended for debugging in the emulator), Release mode, or None - the signing can be postponed, for example for Platform/Vendor signed applications. The settings can be specified either in the external configuration file (format), or during the program call.

In the APK protection mode DexProtector automatically finds places inside of the Dalvik bytecode where to put its protection initialisation methods, this is achieved owing to the fact that DexProtector works with a final application and its lifecycle is known. In the AAR protection mode the automatical approach is not applicable, because it is not known how the protected Android Library will be used. Generally an AAR library has initialisation methods that are to be called first and one of the parameters of these methods is Context. To ensure the correct operation of DexProtector's protection methods it should insert its initialisation code into all those methods before their first call. Because of that while creating a configuration for protection of an AAR library it is needed to set methods where DexProtector will insert its initialisation methods, one of their parameters must be Context. The configuration format is described in the Configuration file format section.

The following protection mechanisms are available for Android Libraries:

  • String Encryption
  • Class Encryption
  • Assets Encryption
  • Hide Access
  • Native Code Encryption
  • Native Code Obfuscation
  • Environment checks and device attestation

Note: As Android Libraries provide a public API that should be available on the build stage, Class Encryption can be used only for inner classes and packages of the library.

DexProtector can be used as a console application, GUI-application, Ant-task, Maven-plugin or Gradle-plugin if you protect APK files, and CLI/Gradle-plugin if you protect AAR files.

DexProtector works under JRE ≥ 1.7. Protected Android applications and libraries are compatible with Android ≥ 2.3 (API Level 9).

Note: In the trial mode you must specify a device that is to be used to run protected applications. See trialDeviceID parameter description. If the parameter is not set, or set incorrectly a protected application will not run on the device. An Android emulator can't be used to launch applications protected in the trial mode.

Important: In order to assess all the features, please use CLI or Gradle/Ant/Maven plugins. The GUI supports only String Encryption, Class Encryption, Hide Access and Resource Encryption.

Important: If you use a name obfuscator alongside DexProtector, for example, ProGuard, in your build chain, it is needed to follow the requirements below:

  1. DexProtector must be the last step of your build chain
  2. If you use annotations to configure DexProtector they should be preserved, here is an example for ProGuard:

    -keepattributes SourceFile, LineNumberTable, *Annotation*
    -keep @interface com.dexprotector.annotations.** { *; }
    
  3. To be able to use original class names in the configuration, instead of using obfuscated names, you might set proguardMappingFile in DexProtector's configuration.

  4. If you use an AAR protected with DexProtector in your APK it is needed to disable ProGuard for all the AAR's packages. For example:

    -keep class com.mylibrary.** { *;}
    

Distribution kit contents

Distribution kit is a zip archive containing the following files:

  • Executable jar file - dexprotector.jar
  • Executable jar file - dexprotector-gui.jar
  • Application for MacOS X - DexProtector-GUI.app
  • Annotations library - dexprotector-annotations.jar
  • Maven plugin - dexprotector-maven-plagin.jar
  • Gradle plugin - dexprotector-gradle-plugin.jar
  • Default config - dexprotector.xml
  • Ant settings file – custom_rules.xml
  • License texts - NOTICE, LICENSE

Using the console and graphic modes

Downloading

The download link will be sent with an activation code via email after requesting a trial license, or after purchasing a full license(s).

In order to get the latest version of DexProtector Enterprise, please request it via the contact form.

Note: You should have a valid license activation code in order to get DexProtector working in full or trial mode. If you do not have a license activation code, please either get a trial activation code, or purchase your DexProtector license(s).

Installation

Unpack the zip file to the destination folder.

Obtaining the activation code

To get the trial activation code, please use the following link: https://dexprotector.com/trial-request

To get a fully functional activation code, purchase the required number of licenses. In this case, registration is obligatory. Your email will be registered automatically during the purchasing process. Further instructions (how to set your password and so on) will be sent to the specified email address.

When purchasing the product via FastSpring, the activation codes are sent within 24 hours after the funds are received. If a contract is signed with a company, the activation codes are sent after the cash receipt to account or after a copy of a payment order is submitted.

E-mail address you have provided in the order, or when getting the trial license, may be used as login to client’s area on the DexProtector’s site. There is information about all your licenses in this area. License status will be displayed as: Generated – meaning that the license code is generated but not used, or Activated - meaning the activation code is used.

The activation codes are single-use. It means that in case the original license file was lost, or if the hardware or software configuration was changed, you have to contact the customer support to get a new code.

Note: DexProtector supports two activation methods: online and offline. If you have an active Internet connection, you may use online activation. Otherwise, if you do not have Internet connection, or if it is limited by various traffic filter systems, you should use offline activation. In this case it is necessary to generate an activation request code using CLI or GUI (Command Line or Graphical User Interface), and send it to dexprotector@licelus.com via email. You can do it from another computer or a device which has an active Internet connection.

Console mode

Online activation via CLI

To activate DexProtector online in the console mode, run the following command:

java -jar dexprotector.jar -activate

and follow the instructions.

After successful activation, the license file dexprotector.licel will be created in the user's home folder.

To use a license file located in a different folder and not in the same folder with the dexprotector.jar, it is necessary to specify the path to the license file via the special option.

Offline activation via CLI

To activate the license offline in the console mode, run the following command:

java -jar dexprotector.jar -activationRequest

After you enter an activation code, a request code will be generated. You should email this code to dexprotector@licelus.com. In 24 hours you will receive a response code; then run the following command:

java -jar dexprotector.jar -activationResponse

and enter the code you have received. After successful activation, the license file dexprotector.licel will be created in the user's home folder.

To use a license file located in a different folder and not in the same folder with the dexprotector.jar, it is necessary to specify the path to the license file.  

Options and parameters
java -jar dexprotector.jar <options> <src> <dest>

Here <src> is a path to the original APK-file, <dest> is a path to the destination APK-file (it may be the same as <src>).

Valid values of <options>:

-activate
Activate the license online

-activationRequest Generate a request code for offline activation

-activationResponse Finish the offline activation process by entering a response code

-info License status

-licenseFile filename Path to license file

-verbose Print the verbose log to stdout (default: off)

-configFile filename Use the configuration parameters from the specified file (see the Configuration file format)

-signMode debug|release Mode of signing the output APK-file (default: debug)

-keystore path Path to the file with the signing keys (for the release mode only)

-alias name Key alias for signing (for the release mode only)

-storepass password Password to the file with the signing keys (for the release mode only)

-keypass password Password to the signing key (for the release mode only)

-proguardMapFile path Path to the ProGuard map file

-trialDeviceID serial number

In the trial mode a protected application can run only on a device specified by this parameter

Note: The serial number can be obtained via adb get-serialno. SN Example: 060aaf11991191c1

Graphic interface mode

Online activation via GUI

To activate DexProtector online in the GUI, double-click on dexprotector-gui.jar (Windows/Linux) or DexProtector-GUI.app (MacOS).

Click the License Info button in the application window.

DexProtector license is not activated

Then click Activate, enter the activation code and click Activate online.

Activate DexProtector's license

After successful activation, the license file dexprotector.licel will be created in the user's home folder.

Offline activation via GUI

To activate the license offline in the GUI, double-click on dexprotector-gui.jar (Windows/Linux) or DexProtector-GUI.app (MacOS).

Click the License Info button in the application window.

DexProtector license information

Click the Activate button, enter the activation code and click Generate activation request.

DexProtector activation request code

You should email the generated code to dexprotector@licelus.com. In 24 hours you will receive a reply with the activation response. It is necessary to enter this code in a field which becomes available after you click Enter activation response. If you exited DexProtector, run it again and follow License Info -> Activate -> Enter activation response.

DexProtector activation response code

After successful activation, the license file dexprotector.licel will be created in the user's home folder.

DexProtector license is activated

Options and parameters

DexProtector main window, options and parameters

Android Project Options:

  • Source APK – a path to the original APK-file
  • Destination APK – a path to the output APK-file
    Destination APK may be the same as the Source APK. If the Destination APK does not exist, it will be created.
  • Sign mode - mode of signing the output APK-file
    The APK-file can be signed in two modes: Debug and Release. In case of the Release mode, it is necessary to specify a keystore, key alias, keystore password and key password in a special dialog window which appears in case the protection process is initiated.

DexProtector signing options, keystore, key and passwords

Note: If you are trying DexProtector out with a trial license you must specify a device that is to be used to run protected applications. If the Android Device ID is not set, or set incorrectly a protected application will not run on the device. An Android emulator can't be used to launch applications protected in the trial mode.

DexProtector Trial Device ID, Android Device ID, Serial Number

Protection Options:

  • String Encryption – turn on/off the string encryption (default: off)
  • Class Encryption – turn on/off the class encryption (default: off)
  • Hide Access – turn on/off hiding the API calls (default: off)
  • Resource Encryption – turn on/off the resource encryption (default: off)

To setup the filter, it is necessary to select Use filter, click the Select button and specify classes which need to be protected in the displayed window. See Filter format section for details.

DexProtector filter format

You can do the following with the help of the filter:

  • encrypt the string constants in a class or classes which correspond to the pattern
  • fully encrypt a class or classes which correspond to the pattern
  • hide API calls in a class or classes which correspond to the pattern

Control elements:

  • License Info – the license status and activation
  • Default config - loads the default configuration with recommended exlusions for common libraries
  • Load config – load settings from the configuration file
  • Save config – save the current settings to a file
    You can use the saved file with settings when starting up DexProtector in other modes.
  • Run – protection process startup

After startup, the information about the protection process and the debugging information are displayed if the option Print verbose output to console is enabled. You can click Save to file button to save the log to a file.

DexProtector license is not activated

Using as Ant-task

Note: To use DexProtector as an Ant-task, it is necessary to download the distribution kit, complete the installation, receive the activation code and use it for obtaining your license following the instructions here: Using the console and graphic modes. There are two ways to activate your license: Activation via CLI or Activation via GUI.

  1. Make sure that Android SDK and ANT are properly installed.

  2. If you already have build.xml, then skip the steps 3-5 and start with the step 6.

  3. Go to the project folder:

    $ cd android-project 
    
  4. Execute the following command:

    $ android-sdk-home/tools/android update project --path .  
    
  5. Check the correctness of build.xml with the help of the ant command; the output should be like this: help:

    [echo] Android Ant Build. Available targets:      
    [echo]    help:      Displays this help.      
    [echo]    clean:     Removes output files created by other targets.     
    [echo]               The 'all' target can be used to clean dependencies      
     ...... 
    BUILD SUCCESSFUL
    
  6. Copy the custom_rules.xml file to the project folder from the DexProtector distribution kit.

  7. In the local.properties file add a property dexprotector.home and set its value to the DexProtector distribution kit path, for example: dexprotector.home=/usr/local/dexprotector.

    IMPORTANT! Do not place DexProtector's jar libraries in the libs folder of your project.

  8. Create the settings file dexprotector.xml in the project folder either manually, or via the DexProtector’s GUI.

  9. Run the command ant release. An example of ANT-task usage is available in the samples folder of the DexProtector distribution kit.

Note: Parameters that were set in the Ant-task has higher priority than parameters set in the configuration file, for example if there is password to keystore – keypass defined in Ant task, than its value will be used instead of the value of keypass tag from the configuration file. 

Using as Maven-plugin

DexProtector is designed for Maven-projects which use Android Maven Plugin for compilation.

Note: To use DexProtector as Maven-plugin, it is necessary to download the distribution kit, get the activation code and use it for obtaining your license following the instructions here: Using the console and graphic modes . There are two ways to activate your license: Activation via CLI or Activation via GUI.

First it is needed to install all the required artifacts (POM files are shipped within the distribution package):

mvn install:install-file -Dfile=$DEXPROTECTOR_HOME/dexprotector.jar -DpomFile=$DEXPROTECTOR_HOME/dexprotector.pom
mvn install:install-file -Dfile=$DEXPROTECTOR_HOME/dexprotector-maven-plugin.jar -DpomFile=$DEXPROTECTOR_HOME/dexprotector-maven-plugin.pom
mvn install:install-file -Dfile=$DEXPROTECTOR_HOME/dexprotector-annotations.jar -DpomFile=$DEXPROTECTOR_HOME/dexprotector-annotations.pom

Example:

mvn install:install-file -Dfile=`pwd`/dexprotector.jar -DpomFile=`pwd`/dexprotector.pom
mvn install:install-file -Dfile=`pwd`/dexprotector-annotations.jar -DpomFile=`pwd`/dexprotector-annotations.pom
mvn install:install-file -Dfile=`pwd`/dexprotector-maven-plugin.jar -DpomFile=`pwd`/dexprotector-maven-plugin.pom

DexProtector replaces maven-jar-signer plugin and is executed at the package phase of a lifecycle of a project build. To use it, it is necessary to replace the current maven-jar-signer plugin, or add the definition of dexprotector if maven-jar-signer is absent in the pom.xml/plugins section.

    <plugin>
        <groupId>com.licel</groupId>
        <artifactId>dexprotector-maven-plugin</artifactId>
        <version>${dexprotector.version}</version>
         <executions>
            <execution>
                <phase>package</phase>
                <goals>
                    <goal>dexprotector</goal>
                </goals>
                <configuration>
                    <keystore>..</keystore>
                    <storepass>android</storepass>
                    <keypass>..</keypass>
                    <alias>..</alias>
                    <configFile>dexprotector.xml</configFile>
                </configuration>
            </execution>
        </executions>  
    </plugin>

An example of Maven-plugin usage is available in the samples folder of the DexProtector distribution kit. Priority of the parameters that are being set with Maven configuration is similar to Ant-task (see note in the Using as Ant-task section).

Using as Gradle-plugin

Note: To use DexProtector as Gradle-plugin, it is necessary to download the distribution kit, get the activation code and use it for obtaining your license following the instructions here: Using the console and graphic modes . There are two ways to activate your license: Activation via CLI or Activation via GUI.

  1. Set the path to DexProtector in your buildscript.repositories (main build.gradle of your project), for example:

    flatDir { dirs '/Users/developer/DexProtector' }
    
  2. Add the following dependencies:

    classpath ':dexprotector-gradle-plugin:'
    classpath ':dexprotector:'
    
  3. Add into an Android Application or Android Library project’s build.gradle file the following line after apply plugin: 'com.android.application' or apply plugin: 'com.android.library':

    apply plugin: 'dexprotector'
    
  4. Add into the desired buildType’s section the following line:

    ext.set("dexprotector.configFile", "${projectDir}/dexprotector.xml")
    
  5. Set up signingConfigs:

    signingConfigs {
        release {
            storeFile file("config/release.keystore")
            storePassword RELEASE_STORE_PASSWORD
            keyAlias RELEASE_KEY_ALIAS
            keyPassword RELEASE_KEY_PASSWORD
        }
    }
    
  6. Thus, it should look like this:

    apply plugin: 'com.android.application'
    apply plugin: 'dexprotector'
        ...
        ...
        ...
    android {
        signingConfigs {
            release {
                storeFile file("config/release.keystore")
                storePassword RELEASE_STORE_PASSWORD
                keyAlias RELEASE_KEY_ALIAS
                keyPassword RELEASE_KEY_PASSWORD
            }
        }
        ...
        ...
        ...
        buildTypes {
            release {
                minifyEnabled false
                proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
                ext.set("dexprotector.configFile", "${projectDir}/dexprotector.xml")
                signingConfig signingConfigs.release
             }
        }
        ...
        ...
        ...
    }
    
  7. In order to build a protected APK file in Android Studio, launch Build - Generate Signed Apk.

Protecting Android Libraries (AARs)

At first it is needed to set a Gradle configuration. It is absolutely the same as for APKs, please see the Using as Gradle-plugin section for details.

The next step is to create a DexProtector configuration for the Android Library Project and add initialisation methods if you are planning to use Class Encryption, Hide Access or Resource Encryption mechanisms, after that you are all set and ready to protect your Android Library.

Important: If you have ClassEncryption and/or HideAccess and/or ResourceEncryption functions enabled it is needed to set aarInitMethod. Thus, DexProtector will be able to inject its initialisation method that is needed for the initialisation of the above-mentioned functions. One of its/their parameters must be Context. The format is FQCN.methodName, for example licel.com.mylibrary.Library.init, You do not have to set a method’s signature, DexProtector will find all the methods that have Context in their signature and inject its initialisation method into there.

In order to set multiple initMethods for AAR initialisation it is needed to create a section in your configuration file that looks like the following one:

<aar>
    <initMethod>com.mylibary.EntryPointClassA.initMethod</initMethod>
    <initMethod>com.mylibary.EntryPointClassB.initMethod</initMethod>
    <initMethod>com.mylibary.EntryPointClassB.initMethodC</initMethod>
    <initMethod>...</initMethod>
</aar>

DexProtector’s logs will be available at build/outputs/dexprotector/<builtType>/log.txt file.

Configuring Environment Checks

The way you configure the environment checks is similar to the APK's one (see Configuration File Format section). You can also set no specific Probe/Callback methods, in case of the AAR protection DexProtector handles this automatically. For example:

<detect>
    <root/>
    <debug/>
    <emulator/>
</detect>

All the checks are being performed during the library's initialization process. In case of a positive result there will be an exception (RuntimeException) thrown containing all the information regarding the anomalies detected.

Protecting Dynamically Loadable Modules

Many Android applications use dynamically loadable modules or plugins, so-called external APKs or dynamic APKs. They are used to extend the functionality of an application, to add an ability to be updated without reinstalling the entire application or to decrease the size of the main application and so on.

It is as important to protect these dynamic APKs as taking care of protection of the main application. Or even more important - usually these dynamic APKs are very sensitive and carry the real value of an application. The crucial thing is integrity control of the dynamic module. To meet these requirements we implemented the ability to protect dynamic APKs in DexProtector Enterprise. The following mechanisms can be used for external APK protection, at the moment:

CODE PROTECTION

  • Secure String Encryption
  • Secure Class Encryption
  • CallHiding via Native invokedynamic Engine
  • Field Access and Field Types Hiding via Native invokedynamic Engine
  • Native Code Obfuscation (for non-public JNI methods)
  • Native Code Encryption
  • Native Code Anti-Debugging (gdb)

CONTENT PROTECTION

  • Assets Encryption

INTEGRITY CONTROL

  • Certificate Checks
  • APK Content Checks

Important:
1. When you protect an external APK it is needed to set the following tag in your configuration file: <mainAPK>false</mainAPK>
2. All the APKs: main and dynamic must be signed with the same key (DexProtector’s signature mode must be release).

Sample: GitHub

Configuration file format

<?xml version="1.0" encoding="UTF-8" standalone="no"?>
<dexprotector>
    <verbose/>
    <licenseFile/>
    <optimize/>
    <signMode/>
    <keystore/>
    <storepass/>
    <alias/>
    <keypass/>
    <certificate/>
    <mainAPK/>
    <proguardMapFile/>
    <trialDeviceID/>
    <platformApplicationSupport/>
    <aar>
        <initMethod>...</initMethod>
    </aar>
    <stringEncryption>
        <filters>
            <filter>...</filter>
        </filters>
    </stringEncryption> 
    <classEncryption>
        <filters>
            <filter>...</filter>
        </filters>
    </classEncryption> 
    <hideAccess>
        <filters>
            <filter>...</filter>
        </filters>
    </hideAccess>
    <resourceEncryption>
        <assets>
            <filters>
                <filter>...</filter>
            </filters>
        </assets>    
        <res>
            <filters>
                <filter>...</filter>
            </filters>
        </res>    
    </resourceEncryption>  
    <nativeLibraryEncryption>
        <filters>
            <filter>...</filter>
        </filters>
    </nativeLibraryEncryption>
    <jniObfuscation>
        <filters>
            <filter>...</filter>
        </filters>
    </jniObfuscation>       
    <integrityControl>
        <checkCertificate/>
    </integrityControl>
    <publicKeyPinning>
        <reportUri>...</reportUri>
        <actions>...</actions>
        <reportMethod>...</reportMethod>
        <cacheTTL>...</cacheTTL>
        <network-security-config>
            ...
        </network-security-config>
    </publicKeyPinning>     
    <detect>
        <root>
            <positiveCheckCallback>...</positiveCheckCallback>
            <negativeCheckCallback>...</negativeCheckCallback>
            <probeMethod>...</probeMethod>
        </root>
        <debug>
            <positiveCheckCallback>...</positiveCheckCallback>
            <negativeCheckCallback>...</negativeCheckCallback>
            <probeMethod>...</probeMethod>
        </debug>
        <emulator>
            <positiveCheckCallback>...</positiveCheckCallback>
            <negativeCheckCallback>...</negativeCheckCallback>
            <probeMethod>...</probeMethod>
        </emulator>
        <integrity>
            <positiveCheckCallback>...</positiveCheckCallback>
            <negativeCheckCallback>...</negativeCheckCallback>
            <probeMethod>...</probeMethod>
        </integrity>
    </detect> 
</dexprotector>


Element: verbose
Description: Sets verbosity level to maximum
Format: boolean
Default value: false
Example: <verbose>true</verbose>

Element: licenseFile
Description: Path to the license file
Format: string
Default value: ${user.home}/dexprotector.licel
Example: <licenseFile>/Users/developer/dexprotector.licel</licenseFile>

Element: optimize
Description: Enables the class optimisation mode
Format: boolean
Default value: false
Example: <optimize>true</optimize>

Element: signMode
Description: Sets mode of signing of the output APK file
Format: string
Valid values: debug - signature is performed with a debug-key, release - signature is performed with the developer's key, none - postponed signature, for example for signing later with a platform vendor key (Enterprise only)
Default value: no default value / DexProtector Gradle Plugin: the mode is set automatically
Example: <signMode>release</signMode>

Element: keystore (only for signMode == release)
Description: Path to the keystore
Format: string
Default value: no default value / DexProtector Gradle Plugin: the value is set automatically
Example: <keystore>/Users/developer/.keystore</keystore>

Element: storepass (only for signMode == release)
Description: Password for the keystore
Format: string
Default value: no default value / DexProtector Gradle Plugin: the value is set automatically
Example: <storepass>android</storepass>

Element: alias (only for signMode == release)
Description: Key alias in the keystore
Format: string
Default value: no default value / DexProtector Gradle Plugin: the value is set automatically
Example: <alias>android</alias>

Element: keypass (only for signMode == release)
Description: Password for the key
Format: string
Default value: no default value / DexProtector Gradle Plugin: the value is set automatically
Example: <keypass>android</keypass>

Element: certificate (only for signMode == none) (Enterprise only)
Description: Path to the certificate file of the signature key
Format: string
Default value: no default value / DexProtector Gradle Plugin: the value is set automatically
Example: <certificate>/Users/developer/vendor.cert</certificate>

Element: mainAPK (Enterprise only)
Description: Attribute for DynamicApkProtection mechanism. To be set to false when protecting dynamically loadable modules, so-called external APKs or dynamic APKs
Format: boolean
Default value: true
Example: <mainAPK>false</mainAPK>

Element: proguardMapFile
Description: Path to ProGuard's map file (class name mappings after name obfuscation)
Format: string
Default value: no default value / DexProtector Gradle Plugin: the value is set automatically
Example: <proguardMapFile>/Users/developer/project/proguard_map.txt</proguardMapFile>

Element: trialDeviceID
Description: Device serial number (required for the trial mode of DexProtector, applications protected in the trial mode will work only on this device)
Format: string
Default value: no default value
Example: <trialDeviceID>01785e678ad56d3a</trialDeviceID>

Element: platformApplicationSupport (Enterprise only)
Description: Sets the support for applications to be signed with a platform vendor key
Format: string
Valid values: on - enable support, off - disable support
Default value: off
Example: <platformApplicationSupport>on</platformApplicationSupport>

Element: aar (Enterprise only)
Description: Process the input file as Android Library Archive (AAR)
Format: contains nested elements
Nested elements:
    Element: aarInitMethod (Many)
    Format: string
    Default value: no default value
    Example: <aarInitMethod>com.sample.Library.initMethod</aarInitMethod>

Example:

<aar>
    <aarInitMethod>com.sample.Library.initMethod</aarInitMethod>
</aar>

Important: A method that is set in aarInitMethod must have a parameter of type android.content.Context

Element: stringEncryption
Description: Encrypt Strings in the input application (APK) or Android Library (AAR)
Attribute: mode
Valid values: all - use filters set in the nested elements, annotations - use annotations
Default value: all
Format: contains nested elements
Nested elements (<filters>List of <filter/> tags</filters>) (Only for mode==all):
    Element: filter (Many)
    Format: string
    Default value: no default value
    Example: <filter>glob:com/sample/Library/**</filter>

Example:

<stringEncryption>
    <filters>
        <filter>glob:com/sample/Library/**</filter>
    </filters>  
</stringEncryption>
<stringEncryption mode="annotations"/>


Element: classEncryption
Description: Encrypt classes in the input application (APK) or Android Library (AAR)
Attribute: mode
Valid values: all - use filters set in the nested elements, annotations - use annotations
Default value: all
Format: contains nested elements
Nested elements (<filters>List of <filter/> tags</filters>) (Only for mode==all):
    Element: filter (Many)
    Format: string
    Default value: no default value
    Example: <filter>glob:com/sample/Library/**</filter>

Example:

<classEncryption>
    <filters>
        <filter>glob:com/sample/Library/**</filter>
    </filters>  
</classEncryption>
<classEncryption mode="annotations"/>


Element: hideAccess
Description: Hides accesses to methods/fields in the input application (APK) or Android Library (AAR)
Attribute: mode
Valid values: all - use filters set in the nested elements, annotations - use annotations
Default value: all
Format: contains nested elements
Nested elements (<filters>List of <filter/> tags</filters>) (Only for mode==all):
    Element: filter (Many)
    Format: string
    Default value: no default value
    Example: <filter>glob:com/sample/Library/**</filter>

Example:

<hideAccess>
    <filters>
        <filter>glob:com/sample/Library/**</filter>
    </filters>  
</hideAccess>
<hideAccess mode="annotations"/>


Element: resourceEncryption
Description: Encrypt resources in the input application (APK) or Android Library (AAR). Due to the Android platform limitations, res folder encryption is not available for AARs.
Attribute: nameObfuscation
Valid values: on - enable resource name obfuscation, off - disable resource name obfuscation
Default value: off
Attribute: webViewSupport
Valid values: on - enable support for webView/Cordova/Phonegap, off - disable support for webView/Cordova/Phonegap
Default value: off
Format: contains nested elements
Nested elements (<assets/>,<res/>):
    Element: assets
    Description: Encryption settings for the assets folder. If the element exists in the configuration file files from the assets folder are encrypted in accordance with the filter.
    Format: contains nested elements
        Nested elements (<filters>List of <filter/> tags</filters>):
        Element: filter (Many)
        Format: string
        Default value: no default value
        Example: <filter>*.html</filter>

    Element: res
    Description: Encryption settings for the res folder. If the element exists in the configuration file files from the res folder are encrypted in accordance with the filter.
    Format: contains nested elements
        Nested elements (<filters>List of <filter/> tags</filters>):
        Element: filter (Many)
        Format: string
        Default value: no default value
        Example: <filter>*.png</filter>

Example:

<resourceEncryption nameObfuscation="on" webViewSupport="on">
    <assets>
        <filters>
            <filter>*.html</filter>
        </filters>
    </assets>    
    <res>
        <filters>
            <filter>*.png</filter>
        </filters>
    </res>    
</resourceEncryption>


Note: If there are no assets/res elements in the configuration file under resourceEncryption section the encryption of assets folder is performed in accordance with the default filter. The root for expressions in assets and res filters is /assets and /res accordingly. For example, the encryption of assets folder is enabled, and there is a filter *.html in the configuration, thus all the HTML files are encrypted in the /assets folder (/assets/*.html). The same for res encryption.

Note: If nameObfuscation is enabled (on) the obfuscation of resources.arsc is performed. In the Enterprise version all the names of files from res folder are obfuscated.


Element: nativeLibraryEncryption (Enterprise only)
Description: Encrypt native libraries in the input application (APK)
Format: contains nested elements
Nested elements (<filters>List of <filter/> tags</filters>) (Only for mode==all):
    Element: filter (Many)
    Format: string
    Default value: no default value
    Example: <filter>libsome.so</filter>

Example:

<nativeLibraryEncryption>
    <filters>
        <filter>libsome.so</filter>
    </filters>  
</nativeLibraryEncryption>


Element: jniObfuscation (Enterprise only)
Description: Obfuscate JNI method names in the native libraries and classes
Attribute: mode
Valid values: all - use filters set in the nested elements, annotations - use annotations
Default value: all
Format: contains nested elements
Nested elements (<filters>List of <filter/> tags</filters>) (Only for mode==all):
    Element: filter (Many)
    Format: string (path the class JNI methods of which must be obfuscated)
    Default value: no default value
    Example: <filter>glob:com/sample/NativeLibrary.class</filter>

Example:

<jniObfuscation>
    <filters>
        <filter>glob:com/sample/NativeLibrary.class</filter>
    </filters>  
</jniObfuscation>
<jniObfuscation mode="annotations"/>

Note: Only classes that have JNI methods should be set in the filter, native libraries that have the JNI methods from those classes will be processed automatically.


Element: integrityControl (Enterprise only)
Description: Controls the configuration of the tamper resistance module
Format: contains nested elements
Nested element:
    Element: checkCertificate
    Format: string
    Valid values: on - enable certificate check, off - disable certificate check
    Default value: on
    Example: <checkCertificate>off</checkCertificate>

Example:

<integrityControl>
    <checkCertificate>off</checkCertificate>
</integrityControl>


Public Key Pinning

Element: publicKeyPinning (Enterprise only)
Description: Settings for SSL/HTTP Public Key Pinning. The followings approaches are available: security configuration file in res/xml (in accordance with specification for Android N), or via a network-security-config nested element.
Attribute: src
Valid values: Path to a security configuration file (see details here), thus if the file exists all the settings are taken from the file. If the src attribute is not set and there is a network-security-config tag all the settings are taken from the configuration defined inside the tag and the res/xml/network_security_config.xml will be created, it will contain settings from the network-security-config tag, and also the following information will be added into the AndroidManifest.xml:

<app ...>
    <meta-data android:name="android.security.net.config"
               android:resource="@xml/network_security_config" />
    ...
</app>

Default value: no default value
Format: contains nested elements (actions/reportUri/network-security-config)
Nested elements:
    Element: actions
        Description: List of actions that are to be performed if there were errors or anomalies in Public Key Pinning's validations
        Format: list with the ',' separator. Available values: block - block the connection, report - send a report regarding the connection.
        Default value: block, report
        Example: <actions>block, report</actions>
    Element: reportUri
        Description: Address that will be used to send JSON reports regarding the errors and anomalies detected during the execution of the Public Key Pinning's checks
        Format: string
        Example:

<reportUri>http://example.com/pkp-report</reportUri>

    Element: reportMethod
        Description: ClassName.methodName a method to which JSON reports are passed to when there were errors of validation of Public Key Pinning checks. These methods should have public static modifier and (Sting jsonStr) signature.

        Format: string
        Example:

<reportMethod>com.sampleapp.MainActivity.pkpReport</reportMethod>

    Element: cacheTTL
        Description: Time to live for a server SSL certificate chain check result for each domain
        Format: int
        Default value: 180
        Example: <cacheTTL>180</cacheTTL>


    Element: network-security-config
        Description: Embedded Security Configuration File
        Format: network-security-config
        Example #1:

        <network-security-config>
            <domain-config>
                <domain includeSubdomains="true">example.com</domain>
                    <pin-set expiration="2018-01-01">
                    <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
                    <!-- backup pin -->
                    <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
                    </pin-set>
            </domain-config>
        </network-security-config>

        Example #2 (Security Configuration File in res/xml APK):

        <publicKeyPinning src="res/xml/network_security_config.xml">
            <reportUri>http://example.com/pkp-report</reportUri>
        </publicKeyPinning>

         Example #3 (Embedded Security Configuration File):

<publicKeyPinning>
    <reportUri>http://example.com/pkp-report</reportUri>
    <network-security-config>
        <domain-config>
            <domain includeSubdomains="true">example.com</domain>
                <pin-set expiration="2018-01-01">
                <pin digest="SHA-256">7HIpactkIAq2Y49orFOOQKurWxmmSFZhBCoQYcRhJ3Y=</pin>
                <!-- backup pin -->
                <pin digest="SHA-256">fwza0LRMXouZHRC8Ei+4PyuldPDcf3UKgO/04cDM1oE=</pin>
                </pin-set>
        </domain-config>
    </network-security-config>
</publicKeyPinning>


Tamper Notifications and Environment Checks

Element: detect (Enterprise only)
Description: Controls the device/environment checks
Format: contains nested elements (root/emulator/debug/integrity)
Nested elements:
    Element: root/emulator/debug/integrity
    Format: contains nested elements (positiveCheckCallback/negativeCheckCallback/probeMethod)
        Nested elements:
        Element: positiveCheckCallback
        Description: ClassName.methodName - callback method to be called if the check was successful
        Format: string
        Example: <positiveCheckCallback>com.sample.MainActivity.positiveCheck</positiveCheckCallback>

        Element: negativeCheckCallback
        Description: ClassName.methodName - callback method to be called if the result of the check is negative
        Format: string
        Example: <negativeCheckCallback>com.sample.MainActivity.negativeCheck</negativeCheckCallback>

        Element: probeMethod
        Description: ClassName.methodName - method to be used for embedment of device/environment checks
        Format: string
        Example: <probeMethod>com.sample.MainActivity.doProbe</probeMethod>

Example:

<detect>
  <root>
     <positiveCheckCallback>com.sampleapp.MainActivity.positiveCheckCallback</positiveCheckCallback>
     <negativeCheckCallback>com.sampleapp.MainActivity.negativeCheckCallback</negativeCheckCallback>
     <probeMethod>com.sampleapp.MainActivity.doProbe</probeMethod >
  </root>
</detect>

Important: Methods that are set in positiveCheckCallback/negativeCheckCallback must have public static modificator and (Object o) signature. Method that is set in probeMethod must have android.content.Context as one of its parameters and must be called in your application prior to using the checks' results.

Filter format

DexProtector provides a flexible mechanism of setting the filters for its protection functions. You can use glob or regex syntax modes. Wherein it is possible to use exclusions by placing ! before the filter's expression.

Let us see at different filter settings (glob syntax is used in the following examples).

Say we want to configure a Class Encryption's filter. In the classes.dex we have got the following structure of packages:

    android/support/...
    com/google/..
    com/facebook/..
    com/mycompany/..
    com/mycompany/ui/..
    com/mycompany/core/..

1. Protection of certain packages

In order to protect the com/mycompany package (i.e. all the classes that lie under com/mycompany) we should set the following filter:

    glob:com/mycompany/**

2. Protection of a certain class

To protect a single class, for example com/mycompany/core/InternalEngine.class we use the following filter:

    glob:com/mycompany/core/InternalEngine.class

3. Exclusion of certain packages from processing

Here are a few examples of how to exclude a certain package or packages from processing:

    glob:!android/support/**
    glob:!com/google/**
    glob:!com/facebook/**

In this case a result will be the same as in the first case, where we included everything except android/support, com/google and com/facebook. And in the second example we excluded everything except com/mycompany.

Exclusion for a single class is made in the same way and it is needed to place ! before the class name:

    glob:!com/mycompany/core/BumpGenerator.class

4. Mixed configuration

DexProtector allows using inclusions and exclusions at the same time. When doing that keep in mind the following logic:

  • At first we add an exclusion filter for all the packages and classes
  • Set include filters
  • Add exclude filters for certain packages and/or classes

In other words DexProtector reads and applies rules from the top to the bottom.

For example:

    glob:!**/**
    glob:com/mycompany/**
    glob:!com/mycompany/ui/**
    glob:com/mycompany/ui/Payment.class

As a result all the classes from com/mycompany and com/mycompany/core are protected, and the com/mycompany/ui/Payment.class is protected as well. Remaining classes from com/mycompany/ui are leaved untouched.

The same approach is used for all the functions that use filters, i.e. String Encryption, Hide Access, Resource Encryption and Native Library Protection.

Please see dexprotector.xml file in the root folder of the distribution kit for additional examples.

Detailed syntax information

Filter is to be defined by the syntax and the pattern and takes the form: syntax:pattern, where ':' stands for itself.

Two syntaxes are supported: the "glob" and "regex". The value of the syntax component is compared without regard to case. When the syntax is "glob" then the String representation of the path is matched using a limited pattern language that resembles regular expressions but with a simpler syntax. For example:
*.* Matches file names containing a dot.
foo.? Matches file names starting with foo. and a single character extension.
com/*/* Matches package /com/test/a.
com/** Matches all packages and classes inside a com package.

The following rules are used to interpret glob patterns:

  • The * character matches zero or more characters of a name component without crossing directory boundaries.
  • The ** characters matches zero or more characters crossing directory boundaries.
  • The ? character matches exactly one character of a name component.
  • The backslash character (\) is used to escape characters that would otherwise be interpreted as special characters. The expression \\ matches a single backslash and \{ matches a left brace for example.
  • The [ ] characters are a bracket expression that matches a single character of a name component out of a set of characters. For example, [abc] matches "a", "b", or "c". The hyphen (-) may be used to specify a range so [a-z] specifies a range that matches from "a" to "z" (inclusive). These forms can be mixed so [abce-g] matches "a", "b", "c", "e", "f" or "g". If the character after the [ is a ! then it is used for negation so [!a-c] matches any character except "a", "b", or "c". Within a bracket expression the *, ? and \ characters match themselves. The - character matches itself if it is the first character within the brackets or the first character after the ! if negating.
  • The { } characters are a group of subpatterns, where the group matches if any subpattern in the group matches. The , character is used to separate the subpatterns. Groups cannot be nested.
  • Leading period/dot characters in the file name are treated as regular characters in match operations. For example, the * glob pattern matches file name ".login".
  • The ! character in the beginning of the pattern component negates the pattern.

When the syntax is "regex" then the pattern component is a regular expression composed in accordance with java regex rules.

Note: If the syntax is not set (glob: or regex:) old filter format will be used in order to preserve backward compatibility with DexProtector’s versions < 5.0.

Annotations

To fine tune your protection process, you can use annotations. Annotations will be used only if you will enable the corresponding parameters in your configuration. You can enable annotations for String Encryption, Class Encryption and Hide Access, the annotations are respectively: @StringEncryption, @ClassEncryption and @HideAccess. If there are the annotations in a project then class files and/or their elements marked with the annotations will be protected.

The @StringEncryption annotation can be used at the following hierarchy levels:

Class field - a specified class String is encrypted:

import com.dexprotector.annotations.*;

public class Test {
 @StringEncryption
  final String SOME_TEXT="12345678";
   ....
}

Class - all Strings of the class are encrypted:

...
import com.dexprotector.annotations.*;

@StringEncryption 
public class Test {
   ....
}

Class method - all Strings of the method are encrypted:

import com.dexprotector.annotations.*;

public class Test {
   ....
  @StringEncryption
  public void someMethod(){
     ...
  }
   ....
}

The @ClassEncryption annotation can be used at the following hierarchy levels:

Class - the class is encrypted:

...
import com.dexprotector.annotations.*;

@ClassEncryption 
public class Test {
   ....
}

The @HideAccess annotation can be used at the following hierarchy levels:

Class - all calls of all class methods are hidden:

...
import com.dexprotector.annotations.*;

@HideAccess 
public class Test {
   ....
}

To use the annotations in your projects, add the dexprotector-annotations.jar library from the distribution kit to the project classpath.

Important Note: If you are using ProGuard alongside DexProtector, please make sure you have the following rules in your ProGuard configuration file:

-keep interface com.dexprotector.annotations.ClassEncryption
-keep interface com.dexprotector.annotations.HideAccess
-keep interface com.dexprotector.annotations.StringEncryption

Samples

The samples are available on GitHub.

Uninstallation Information

In order to uninstall DexProtector from your computer, please delete your DEXPROTECTOR_HOME directory (where you unpacked the distribution kit) and your license file, it is located in your home folder and called dexprotector.licel.

Last update: 10.05.2017 - 22:48