Ghidra Workflow for CTF
A practical guide to navigating Ghidra — importing a binary, reading the decompiler, and renaming your way to an answer.
// prerequisite reading
Import and initial analysis
- File → New Project → Non-Shared Project → name it.
- File → Import File → drag the binary in.
- Double-click the file in the project → Yes to auto-analyse.
- Accept all defaults and click Analyse.
Auto-analysis takes 10–60 s. It finds functions, labels known API calls, and runs the decompiler on every function it finds.
Navigation shortcuts
| Key | Action |
|---|---|
G |
Go to address |
L |
Rename symbol under cursor |
T |
Edit type of variable |
X |
Show cross-references (where is this called?) |
F |
Function graph view |
/ |
Comment |
Ctrl+F |
Search in current view |
Finding main when there’s no symbol
If the binary is stripped (no debug symbols), main is not labelled.
- Open the Symbol Tree → Functions → look for
entry(the ELF entry point). - In
_start, find the call to__libc_start_main; the first argument is the address ofmain. - Double-click it. Rename it
mainwithL.
Reading the decompiler
The Decompile window shows pseudocode. It is not C — it is Ghidra’s best guess. Common issues:
- Variables named
local_18→ rename them as you understand them. undefined8types → change tochar *orintwhen you know the type.*(long *)(ptr + 8)→ Ghidra doesn’t know the struct; define it in the Data Type Manager and it will render field names.
Finding the flag check
Search → Search Memory → type flag{ or the known flag prefix to find where
flag data lives in the binary.
Then look at cross-references (X) on that address to find which function
reads or compares it.
Patching to skip checks
Right-click an instruction → Patch Instruction → change JNE to JE to
invert a branch. Use File → Export Program → Original File to extract the
patched binary and run it.