To configure App Shielding for your applications, select the options on the Configuration Page of the OneSpan Customer Portal as needed.

Configuration options for Android

Configuration options
Option Description
Settings
Query All Packages Permission

Applications which are compiled for Android 11 and later (compileSdkVersion) have to declare the configuration option queryAllPackagesPermission.

Default Obfuscate

Specify whether the entire app has to be obfuscated or nothing. By default, only App Shielding-related classes are obfuscated.

If you enable the Default Obfuscate feature, the Rules.cfg toggle switch is not displayed.

Rules.cfg

You can customize the settings for obfuscation by defining rules in the Rules.cfg file. This determines how App Shielding will modify the Android application, especially in the context of shielding and obfuscation (see Configuration of Shielding Tool rules).

This feature is only available if Default Obfuscate is disabled.

Block screenshots

Determines whether to prevent that screenshots of the app are taken. Screenshots can only be blocked on Android version 4.4 and later. This protection applies to both user and system screenshots. System screenshots are automatically taken when recently used applications are listed.

You can also exclude an activity from this block if your app wants the users to take a screenshot, for instance to verify payments, receipts etc.

Exclude an activity with the Shielding Tool rule allowScreenshotsForActivity:

Add an allowScreenshotsForActivity rule to .my-rules.cfg to tell App Shielding to allow screenshots if the specified activity is visible, even if the Block screenshots option is enabled.

Check rooting deep scan

Performs additional scanning of executable files to look for potential root shells. This scan can potentially detect more threats, but there is also a risk of false positives. The app will consume more battery, and will take longer to launch.

This option enables the FILESYSTEM_SCANNING callback, but this can take anywhere from a few seconds to multiple minutes, depending on the device. See FilesystemScanningData for more information on FILESYSTEM_SCANNING.

Enabling this option is only recommended for fraud-detection or reporting via callback rather than for strict enforcement of root detection (exitOnRooting).

This option is known to cause false positives on some devices due to anomalies on the device introduced by device vendors.

This option is also known to emergency reboot older devices where the battery cannot provide enough power for the duration of the scanning operation. Because of this, the option has been limited to devices running Android 4.2 (API level 17) and above.

Exit on rooting

Determines whether to exit the app when the device is rooted.

Exit on rooting heuristics threshold

The threshold value to use for heuristics detection to determine if the device is rooted. If App Shielding is sure that the device is rooted, and Exit on rooting is set, the app will shut down.

Otherwise, rooting can be detected using heuristics. This will give a probability value between 5% and 95%. If this option is not specified or set to 0, App Shielding will not shut down the app based on the heuristics detection. If the value is greater than 0, it will be interpreted as a threshold. If the calculated heuristics value is equal to or greater than the threshold, the app will be shut down (provided that Exit on rooting is set).

Depends on: Exit on rooting

Exit on rooting URL

Depends on: Exit on rooting

Exit on hooking frameworks

Determine whether or not to exit the app if a hooking framework or Java-level hooks are detected.

Depends on: Check hooking frameworks

Exit on hooking frameworks URL

Depends on: Exit on hooking frameworks

Check untrusted installer

Checks if any application on the device has been installed via unknown and/r untrusted sources .

This option can only be enabled when the Query All Packages permission is set!

Check untrusted installer mode

The configuration for the untrusted installer check.

Set one of the following values:

  • all: Check all the apps that are installed on the device.
  • sideloaded-apps-only: check only the apps that are sideloaded (installed via ADB)

Depends on the setting of Query All Packages Permission and checkUntrustedInstaller!

Exit on untrusted installer

Determines whether to exit the app when one or more untrusted source applications are installed on the device.

Depends on: Check untrusted installer

Exit on untrusted installer URL

If Exit on untrusted installer is used, a web browser can be started with a preconfigured URL to explain the problem to the user. If no URL is configured, then the browser is not invoked.

Depends on: Exit on untrusted installer

Additional Trusted Installer Signatures

This option allows adding the signing certificate of a trusted app store to an allowlist when the Check untrusted installeroption is enabled.

With this option, you can add multiple certificates to include multiple app stores to the allowlist.

Add each certificate in a new line of this input field to allow multiple app stores!

Depends on: Check untrusted installer

Process Name Cloak Determines how App Shielding cloaks the process name fo the app. On starting a shielded app, App Shielding cloaks the application ID in /proc/seld/cmdline by selecting a random name from a list. This makes it harder for an attacker to automatically detect your application.
Application signer certificate

This option provides the certificate used to sign the app.

Use original certificate

Insert the original certificate, if the original application is already signed.

AliPay support This option helps to prevent the application from terminating unexpectedly which may happen when AliPay is used. This option should be enabled to support AliPay in such situations.
Flutter Webview Support

This option provides support to add WebView in Flutter.

When you enable this option, the Block Screenshots option must be disabled!

Check app in virtual space

Checks if the application is launched via a virtual space app. If this option is enabled, App Shielding will detect if the application was launched as a copy inside applications such as Parallel Space, Dual Space, or similar.

Exit on app in virtual space

Determines whether to exit the app when the application is launched via a virtual space app.

Depends on: Check app in virtual space

Exit on app in virtual space URL

Depends on: Exit on app in virtual space

Allow work profile and device vendor virtual spaces

Allow virtual spaces and work profiles or managed devices provided by device vendors such as Google Workspace, Samsung Secure Folder, Xiaomi Dual Apps, Microsoft Workspace, etc.

For more information, see the entry for the Check app in virtual space option in this table.

Depends on: Check app in virtual space

Trusted Virtual Space App Signatures

This option allows adding the signing certificate of a trusted virtual space app to an allowlist. With this, App Shielding accepts all virtual space apps signed with this certificate.

You can add multiple certificates with the Trusted Virtual Space App Signatures option to include multiple apps to the allowlist.

Add each certificate in a new line of this input field to allow multiple applications!

Depends on: Check app in virtual space

Check adb status

Checks if adb is active on the device.

Exit when adb enabled

Determines whether to exit the app if adb is enabled on the device.

Depends on: Check adb status

Exit when adb enabled URL

If Exit when adb enabled is used, a web browser can be started with a preconfigured URL to explain the problem to the user. If no URL is configured, then the browser is not invoked.

For more information, see Exit URL Launching.

Depends on: Exit when adb enabled

Exit on Java debugger URL

If Exit on debugger is used, a web browser can be started with a preconfigured URL to explain the problem to the user. If no URL is configured, then the browser is not invoked.

Depends on: Exit on debugger

Check developer options

Checks if Developer Options is enabled on the device.

Exit when developer options enabled

Determines whether to exit the app if Developer Options is enabled.

Depends on: Check developer options

Exit when developer options enabled URL

If Exit when developer options enabled is used, a web browser can be started with a preconfigured URL to explain the problem to the user. If no URL is configured, then the browser is not invoked.

Depends on: Check developer options

Block emulated input

With this option, you can block emulated input from being injected into the screen. If you enable this feature, App Shielding checks if input is emulated or physical.

When you enable Block emulated input, the portal displays the Emulated input threshold field where you can enter a number. The recommended value for this threshold is between 25 and 30. By default, this value is set to 30.

Depends on: Check rooting, Check trusted screenreaders, Check adb status.

Check screen mirroring

Checks for external screens, or screen mirroring such as ChromeCast, MiraCast, AllShare Cast, Samsung Smart View, and others. Screen mirroring and detection of screen mirroring is available for Android 4.2 (API level 17) and later.

Block screen mirroring

Block external screens by drawing an empty view or a customized layout on the secondary displays (see App Shielding screen mirroring). The Check screen mirroring option must be enabled for block screen mirroring to work. When active mirroring is detected, the blocking functionality prevents screen rotation and thus flickering for the duration of the rotation. This flickering would otherwise show the original screen on the projected display.

Depends on: Check screen mirroring

Additional Display Name

This setting allows adding a trusted display by entering one or several additional display names in this input field to avoid false positive screen mirroring or screen sharing detection.

By default, this field is empty on the Configuration page.

Check trusted keyboard

Checks if the currently used software keyboard is trusted. By default, all system installed keyboards are trusted. It is possible to add specific trusted third-party keyboards using the Additional trusted keyboard signatures option.

Exit on untrusted keyboard

Determines whether to exit the app when the currently used software keyboard is untrusted.

Depends on: Check trusted keyboard

Exit on untrusted keyboard URL

Depends on: Exit on untrusted keyboard

Additional trusted keyboard signatures

With this option you can add the signing certificate of a trusted software keyboard to an allowlist. All keyboards signed with this certificate would then be accepted by App Shielding. You can add multiple trusted keyboards to the allowlist.

Add each signature in a new line of this input field to add multiple signatures!

Depends on: Check trusted keyboard

Please contact OneSpan ([email protected]) if you need to validate the values for this option.

Check trusted screen readers

Checks if any currently active screen readers are trusted. If this option is enabled, any screen readers that are installed but not used will not be considered. It is possible to add trusted third-party screen readers to an allowlist by using the Trusted screenreaders option.

Block untrusted screen readers

Blocks screenreaders if a currently active untrusted screen reader is found. Blocking works in two scenarios:

  • An untrusted screenreader is activated, then the protected application is started. In this case, App Shielding blocks all screenreaders on startup.
  • The protected application is started and the user switches to settings, activates the untrusted screenreader, then switches back to the application. In this case, App Shielding notices activation of the screenreader and also blocks screen readers.

If an untrusted screenreader is detected, all screenreaders will be blocked because it is impossible to block screenreaders selectively.

Depends on: Trusted screenreaders

Exit on untrusted screen readers

Determine whether to exit the app when one or more of the active screen readers are untrusted.

Depends on: Check trusted screen readers

Exit on untrusted screen readers URL

Depends on: Exit on untrusted screen readers

Additional trusted screen reader signatures

Hash of the certificate of a trusted screen reader's signatures.

Depends on: Check trusted screen readers

Please contact OneSpan ([email protected]) if you need to validate the values for this option.

Shutdown immediately

Determine whether to exit the app immediately when a security policy problem is detected.

Advanced debug guard

Executes security checks to ensure authenticity of the App Shielding guard component. If enabled, App Shielding sends secret commands to the guard component and expects predefined results. It prevents usage of third party debuggers, even if the guard component is circumvented.

This option might have a negative effect on performance during runtime.

Shielding options
Disable push binding

Limits the push binding that is performed upon application startup. This option speeds up the application startup, however it also reduces the security provided by Mobile Application Shielding.

When using this option, only one shielding method is used (pull binding), and thus less data can be bound. Use this option only, if the number of push bindings is very high, and if it slows down the application startup.

Limit binding on classes

Reduce the number of bindings per class to a minimum. This stops extraction after the first class binding has been extracted. This option speeds up the application startup, however it also reduces the security provided by Mobile Application Shielding.

When using this option, less data can be bound. Use this option only if the number of bindings is very high and it slows down the application startup.

Limit binding on methods

Reduce the number of bindings per method to a minimum. This stops binding extraction inside a specific method after a binding has already been extracted. This option speeds up the application startup, however it also reduces the security provided by Mobile Application Shielding.

Enabling Limit binding on classes also implies that Limit binding on methods is enabled.

When using this option, less data can be bound. Use this option only if the number of bindings is very high and it slows down the application startup.

Updatable configuration
Updatable configuration

Specify whether the app will use the Automatic Configuration feature.

 
Debug

Specify whether shielding must be done in debug mode. Several security features are disabled in debug mode to ease the testing of the app during the development.

This option must be disabled for a production app. When this option is enabled, the shielded APK is configured in debug mode (i.e. android:testOnly="true" in AndroidManifest.xml). The allow test packages option (i.e. -t) must be used when installing the APK via ADB to avoid the error INSTALL_FAILED_TEST_ONLY (e.g. adb install -t myapp.apk).

 
Add support of architectures automatically If you enable this feature, App Shielding will try to determine the supported architectures by searching for native libraries present in the application.

QUERY_ALL_PACKAGES permission

With the declaration of the Query All Packages permission configuration option, Google restricts apps and packages from viewing other apps / packages installed on an Android device.

As of July 2022, Google Play has restricted the use of privacy sensitive Android permissions, such as QUERY_ALL_PACKAGES, for all new apps or app updates submitted.

An app with this permission can see and access details of all other installed apps on the device.

App Shielding does not require this permission by default, however, one feature — checkUntrustedInstaller — requires the QUERY_ALL_PACKAGES permission to work correctly.

The checkUntrustedInstaller configuration option is intended to be used for apps that require PCI compliance. When this feature is enabled, App Shielding will check if any apps are either side-loaded or installed from non-trusted app sources. This check is performed inside the app, and fundamentally depends on the QUERY_ALL_PACKAGES permission in order to work.

If an application needs to use the QUERY_ALL_PACKAGES permission, or otherwise requires the checkUntrustedInstaller configuration option to be enabled, then the application owner needs to use the Declaration Form in Google Play Console to get acceptance for using this permission.

If the application owner does not submit a declaration form, or if the permission has not been granted, any app updates may be rejected, or the application may be removed from Google Play.

The Shielding Tool normally enables required permissions automatically by default. However, the Shielding Tool will only enable QUERY_ALL_PACKAGES if both the queryAllPackagesPermission and checkUntrustedInstaller are enabled.

Only enable the queryAllPackagesPermission configuration option if this has been explicitly granted by Google Play.

Reference links: QUERY_ALL_PACKAGES Permission, Package visibility filtering on Android.

OneSpan strongly recommends reading the reference links before setting this value. If queryAllPackagesPermission is enabled, the Shielding Tool will insert android.permission.QUERY_ALL_PACKAGES permission to AndroidManifest.xml. Enabling the queryAllPackages permission is going to indicate to App Shielding and the Shielding Tool that the permission is granted by Google Play Console.

If the Query All Packages permission is disabled but e.g. the checkUntrustedInstaller check is switched on, the shielding of the application will fail because the checkUntrustedInstaller requires the Query All Packages permission to be enabled. In contrast, if both settings are either enabled or both are disabled, the shielded .apk file can be downloaded from the OneSpan Customer Portal or OneSpan Mobile Portal.

Application signer certificate

This option provides the certificate used to sign and verify the app, and can be configured in this field. When App Shielding verifies the signature of the application, it will then validate if the configured certificate matches.

If this value is not set, or is set incorrectly, then App Shielding will consider the app as repackaged.

This public certificate can be safely extracted from the keystore you will use to sign the app. Upload the certificate in .pem, .der or .cer format. It can be exported from the keystore using the following command:

keytool –keystore $keystore_file –storepass $keystore_password –alias $keyname –exportcert –rfc –file cert.pem

If the original application is already signed, it is possible to insert the original certificate with the Original certificate option.

Shutdown immediately

This option determines whether to exit the app immediately when a security policy problem is detected. If this option is enabled, the app will simply exit as soon as possible. If this option is disabled, an error reporting will be processed, andApp Shielding will throw a Java exception and give the user a 30-second grace period to report the problem to Google Play.

A 30-second grace period gives an attacker a time window to perform an attack on the app, even after the app has shut down. However, shutting down immediately may have some side effects such as Android re-launching the app. This may lead to the app launching and exiting in an infinite loop on most Android devices and should therefore be used with care.

For more information about error reporting, see App Shielding Error Reporting.

Updatable configuration

With this option, you can specify whether the app will use the Automatic Configuration feature.

When you enable this option, the portal displays additional configuration fields:

  • Request timeout (seconds): Specify the duration in seconds before the client device stops connecting to the server and sends a request timeout error.
  • Config Identifier: Identify for which application the configuration update is intended. A configuration update file must contain the identical config identifier as the original configuration for the app, and must be created with the exact same version of App Shielding.

    If not specified or set to an empty string, the config identifier is set to the package ID of the app, which means that any configuration update for the app must be created with the same input app. However, using the config identifier option allows for multiple apps to use a common source for the updatable configuration file.

  • Certificate type: Use this field to upload your server certificate in the .pem file format.
  • URL: Specify the URL of the web page where the configuration can be downloaded. The server must be running with a config.dat file accessible in the destination path.

    It is possible to use substitution variables encoded in the URL, consistent with the substitution variables launching Exit URL. For more information, see URL variable substitution for the updatable configuration.

  • Client Certificate: Upload a TLS client certificate. This must be exported as a base64 string from a pkcs12 file.

    The base64 string can be extracted from the pkcs12 file using this command:

    base64 client_cert.p12 > client_cert.b64
  • Password: Password used to generate the pkcs12 client certificate file.

Launch performance

With very large apps, launch times can suffer from having a very large number of bindings. The purpose of binding is first and foremost to ensure that the app cannot be decoupled from App Shielding to run the app in a less secure manner. However, after a certain point of adding bindings, no real value or benefit is added from a security point of view.

If the app becomes too slow during launch, the following options can be explored to reduce the number of bindings extracted:

  • Limit binding on classes
  • Limit binding on methods
  • Disable push binding

The options to limit bindings per class and method minimize the number of bindings per class and method, respectively, ensuring that there is at least one such binding. This will reduce the number of bindings significantly for most apps, and at the same time retain a good distribution of bindings.

The downside of using these options is that constants such as strings are not as aggressively removed from the code, which reduces the obfuscation side-effect of binding.

Configuration of Shielding Tool rules

You can specify a rules list in the App Shielding configuration. This list determines how App Shielding will modify the Android application, especially with regards to shielding and obfuscation.

Find below information about how the rules list can be used to match classes, fields, and methods to resolve issues with shielding or obfuscation.

Syntax

class_op+ [[!]@annotation] [[!]access] [[!]flag]* [[!]class_spec] class_name [[!]extension class_name] (; | {
  [member_op]* [[!]@annotation] [[!]access] [[!]flag]* [member_type]
  [return_type] member_name [method_arguments];
})

You can specify as many rules as needed, and the rules are matched from top to bottom.

When configuring rules, you can use one line per rule, or, for better readability, you can use multiple lines for one rule.

 

# Comment
class_operation [[!]access] [!]class_spec class_name [[!]extension class_name] (; | {
[[!]access] [[!]class_mod] member type name;
})
set_operation name value;
firstdex class_name;
verify regex;

Definitions

The following tables list the commands to be used in a rules list.

List of class_operation options
class_operation (class_op) opposite of Description
match - Select classes or members for some operation.
bind untouchable, unbind Select classes or members to bind or exclude from binding.
scrambleStrings keepStrings Select classes or members in which to scramble constant string values.
obfuscate preserve Select classes or members to obfuscate or exclude from obfuscation.
removeAnnotation keepAnnotation Select classes or members from which to remove annotations.
removeDebug keepDebug Select classes or members from which to remove debug information.
removeLines keepLines Select classes or members from which to remove line numbers.
removeSourceFile keepSourceFile Select classes from which to remove the source file name.
firstdex secondarydex Select classes to include in the first (or secondary) classes.dex.
List of member_operation options
member_operation (member_op) opposite of Description
match - Select members for some operation.
bind untouchable, unbind Select members to bind or exclude from binding.
scrambleStrings keepStrings Select classes or members in which to scramble constant string values.
obfuscate preserve Select members to obfuscate or exclude from obfuscation.
removeAnnotation keepAnnotation Select classes or members from which to remove annotations.
removeDebug keepDebug Select members from which to remove debug information.
removeLines keepLines Select members from which to remove line numbers.
List of class and member definitions
Element Description Supports wildcards Can be negated
@annotation Optional. A qualified class name, e.g. @com.example.myannotation.
access

Optional. Possible values:

  • public
  • private
  • protected
 
flag

Optional. Possible values:

  • static
  • abstract
  • final
  • native

Multiple choices are allowed.

 
class_spec

Optional. Possible values:

  • class
  • enum
  • interface
 
class_name Mandatory. The fully qualified name of the Java class.  
extension

Optional. Possible values:

  • extends
  • implements

Must be followed by class_name.

 
member_type

Optional. Possible values:

  • method
  • field
   
return_value Optional. Primitive type or fully-qualified name of a Java class.  
member_name

Mandatory. The name of the class field(s) and/or method(s).

The following additional matchers are available:

  • <any>,<members> match any/all fields and methods.
  • <fields> matches all fields.
  • <methods> matches all methods.
 
value Optional. A double-quote string, any integer or Boolean (true or false).    
method_arguments

Optional. Comma-separated list of arguments in class_name format in brackets, e.g. (class_name, class_name)

To be used for method identification only. Use (...) to match methods with at least 1 argument (any type).

 

Specification

Negating

For the rules, most class specifiers can be negated by adding an exclamation mark in front of them.

Wildcards

Wildcards can be used as follows:

  • * matches zero or more characters.
  • + matches one or more characters.
  • ? matches exactly one character.

*Test matches MyTestOne and Test but not TestTwo.

Comments

Comments are prefixed with #.

Binding

Using the untouchable or unbind operation will ensure that a matching class, method, or field will not be affected when values are removed during the binding operation. Optionally, the bind operation asks the Shielding Tool to include the specific value in the binding process (which would most likely bind the value regardless).

After shielding, the performance of the application can be impacted at startup. In this case, exclusion options can be defined to reduce the impact of shielding on the application.

The security provided by App Shielding is reduced by excluding classes from the shielding process. The number of bindings must be high enough to ensure security requirements (more than 2,000 push/pull bindings).

Since certain parts of the app code need to run for App Shielding to be launched, the shielding process will automatically trace and mark the relevant parts as untouchable: they cannot be modified in any way.

By default, the <clinit> class initializers, all variables, and method calls called from these are marked as untouchable. In some cases, however, tracing is not possible because the method call flow cannot be determined. Issues may occur especially with code reflection or provider classes in the Android manifest.

For these cases, a generic way to exclude classes and methods in a declarative manner is available so that the shielding process will not modify them in any way by marking them as untouchable.

String scrambling

Using the keepStrings operation will ensure that a matching class, method, or field will not be affected by the string scrambling operation. Optionally, the scrambleStrings operation asks the Shielding Tool to scramble string values.If both bind and scrambleStrings are enabled for a class or method, some constants are used for push and pull binding, and the remaining constants are used for string scambling.

Obfuscation

Using the preserve operation will ensure that a matching class, method, or field will not be affected when renamed as part of the obfuscation process.

Enabling obfuscation is not a mere ON / OFF feature. Rules must be configured manually. The effort to fine-tune the configuration is comparable to the one required to fine-tune similar commercially available obfuscation tools.

Repackaging checks

App Shielding checks at the start of the application if the application is repackaged. The repackaging check consists of three parts:

  • Check that all expected files are present, that is, no file was removed.
  • Check that no unexpected file was added to the apk.
  • Verify the file integrity of a few selected files, that is, verify that the content of the file was not modified.

If the repackaging check fails, App Shielding reports the app as repackaged.

By default, all files that are present in the application when integrating App Shielding are expected, although there are a few well known exceptions. For example, Google Play inserts some files on converting an app bundle to an apk before the apk is installed.

By default, App Shielding verifies the file integrity of:

  • AndroidManifest.xml
  • classesX.dex
  • the App Shielding library.

For more information about repackaging, see Repackaging detection.

 

# Verify a single file
verify "assets/my-asset.bin";
# Verify all files in the assets folder
verify "^assets/.*";
# Verify all HTML/JS in the assets folder
verify "^assets/(.+)\.(html|js)$";
# Verify all files inside the APK
verify ".*";

By default, not all application files are specifically checked at startup for possible application launch time performance considerations. Integrity checks of large files may cause noticeably longer launch times.

Amazon App Store and repackaging checks

Amazon App Store will modify your application’s files. For all applications, Amazon App Store will also inject some code and files into the application, which for most applications also shuffles the classes in the apps' classesX.dex files. Since this modification would trigger the default repackaging checks of App Shielding, the file integrity checking must be tuned for apps published on Amazon App Store.

Due to the changes, the file integrity checking for Amazon App Store must be tuned for Amazon App Store.

The Shielding Tool has a built-in rules file, builtin:amazon-app-store-support.cfg, for the Amazon App Store. To use the file, you must use the following in your rules file:

include "builtin:amazon-app-store-support.cfg";

These rules will skip the classesX.dex files and the files that are known to be injected by Amazon App Store. The content of builtin:amazon-app-store-support.cfg:

# Amazon App Store modifies classes.dex, all the classesX.dex files must be skipped
skipVerifyPath "classes*.dex";

# Amazon App Store injects these files
skipVerifyPath "com.amazon.*";
skipVerifyPath "kiwi";

Rule examples

Class-level rule

  • No values from MyClass will be removed:

    untouchable class com.example.MyClass;
  • No values from any class inside the com.example.* package will be removed:

    untouchable class com.example.*;
  • No class that implements MyInterface will be modified:

    untouchable class * implements com.example.MyInterface;
  • No class that (immediately) derives from MyBaseClass will be modified:

    untouchable class * extends com.example.MyBaseClass;

Method-level rule

  • This rule only matches the public static method getValue that returns int within MyClass:

    untouchable class com.example.MyClass
    {
      public static method int getValue;
    }
  • This method matches any public method called getValue and setValue in any class that implements SomeInterface. All other methods in these classes can still be modified:

    untouchable class * implements SomeInterface
    {
      public method * getValue;
      public method void setValue;
    }
  • To match a constructor, it must be added as a regular method <init> with a void return value:

    untouchable class * implements SomeInterface
    {
      public method * getValue;
      public method void setValue;
    }

Troubleshooting

To identify issues in cases where the application cannot be started after successful application wrapping, you need to disable all bindings and obfuscation.

This can be achieved by creating new exclusion rules, to which you need to add the following:

  1. # disable all bindings
  2. untouchable class *;

These lines will ensure that no bindings are created for any parts of the application.

Update your configuration to disable obfuscation. This version of the shielded application should work with these settings, since App Shielding has made very few changes to the application.

At this point you can try re-enabling features one by one.

  1. Re-enable bindings gradually (see Troubleshooting the shielding of an app). This can be somewhat time consuming in certain cases.
  2. (Optional) Enable full app obfuscation if you wish to obfuscate the entire app.

The effort needed to enable obfuscation is not fully automatic, and is comparable to the effort needed when integrating ProGuard and other similar code shrinking and obfuscation tools.

Troubleshooting the shielding of an app

This section provides an overview of classes you may need to exclude from the binding process if you experience issues (e.g. the application does not start properly).

  • If the application terminates unexpectedly during startup, it may be useful to attempt to run the application without any form of binding first. This can be done by adapting the exclusion list and adding a line that excludes all classes:

    untouchable *;

    If the application can be started, try to identify the class, method, or field that is causing the problem.

  • In the event of general binding problems, you will get an exception and stack trace in the log. This message may vary significantly from case to case, depending on the cause, but always includes ClassNotFoundException.

    D/dalvikvm( 6367): Added shared lib 
    /data/data/com.example.mytestapp/files/libshield.png 0 ← x4273ffb0

    In this case, App Shielding is loaded as a library by the runtime, and the process ID is 6367.

    Now, you need to locate messages related to the same process ID, for example:

    W/dalvikvm( 6367): Exception Ljava/lang/NullPointerException; thrown while
    initializing ← Lcom/example/mytestapp/BadClass;
    I/dalvikvm( 6367): Rejecting re-init on previously-failed class
    Lcom/example/mytestapp/ ← BadClass; v=0x0

    From this message, it is clear that Dalvik attempted to initialize the class BadClass, but failed due to a NullPointerException.

    To resolve this, add the following rule to the rules list:

    untouchable class com.example.mytestapp.BadClass;

    Now, you can re-wrap the application.

To configure App Shielding for your applications, select the options on the Configuration Page of the OneSpan Customer Portal as needed.

Debug your configuration

You can run your configuration in debug mode. Several security features are disabled in this mode to ease the testing of the app during development.

Debug mode must be disabled for a production app! When enabled, the shielded apk or aab is configured in debug mode (i.e. android:testOnly="true" in AndroidManifest.xml). The allow test packages option (i.e. -t) must be used when installing the apk or aab via adbto avoid the INSTALL_FAILED_TEST_ONLY error (e.g. adb install -t myapp.apk).

Configuration options for Android

Configuration options
Option Description
Query All Packages Permission
Query All Packages Permission

Applications which are compiled for Android 11 and later (compileSdkVersion) have to declare the configuration option queryAllPackagesPermission.

For more information, see QUERY_ALL_PACKAGES permission.

Obfuscation & Rules
Default Obfuscate

Specifies whether to obfuscate the entire app. If this option is not enabled, nothing will be obfuscated. By default, only App Shielding-related classes are obfuscated.

You can customize this setting by enabling the Rules.cfg option. If you enable the Default Obfuscate feature, the Rules.cfg toggle switch is not displayed.

Rules.cfg

You can customize the settings for obfuscation by defining rules in the Rules.cfg file. This determines how App Shielding will modify the Android application, especially in the context of shielding and obfuscation (see Configuration of Shielding Tool rules).

This feature is only available if Default Obfuscate is disabled.

Screenshots
Block screenshots

Determines whether to prevent that screenshots of the app are taken. Screenshots can only be blocked on Android version 4.4 and later. This protection applies to both user and system screenshots. System screenshots are automatically taken when recently used applications are listed.

You can also exclude an activity from this block if your app wants the users to take a screenshot, for instance to verify payments, receipts etc.

Exclude an activity with the Shielding Tool rule allowScreenshotsForActivity:

Add an allowScreenshotsForActivity rule to .my-rules.cfg to tell App Shielding to allow screenshots if the specified activity is visible, even if the Block screenshots option is enabled.

Rooting
Check rooting Checks if the device on which the app runs is rooted.
Check rooting deep scan

Performs additional scanning of executable files to look for potential root shells. This scan can potentially detect more threats, but there is also a risk of false positives. The app will consume more battery, and will take longer to launch.

This option enables the FILESYSTEM_SCANNING callback, but this can take anywhere from a few seconds to multiple minutes, depending on the device. See FilesystemScanningData for more information on FILESYSTEM_SCANNING.

Enabling this option is only recommended for fraud-detection or reporting via callback rather than for strict enforcement of root detection (exitOnRooting).

This option is known to cause false positives on some devices due to anomalies on the device introduced by device vendors.

This option is also known to emergency reboot older devices where the battery cannot provide enough power for the duration of the scanning operation. Because of this, the option has been limited to devices running Android 4.2 (API level 17) and above.

Exit on rooting

Determines whether to exit the app when the device is rooted.

Exit on rooting heuristics threshold

Rooting can be detected by calculating a rooting heuristics threshold. With this option you determine whether to exit the application when the configured setting and underlying threshold value is reached. If App Shielding is sure that the device is rooted, and the Exit on rooting option is enabled, the application will shut down.

Possible values:

  • Very restrictive
  • Restrictive
  • Medium
  • Permissive

If this option is not set or set to Permissive, App Shielding will not shut down the application based on the heuristics detection.

The default setting is Restrictive.

Depends on: Exit on rooting

Exit on rooting URL

The URL of a web page with an explanation to launch when the app is shut down because it runs on a rooted device.

For more information, see Exit URL Launching.

Depends on: Exit on rooting

Hooking Frameworks

Check hooking frameworks

Check the app for Java-level code hooks created by hooking tools and frameworks. For more information see Code injection protection.
Exit on hooking frameworks

Determine whether to exit the app if a hooking framework or Java-level hooks are detected.

Depends on: Check hooking frameworks

Exit on hooking frameworks URL

The URL of a web page with an explanation to launch when the app is shut down because a Java-level or hooking framework or was detected.

For more information, see Exit URL Launching.

Depends on: Exit on hooking frameworks

Native Code Hooks
Check native code hooks

Checks if there are hooks in the native code.

Exit on native code hooks

Determines whether to exit the app when there are hooks in the native code.

In production versions of App Shielding this option is always enabled and cannot be disabled.

Exit on native code hooks URL

The URL of a web page with an explanation to launch when the app is shut because a native code hook was detected.

For more information, see Exit URL Launching.

Depends on: Exit on native code hooks

Repackaging
Check repackaging

Checks if the app was repackaged. You also need to set the Application Signer Certificate option to configure this check.

Depends on: Application Signer Certificate

Exit on repackaging

Determines whether to exit the app when it was repackaged.

In production versions of App Shielding this option is always enabled and cannot be disabled.

Untrusted installer
Check untrusted installer

Checks if any application on the device has been installed via unknown and/r untrusted sources .

This option can only be enabled when the Query All Packages permission is set!

Exit on untrusted installer

Determines whether to exit the app when one or more untrusted source applications are installed on the device.

Depends on: Check untrusted installer

Exit on untrusted installer URL

The URL of a web page with an explanation to launch when the application is shut down because an untrusted source application was detected.

For more information, see Exit URL Launching.

Depends on: Exit on untrusted installer

Check untrusted installer mode

The configuration for the untrusted installer check.

Set one of the following values:

  • all: Check all the apps that are installed on the device.
  • sideloaded-apps-only: check only the apps that are sideloaded (installed via ADB)

Depends on the setting of Query All Packages Permission and checkUntrustedInstaller!

Additional Trusted Installer Signatures

This option allows adding the signing certificate of a trusted app store to an allowlist when the Check untrusted installeroption is enabled.

With this option, you can add multiple certificates to include multiple app stores to the allowlist.

Add each certificate in a new line of this input field to allow multiple app stores!

Depends on: Check untrusted installer

Process Name Cloak Determines how App Shielding cloaks the process name fo the app. On starting a shielded app, App Shielding cloaks the application ID in /proc/seld/cmdline by selecting a random name from a list. This makes it harder for an attacker to automatically detect your application.
Application Signer Certificate
Application signer certificate

This option provides the certificate used to sign the app.

This option is not compatible with the Updatable configuration option.

For more information, see Application signer certificate.

Original certificate

Insert the original certificate, if the original application is already signed.

AliPay Support This option helps to prevent the application from terminating unexpectedly which may happen when AliPay is used. This option should be enabled to support AliPay in such situations.
Flutter Webview Support

This option provides support to add WebView in Flutter.

When you enable this option, the Block screenshots option must be disabled!

App in Virtual Space
Check app in virtual space

Checks if the application is launched via a virtual space app. If this option is enabled, App Shielding will detect if the application was launched as a copy inside applications such as Parallel Space, Dual Space, or similar.

Exit on app in virtual space

Determines whether to exit the app when the application is launched via a virtual space app.

Depends on: Check app in virtual space

Exit on app in virtual space URL

The URL of a web page with an explanation to launch when the application is shut down because it was launched via a virtual space app.

For more information, see Exit URL Launching.

Depends on: Exit on app in virtual space

Allow work profile and device vendor virtual spaces

Allow virtual spaces and work profiles or managed devices provided by device vendors such as Google Workspace, Samsung Secure Folder, Xiaomi Dual Apps, Microsoft Workspace, etc.

For more information, see the entry for the Check app in virtual space option in this table.

Depends on: Check app in virtual space

Trusted Virtual Space App Signatures

This option allows adding the signing certificate of a trusted virtual space app to an allowlist. With this, App Shielding accepts all virtual space apps signed with this certificate.

You can add multiple certificates with the Trusted Virtual Space App Signatures option to include multiple apps to the allowlist.

Add each certificate in a new line of this input field to allow multiple applications!

Depends on: Check app in virtual space

Android Debug Bridge
Check adb status

Checks if adb is active on the device.

Exit when adb enabled

Determines whether to exit the app if adb is enabled on the device.

Depends on: Check adb status

Exit when adb enabled URL

The URL of a web page with an explanation to launch when the application is shut down because adb is enabled on the device.

For more information, see Exit URL Launching.

Depends on: Exit when adb enabled

Java Debugger
Block Java debugger

Block Java debuggers from attaching to the app. During development, this setting may cause development tools to behave in unexpected ways, and this option should only be used for production builds (release versions).

In production versions of App Shielding this option is always enabled and cannot be disabled.

Check Java debugger

Checks if a Java-level debugger is attached to the application. We recommend also using the Block Java debugger option, as this will already prevent any debuggers from attaching to the application's process. This feature may be useful in cases where blocking the Java debugger interface fails.

Exit on Java debugger Enable to exit the application when a debugger is attached. If the Block Java Debugger option is enabled, this is unlikely, but can happen if the Android system is modified or otherwise incompatible with the current blocking mecha nism.
Exit on Java debugger URL

The URL of a web page with an explanation to launch when the application is shut down because a debugger has been detected.

For more information, see Exit URL Launching.

Depends on: Exit on debugger

Developer Options
Check developer options

Checks if Developer Options is enabled on the device.

Exit when developer options enabled

Determines whether to exit the app if Developer Options is enabled.

Depends on: Check developer options

Exit when developer options enabled URL

The URL of a web page with an explanation to launch when the application is shut down because Developer Options is enabled on the device.

For more information, see Exit URL Launching.

Depends on: Check developer options

Emulator
Check emulator Check if the application is run in an emulator, the official Android SDK emulators, or typical virtualization environments.
Exit on emulator Determines whether to exit the app when it is running in an emulator.
Exit on emulator URL

The URL of a web page with an explanation to launch when the application is shut down becausethe app is run in an emulator.

For more information, see Exit URL Launching.

Depends on: Exit on emulator

Emulated Input
Block emulated input

Block emulated inputs that are injected into the screen. If you enable this feature, App Shielding checks if input is emulated or physical.

This option will block input from all sources except physical input.

When you enable Block emulated input, the portal displays the Emulated input threshold field where you can enter a number. The recommended value for this threshold is between 25 and 30. By default, this value is set to 30.

Depends on: Check rooting, Check trusted screenreaders, Check adb status.

For more information, see Block emulated input.

Emulated input threshold App Shielding assigns a score value for each input to determine if the input is emulated. Any input scores above this threshold will be considered as emulated. The recommended threshold is between 25 and 30. When you enable the Block emulated input option, the OneSpan Mobile Portal displays this field, and you can enter the required number. By default, this is set to 30.
Screen mirroring
Check screen mirroring

Checks for external screens, or screen mirroring such as ChromeCast, MiraCast, AllShare Cast, Samsung Smart View, and others. Screen mirroring and detection of screen mirroring is available for Android 4.2 (API level 17) and later.

Block screen mirroring

Block external screens by drawing an empty view or a customized layout on the secondary displays (see App Shielding screen mirroring). The Check screen mirroring option must be enabled for block screen mirroring to work. When active mirroring is detected, the blocking functionality prevents screen rotation and thus flickering for the duration of the rotation. This flickering would otherwise show the original screen on the projected display.

Depends on: Check screen mirroring

Additional Display Name

This setting allows adding a trusted display by entering one or several additional display names in this input field to avoid false positive screen mirroring or screen sharing detection.

By default, this field is empty on the Configuration page in the OneSpan Mobile Portal.

Trusted Keyboard
Check trusted keyboard

Checks if the currently used software keyboard is trusted. By default, all system installed keyboards are trusted. It is possible to add specific trusted third-party keyboards using the Additional trusted keyboard signatures option.

Exit on untrusted keyboard

Determines whether to exit the app when the currently used software keyboard is untrusted.

Depends on: Check trusted keyboard

Exit on untrusted keyboard URL

The URL of a web page with an explanation to launch when the application is shut down because an untrusted keyboard has been detected.

For more information, see Exit URL Launching.

Depends on: Exit on untrusted keyboard

Trusted keyboards

With this option you can add the signing certificate of a trusted software keyboard to an allowlist. All keyboards signed with this certificate would then be accepted by App Shielding. You can add multiple trusted keyboards to the allowlist.

Add each signature in a new line of this input field to add multiple signatures!

Depends on: Check trusted keyboard

Please contact OneSpan ([email protected]) if you need to validate the values for this option.

Trusted Screenreaders
Check trusted screenreaders

Checks if any currently active screen readers are trusted. If this option is enabled, any screen readers that are installed but not used will not be considered. It is possible to add trusted third-party screen readers to an allowlist by using the Trusted screenreaders option.

Block untrusted screenreaders

Blocks screenreaders if a currently active untrusted screen reader is found. Blocking works in two scenarios:

  • An untrusted screenreader is activated, then the protected application is started. In this case, App Shielding blocks all screenreaders on startup.
  • The protected application is started and the user switches to settings, activates the untrusted screenreader, then switches back to the application. In this case, App Shielding notices activation of the screenreader and also blocks screen readers.

If an untrusted screenreader is detected, all screenreaders will be blocked because it is impossible to block screenreaders selectively.

Depends on: Trusted screenreaders

Exit on untrusted screenreaders

Determine whether to exit the app when one or more of the active screen readers are untrusted.

Depends on: Check trusted screen readers

Exit on untrusted screenreaders URL

The URL of a web page with an explanation to launch when the application is shut down because an untrusted screen reader has been detected.

For more information, see Exit URL Launching.

Depends on: Exit on untrusted screenreaders

Trusted screenreaders

Hash of the certificate of a trusted screen reader's signatures.

Depends on: Trusted screenreaders

Please contact OneSpan ([email protected]) if you need to validate the values for this option.

Shutdown Immediately

Determine whether to exit the app immediately when a security policy problem is detected.

For more information, see Shutdown immediately.

Advanced debug guard

Executes security checks to ensure authenticity of the App Shielding guard component. If enabled, App Shielding sends secret commands to the guard component and expects predefined results. It prevents usage of third party debuggers, even if the guard component is circumvented.

This option might have a negative effect on performance during runtime.

Binding
Limit binding on classes

Reduce the number of bindings per class to a minimum. This stops extraction after the first class binding has been extracted. This option speeds up the application startup, however it also reduces the security provided by App Shielding.

When using this option, less data can be bound. Use this option only if the number of bindings is very high and it slows down the application startup.

Limit binding on methods

Reduce the number of bindings per method to a minimum. This stops binding extraction inside a specific method after a binding has already been extracted. This option speeds up the application startup, however it also reduces the security provided by App Shielding.

Enabling Limit binding on classes also implies that Limit binding on methods is enabled.

When using this option, less data can be bound. Use this option only if the number of bindings is very high and it slows down the application startup.

Push binding

Limits the push binding that is performed upon application startup. This option speeds up the application startup, however it also reduces the security provided by App Shielding.

When using this option, only one binding method is used (pull binding), and thus less data can be bound. Use this option only, if the number of push bindings is very high, and if it slows down the application startup.

Architecture support
Add support of architectures automatically

If you select Automatic, App Shielding will try to determine the supported architectures by searching for native libraries present in the application.

If no native libraries are present, all platforms will be supported.

Updatable configuration

Determines whether the app will use the Automatic Configuration feature.

When App Shielding has been integrated in existing apps, the Automatic Configuration feature allows you to deploy a new configuration of App Shielding without the need to re-deploy and re-publish the apps through the various app distribution channels.

For more information, see Updatable configuration.

QUERY_ALL_PACKAGES permission

With the declaration of the Query All Packages permission configuration option, Google restricts apps and packages from viewing other apps / packages installed on an Android device.

As of July 2022, Google Play has restricted the use of privacy sensitive Android permissions, such as QUERY_ALL_PACKAGES, for all new apps or app updates submitted.

An app with this permission can see and access details of all other installed apps on the device.

App Shielding does not require this permission by default, however, one feature — checkUntrustedInstaller — requires the QUERY_ALL_PACKAGES permission to work correctly.

The checkUntrustedInstaller configuration option is intended to be used for apps that require PCI compliance. When this feature is enabled, App Shielding will check if any apps are either side-loaded or installed from non-trusted app sources. This check is performed inside the app, and fundamentally depends on the QUERY_ALL_PACKAGES permission in order to work.

If an application needs to use the QUERY_ALL_PACKAGES permission, or otherwise requires the checkUntrustedInstaller configuration option to be enabled, then the application owner needs to use the Declaration Form in Google Play Console to get acceptance for using this permission.

If the application owner does not submit a declaration form, or if the permission has not been granted, any app updates may be rejected, or the application may be removed from Google Play.

The Shielding Tool normally enables required permissions automatically by default. However, the Shielding Tool will only enable QUERY_ALL_PACKAGES if both the queryAllPackagesPermission and checkUntrustedInstaller are enabled.

Only enable the queryAllPackagesPermission configuration option if this has been explicitly granted by Google Play.

Reference links: QUERY_ALL_PACKAGES Permission, Package visibility filtering on Android.

OneSpan strongly recommends reading the reference links before setting this value. If queryAllPackagesPermission is enabled, the Shielding Tool will insert android.permission.QUERY_ALL_PACKAGES permission to AndroidManifest.xml. Enabling the queryAllPackages permission is going to indicate to App Shielding and the Shielding Tool that the permission is granted by Google Play Console.

If the Query All Packages permission is disabled but e.g. the checkUntrustedInstaller check is switched on, the shielding of the application will fail because the checkUntrustedInstaller requires the Query All Packages permission to be enabled. In contrast, if both settings are either enabled or both are disabled, the shielded .apk file can be downloaded from the OneSpan Customer Portal or OneSpan Mobile Portal.

Application signer certificate

This option provides the certificate used to sign and verify the app, and can be configured in this field. When App Shielding verifies the signature of the application, it will then validate if the configured certificate matches.

If this value is not set, or is set incorrectly, then App Shielding will consider the app as repackaged.

This public certificate can be safely extracted from the keystore you will use to sign the app. Upload the certificate in .pem, .der or .cer format. It can be exported from the keystore using the following command:

keytool –keystore $keystore_file –storepass $keystore_password –alias $keyname –exportcert –rfc –file cert.pem

If the original application is already signed, it is possible to insert the original certificate with the Original certificate option.

Shutdown immediately

This option determines whether to exit the app immediately when a security policy problem is detected. If this option is enabled, the app will simply exit as soon as possible. If this option is disabled, an error reporting will be processed, andApp Shielding will throw a Java exception and give the user a 30-second grace period to report the problem to Google Play.

A 30-second grace period gives an attacker a time window to perform an attack on the app, even after the app has shut down. However, shutting down immediately may have some side effects such as Android re-launching the app. This may lead to the app launching and exiting in an infinite loop on most Android devices and should therefore be used with care.

For more information about error reporting, see App Shielding Error Reporting.

Updatable configuration

With this option, you can specify whether the app will use the Automatic Configuration feature.

When you enable this option, the portal displays additional configuration fields:

  • Request timeout (seconds): Specify the duration in seconds before the client device stops connecting to the server and sends a request timeout error.
  • Config Identifier: Identify for which application the configuration update is intended. A configuration update file must contain the identical config identifier as the original configuration for the app, and must be created with the exact same version of App Shielding.

    If not specified or set to an empty string, the config identifier is set to the package ID of the app, which means that any configuration update for the app must be created with the same input app. However, using the config identifier option allows for multiple apps to use a common source for the updatable configuration file.

  • Certificate type: Use this field to upload your server certificate in the .pem file format.
  • URL: Specify the URL of the web page where the configuration can be downloaded. The server must be running with a config.dat file accessible in the destination path.

    It is possible to use substitution variables encoded in the URL, consistent with the substitution variables launching Exit URL. For more information, see URL variable substitution for the updatable configuration.

  • Client Certificate: Upload a TLS client certificate. This must be exported as a base64 string from a pkcs12 file.

    The base64 string can be extracted from the pkcs12 file using this command:

    base64 client_cert.p12 > client_cert.b64
  • Password: Password used to generate the pkcs12 client certificate file.

Launch performance

With very large apps, launch times can suffer from having a very large number of bindings. The purpose of binding is first and foremost to ensure that the app cannot be decoupled from App Shielding to run the app in a less secure manner. However, after a certain point of adding bindings, no real value or benefit is added from a security point of view.

If the app becomes too slow during launch, the following options can be explored to reduce the number of bindings extracted:

  • Limit binding on classes
  • Limit binding on methods
  • Disable push binding

The options to limit bindings per class and method minimize the number of bindings per class and method, respectively, ensuring that there is at least one such binding. This will reduce the number of bindings significantly for most apps, and at the same time retain a good distribution of bindings.

The downside of using these options is that constants such as strings are not as aggressively removed from the code, which reduces the obfuscation side-effect of binding.

Configuration of Shielding Tool rules

You can specify a rules list in the App Shielding configuration. This list determines how App Shielding will modify the Android application, especially with regards to shielding and obfuscation.

Find below information about how the rules list can be used to match classes, fields, and methods to resolve issues with shielding or obfuscation.

Syntax

class_op+ [[!]@annotation] [[!]access] [[!]flag]* [[!]class_spec] class_name [[!]extension class_name] (; | {
  [member_op]* [[!]@annotation] [[!]access] [[!]flag]* [member_type]
  [return_type] member_name [method_arguments];
})

You can specify as many rules as needed, and the rules are matched from top to bottom.

When configuring rules, you can use one line per rule, or, for better readability, you can use multiple lines for one rule.

 

# Comment
class_operation [[!]access] [!]class_spec class_name [[!]extension class_name] (; | {
[[!]access] [[!]class_mod] member type name;
})
set_operation name value;
firstdex class_name;
verify regex;

Definitions

The following tables list the commands to be used in a rules list.

List of class_operation options
class_operation (class_op) opposite of Description
match - Select classes or members for some operation.
bind untouchable, unbind Select classes or members to bind or exclude from binding.
scrambleStrings keepStrings Select classes or members in which to scramble constant string values.
obfuscate preserve Select classes or members to obfuscate or exclude from obfuscation.
removeAnnotation keepAnnotation Select classes or members from which to remove annotations.
removeDebug keepDebug Select classes or members from which to remove debug information.
removeLines keepLines Select classes or members from which to remove line numbers.
removeSourceFile keepSourceFile Select classes from which to remove the source file name.
firstdex secondarydex Select classes to include in the first (or secondary) classes.dex.
List of member_operation options
member_operation (member_op) opposite of Description
match - Select members for some operation.
bind untouchable, unbind Select members to bind or exclude from binding.
scrambleStrings keepStrings Select classes or members in which to scramble constant string values.
obfuscate preserve Select members to obfuscate or exclude from obfuscation.
removeAnnotation keepAnnotation Select classes or members from which to remove annotations.
removeDebug keepDebug Select members from which to remove debug information.
removeLines keepLines Select members from which to remove line numbers.
List of class and member definitions
Element Description Supports wildcards Can be negated
@annotation Optional. A qualified class name, e.g. @com.example.myannotation.
access

Optional. Possible values:

  • public
  • private
  • protected
 
flag

Optional. Possible values:

  • static
  • abstract
  • final
  • native

Multiple choices are allowed.

 
class_spec

Optional. Possible values:

  • class
  • enum
  • interface
 
class_name Mandatory. The fully qualified name of the Java class.  
extension

Optional. Possible values:

  • extends
  • implements

Must be followed by class_name.

 
member_type

Optional. Possible values:

  • method
  • field
   
return_value Optional. Primitive type or fully-qualified name of a Java class.  
member_name

Mandatory. The name of the class field(s) and/or method(s).

The following additional matchers are available:

  • <any>,<members> match any/all fields and methods.
  • <fields> matches all fields.
  • <methods> matches all methods.
 
value Optional. A double-quote string, any integer or Boolean (true or false).    
method_arguments

Optional. Comma-separated list of arguments in class_name format in brackets, e.g. (class_name, class_name)

To be used for method identification only. Use (...) to match methods with at least 1 argument (any type).

 

Specification

Negating

For the rules, most class specifiers can be negated by adding an exclamation mark in front of them.

Wildcards

Wildcards can be used as follows:

  • * matches zero or more characters.
  • + matches one or more characters.
  • ? matches exactly one character.

*Test matches MyTestOne and Test but not TestTwo.

Comments

Comments are prefixed with #.

Binding

Using the untouchable or unbind operation will ensure that a matching class, method, or field will not be affected when values are removed during the binding operation. Optionally, the bind operation asks the Shielding Tool to include the specific value in the binding process (which would most likely bind the value regardless).

After shielding, the performance of the application can be impacted at startup. In this case, exclusion options can be defined to reduce the impact of shielding on the application.

The security provided by App Shielding is reduced by excluding classes from the shielding process. The number of bindings must be high enough to ensure security requirements (more than 2,000 push/pull bindings).

Since certain parts of the app code need to run for App Shielding to be launched, the shielding process will automatically trace and mark the relevant parts as untouchable: they cannot be modified in any way.

By default, the <clinit> class initializers, all variables, and method calls called from these are marked as untouchable. In some cases, however, tracing is not possible because the method call flow cannot be determined. Issues may occur especially with code reflection or provider classes in the Android manifest.

For these cases, a generic way to exclude classes and methods in a declarative manner is available so that the shielding process will not modify them in any way by marking them as untouchable.

String scrambling

Using the keepStrings operation will ensure that a matching class, method, or field will not be affected by the string scrambling operation. Optionally, the scrambleStrings operation asks the Shielding Tool to scramble string values.If both bind and scrambleStrings are enabled for a class or method, some constants are used for push and pull binding, and the remaining constants are used for string scambling.

Obfuscation

Using the preserve operation will ensure that a matching class, method, or field will not be affected when renamed as part of the obfuscation process.

Enabling obfuscation is not a mere ON / OFF feature. Rules must be configured manually. The effort to fine-tune the configuration is comparable to the one required to fine-tune similar commercially available obfuscation tools.

Repackaging checks

App Shielding checks at the start of the application if the application is repackaged. The repackaging check consists of three parts:

  • Check that all expected files are present, that is, no file was removed.
  • Check that no unexpected file was added to the apk.
  • Verify the file integrity of a few selected files, that is, verify that the content of the file was not modified.

If the repackaging check fails, App Shielding reports the app as repackaged.

By default, all files that are present in the application when integrating App Shielding are expected, although there are a few well known exceptions. For example, Google Play inserts some files on converting an app bundle to an apk before the apk is installed.

By default, App Shielding verifies the file integrity of:

  • AndroidManifest.xml
  • classesX.dex
  • the App Shielding library.

For more information about repackaging, see Repackaging detection.

 

# Verify a single file
verify "assets/my-asset.bin";
# Verify all files in the assets folder
verify "^assets/.*";
# Verify all HTML/JS in the assets folder
verify "^assets/(.+)\.(html|js)$";
# Verify all files inside the APK
verify ".*";

By default, not all application files are specifically checked at startup for possible application launch time performance considerations. Integrity checks of large files may cause noticeably longer launch times.

Amazon App Store and repackaging checks

Amazon App Store will modify your application’s files. For all applications, Amazon App Store will also inject some code and files into the application, which for most applications also shuffles the classes in the apps' classesX.dex files. Since this modification would trigger the default repackaging checks of App Shielding, the file integrity checking must be tuned for apps published on Amazon App Store.

Due to the changes, the file integrity checking for Amazon App Store must be tuned for Amazon App Store.

The Shielding Tool has a built-in rules file, builtin:amazon-app-store-support.cfg, for the Amazon App Store. To use the file, you must use the following in your rules file:

include "builtin:amazon-app-store-support.cfg";

These rules will skip the classesX.dex files and the files that are known to be injected by Amazon App Store. The content of builtin:amazon-app-store-support.cfg:

# Amazon App Store modifies classes.dex, all the classesX.dex files must be skipped
skipVerifyPath "classes*.dex";

# Amazon App Store injects these files
skipVerifyPath "com.amazon.*";
skipVerifyPath "kiwi";

Rule examples

Class-level rule

  • No values from MyClass will be removed:

    untouchable class com.example.MyClass;
  • No values from any class inside the com.example.* package will be removed:

    untouchable class com.example.*;
  • No class that implements MyInterface will be modified:

    untouchable class * implements com.example.MyInterface;
  • No class that (immediately) derives from MyBaseClass will be modified:

    untouchable class * extends com.example.MyBaseClass;

Method-level rule

  • This rule only matches the public static method getValue that returns int within MyClass:

    untouchable class com.example.MyClass
    {
      public static method int getValue;
    }
  • This method matches any public method called getValue and setValue in any class that implements SomeInterface. All other methods in these classes can still be modified:

    untouchable class * implements SomeInterface
    {
      public method * getValue;
      public method void setValue;
    }
  • To match a constructor, it must be added as a regular method <init> with a void return value:

    untouchable class * implements SomeInterface
    {
      public method * getValue;
      public method void setValue;
    }

Troubleshooting

To identify issues in cases where the application cannot be started after successful application wrapping, you need to disable all bindings and obfuscation.

This can be achieved by creating new exclusion rules, to which you need to add the following:

  1. # disable all bindings
  2. untouchable class *;

These lines will ensure that no bindings are created for any parts of the application.

Update your configuration to disable obfuscation. This version of the shielded application should work with these settings, since App Shielding has made very few changes to the application.

At this point you can try re-enabling features one by one.

  1. Re-enable bindings gradually (see Troubleshooting the shielding of an app). This can be somewhat time consuming in certain cases.
  2. (Optional) Enable full app obfuscation if you wish to obfuscate the entire app.

The effort needed to enable obfuscation is not fully automatic, and is comparable to the effort needed when integrating ProGuard and other similar code shrinking and obfuscation tools.

Troubleshooting the shielding of an app

This section provides an overview of classes you may need to exclude from the binding process if you experience issues (e.g. the application does not start properly).

  • If the application terminates unexpectedly during startup, it may be useful to attempt to run the application without any form of binding first. This can be done by adapting the exclusion list and adding a line that excludes all classes:

    untouchable *;

    If the application can be started, try to identify the class, method, or field that is causing the problem.

  • In the event of general binding problems, you will get an exception and stack trace in the log. This message may vary significantly from case to case, depending on the cause, but always includes ClassNotFoundException.

    D/dalvikvm( 6367): Added shared lib 
    /data/data/com.example.mytestapp/files/libshield.png 0 ← x4273ffb0

    In this case, App Shielding is loaded as a library by the runtime, and the process ID is 6367.

    Now, you need to locate messages related to the same process ID, for example:

    W/dalvikvm( 6367): Exception Ljava/lang/NullPointerException; thrown while
    initializing ← Lcom/example/mytestapp/BadClass;
    I/dalvikvm( 6367): Rejecting re-init on previously-failed class
    Lcom/example/mytestapp/ ← BadClass; v=0x0

    From this message, it is clear that Dalvik attempted to initialize the class BadClass, but failed due to a NullPointerException.

    To resolve this, add the following rule to the rules list:

    untouchable class com.example.mytestapp.BadClass;

    Now, you can re-wrap the application.