Runtime Tampering Detection

Runtime tampering (also called dynamic instrumentation) refers to techniques that allow an attacker to inspect and modify the behavior of a running app without altering its binary. Various tools and hooking frameworks can attach to a live process and intercept or replace method calls, read memory, or alter application logic at runtime. Detecting these tools is a key RASP feature because their presence in a production environment is a strong indicator of a reverse engineering or active attack attempt.

Malwarelytics for Android is able to detect the presence of several runtime tampering technologies and can be configured to terminate the app when such a technology is detected.

Configuration

This feature can be configured during the Malwarelytics initialization phase:

val raspConfig = RaspConfig.Builder()
    .runtimeTampering(DetectionConfig)
    // configuration of other RASP features
    .build()

Available values of DetectionConfig:

Value Description
NoAction indicates that runtime tampering will not be automatically detected. A manual check is still possible.
Notify indicates that runtime tampering will be automatically detected and observers will be notified.
Exit(
exitUrl:String?)
indicates that runtime tampering will be automatically detected and the app will be terminated when a tampering tool is automatically detected.

Runtime tampering detection defaults to DetectionConfig.Notify.

List of available parameters for some config values:

Parameter Description
exitUrl:String? defines the URL to be opened when the app is terminated because of the automatic detection. Defaults to null.

Usage

After initialization, the runtime tampering detection feature can be accessed via RaspManager. This can be used to register an observer or to trigger a manual check.

Registering an Observer

Runtime tampering detection can trigger a certain action. To achieve that, an observer needs to be configured and registered.

Observer configuration:

val raspObserver = object : RaspObserver {
    // The callback is delivered on a background thread
    override fun onRuntimeTamperingDetected(runtimeTamperingDetection: RuntimeTamperingDetection) {
        // Handle runtime tampering detection
    }
    // Handle detection of other RASP features
}

The observer can be registered in RaspManager. When it is no longer needed, it can be unregistered again.

raspManager.registerRaspObserver(raspObserver)
raspManager.unregisterRaspObserver(raspObserver)

The RuntimeTamperingDetection data class contains the following properties:

Property Description
isRuntimeTamperingPresent: Boolean indicates whether a runtime tampering technology is detected with non-zero confidence.
detectionConfidence: Float indicates the confidence of the runtime tampering detection, the value is in the range [0.0, 1.0].
troubleshootingMessage: String contains troubleshooting information. The value is used for troubleshooting purposes only and may be changed at any version.

Triggering a Manual Check

Runtime tampering detection can be triggered manually in RaspManager. Two methods are available – isRuntimeTamperingPresent() gives a simple boolean answer, whereas getRuntimeTamperingDetection() provides more details.

// Always run on a background thread
val runtimeTamperingDetection: RuntimeTamperingDetection = raspManager.getRuntimeTamperingDetection()
// Always run on a background thread
val isRuntimeTamperingPresent: Boolean = raspManager.isRuntimeTamperingPresent()

More information on general RASP feature configuration and usage can be found in this overview.

Last updated on May 11, 2026 (10:32) View product

develop

Malwarelytics for Android