PreEmptive Protection - DashO v8.1 User Guide

Debug Checks and Responses

PreEmptive Protection - DashO can instrument Java and Android applications to detect if they are being run in a debuggable mode, or if they are being actively debugged. The debugging checks are implemented using Custom Annotations that can be placed in your source code or configured on the Debug Check screen.

Debugging Check

To detect if an application is being debugged, place a DebuggingCheck on one or more methods in your application. DashO adds code that performs a runtime check that determines if it is being debugged. If the check determines it is being debugged you can configure one or more ways to respond to it. You can choose one or both of the following at the time the check is performed:

  • Send a fault message. A fault 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 DebuggingChecks 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 debugging state passed back to your application by invoking a method that takes a single boolean or by setting a boolean field. When a debugging check succeeds (being debugged), the boolean value is true. If the check fails (not being debugged) then false is used. Your application can act on this information immediately or store it for later interaction with a DebuggingResponse annotation. 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 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 debugging check will be skipped and DashO will produce a warning message.

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

private static boolean debuggingFlag;

@DebuggingCheck(sendMessage=true, customDataSource="@myProps", action="@debuggingFlag")
public void onCreate(Bundle check){

}

@DebuggingCheck(response=ResponseType.Hang)
private int computeResult(){

}

Note: On non-Android platforms, if a debugger is attached after the application has started, it will not be detected correctly.

Debugging 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 debugging application as simple or as complex as you desire.

The DebuggingResponse annotation adds code that interacts with a DebuggingCheck to separate the detection and response code. You can add one or more DebuggingResponses to your application.

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

Like DebuggingCheck, DebuggingResponse 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 debuggingFlag;

@DebuggingCheck(sendMessage=true, action="@debuggingFlag")
public void onCreate(Bundle state){

}

@DebuggingResponse(source="@debuggingFlag", sendMessage=true, customDataSource="customData()", response=ResponseType.Exit, probability=0.05f)
private int computeResult(){

}

@DebuggingResponse(source="@debuggingFlag", sendMessage=true, response=ResponseType.Error, probability=0.1f)
private FileInputStream readInput(){

}

Debug Enabled Check

To detect if an app is setup to be debugged, place a DebugEnabledCheck on one or more methods in your application. DashO adds code that performs a runtime check that determines if it is setup to allow debugging. If the check determines it is so setup, you can respond to it in one or more ways. You can choose one or both of the following at the time the check is performed:

  • Send a fault message. A fault 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 DebugEnabledChecks 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 debug enabled state passed back to your application by invoking a method that takes a single boolean or by setting a boolean field. When a debug enabled check succeeds (setup for debugging), the boolean value is true. If the check fails (not setup for debugging) then false is used. Your application can act on this information immediately or store it for later interaction with a DebugEnabledResponse annotation. 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 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 debug enabled check will be skipped and DashO will produce a warning message.

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

private static boolean debuggingFlag;

@DebugEnabledCheck(sendMessage=true, customDataSource="@myProps", action="@debuggingFlag")
public void onCreate(Bundle check){

}

@DebugEnabledCheck(response=ResponseType.Hang)
private int computeResult(){

}

Note: The debug enabled 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 debug enabled check into class which extends android.context.Context, like an Application or Service class, 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.

Debug Enabled 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 debug enabled application as simple or as complex as you desire.

The DebugEnabledResponse annotation adds code that interacts with a DebugEnabledCheck to separate the detection and response code. You can add one or more DebugEnabledResponses to your application.

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

Like the DebugEnabledCheck the DebugEnabledResponse 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 debuggingFlag;

@DebugEnabledCheck(sendMessage=true, action="@debuggingFlag")
public void onCreate(Bundle state){

}

@DebugEnabledResponse(source="@debuggingFlag", sendMessage=true, customDataSource="customData()", response=ResponseType.Exit, probability=0.05f)
private int computeResult(){

}

@DebugEnabledResponse(source="@debuggingFlag", sendMessage=true, response=ResponseType.Error, probability=0.1f)
private FileInputStream readInput(){

}

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