Getting started with Ghidra for reverse engineering
Ghidra is free, NSA-developed, and the closest thing the RE community has to a standard. This guide covers enough to get a binary open and start making sense of it — not every feature, just the workflow that gets used constantly.
Setting up a project
Ghidra organises work into projects, and projects hold programs (the binaries you’re analysing). Create one project per engagement or research target rather than dumping everything into a single project — it keeps the project window navigable and makes it obvious what belongs together.
File → New Project → Non-Shared Project → choose a directory
Import the binary with File → Import File. Accept the default format detection unless you have a specific
reason to override it (a raw firmware dump with no header is the usual case where you do).
Auto-analysis
Double-clicking the imported binary opens the CodeBrowser and immediately offers to run analysis. Let it run with the default options the first time. The defaults cover function identification, reference analysis, and basic data type propagation — disabling things prematurely usually just means redoing it later once you realise you needed one of them.
For stripped binaries or anything obfuscated, the Decompiler Parameter ID and Shared Return Calls analyzers are worth a second look afterward — they sometimes need re-running once you’ve manually identified a few functions, since each pass can improve the input for the next.
The two views that matter
Listing view (left, disassembly) and Decompiler view (right, pseudo-C) sit side by side by default. Read the decompiler first — it’s faster to understand intent from. Drop into the listing view when the decompiler’s guess about a type or a variable looks wrong, or when you need to see the actual instructions (timing-sensitive code, anything dealing with flags registers directly).
Renaming as you go
The single highest-value habit: rename variables and functions the moment you understand what they do, not
after you’ve finished reading the whole function. Ctrl+L renames whatever’s under the cursor. A function
named sub_401190 tells you nothing on a second read; a function renamed validate_serial tells you
everything, including to your future self three functions later when something calls it.
This compounds — a decompiled function with five renamed locals and a renamed function name reads almost
like source code. The same function with Ghidra’s defaults (local_38, uVar2, sub_401190) reads like
nothing.
Useful shortcuts
| Shortcut | Action |
|---|---|
Ctrl+L | Rename symbol under cursor |
Ctrl+Shift+G | Find references to symbol |
G | Go to address |
Ctrl+E | Edit function signature |
; | Add comment at current line |
Ctrl+Shift+E | Retype a variable |
Cross-references over linear reading
Don’t read a binary top to bottom. Find something you recognise — a string, an imported function like
strcmp or connect, an interesting constant — and work outward from its cross-references. Ghidra’s
Show References To (right-click any symbol) is the single most-used feature after the decompiler itself.
This is almost always faster than trying to find main and reading forward through everything it calls.
Where to go next
Once navigation feels natural, the next useful skill is scripting the analysis itself — Ghidra’s Python and Java scripting API can automate repetitive renaming or pattern-matching across many functions at once. That’s a guide on its own; this one is just enough to get comfortable inside a single binary.