Your First Frida Hook: Bypassing Android Root Detection in 12 Lines
For mobile security beginners who want to learn dynamic instrumentation, this tutorial demonstrates writing a practical Frida script to bypass common root detection in Android apps.

Prerequisites
- An Android device or emulator (rooted preferred but not required)
- Frida installed on your computer (
pip install frida-tools) - USB debugging enabled on your device
- Basic understanding of JavaScript
- A target app (we'll use a generic banking app pattern)
What is Frida?
Frida is a dynamic instrumentation toolkit that lets you inject JavaScript into running processes. Instead of decompiling and recompiling apps, you modify behavior at runtime—perfect for bypassing security checks, analyzing malware, or understanding app logic.
Step 1: Install Frida Server on Android
Find your device architecture:
bashadb shell getprop ro.product.cpu.abi
Download the matching frida-server from https://github.com/frida/frida/releases (e.g., frida-server-16.1.4-android-arm64):
bashwget https://github.com/frida/frida/releases/download/16.1.4/frida-server-16.1.4-android-arm64.xz unxz frida-server-16.1.4-android-arm64.xz
Push and run it:
bashadb push frida-server-16.1.4-android-arm64 /data/local/tmp/frida-server adb shell "chmod 755 /data/local/tmp/frida-server" adb shell "/data/local/tmp/frida-server &"
Verify it's running:
bashfrida-ps -U
You should see a list of running processes.
Step 2: Identify the Root Detection Method
Most Android apps check for root using common methods:
- Checking for
subinary - Looking for Magisk/SuperSU packages
- Calling
RootBeerlibrary methods
Let's target a common pattern. Launch your target app:
bashadb shell am start -n com.example.bankingapp/.MainActivity
Use Frida to explore loaded classes:
bashfrida -U -n com.example.bankingapp --no-pause
In the Frida REPL, search for root-related classes:
javascriptJava.perform(function() { Java.enumerateLoadedClasses({ onMatch: function(className) { if (className.toLowerCase().includes('root') || className.toLowerCase().includes('security')) { console.log(className); } }, onComplete: function() {} }); });
Step 3: Write Your First Hook Script
Create a file called bypass-root.js. Here's a complete script that hooks common root detection methods:
javascriptJava.perform(function() { console.log("[*] Starting root detection bypass..."); // Hook the isRooted() method from RootBeer library var RootBeer = Java.use('com.scottyab.rootbeer.RootBeer'); RootBeer.isRooted.implementation = function() { console.log("[*] isRooted() called - returning false"); return false; // Always return "not rooted" }; // Hook Runtime.exec() to catch 'su' checks var Runtime = Java.use('java.lang.Runtime'); Runtime.exec.overload('java.lang.String').implementation = function(cmd) { if (cmd.includes('su')) { console.log("[*] Blocked 'su' command: " + cmd); throw new Error("Command not found"); } return this.exec(cmd); // Allow other commands }; console.log("[*] Root detection bypass active!"); });
Step 4: Run Your Hook
Exit the Frida REPL and attach your script to the running app:
bashfrida -U -l bypass-root.js -f com.example.bankingapp --no-pause
The -f flag spawns the app with Frida attached from the start, catching early checks.
You should see:
code[*] Starting root detection bypass... [*] Root detection bypass active! [*] isRooted() called - returning false
Step 5: Understanding What Happened
Let's break down the key parts:
javascriptJava.perform(function() { ... });
This wraps your code to run in the Java VM context.
javascriptvar RootBeer = Java.use('com.scottyab.rootbeer.RootBeer');
Java.use() gets a reference to the Java class.
javascriptRootBeer.isRooted.implementation = function() { ... };
This replaces the original method with your custom version.
javascriptRuntime.exec.overload('java.lang.String').implementation = ...
overload() specifies which version of an overloaded method to hook.
Step 6: Make It Reusable
Save your script and create an alias:
bashecho "alias frida-bypass='frida -U -l ~/frida-scripts/bypass-root.js'" >> ~/.bashrc source ~/.bashrc
Now you can quickly bypass root detection:
bashfrida-bypass -f com.any.app
Step 7: Handle Multiple Detection Methods
Extend your script to catch more patterns:
javascript// Hook File.exists() to hide Magisk var File = Java.use('java.io.File'); File.exists.implementation = function() { var path = this.getAbsolutePath(); if (path.includes('magisk') || path.includes('su')) { console.log("[*] Hidden file: " + path); return false; } return this.exists(); };
Where to Go Next
- Learn Frida's Interceptor API for native library hooking
- Explore
frida-tracefor automatic method tracing - Study the Frida CodeShare (https://codeshare.frida.re) for community scripts
- Practice on OWASP MSTG Crackmes (https://github.com/OWASP/owasp-mstg)
- Read "Frida Handbook" for advanced techniques
- Try hooking SSL pinning next—same principles, different target
You've just learned the fundamental Frida pattern that applies to 90% of mobile security tasks!