How Hackers Reverse Engineer Apps With Ghidra

By Abdul Shakoor

Here’s something most people never think about when they install an app: the moment that app lands on a phone, it’s no longer fully under the developer’s control. It’s sitting on someone else’s device, and anyone curious enough — or malicious enough — can pull it apart and look inside. The code you worked hard to protect is now, in a very real sense, in enemy hands.

I find this is the single hardest idea for new developers to accept. We tend to assume our compiled app is a sealed box. It isn’t. With free tools and a weekend of patience, a determined person can crack that box open, read the logic, and find the secrets you thought were hidden. The tool that made this genuinely accessible to everyone is Ghidra — a reverse engineering framework built and released for free by the NSA.

This guide walks through how that process actually works, why it matters, and — most importantly — what you can do to make your app a frustrating target rather than an easy one. Understanding the attacker’s side isn’t about enabling them; it’s the only honest way to defend properly. You can’t protect against an attack you don’t understand.

What “reverse engineering” actually means

Strip away the jargon and reverse engineering is simple: you take a finished product and work backwards to figure out how it was built.

The analogy I always reach for is a locked watch. A normal person wears it. A curious one opens the case, studies the gears, traces how each piece drives the next, and slowly understands the whole mechanism — without ever being handed the blueprints. Reverse engineering an app is exactly that, except the “gears” are code: the APK package, the compiled DEX bytecode, and the native .so libraries underneath.

So when someone asks “can my app really be reverse engineered?” — the honest answer is yes, and more easily than you’d hope. That’s not a reason to panic. It’s a reason to build with the assumption that someone will look inside.

Why Ghidra became the go-to tool

Before Ghidra, serious reverse engineering usually meant paying for expensive professional software. Then in 2019 the NSA open-sourced Ghidra, and the barrier basically collapsed.

A few things make it the default choice today. It’s completely free and open-source, so there’s no cost barrier to entry. It supports a huge range of processor architectures, which matters when you’re dealing with native mobile libraries. Its decompiler — the part that turns raw machine code into something resembling readable C — is genuinely good. And there’s a large, active community, so when you get stuck, someone has usually already documented the answer.

In practical terms, Ghidra takes compiled code that looks like meaningless hexadecimal and turns it into something a human can actually read and reason about. That’s the whole game.

How the reverse-engineering process actually flows

Let me walk through the real sequence an attacker follows when taking apart an Android app. I’m describing this so you understand where your defences need to go — every step here is a step you can make harder.

It starts with getting the APK. Android apps ship as APK files, and there are plenty of ways to obtain one — extracting it from a device, pulling it through a tool, or grabbing it during installation. This first step is essentially impossible to prevent; if your app is installable, the APK is obtainable.

Next comes unpacking the resources, usually with a tool like Apktool. This decodes the app’s structure — the XML files, the layout, the manifest — and reveals how the app is assembled. It’s the equivalent of taking the back off the watch.

Then there’s turning the code back into something readable. A tool like Dex2jar converts Android’s DEX bytecode into standard Java bytecode, which can then be read almost like source. This is the stage where business logic, class names, and method flow start becoming visible — and where sloppy mistakes like hardcoded secrets get exposed.

For apps that push sensitive logic into native libraries, this is where Ghidra takes over. Attackers load the .so files into Ghidra, decompile the binary, map out the functions, and trace how execution flows. Developers often move critical code into native libraries thinking it’s safer there. It’s harder to read — but, as anyone who’s spent time in Ghidra will tell you, “harder” is not “impossible.”

Finally, there’s modifying and rebuilding. Once the attacker understands the app, they can strip out protections, change behaviour, and repackage it — which is how you end up with cracked apps, bypassed license checks, and malware-injected clones floating around third-party stores.

What about Flutter apps?

Flutter throws a small curveball. Because Flutter compiles to native ARM binaries rather than standard Android bytecode, the usual Dex2jar route doesn’t apply, and reversing it is genuinely a bit harder.

But “harder” keeps being the theme here, not “safe.” Specialised tooling exists specifically for pulling apart Flutter apps, and combined with Ghidra’s binary analysis, a Flutter app with no extra protection is still very much readable. If you build in Flutter and assume the framework alone is protecting you, that’s a dangerous assumption.

Real scenarios where this goes wrong

Abstract risk is easy to ignore, so here are the patterns that actually cause damage.

The one that makes me wince most is the hardcoded secret. A fintech or startup app ships with an API key baked directly into the code. An attacker decompiles the APK, finds that key sitting in plain sight, and now has a direct line to the backend servers — leading to exactly the kind of data leak that ends up in the news. This single mistake is depressingly common, and it’s entirely preventable.

Then there’s game cracking — popular paid or freemium games get reversed, their in-app purchase checks removed, and “modded” versions redistributed for free. The developer simply loses the revenue.

And the nastiest one: malware injection. Attackers take a legitimate app, inject malicious code, repackage it, and push it through third-party stores to unsuspecting users. The original developer’s reputation takes the hit for something they didn’t do.

So how do you actually defend against this?

This is the part that matters, because you can’t stop reverse engineering — you can only make it expensive and frustrating enough that it isn’t worth the effort. Here’s where to focus, roughly in order of impact.

Obfuscate your code.

Tools like ProGuard or R8 rename classes and methods into meaningless characters and tangle the logic, so even a successful decompile produces a confusing mess instead of a clean roadmap. This is the cheapest, highest-impact step, and there’s no excuse to skip it.

Encrypt what matters.

Sensitive strings, API keys, and critical logic should never sit in plain text. If a secret has to exist on the device, it should at least be encrypted rather than readable at a glance.

Don’t trust the client.

This is the big one. Move real validation — auth, payments, anything that matters — onto your server. Secure, server-side checks are the backbone of resisting these attacks, and they’re why solid API security practices matter so much; the app on the phone should be a thin client, not the keeper of your secrets.

Add anti-tampering and anti-debugging.

Verify your app’s signature at runtime so a repackaged version fails to run, and add checks that make live debugging harder. These won’t stop a determined expert, but they filter out the casual attacker entirely.

Consider root detection.

Blocking or limiting functionality on rooted devices removes a big chunk of the easy attack surface, since much of this work happens on rooted test devices.

Layered together, these don’t make you invincible — nothing does — but they turn your app from low-hanging fruit into a job most attackers won’t bother finishing. This whole mindset is really just secure development applied to the mobile world: assume the worst, defend in depth, and never rely on a single wall.

Ghidra vs IDA Pro — which should you learn?

If you’re getting into this from the defensive side, you’ll eventually hit the Ghidra-versus-IDA-Pro question. The short version:

Ghidra is free, capable, and has a fast-growing community — which makes it the obvious starting point, especially for beginners. IDA Pro is the long-standing industry standard with a more advanced (and very expensive) toolset, favoured by professionals who reverse-engineer for a living.

For almost everyone reading this, Ghidra is the right place to start. You can always graduate to IDA Pro later if reverse engineering becomes your profession rather than a defensive skill.

A few hard-won principles

If I had to compress the defensive mindset into a handful of rules, it’d be these. Never trust client-side code — assume an attacker can read everything your app contains. Protect your APIs and backend, not just the app, because that’s where the real damage happens. Use layered security rather than betting everything on one protection. And — this is the one people skip — test your own app with these same reverse-engineering tools. The fastest way to find your hardcoded API key is to go looking for it the way an attacker would. Understanding how attackers think about mobile app security is genuinely your strongest advantage.

The bottom line

Reverse engineering isn’t exotic any more. Free tools like Ghidra have put it within reach of anyone with curiosity and time, which means “nobody will bother looking inside my app” is no longer a security strategy — it’s wishful thinking.

The realistic goal isn’t to make reverse engineering impossible. It’s to make it so tedious and low-reward that attackers give up and move to an easier target. Obfuscate, encrypt, push trust to the server, and build every feature assuming someone is already reading your code on their workbench. Do that, and you’ve shifted the odds firmly back in your favour.

If your app is on a user’s device, treat it as readable. Build accordingly, and most of these attacks simply stop being worth the attacker’s time.

Frequently asked questions

Is it possible to reverse engineer any app?

In principle, yes — if an app runs on a user’s device, its code can be analysed. Proper protections like obfuscation and encryption don’t make this impossible, but they make it far harder and less rewarding.

What tools are commonly used for reverse engineering?

The usual toolkit includes Apktool for unpacking, Dex2jar and JADX for converting bytecode, and Ghidra for analysing native binaries. Each handles a different stage of the process.

Which security measure best protects an app from reverse engineering?

There’s no single silver bullet — the strongest approach layers several: code obfuscation, encryption of sensitive data, tamper and root detection, and (most importantly) keeping real validation on a secure server rather than on the device.

Is Ghidra better than IDA Pro?

For beginners and defensive work, Ghidra is ideal — free, powerful, and well-supported. IDA Pro offers more advanced features for full-time professionals but comes at a significant cost. Start with Ghidra.

Are Flutter apps safe from reverse engineering?

Safer by default than standard bytecode apps, because Flutter compiles to native binaries — but not immune. Dedicated tools can still analyse them, so Flutter apps need the same protections as any other.

Want to go deeper on protecting what you build? Explore our Secure Development and Mobile App Security guides.

Scroll to Top