Ghidra Is Best: Android Reverse Engineering

Jun 12, 2025

6 mins read

Ghidra is the best Android app RE tool. It just seems like it’s not, because the loader has easily fixed quirks. Let me demonstrate.

A friend reached out and aired some valid grievances the Java community had with this post, particularly “Ghidra is the best Android app RE tool”. I’ve added a section labeled “Community Feedback” that provides some context for why I made this statement (despite desperately wishing there was other options for my use-case). However, at it’s core: Ghidra can, and does.

  • Control Flow Graph of DEX? Yes.
  • Scripting? Yes.
  • Headless? Yes.
  • GUI? Yes.
  • Native multi-architecture ELF loading? Yes.
  • Ability to link external /lib/arch/elf.so with JNI to DEX call? Yes.
  • Low failure rate? Yes.

When I want to do a quick analysis of an Android APK, I use APKLab:

It is a one-click install in VSCode that wraps the other common tools for apktool/jadx/etc… to allow decompiling to Smali and/or Java.

APKLab

Pretty neat right? It’s great. I love it. I love it right up until the Java language server for VSCode kicks in and starts trying to index and find all of the references between functions and classes and it all goes haywire, so I disable it.

And then I’m left with a bunch of nested plain text files and using CTRL+F to navigate around.

Use Ghidra

The most recent version of Ghidra (used in this blog) v11.3.2 still has some quirks around the workflow for loading an APK, though it’s miles better than older versions. Regardless I will demonstrate how to get an APK loaded correctly.

For sample.apk there are two DEX bytecode classes contained in the APK: classes.dex and classes2.dex. If you’re analyzing a different APK, you may have more.

To import an APK for analysis, you may be tempted to do the following from the main screen. And you would be wrong. DO NOT import the APK like this, it’s hard to explain but it messes with “Listings” (explained later).

DO NOT

Instead, Launch the “Code Browser” directly like so:

DO

Then select File --> Import File...

Code Browser

Select Import mode of Single file, as an Android APK is actually a PKZip archive. It should Auto-Detect the format as Android APK, select “Ok”.

Single file

Import

(DONT) Analyze the Binary

If you thought you knew what you were doing and clicked “Yes” on Analyze in the next step; trying to skip ahead: slow down… because you just ended up with an (incorrect) program listing of only classes.dex and are missing the entirety of classes2.dex.

This is the singular core mistake I see so many people do with Android RE in Ghidra. It’s a quirk that is easily worked around if you follow directions.

ufuckedup

Instead, you should have clicked “No”:

No

Then go to Window --> External Programs and at the top of the list, Right Click and Set External Name Association.

External Programs

A window will appear, and I know it sounds dumb, but click through the prompts to point classes2.dex to… classes2.dex. There’s something about relative paths vs absolute when Ghidra is working with a binary format which is also an archive. Just trust me.

Set Dialog

Then go to Window --> Listings and classes2.dex should appear. Just list before, fix up the Set External Name Association for classes2.dex such that classes.dex points to classes.dex.

Listings

If classes2.dex has not appeared at this point, you may select File --> Open and select it from there:

Open

At this point, you should have all relevant classes<number>.dex files available in the Listing view with the appropriate External Program references set.

(DO) Analyze the Binary

Now, you can click Analysis --> Analyze All Open...

Analyze All

For options, I use the following (which actually work when the External Programs are set up correctly).

Analysis Options

Reverse the Binary

My favorite window layout for Android RE is Listing, Decompile, Function Call Graph at the top, with References and Function Call Tree at the bottom.

Full Nav

If set up correctly, XREF’s work across multiple DEX files in the listings. Double-clicking on an external function will automatically hop you to the relevant listing. Control-Flow Graphs are resolved correctly.

…And you can use all your normal Java/Python automated analysis.

Community Feedback

Blog post hook: Ghidra is the best for android RE

Java community response: “wtf”

Fair. And to be blunt, I’ve not exactly ecstatic about the statement either. There is nothing I’d love more than to have another stable tool with comparable features to Ghidra when it comes to Android App Reverse Engineering. There’s a lot of great Java/Smali/DEX reverse engineering tools for which I have used… probably all of them over the past few years. I’ve even written a few of my own after seeing how slow Ghidra can be.

When I talk about Android app reverse engineering, I’m referring to as much of the executable code in the app as possible. There’s a lot of executable code in an APK, but the most prominent one I’ll mention is probably all of the native architecture specific ELF’s in /lib/<arch>/lib<name>.so.

Whether it’s dipping my toes into bluetooth, learning a lot and failing, designing custom scanning hardware that respects unknown medical devices, publicly criticizing (with evidence) those who didn’t, ivestigating the exact differences between iOS and Android that resulted in a FDA class I recall, building a remote bluetooth identification analysis engine on Android APKs resulting in 2 CVEs, dumping the API for a network of insecure P2P IP cameras, giving a conference talk about this exact subject, or de-FUD’ing a “backdoor” in a popular chinese social media app

I believe being able to decompile as much of the executable code in one tool is necessary. My perspective may be skewed, but hopefully the above links provide some context for why I believe this.

As part of my Bluetooth arc, I now have a corpus of 45k+ real-world Android APKs. I didn’t start off using Ghidra, but I did end there, because it does everything, reliably. This isn’t to say it doesn’t have its own problems that piss me off to no end.

Ghidra can handle APK’s and DEX (and VDEX, and OAT, and ART, and …) but far more importantly it can also handle the native code in the ELFs in /lib and let me resolve the JNI references into a unified control flow graph of all executable code, not just the DEX or its Java abstractions.

When I make the personal statement of “Ghidra is the best Android app RE tool”, it’s because I don’t actually believe there’s any feature complete alternatives. Lord knows I’ve tried em.

I’d love to have a reliable alternative, or at the very least assist improvements in the scope of the DEX/Smali/Java world. As stated above, I’ve got a 45k+ and growing corpus. Feel free to reach out if you want to run the gauntlet 😊

Sharing is caring!