beginnercat/rev~2 min read

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

  1. File → New Project → Non-Shared Project → name it.
  2. File → Import File → drag the binary in.
  3. Double-click the file in the project → Yes to auto-analyse.
  4. 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.

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.

  1. Open the Symbol Tree → Functions → look for entry (the ELF entry point).
  2. In _start, find the call to __libc_start_main; the first argument is the address of main.
  3. Double-click it. Rename it main with L.

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.
  • undefined8 types → change to char * or int when 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.