DashO runtime protection checks add detection logic to protected applications. They can identify debugging, debug-enabled environments, Android emulators, runtime hooking, rooted Android devices, expired application builds, and modified application code.
A check can trigger a built-in response immediately, call application code, or store its result so that one or more responses can run elsewhere in the application. You can configure checks in the DashO user interface or with code annotations.
Available runtime protection features
| Feature | What it detects or controls | Applies to |
|---|---|---|
| Debugging | Detects whether the application is actively being debugged. | Java and Android applications |
| Emulator | Detects whether an Android application is running on an emulator. | Android applications and libraries |
| Hook | Detects runtime hooking in an Android application. | Android applications and libraries |
| Root | Detects whether an Android application is running on a rooted device. | Android applications and libraries |
| Tamper | Verifies that application code is signed with an expected certificate. | Signed Java and Android applications |
| Shelf Life | Applies expiration and optional warning logic to an application. | Java and Android applications |
Configure checks
You can configure runtime protection in either of these ways:
- DashO user interface: enable check injection, choose a check type, select injection locations, and configure actions or built-in responses.
- Code annotations: add the corresponding Check or Response annotation to application methods. When Honor Annotations is enabled, DashO combines annotation-based configuration with the checks defined in the project.
For user-interface fields and procedures, see Configure Runtime Protection Checks in DashO.
How checks and responses work
Check: DashO injects detection code into one or more selected methods. When the condition is detected, the check can call a custom action, perform a built-in response, or do both.
Custom action: The check passes a Boolean value to a compatible field or method: true when the condition is detected and false when it is not. Shelf Life is the exception; its action receives a Token object.
Separate response: A response reads the Boolean value stored by a check and acts as configured. Separating detection from reaction makes the protection more difficult to identify and remove.
Built-in responses
| Response | Behavior |
|---|---|
| None | Take no built-in action. Use this when the application handles the result through a custom action. |
| Exit | Exit with a randomized nonzero return code. |
| Hang | Cause the current thread to hang indefinitely. |
| Error | Throw a randomly selected subclass of java.lang.Error. |
| Exception | Throw a randomly selected unchecked subclass of java.lang.Exception. |
Errors and exceptions are thrown with an empty stack trace to conceal their origin. On Android, exit only closes the top Activity on the activity stack. The application closes if there is only one Activity on that stack.
Separate detection from response
To separate a check from its response, configure the check action to write to a Boolean field or call a Boolean-compatible method. Configure one or more matching responses to read that value through their source setting. A response can also use a probability from 0.0 to 1.0; 0.0 never runs the built-in response, and 1.0 always runs it when the source is true.