A beginners guide to using Frida to bypass root detection.

DianaOpanga
3 min readNov 27, 2023

--

Photo by FLY:D on Unsplash

This is a simple use case to bypass root detection using Frida. For this example we have created a sample APK that has implemented root checking mechanism if the app runs on a rooted phone.

We will then try bypass the root checks implemented to allow the app to run on a rooted phone.

Mobile Application Security Controls.

Mobile apps implement a number of security controls to ensure that the app maintains its integrity and that its secure. Some of the basic checks include;

Implementing SSL Pinning — to prevent attackers from analysing your backend traffic and how the app functions.

Implementing root checks — to ensure that your application does not run on a rooted phone which prevents attackers from analysing the apps binary, reverse engineering it and manipulating the apps content.

Obfuscation — to ensure that the app cannot be reverse engineered by making the apps source code harder to understand and tamper with.

Requirements.txt

  1. A rooted phone.
  2. Install Frida beforehand — you can follow this guide for installation.
  3. A vulnerable app — in this case a custom made apk was created for learning purposes.

#Part 1 — Simple implementation of root checks

Root check done

#Part 2 — Let’s bypass the checks

What is Frida? — Its a dynamic instrumentation toolkit for developers, reverse-engineers, and security researchers. Used to allow you to inject custom scripts.

  1. Analyse the code used for root detection. This can be done by decompiling the app using jadx-gui.

2. Analyse the functions used for root detection. This checks if the device is rooted.

3. Start Frida server on your phone and ensure the USB cable is properly connected to the phone. Your phone should be rooted (In this case frida is already started and running).

4. Save your custom script and prepare to inject. There are also ready to use frida scripts on frida codeshare.

console.log("Script Loaded");

Java.perform(() => {
const rootBeerClass = Java.use("com.scottyab.rootbeer.RootBeer");

hookMethod(rootBeerClass, "isRooted");
hookMethod(rootBeerClass, "checkForBinary");
});

function hookMethod(javaClass, methodName) {
console.log(`[*] Hooking ${javaClass}.${methodName}() Method`);

javaClass[methodName].implementation = function() {
console.log(`[+] Inside ${javaClass}.${methodName}() Method`);

const originalReturnValue = this[methodName]();
console.log(`[*] Original return value of ${javaClass}.${methodName}() Method = ${originalReturnValue}`);

const newReturnValue = false;
console.log(`[*] New return value of ${javaClass}.${methodName}() Method = ${newReturnValue}`);

return newReturnValue;
};
}

5. Run your script

6. Check your app for the result.

Root check bypassed

#Part 3 — Controls, Conclusion…

Ensure that your apps have a strongly developed root checking mechanism. This can be tied together with code hardening through obfuscation and encryption to reduce chances that your app is not reverse engineered and exploited.

Finally, the scripts might not always work as applications implement more secure controls when it comes to root bypass. This is just for learning purposes 😊

Happy learning!!!!

--

--