Using apkdefender
XTD Protect for Android: Command Line Tools
APKDefender Tool
The apkdefender tool protects an unprotected Android application (APK).
apkdefender operation is controlled with configuration directives given via command line and a JSON configuration file.
The protected application file is named <original-name>-protected.apk and placed in the same directory as the original application. During protection bytecode is translated to native code, and anti-tamper protections and obfuscation then applied. The protection step can be integrated into your development process, for example in gradle builds.
As much of the bytecode as possible is translated to native code, for best protection. However, specific classes and methods may be excluded, either by default or through manual configuration.
apkdefender directs output information to the stdout. More extensive debug output is saved to the apkdefender.log file in the current working directory.
Basic Usage
To use apkdefender:
- Generate a configuration file
- Update the configuration file with your certificate information
- If required, tune the protection by adjusting configuration parameters
- Protect the application
To generate a new JSON configuration file
In the directory containing apkdefender and your .apk file, enter the following command:
apkdefender -b new-config <app-release.apk>
where <app-release.apk> is the name of your .apk file.
To update the configuration file
Before protection, you must update the signing certificate location in the configuration file. In a text editor, open the configuration file.
Signing_certificate:
A file path or a list of the file paths for one or more signing certificates. Only RSA certificates are supported, and the certificate must be given in DER or PEM format.
The generated configuration file creates protection scope based on the contents of the .apk file. To validate the scope or to tune it, refer to Defining the Protection Scope. For information on the configuration options refer to Configuration.
To protect the application
Enter the following command:
apkdefender -c <path-to-configuration-file> <app-release.apk>
The resulting protected app is named app-release-protected.apk.
Command Reference
| Option | Required? | Description |
|---|---|---|
| -c / --configuration-file | Required | Path to the JSON configuration file. |
| -m / --mapping-file | Required | Path to the R8 mapping file. For details on how to use the mapping file for filtering, see section R8 mapping file support. |
| -b / --build-mode | Optional | Build mode options: new-config: Generate a new sample configuration JSON file, with a protection scope derived from the application activities. The produced scope must be validated, and the signing_certificate option value must be added before use. check-protection-status: Check protection status of the application. |
| -w / --working-directory | Optional | The absolute path to a working directory where directory mfjava/mfjava-<app-ID> containing the build files is created. The default working directory location is: - Linux: /tmp/mfjava/mfjava-<app-ID>- macOS: $TMPDIR/mfjava/mfjava-<app-ID>- Windows: %TEMP%/mfjava/mfjava-<app-ID>On Windows, the working directory must be on the same drive as the NDK. |
| -G / --generate-report | Optional | Outputs the protection report file under the current working directory, with name <app-filename>-efficacy_report-<timestamp>, for example app-release.apk-efficacy_report-2024-06-24T11-30-52Z.json. |
| -v / --version | Optional | Outputs the apkdefender tool version information and build date. |
Configuration
A sample of the JSON configuration file format and options is given below.
{
"general_configuration": {
"enable_asset_encryption": false,
"enable_debugger_detection": true,
"enable_method_wiping": false,
"enable_root_detection": false,
"enable_bytecode_renaming": true,
"signing_certificate": "./rsa-cert.bin",
"library_name": "sample_library"
},
"keystore_configuration": {
"key_password": "testks",
"keyalias": "testkey",
"keystore_file": "../testsuite/testkeystore.jks",
"keystore_password": "testks"
},
"protection_scope": {
"exclude_classes": [],
"exclude_methods_from_translation": [],
"exclude_packages": [],
"exclude_translated_methods_from_wiping": [],
"include_packages": []
}
}
If an optional element is not given, the tool will use the default value.
General Configuration
Option | Required? | Type | Description |
|---|---|---|---|
abis | Optional | Array | A list of application binary interfaces (ABIs) for which the application native libraries are built during protection. Support for any ABIs not in this list is dropped. By default the native libraries are built for all ABIs supported by the application. |
api_level | Optional | Integer | Specifies the minSdk level as an integer, for example "24" (Android 7.0 "Nougat"). Normally the API level is retrieved from the AndroidManifest.xml file, but it can be overridden with this option. The API level is needed to use the Android platform libraries required during compilation. Android API levels from 24 to 36 are supported. |
app _store_compatibility | Optional | String | Enable APK distribution via non-Google systems. Note that this option is exclusive, and other distribution systems cannot then be used for the protected application. |
asset_encryption_mode | Optional | String | Choose the asset encryption mode, |
connection_whitelist | Optional | Array | The list of allowed DNS names for connections. If the list is empty or unspecified, the feature is automatically disabled. This feature requires that the Monitoring service is enabled for the application, as any connection attempts to unauthorized DNS hosts are reported to the monitoring interface. |
dex_encryption_mode | Optional | String | The DEX encryption mode: This setting overrides the enable_dex_encryption setting. |
emulator_detection_action | Optional | String | Choose the action when it is detected that the application not running on a real hardware: |
enable_asset_encryption | Optional | Boolean | Set to 'true' to enable asset encryption feature. Asset encryption is disabled by default. |
enable_bytecode_literal_obfuscation | Optional | Boolean | Set to 'true' to enable removal of bytecode literals. String literals are completely removed from the bytecode, and replaced with native lookup calls that load the actual string values from the native code. Int literals are obfuscated using control flow obfuscation with junk code injection, where the actual literal initialization code path taken is determined using a native predicate function that is opaque to the bytecode level analysis. The scope of bytecode literal obfuscation is the untranslated plaintext bytecode within the protection scope. Literals within static class initializers are not obfuscated. Bytecode literal obfuscation is disabled by default. |
enable_bytecode_renaming | Optional | Boolean | Set to 'true' to enable bytecode renaming feature. Configure the feature scope in the renaming_scope section. Bytecode renaming feature is disabled by default. |
enable_bytecode_visual_spoofing | Optional | Boolean | Set to 'false' to disable invisible character usage with the bytecode renaming feature. Note that the invisible characters are not used when protecting in a macOS host, due to limitations in the platform file system. |
enable_debugger_detection | Optional | Boolean | Set to false to disable debugger detection. If enabled, applications marked as debuggable in the AndroidManifest.xml cannot be protected. Debugger detection is enabled by default. |
enable_dex_encryption | Optional | Boolean | Set to 'false' to disable loading and executing Dalvik executable DEX bytecode dynamically from obfuscated static files. DEX encryption is enabled by default. This option will be deprecated in a future version. For new configurations, please use dex_encryption_mode instead. |
enable_emulator_detection | Optional | Boolean | Set to false to allow the application to run on an emulator. By default running the application on an emulator is not allowed. |
enable_heuristic_debugger_detection | Optional | Boolean | Set to true to enable stronger anti-debug measures using heuristics to detect ptrace attacks, even from kernel-level exploits. Disabled by default. |
enable_install_on_removable_media | Optional | Boolean | Set to 'true' to allow installing the application on a removable medium. Installing protected applications on removable media is disabled by default. |
enable_method_wiping | Optional | Boolean | Set to true to enable method wiping. When enabled, unused translated static methods are completely removed. Disabled by default. |
enable_native_library_encryption | Optional | Boolean | Set to 'true' to enable native library encryption feature. Native library encryption feature is disabled by default. |
enable_overlay_detection | Optional | Boolean | Set to 'true' to enable notification that some other application is presenting content on top. The overlay protection is applied at Activity level, and it is possible to select the scope with option from the application activities, with the include_overlays option. The screen overlay detection is disabled by default. |
enable_require_v3_signature | Optional | Boolean | Set to 'true' to prevent fallback to older, less secure signature schemes if v3 signature block does not exist. |
enable_resource_encryption | Optional | Boolean | Set to 'true' to enable resource strings encryption feature. String resources from the application are encrypted, excluding any strings that are nested inside other resource types, or referenced from the Android manifest. Resource encryption is disabled by default. |
enable_root_detection | Optional | Boolean | Set to true to enable jailbreak detection. If an attempt is made to run the protected application on a rooted device, it will exit. If root detection is enabled, debugger detection must also be enabled. Root detection is disabled by default. |
enable_scope_autoconfiguration | Optional | Boolean | Enable automatic generating of the protection scope, producing a minimal stable scope based on Android application lifecycle hooks. Disabled by default. |
enable_screen_capture_protection | Optional | Boolean | Set to 'true' to enable screen capture protection. The screen capture protection is applied at Activity level, and it is possible to fine tune the scope in with option from the application activities with the exclude_activities and include_activities options. Disabled by default. |
enable_strace_detection | Optional | Boolean | Set to 'true' to enable |
enable_wipe_string_fields | Optional | Boolean | Set to 'false' to disable wiping string field initializers from classes, whenever the class is in translation scope. The string field initializers cannot be wiped if reflection is used to retrieve the fields. Enabled by default. |
enable_xamarin_protection | Optional | Boolean | Set this option to 'true' to deploy the Xamarin for Android specific protective measures. Xamarin protection is disabled by default. |
keystore_configuration_file | Optional | String | Specifies the JSON file from where to load the keystore configuration used for application signing. Can be given as an alternative to the Keystore Configuration section. Syntax is as described in the Keystore Configuration section. |
library_name | Required | String | Specifies the library name for the native library generated by apkdefender. Provide the name without the "lib" prefix and ".so" suffix. |
limit_allowed_installers | Optional | Array | A list of package installers that are allowed as the installation source. Usually the allowed sources are application stores. For example |
monitor_api_key | Optional | String | API key to retrieve Monitoring service configuration. The key can be obtained from the App Shield Portal. The monitor_api_key corresponds to the appClientSecret field in the generated API key JSON. Monitoring is described in section Monitoring service. |
monitor_api_key_id | Optional | String | ID of the Monitoring service API key given with the option monitor_api_key. The monitor_api_key_id corresponds to the appClientId field in the generated API key JSON. |
monitor_api_key_owner_email | Optional | String | Email address connected to the account that was used to create the Monitoring service API key on Verimatrix Platform. |
overlay_detection_action | Optional | String | Choose the action when screen overlay is detected: |
root_detection_action | Optional | String | Choose the action when device rooting is detected: |
signing_certificate | Required for apkdefender and aabdefender, optional for aardefender | Array or String | A file path or a list of the file paths for one or more signing certificates. Only RSA certificates are supported, and the certificate must be given in DER or PEM format.
The signing certificate must be given to enable the full application integrity verification. At least one signing certificate must be given for binding. |
signing_certificate_fingerprint | Optional | String | Use the signing_certificate option to configure the certificate binding for the full application integrity verification. However, in some cases only the certificate fingerprint is available, for example if an external distribution signing system is used. In such case the signing_certificate_fingerprint option can be used as an alternative. Note that in this case it is not possible to verify the signing algorithm, but the requirement still applies. |
status_response_method | Optional | String | Configuration option to set the event callback method. This option is an alternative to annotating the method in the source code. The method name must be given including the package namespace and class name. If the method is in an inner class, an annotation must be used instead of this configuration option. For more details, see section Event callback |
system_integrity_mode | Optional | String | Choose the system integrity verification mode: |
system_integrity_product_whitelist | Optional | Array | Device specific exemption for skipping the system integrity verification, while still performed for any other device. Defined by listing the ro.build.product property values for the exempted devices. |
system_integrity_root_certificates | Optional | Array | Path to additional accepted root certificate files in PEM format for system integrity verification. By default only the Google certificates are included. Configuring custom root certificate is needed for any environment that is not CTS compliant. |
Hooking Detection
This feature is always enabled for protected applications. There is no configuration option to disable it.
Keystore Configuration - keystore_configuration
| Option | Required | Type | Description |
|---|---|---|---|
| keystore_file | Optional | String | Specifies the path to the keystore containing a developer certificate required for signing the protected application. If signing_certificate option is given, the certificates must match. |
| keystore_password | Optional | String | The keystore password for signing the protected application using the developer certificate. |
| keyalias | Optional | String | Name identifying the private key used for signing the application. Only RSA keys are supported. |
| key_password | Optional | String | Password for the private key for signing the application. Uses keystore_password if not given. |
Network Security Configuration - network_security_configuration
| Option | Required | Type | Description |
|---|---|---|---|
| certificate_pinning | Optional | Array | Configuration for domains with certificate pinning. Certificate pinning feature is described further in section Certificate pinning. |
| domain | Optional | String | The connection specific destinations that given certificates are pinned to. Required element if the certificate_pinning option is configured. |
| pins | Optional | Array | File paths to the pinned certificates. For a secure connection to be trusted, one of the public keys in the chain of trust must be in the set of pinned certificates. At least one certificate must be given, if the certificate_pinning option is configured. |
| expiration | Optional | Boolean | The date when the pin expires and pinning is disabled. If not given, the pin does not expire. |
| subdomains | Optional | Boolean | Indicates whether subdomains are included in the pin. Set to 'true' to match the domain rule also to all subdomains, including subdomains of subdomains. Otherwise the rule only applies to exact match. |
| cleartext | Optional | Boolean | Indicates whether cleartext traffic is allowed to the pinned domain. Set to 'false' to prevent cleartext traffic. |
Protection Scope - protection_scope
| Option | Required | Type | Description |
|---|---|---|---|
| exclude_activities | Optional | Array | List any application activities that should be exclude from the screen capture protection feature. Wildcards are supported. |
| exclude_assets | Optional | Array | List any assets to be blacklisted for encryption. In some cases it may be necessary to exclude any problematic asset files manually to work around decryption problems. Wildcards are supported. |
| exclude_classes | Optional | Array | Matching classes are removed from the protection scope. This may be useful as a quick workaround to exclude individual classes causing performance issues or other unexpected problems. Wildcards are supported. |
| exclude_methods_from_translation | Optional | Array | Matching methods are excluded from being translated, allowing a finer-grained protection scope. Wildcards are supported. |
| exclude_native_libraries | Optional | Array | List any native library file name to be blacklisted for encryption. In some cases it may be necessary to exclude any problematic native library files manually to work around decryption problems. Wildcards are supported. |
| exclude_packages | Optional | Array | Matching packages are removed from the protection scope. This may be useful as a quick workaround to exclude individual classes causing performance issues or other unexpected problems. Wildcards are supported. |
| exclude_strings | Optional | Array | List any public string resource names to be blacklisted for encryption. In some cases it may be necessary to exclude any problematic string IDs manually to work around decryption problems. Wildcards are supported. |
| exclude_translated_methods_from_wiping | Optional | Array | Matching methods are excluded from wiping. Wiping some specific methods may not be feasible, e.g. because they are called from the native libraries. Wildcards are supported. |
| include_activities | Optional | Array | List any application activities that should be included in the screen capture protection feature. Wildcards are supported. |
| include_assets | Optional | Array | List any assets to be whitelisted for encryption. Wildcards are supported. |
| include_native_libraries | Optional | Array | List any native library file name to be whitelisted for encryption. Wildcards are supported. |
| include_overlays | Optional | Array | The overlay protection is applied at Activity level. List the activities for which the protection is active. The activities must be present in the application bytecode. |
| include_packages | Optional | Array | If any packages are specified in the list, all packages whose name does not match any of the specified include rules are removed from the protection scope. Wildcards are supported. |
| include_strings | Optional | Array | List any public string resource names to be whitelisted for encryption. Wildcards are supported. |
| translated_packageless_classes | Optional | Boolean | Set to 'true' to include classes that do not have package in the translation scope. By default packageless classes are not translated. |
Renaming Scope - renaming_scope
| Option | Required | Type | Description |
|---|---|---|---|
| exclude_packages | Optional | Arrays | Matching packages are removed from the renaming scope that is defined in the include_packages option. Wildcards are supported. |
| include_packages | Optional | Arrays | Only packages that match the specified list are included in the renaming scope. Wildcards are supported. By default the renaming scope is empty. |
| keep_classes | Optional | Arrays | Original name is preserved for the matching classes in the renaming scope. Wildcards are supported. |
| keep_fields | Optional | Arrays | Original name is preserved for the matching fields in the renaming scope. Wildcards are supported. |
Updated 13 days ago
