PreEmptive Protection - DashO v8.1 User Guide

Tamper Checking and Response

PreEmptive Protection - DashO can instrument applications to detect if they have been tampered with and optionally send a message to a PreEmptive Analytics server. Tamper checking requires that your application be signed either by DashO or by another process following instrumentation by DashO. The tamper checking and response are implemented using Coded Annotations or configured via the Tamper Check UI.

Tamper Check

To detect tampering place a TamperCheck on one or more methods in your application. DashO adds code that performs a runtime check that verifies the code has been signed by a particular certificate. If the check fails you can respond to it in one or more ways. You can choose one or all of the following at the time the check is performed:

  • Send a tamper message. A tamper message will be sent to a PreEmptive Analytics server. The message can optionally include custom data. The default is to not send a message. If your application is using analytics and contains an ApplicationStart you need no further configuration. If you are only using TamperChecks then you need to supply the company and application IDs using other annotations or provide them on the Injection Options panel. The message will be sent regardless of any opt-in setting. See PreEmptive Analytics Overview for additional information if injecting instrumentation into an Android application.

  • Call a method or set a field. You can have the tamper state passed back to your application by invoking a method that takes a single boolean or by setting a boolean field. When a tamper check fails the boolean value is true. If the check passes then false is used. Your application can act on this information immediately or store it for later interaction with a TamperResponse. See Specifying Sources and Actions for more information.

  • Perform a response. There are several immediate responses that can be taken:

    • exit – exit the application with a randomly non-zero return code
    • hang – cause the current thread to hang
    • error – throw a randomly selected error
    • exception – throw a randomly selected unchecked exception.
    • none - no action is taken (default)

Note: The randomization of return codes and the selection of a Throwable is performed at time the check is injected not at run time. Errors and exceptions are thrown with an empty stack trace to conceal their origin.

When you select more than one of these actions they are performed in the order listed above. If you do not request any of these, the tamper check will be skipped and DashO will produce a warning message.

An application can contain multiple uses of TamperCheck with various configurations. Using more than one check or mixing the responses will hamper attackers.

private static boolean tamperFlag;

@TamperCheck(sendMessage=true, customDataSource="@myProps", action="@tamperFlag")
public static void main(final String[] args){


private int computeResult(){


Interaction with Signing

The tamper check is performed by verifying at runtime that the code has been signed by a particular certificate. If DashO is used to sign the resulting jars, then no further configuration is required. If the jars are signed by another process, after they have been obfuscated using DashO, you need to tell DashO about the signing information with additional attributes of the TamperCheck. This allows DashO to retrieve the key information required to perform the runtime tamper checking. The information specified is similar to what is found on the Output Signing panel.

@TamperCheck(sendMessage=true, action="@tamperFlag", storepass="${master.psw}", storetype="JKS", alias="ProdKey")
public static void main(final String[] args){


When you use the user interface to enter a password for storepass value and it does not contain property references DashO will store the password in an encrypted form.


If your application uses a custom class loader, make sure it loads the signing certificates.

For Example: In an OSGI (Eclipse Equinox) based application, you must configure It needs to allow at least certificate and you cannot set to false.

If your application utilizes code generation, make sure it works properly with signed jars before adding Tamper Detection. You may need to sign the jars which generate the code with the same certificate.
For Example: In a Spring-based application, you would need to sign spring-core-4.0.1.RELEASE.jar (or a similar jar).

The tamper check for Android requires access to the application's context; it expects a getApplicationContext() method to exist on the class where it is being injected. If you inject the tamper check into class which extends android.context.Context, like,, or, it is fine. If not, you will need to add the getApplicationContext() method and make sure it returns a proper Context. If you plan to send messages and want offline message support, you will also need to exclude the added getApplicationContext() method from renaming.

Tamper Response

Separating the detection and response makes it more difficult for attackers. Having multiple and different responses scattered throughout the application increases the difficulty. Making those responses non-deterministic can make the process maddening. DashO lets you configure your response to a tampered application as simple or as complex as you desire.

The TamperResponse annotation adds code that interacts with a TamperCheck to separate the detection and response code. You can add one or more TamperResponses to your application.

  • The TamperResponse coordinates with the TamperCheck via a boolean value. A value set using the action of the TamperCheck is retrieved with the source of the TamperResponse. If the retrieved value is true then the response is executed. See Specifying Sources and Actions for more information.

Like the TamperCheck the TamperResponse can send a message and/or perform a response. In addition the response action can be made conditional based on a probability factor ranging from 0.0 (never) to 1.0 (always) – the default is 1.0.

private static boolean tamperFlag;

public static void main(final String[] args){


@TamperResponse(source="@tamperFlag", sendMessage=true, customDataSource="customData()")
private void init() {


@TamperResponse(source="@tamperFlag", response=ResponseType.Exit, probability=0.05f)
private int computeResult(){


@TamperResponse(source="@tamperFlag", response=ResponseType.Error, probability=0.1f)
private FileInputStream readInput(){


When you are requesting the sending of analytics messages with TamperResponses you may need to provide some additional configuration information. If your application is using analytics and contains an ApplicationStart you need no further configuration. If you are using TamperResponses that send messages then you need to supply the company and application IDs using other annotations or provide them on the Injection Options panel.

PreEmptive Protection - DashO Version 8.1.0. Copyright © 2017 PreEmptive Solutions, LLC