Ghidra is a free, open-source reverse engineering framework developed by the NSA and released to the public in 2019. It rivals commercial tools like IDA Pro and Binary Ninja, featuring a powerful decompiler that converts assembly back into readable C-like pseudocode. This guide gets you productive with Ghidra for CTF challenges, malware analysis, and security research.
Installation
Ghidra requires Java 17+:
# Install Java
sudo apt install openjdk-17-jdk
# Download Ghidra from ghidra-sre.org
wget https://github.com/NationalSecurityAgency/ghidra/releases/download/Ghidra_11.1_build/ghidra_11.1_PUBLIC_20240607.zip
unzip ghidra_11.1_PUBLIC_20240607.zip
cd ghidra_11.1_PUBLIC
# Launch
./ghidraRun
On Windows: download the zip from ghidra-sre.org, extract, run ghidraRun.bat.
Creating a Project
- File → New Project → Non-Shared Project
- Choose a project directory and name
- File → Import File — drag in your binary (ELF, PE, Mach-O, etc.)
- Accept auto-detected format settings
- When prompted, click Analyze to run auto-analysis
Auto-analysis runs 30+ analyzers: function identification, string detection, data type propagation, and more. Let it complete before exploring.
The Ghidra Interface
The main CodeBrowser has five key panes:
- Listing (disassembly): Assembly code view with addresses
- Decompiler: C pseudocode view — your most-used pane
- Symbol Tree: Functions, labels, imports/exports
- Data Type Manager: Struct definitions, type libraries
- Program Trees: Segment and section view
Navigation shortcuts:
G: Go to address
F: Find / search
Ctrl+F: Search all text
Alt+←/→: Navigate back/forward
- Double-click any function/variable: jump to definition
Reading Decompiled Code
Click any function in the Symbol Tree to open it in the Decompiler. Example output:
undefined8 main(int argc, char **argv) {
int iVar1;
char local_48 [64];
printf("Enter password: ");
fgets(local_48, 64, stdin);
iVar1 = strcmp(local_48, "s3cr3t_p@ssw0rd\n");
if (iVar1 == 0) {
puts("Access granted!");
} else {
puts("Wrong password.");
}
return 0;
}
The decompiler isn’t perfect but gives an excellent starting point for understanding logic.
Renaming and Retyping
Good reverse engineering is about building understanding incrementally. Rename everything you identify:
- Right-click variable → Rename (or press
L)
- Right-click → Retype Variable to assign correct data types
- Right-click function → Edit Function Signature to fix parameters
Renamed variables persist and improve decompiler output across the entire binary as Ghidra propagates type information.
Finding Interesting Strings
Strings often reveal hardcoded credentials, file paths, error messages, and C2 server URLs:
- Window → Defined Strings
- Or:
Search → For Strings
- Double-click any string to jump to its location
- Right-click → References to see where it’s used in code
Cross-References (XREFs)
Find every place a function or variable is called/accessed:
- Click a function name, press
Ctrl+Shift+F or right-click → References → Find References
- The XREF panel shows all callers — trace execution flow upward
Analyzing a Crackme CTF Challenge
- Run
file binary and strings binary first (Linux terminal)
- Import into Ghidra, let analysis complete
- Check the Symbol Tree for
main or entry point functions
- Find string comparisons (
strcmp, strncmp) — right-click, find references
- Trace back to understand validation logic
- Rename variables as you understand them
- Look for anti-debugging tricks:
ptrace(PTRACE_TRACEME), timing checks
Ghidra Scripting
Ghidra has a built-in Python (Jython) and Java scripting environment:
Script Manager: Window → Script Manager
Useful built-in scripts:
FindImmediate.py: find all references to a specific constant value
RecoverClassesFromRTTI.java: recover C++ class structures
Write your own script:
# List all functions containing "crypt" in their name
from ghidra.app.script import GhidraScript
listing = currentProgram.getListing()
for func in listing.getFunctions(True):
if "crypt" in func.getName().lower():
print(func.getName(), func.getEntryPoint())
Analyzing Malware
When analyzing suspicious binaries:
- Work in a VM — never run malware on a real machine
- Use
strings and floss (FLARE FLOSS) to extract obfuscated strings before Ghidra
- Check imports:
CreateRemoteThread, VirtualAllocEx, WriteProcessMemory = code injection
- Look for
WSAStartup, connect, send = networking
RegSetValueEx, RegOpenKey = persistence via registry
- Use Ghidra’s Entropy View to identify packed/encrypted sections
Useful Plugins and Extensions
- Kaiju (CERT): function hashing, YARA integration
- GhidraNinja: improved dark theme
- pwndbg integration: combine Ghidra with GDB for dynamic analysis
- BinExport: export to BinDiff for binary diffing (patch analysis)
Comparing with Dynamic Analysis
Ghidra is static analysis — it reads the binary without running it. Combine with:
- GDB / pwndbg: runtime debugging
- Frida: dynamic instrumentation, hook functions at runtime
- x64dbg (Windows): GUI debugger for Windows malware
- strace / ltrace: trace system calls and library calls
The best workflow alternates between static (Ghidra) and dynamic (debugger) analysis — use Ghidra to understand overall structure, then confirm with a debugger at runtime.