PreEmptive Protection™ DashO™ can inject checks into Android applications or libraries to detect if they are being run on a rooted device. The Root Checks and Responses are configured on the Checks - Root screen or by adding code annotations.
Root Check
To detect if an application is being run on a rooted device, place a RootCheck on one or more methods in your application. DashO adds code that performs several runtime checks that determine if it is being run on a rooted device. This check can be configured as described in the Overview.
An application can contain multiple uses of RootCheck
with various configurations. Using more than one Check or mixing the Responses will hamper attackers.
private static boolean rootedFlag;
@RootCheck(action="@rootedFlag")
public void onCreate(Bundle check){
}
@RootCheck(response=ResponseType.Hang)
private int computeResult(){
}
Notes:
The Root Check for Android requires access to the application's context; it expects agetApplicationContext()
method to exist on the class where it is being injected.Classes extending
android.context.Context
, likeandroid.app.Activity
,android.app.Application
,android.app.Service
, etc. will inheritgetApplicationContext()
, and require no additional changes.Otherwise, you will need to add a
getApplicationContext()
method and make sure it returns a properContext
.Enabling the
QUERY_ALL_PACKAGES
permission improves Root Check detection.You may also need to suppress the
QueryAllPackagesPermission
lint check.Root Checks may also trigger when running on an emulator or unsecured custom ROM.
Google permits using QUERY_ALL_PACKAGES
only for certain circumstances. This is due to the latest update on Developer Program Policy. You can still use Root Check functionality without QUERY_ALL_PACKAGES
.
Root Response
The RootResponse annotation interacts with the RootCheck. This Response can be configured as described in the Overview.
private static boolean rootedFlag;
@RootCheck(action="@rootedFlag")
public void onCreate(Bundle state){
}
@RootResponse(source="@rootedFlag", response=ResponseType.Exit, probability=0.05f)
private int computeResult(){
}
@RootResponse(source="@rootedFlag", response=ResponseType.Error, probability=0.1f)
private FileInputStream readInput(){
}