Reversing Android Apps: Bypassing Detection Like a Pro

4 min read

July 6, 2025

Reversing Android Apps: Bypassing Detection Like a Pro

Table of contents

Hey everyone

Over the past couple of weeks, I’ve been working on some Android app assessments that turned out to be much more annoying than expected. Not because the logic was complex, but because the apps just refused to cooperate.

Frida was detected. The app crashed instantly. Root checks blocked everything. And SSL pinning made traffic analysis painful.

But here’s the thing: if an APK runs on your device, you can break it. Sometimes it just takes a little persistence, a lot of script tweaking, and a few clever tricks.

In this issue, we’re going to explore how to reverse engineer APKs, beat common detection techniques, and get your hooks in even when the app is fighting back hard.

Let’s get into it

First Things First: Try Magisk DenyList

If you're testing on a rooted device, the quickest trick to try is Magisk’s DenyList.

DenyList allows you to select apps that should be "shielded" from root visibility. When enabled, Magisk hides things like su, root binaries, and known Magisk paths, making your device appear clean.

It works because most apps just scan for common root indicators. If those are missing, the app often stops caring.

To enable:

  1. Turn on Zygisk in Magisk settings
  2. Enable DenyList
  3. Add your target app
  4. Reboot and test

Sometimes, that’s all it takes.

Frida Codeshare Scripts: Quick and Dirty Bypasses

Next, head to Frida Codeshare and try out some common scripts:

  • anti-root-bypass.js
  • anti-frida-detection.js
  • hide_frida_gum.js

These scripts patch common detection logic dynamically, overriding checks like getRunningAppProcesses, isDebuggerConnected() or native ptrace() calls.

frida -U -f com.example.app -l anti-frida-detection.js

I’ve had mixed results. On lightly protected apps, they work. On well-defended ones, not so much.

Still, these scripts take 30 seconds to try, and sometimes they’re enough to get you through.

Don’t Launch With Frida – Attach After

Some apps only perform detection at launch. If Frida is already injected, the app sees it and crashes.

But if you:

  1. Launch the app normally (via Android launcher or adb)
  2. Wait for it to load
  3. Then attach using:
frida -U -n com.example.app

You might slip past those weak checks.

This works especially well when detection logic runs in Application.onCreate() or early init code. If Frida isn't present at that moment, the app might assume you're legit.

Static Reversing: Find Detection Code with Jadx

Once you’ve unpacked the APK, drop it into Jadx and start searching for juicy strings:

  • "frida"
  • "root"
  • "magisk"
  • "ptrace"
  • "su"
  • "getprop"
  • "debugger"

These often lead you to custom detection logic like:

public boolean isFridaDetected() {
    return getRunningServices().contains("frida");
}

Or native JNI bridges doing sketchy stuff.

Once found, hook and patch them:

Java.perform(() => {
  const Check = Java.use("com.example.security.Checks");
  Check.isFridaDetected.implementation = function () {
    return false;
  };
});

Detection bypassed.

Objection Patch: When You’re in a Hurry

Objection has a handy feature that tries to remove common protections from the APK directly.

objection patchapk --source app.apk

It attempts to inject a Frida gadget basically.

But there’s a catch. Objection relies on apktool. If you're on Kali or another pentest distro, the default apktool is probably outdated or broken. So what you can do It's to install the latest version manually https://apktool.org/docs/install. After this the patching should work perfectly 😄

Dump Loaded Classes Before the Crash

If the app still crashes when Frida attaches, try this:

Java.perform(() => {
  Java.enumerateLoadedClasses({
    onMatch: function (name) {
      console.log(name);
    },
    onComplete: function () {
      console.log("Done");
    }
  });
});

Run the script right before the crash happens. You’ll get a list of loaded classes, including the ones likely involved in detection.

Then, take it further.

Log Which Methods Are Being Called

You can use Frida to hook and log every method from those suspicious classes:

Java.perform(() => {
  const target = Java.use("com.example.security.DetectionManager");
  target.checkFrida.implementation = function () {
    console.log("checkFrida() called!");
    return false;
  };
});

Track which functions execute just before the crash. That’ll help you pinpoint where to dig deeper.

JNI Detection: Follow the Native Trail

If Java-level detection isn’t working, the app may be using native code via JNI.

Use frida-trace to hook into JNI_OnLoad or other suspicious exports:

frida-trace -n com.example.app -i "JNI_OnLoad"

Then use tools like nm, objdump, or strings to peek inside native .so files.

Worst case, you’ll need to reverse with Ghidra or r2frida to understand what the native libs are doing.

This can take time, but when apps crash early or use aggressive native checks, it’s often your only real option.

When Nothing Works: Patch for SSL Only

If all else fails, and the app is still detecting Frida, crashing on root, or obfuscating everything, and you're on a short pentest…

At least get network visibility.

apk-mitm patches the APK to disable SSL pinning so you can inspect HTTPS traffic in Burp or mitmproxy.

apk-mitm app.apk

Install the patched APK, run the app, and proxy the traffic.

This won’t let you hook with Frida, but you’ll still be able to watch tokens, endpoints, headers, and more.

Not ideal, but when the clock is ticking, it’s a life-saver.

Wrapping Up

APK reversing is like picking a lock. Sometimes the first tool works. Sometimes you need to go layer by layer, Java, then JNI, then native assembly, until something cracks.

To recap:

  • Try Magisk DenyList for quick wins
  • Use Frida codeshare scripts to bypass common detections
  • Attach after launch to dodge init-time checks
  • Use Jadx to find detection logic and patch it
  • Patch with Objection, but make sure your apktool isn’t broken
  • Dump classes and trace methods before the crash
  • Trace JNI and reverse native code if needed
  • Patch SSL with apk-mitm if all else fails

Hope this gives you a solid framework to tackle stubborn Android apps. If you hit a wall, don’t give up. You’re probably just one hook or stub away from getting in.

Thanks for reading and see you next time
Stay stealthy out there

— Ruben

Chapters

Botón Anterior
When Web3 Withdrawals Meet Web2 Logic

Previous Issue

Breaking Mobile-to-Device Logic: When BLE Access Falls Apart

Next Issue

Enjoyed the article?

Subscribe to the newsletter and get technical insights, cybersecurity tips, and development content straight to your inbox. Or support my work with a coffee ☕ if you found it useful!

📫 Subscribe now ☕ Buy me a coffee