Tutorial Dexguard, Android and React Native
DexGuard is a specialized optimizer and obfuscator for Android applications. Once applied to your application or library, it produces code that is optimized and more difficult to crack.
Tutorial guide for the basic steps of processing your application with DexGuard in your React Native applications.
- Setup your android project.
- Setup the security features.
- Setup Bitrise workflow.
- Build and validate report.
Dexguard Technical aspects
From official documentation.
DexGuard processes Android applications and libraries, making them smaller, more efficient, and better hardened against reverse engineering and tampering.
Optimizing and protecting applications
DexGuard can be used to protect applications that have been produced by the Android build toolchain.
Source code and resources optimized and protected (.apk) with dexguard.
- Android manifest (text .xml)
- Java source code (.java)
- Native source code (.c, .cpp)
- Resources (text .xml)
- Resource files (text .xml, .png,...)
- Assets (.txt,...)
DexGuard reads the input .apk file and optimizes and protects the code and the resources.
DexGuard packages the processed output into an output apk. DexGuard can optionally sign and align the output, removing the need for external tools.
How it works?
DexGuard processes the resources and the code in distinct but seamless steps.
Input: Compiled, unprotected code and resources.
- Shrinking: the shrinking step detects and removes unused resources, resource files, native libraries, classes, fields, methods, and attributes.
- Optimization: the optimization step analyzes and optimizes the resources and the bytecode of the methods.
- Obfuscation Encryption: the obfuscation step renames the remaining resources, resource files, native libraries, classes, fields, and methods using short meaningless names. It obfuscates the bytecode inside specified methods. Finally, it encrypts specified strings, classes, native libraries, resource files, and assets.
- Final conversion: the final conversion step translates the Java bytecode (*.class) to Dalvik bytecode (classes.dex).
Output: Protected, secure code and resources.
Setup your android project
Configuring Android Gradle's
Edit android/build.gradle
We recommend to install Dexguard using the maven repository.
Add to the buildscript dependency plugin:
Edit android/gradle.properties and add the variables, you can inject this values from a CD/CI like bitrise.
Edit your android/app/build.gradle
Configure security features
Dexguard security features review
Reflection
DexGuard will replace invocations by reflection and then encrypt the resulting strings. Very difficult to find with static analysis.
Verification: read the verbose logs of building.
File detection, Tamper Detection and Certificate Verification
Anti-tamper technology keeps hackers from modifying your app’s execution to learn its weaknesses and bypassing security features to misuse the software.
Tamper detection actively checks the integrity of the application at runtime and acts suitably if the application has been modified.
Verification: by unpacking the application and repackaging it, with unzip and zip.
zipalign -v -f 4 binary.apk
Use our method passTamperDetection to verify tamper and certificate.
Debugger Detection, Hook Detection, Root Detection, Virtual Environment
Sanity check to detect the environment in which the application is running.
Use our method passEnvironmentChecks to detect multiple environment checks.
The following checks are performed:
- HookDetector: Checks if the application is being hooked with a specialized framework like Xposed or Substrate
- RootDetector: Checks if the application is running on a rooted device.
- DebugDetector: Checks if the application can be debugged or if it is being debugged.
- EmulatorDetector: Checks if the application is running on an emulator.
Verification: use a rooted android, APK emulator or try to attach some debugging point with Xposed.
Code Obfuscation
It allows to obfuscate all methods of all classes inside package.
Verification: decompile the apk and compare the resulting class with the original one, as well the verbose option will print how many clases are obfuscated.
Code Virtualization
Use code virtualization when Class encryption cannot be used due to technical constraints (e.g. Activities referenced by the AndroidManifest) or when it is too heavy to efficiently use as a final protection layer.
Verification: decompile the apk and compare the resulting class with the original one, as well the verbose option will print how many clases are obfuscated.
Native Library Encryption
DexGuard obfuscates JNI functions inside native libraries. This technique prevents static analysis of the native code.
Verification: unpack encrypted native library and visualize the encrypted content opposite to the ELF format.
Asset Encryption
Dexguard can encrypt specific asset files.
Verification: unpack encrypted binary and visualize the encrypted content opposite to the original format.
Resource Encryption and Resource File obfuscation
DexGuard encrypts only inlines resource strings but it posible to explicitly specify to encrypt sensitive resource strings.
Verification: Use appt to dump the strings in the hardened binary.
aapt d --values strings [APK_FILE]
Metadata Encryption
DexGuard encrypts only inlines metadata in the Android Manifest but it posible to explicitly specify encrypt other metadata values.
Verification: unpack and explore the Android Manifest in the hardened release version.
Class Encryption
Name obfuscation, string encryption, reflection, asset encryption, resource encryption and native library encryption harden the code and resources against static analysis.
Specially usefully to add extra security layer to the reflection and other secure techniques applied to our binary.
Verification: hook a disassembler to the hardened version to find traces of string encryption, reflection, tamper detection and environment checks, them compare after adding class encryption in some classes, they won't longer be visible.
Name Obfuscation
DexGuard obfuscates the names of identifiers like resource files, resources, classes, fields, and methods using meaningless names. This is a default behavior so there is no code to apply.
Verification: use dexdump or baksmali to disassemble the code and explore the names.
String Encryption
DexGuard can encrypt sensitive string constants, so they become invisible to static analysis. If you have string obfuscation applied they can be hidden completely with string encryption.
Verification: DexGuard will write the list of strings it encrypted, grouped per class, to a file.
Javascript obfuscation
DexGuard can obfuscate JavaScript files using DexGuard's built-in JavaScript obfuscator. Specify a Javascript configuration with the option configuration.yml.
Verification: unpack the binary and open the javascript files.
Setup BITRISE workflow
1. Configure your credentials as secret variables
Configure your dexguard username and password as secret variables
2. Configure your dexguard license
Upload the dexguard license into the GENERIC STORAGE service and create a download step to import the file in the bitrise VM build time.
3. Configure the Maven credentials
Create a new script step in your workflow before the build step, this will append the creds to the gradle properties.
4. Configure Artifacts step to export the Dexguard report
Configure a new Deploy artifacts step to export the generated security report on each new build.
Build and iterate
We recommend to test your obfuscated application's functionality with a QA Test Suite, having diferente test plan for each security feature, from this point you can have a full secure continuous integration and deployment flow.
Verify
- dexdump (Android SDK): disassembles Dalvik bytecode to a readable text format.
- aapt (Android SDK): disassembles binary resource XML files to a readable text format.
- baksmali (open source): disassembles Dalvik bytecode to a readable source format.
- smali (open source): assembles this source format to Dalvik bytecode again.
- apktool (open source): disassembles and assembles entire applications: bytecode, Android manifest files, resource files, and assets.
- dex2jar (open source): converts Dalvik byte code to Java bytecode.
- jad (free): decompiles Java bytecode to Java source code.
Hopefully this guide may be good to you.