Reverse Engineering (2/5): static analysis with Ghidra, IDA and Binary Ninja
TL;DR
Static analysis is not reading every function; it is finding an anchor via strings and xrefs, then renaming and retyping iteratively. Free Ghidra is the default place to start.
The first time you open a binary in a decompiler, you see thousands of functions called FUN_00401a30 and variables called local_28. Reading them all is impossible. Part 2 of the Reverse Engineering for Developers series covers static analysis — understanding a program without running it: choosing a tool, the first 15 minutes, and turning decompiler output into something that reads like real source code.
Choosing a tool
| Tool | Cost | Strengths | Best for |
|---|---|---|---|
| Ghidra (NSA) | Free, open source | Strong decompiler, many architectures, Java/Python scripting | Default choice for learners and teams |
| IDA Pro / IDA Free | Commercial; Free edition is limited | Industry standard, FLIRT library signatures, many plugins | Professional malware and vulnerability work |
| Binary Ninja | Commercial | Clean IL layers, strong Python API | Automation and custom analyses |
| radare2 / Rizin / Cutter | Free | Scriptable CLI, runs anywhere | Quick triage on servers |
Pick one and go deep; the concepts transfer between tools.
The first 15 minutes
- Identify:
file,checksec, Detect It Easy — architecture, compiler, packer, protections (PIE, NX, canary, RELRO). - Strings and imports: flag URLs, crypto names, error messages, registry keys.
- Find an anchor: start from
main(on Linux, the first argument to__libc_start_main) or from xrefs to an interesting string or import, such as "invalid license". - Work outward: follow callers and callees; ignore library code.
Making the decompiler readable
The real work is iterative renaming and retyping:
- Rename immediately once you have a guess (
Lin Ghidra,Nin IDA). A wrong name you fix later beats no name. - Set function signatures: once
param_1is typed asConfig *, the type propagates to every caller. - Create structs: when
*(int *)(param_1 + 0x18)keeps appearing, right-click, Auto Create Structure, and name each field. - Apply library signatures: FLIRT (IDA) and Function ID (Ghidra) recognise statically linked libc, OpenSSL and zlib, removing large numbers of functions from view.
- Spot crypto by its constants:
0x67452301(MD5/SHA-1),0x6A09E667(SHA-256), the AES S-box starting63 7C 77 7B. - Comment and bookmark every finding; this is a long investigation.
Language-specific notes
- C++: use RTTI and vtables to recover class hierarchies; demangle with
c++filt. - Go: binaries keep a
pclntabtable with function names even when stripped. - Rust: heavy inlining and long mangled names; panic strings leak source file paths.
- .NET / Java: these are bytecode — ILSpy/dnSpyEx or jadx/CFR give you near-original source.
Automation
Ghidra's headless mode lets you batch-analyse binaries with scripts:
$GHIDRA_HOME/support/analyzeHeadless /tmp/proj MyProj \
-import ./target.bin -postScript MyScript.py
Risks and caveats
- Decompilers can be wrong: output is a best guess; when in doubt, check the assembly or confirm with dynamic analysis (part 3).
- Avoid rabbit holes: start with a concrete question ("where is the key derived?") so you don't wander through unrelated code.
- Legal scope: only analyse software you have the right to analyse.
How to apply it
- Dev: grab an easy crackme from crackmes.one, open it in Ghidra, find the password check, rename every variable and write down the valid input — without running it.
- Tech Lead: use Ghidra to vet closed-source libraries before shipping them: does it talk to the network, does it hardcode anything?
- PM: free Ghidra lets a team start without licence costs; buy IDA or Binary Ninja only when the workload really needs it.
Sources & references
- Ghidra Software Reverse Engineering Framework — NSA
- NationalSecurityAgency/ghidra — GitHub
- crackmes.one — crackmes.one
- Reverse Engineering for Beginners — Dennis Yurichev