Bypassing Commercial RASP and Root Detection - A Reality Check

Bypassing Commercial RASP and Root Detection - A Reality Check

By Lior • 2025-06-30

0. TL;DR

We analyzed real-world commercial RASP (Runtime Application Self-Protection) and anti-root protections embedded in high-security Android apps. Despite layers of dynamic protections, code obfuscation, integrity validation, and root detection, we show how sophisticated adversaries can bypass them — enabling full app functionality on rooted devices.

What is RASP?

Runtime Application Self-Protection (RASP) is a category of security solutions embedded inside apps. It aims to protect against tampering, debugging, rooting, and reverse engineering in real time. RASP typically includes code obfuscation, integrity checks, anti-hooking defenses, and environment checks — like root or emulator detection.

1. Introduction

App developers often rely on commercial Runtime Application Self-Protection (RASP) solutions to protect apps from tampering, rooting, and reverse engineering. These solutions typically include root detection, code integrity checks, anti-debugging, emulator detection, and more.

The assumption is that these RASP solutions will reliably block attackers from analyzing or modifying app behavior. But what if this assumption is wrong?

We examined real-world implementations of such solutions in high profile mobile apps, and evaluate their effectiveness against a determined, technically capable adversary.

2. Magisk’s Anti-Anti-Root Detection Features

Magisk has evolved significantly to counter increasingly sophisticated root detection. The latest approach involves Zygisk, which injects modules directly into the Zygote process, allowing deeper control and stealth capabilities. Features like denylist allow users to specify which apps should not detect root, effectively cloaking Magisk from chosen apps. Additionally, multiple Magisk modules emerged, attempting to provide stronger root-detection bypasses.

We intentionally worked with apps that remained protected even with Magisk, Zygisk, and common hiding modules enabled — illustrating that defeating these RASP protections required deeper runtime manipulation.

our analysis aimed at bypassing apps that successfully detect root even with all anti-anti-root protections enabled, and with root-hiding modules installed.

3. The Targets

We selected multiple target applications, each from an industry where strong security is essential — including finance, digital identity, and mobile security. These apps have clear incentives to enforce strict protection measures. Our targets included:

As our goal is showing that root detection solutions are not to be relied on alone, we will not disclose the apps themselves to avoid any negative impact.

4. Anti research techniques

High-end commercial app protection solutions often employ various anti research techniques, which we quickly encountered. One notable method of anti research we’ve seen, is combining reflection with method name encryption:

Decompiled class that sets up runtime string-decryption for root checks

The above sets up runtime string decryption for a certain class.

Runtime string decryption

Here we see:

  1. Encrypted method names, decrypted at runtime via PullRefreshKt.c()
  2. Dynamic resolution of (encrypted) method names
  3. Reflection-based invocation (getMethod() and invoke()), used to obscure control flow and hinder static analysis

Combined, these techniques raise the difficulty level for analysis.

Some of the additional anti research methods we’ve encountered include:

  1. Emulator detection (not running on emulator)
  2. Strings encryption (almost all strings are encrypted)
  3. Code integrity checks, as indicated by the below image

Code integrity checks

5. An efficient research approach

A naive approach would be to find all root detection methods, and resolve them one after the other. However, as reverse engineering is a resource intensive art, especially in the presence of considerable anti research, and we aim to be highly efficient - we chose a more effective approach; As commercial RASP solutions are typically integrated as SDKs, the likely general structure of the code would be something like this:

  1. App asks the SDK if device is rooted
  2. SDK checks for root (in various methods)
  3. SDK returns true / false
  4. App decides whether to allow normal execution or not based on the result

Considering this, it becomes clear that we don’t need to defeat every root detection method, nor confront all of the anti research techniques. It would be enough to find the critical decision points - the code responsible for deciding whether to execute normally or not. Each of our target apps turned out to contain one or a few such points.

As a starting point, we located strings related to root detection. These strings were used for logging purposes, configued by a disabled flag which is likely turned on for debug builds. By turning on the flag with FRIDA, and by hooking string decryption methods and logging their outputs dynamically, we were able to learn a lot about how root is detected, and more importantly, find the specific classes and functions responsible for root detection.

An example of some interesting strings we quickly found, which led us to a decision point:

Interesting strings

These led to the following code area:

Interesting code

And here's our complete decision point:

Critical code area for root bypass

In the above case, it is enough to force the hashSet0.isEmpty() branch to be taken (every time the root detection logic runs) - after that, the app runs smoothly, with root undetected.

We’ve seen similar behavior in all applications we’ve inspected, and pinpointed the critical functions in which the decision (rooted or not rooted) is made. At some, it was enough to choose correctly in a single if-else branch, at others we needed to prevent a certain activity from starting, or return a different value from a certain function - but with all apps, it was sufficient to alter behavior in 1-3 critical places, to have the app behave as if no root was detected.

From this point - once we've detected the critical functions which decide if the device is rooted or not - all that is left is reliably forcing the code to choose the right branch

In the next section, we'll show how attackers can reliably (and quickly) implement root detection bypasses, once the functions that decide if the device is rooted or not are pinpointed.

6. Bypassing Root Detection - Going Beyond Frida

In order to show that RASP bypasses — including root detection and runtime enforcement — can be practically and widely deployed, we decided to design bypasses that are robust, consistent, and easy to distribute and use. The bypass should be:

Considering our requirements, we chose to use LSPosed - a framework for Magisk, built on top of Zygisk, that allows developers to hook and modify app and system behavior at runtime without altering APKs.

We built a single LSPosed module that hooks the critical functions that determine whether the device is rooted or not, and force them to return the desired result (not rooted). The same module can hook functions belonging to different target apps - so a single module was enough to bypass root detection for all target apps (by implementing hooks for each of the apps individually).

Here's an example of LSPosed function we implemented to bypass a critical function to avoid root detection: LSPosed code example

After installing our custom LSPosed module, all target apps can be used with no limits whatsoever. The apps work smoothly and consistently, even through app updates and device reboots.

7. Root detection techniques

we’ve seen a wide variety of methods used for root detection. As our goal is bypassing them, we don’t really need to know how most of them work, but we’ll share a few here:

  1. Enumerating installed APKs and looking for root managers, as well as apps that require root to function.
  2. Looking for certain system property values.
  3. Looking at various device information - model, CPU info, screen size, resolution, and more. This doesn’t directly detect root, but likely looks for suspicious / unusual environments.
  4. Looking for files related to root solutions.
  5. JNI library that iterates over all mounts and looks for various magisk / su related entries.
  6. And more.

A part of the JNI logic iterating through mounts:

JNI code iterating mounts

8. Implications for Sensitive Apps

RASP is designed to provide in-app runtime protection against dynamic tampering and rooted environments. But as shown, even robust RASP layers are not immune. Advanced adversaries can override key logic, disable protections, and persistently circumvent RASP controls.

For users, this exposes risks of data theft and fraud. Those are critical risks when considering these highly sensitive apps.

For app developers, this exposes multiple risks. Availability of premium features, bypassing geographic restrictions and licensing checks are only the start; Among other issues, attackers can:

  1. Defeat server-side rate limits or fraud controls — by altering client behavior, faking telemetry, or suppressing detection triggers.
  2. Exfiltrate session tokens and cryptographic material — giving attackers persistent access to services as real users.
  3. Automate abuse at scale — rooted devices allow attackers to mass-scale manipulation via instrumentation frameworks, beyond what’s possible with unmodified devices.
  4. Undermine compliance efforts — making it impossible to guarantee device posture, user consent, or legal data boundaries.

9. Improving Root Detection and App Security

The most important takeaway is this: never assume the app is running in a trusted or non-rooted environment. This assumption creates dangerous blind spots. Instead, app developers must adopt a defense-in-depth strategy, treating root detection as one layer — not a silver bullet.

To improve resilience against modern bypass techniques:

10. About Lucid Bit Labs

We’re a boutique security research team specializing in mobile-application security, reverse engineering, and exploitation. Our analysts have a long track record of uncovering real-world vulnerabilities in Android apps and system components.

Need similar expertise on your side? Check out our Mobile Security & Reverse-Engineering Services or schedule a quick discovery call. We’ll help you uncover—and fix—the issues that matter most.