This repository has no description
6.6 kB
195 lines
1---
2name: reverse-engineering
3description: Reverse engineer and debug binaries using Ghidra (static analysis, decompilation) and GDB (live debugging of running processes). Use when the user wants to analyze binaries, decompile functions, debug running processes, set breakpoints, or inspect memory.
4---
5
6# Reverse Engineering & Debugging Skill
7
8Use Ghidra for static analysis/decompilation and GDB for live debugging of running processes.
9
10All commands use `nix shell` to get the tools without installing them globally.
11
12## Ghidra Headless Analysis
13
14Use `ghidra-analyzeHeadless` for static analysis without the GUI.
15
16### Import and analyze a binary
17
18```bash
19nix shell nixpkgs#ghidra -c ghidra-analyzeHeadless /tmp/ghidra_projects MyProject \
20 -import /path/to/binary -overwrite
21
22# With specific processor (e.g., ARM, MIPS)
23nix shell nixpkgs#ghidra -c ghidra-analyzeHeadless /tmp/ghidra_projects MyProject \
24 -import /path/to/binary -processor x86:LE:64:default -overwrite
25```
26
27### Run analysis scripts
28
29Ghidra ships with many built-in scripts. Use `-postScript` to run them after analysis.
30
31```bash
32# Decompile all functions
33nix shell nixpkgs#ghidra -c ghidra-analyzeHeadless /tmp/ghidra_projects MyProject \
34 -process binary_name -postScript DecompileAllFunctions.java \
35 -noanalysis -readOnly -scriptlog /dev/stdout 2>/dev/null
36
37# List all functions
38nix shell nixpkgs#ghidra -c ghidra-analyzeHeadless /tmp/ghidra_projects MyProject \
39 -process binary_name -postScript ListFunctions.java \
40 -noanalysis -readOnly -scriptlog /dev/stdout 2>/dev/null
41```
42
43### Custom Ghidra scripts (Java)
44
45Write a custom script to extract specific information. Save as `.java` and pass with `-postScript`:
46
47```java
48// SaveTo: /tmp/ghidra_scripts/DecompileFunction.java
49import ghidra.app.script.GhidraScript;
50import ghidra.app.decompiler.*;
51import ghidra.program.model.listing.*;
52
53public class DecompileFunction extends GhidraScript {
54 @Override
55 public void run() throws Exception {
56 String targetName = getScriptArgs()[0];
57 DecompInterface decomp = new DecompInterface();
58 decomp.openProgram(currentProgram);
59
60 FunctionManager fm = currentProgram.getFunctionManager();
61 for (Function f : fm.getFunctions(true)) {
62 if (f.getName().contains(targetName)) {
63 DecompileResults res = decomp.decompileFunction(f, 30, monitor);
64 if (res.decompileCompleted()) {
65 println("=== " + f.getName() + " at " + f.getEntryPoint() + " ===");
66 println(res.getDecompiledFunction().getC());
67 }
68 }
69 }
70 decomp.dispose();
71 }
72}
73```
74
75```bash
76nix shell nixpkgs#ghidra -c ghidra-analyzeHeadless /tmp/ghidra_projects MyProject \
77 -process binary_name \
78 -postScript /tmp/ghidra_scripts/DecompileFunction.java "main" \
79 -scriptPath /tmp/ghidra_scripts -noanalysis -readOnly \
80 -scriptlog /dev/stdout 2>/dev/null
81```
82
83### Workflow: Analyze an unknown binary
84
851. Import: `nix shell nixpkgs#ghidra -c ghidra-analyzeHeadless /tmp/ghidra_projects Proj -import /path/to/binary -overwrite`
862. List functions to find interesting targets
873. Decompile specific functions of interest
884. Look for strings, cross-references, and data structures
89
90## GDB Live Debugging
91
92Use GDB to attach to running processes, set breakpoints, and inspect state.
93
94### Attach to a running process
95
96```bash
97# By PID
98sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "bt"
99
100# By name (find PID first)
101nix shell nixpkgs#gdb -c gdb -batch -p $(pidof process_name) -ex "bt"
102```
103
104### Non-interactive GDB commands
105
106Use `-batch` and `-ex` for scripted debugging:
107
108```bash
109# Get backtrace of a running process
110sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "thread apply all bt"
111
112# Print a variable
113sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "print some_global_var"
114
115# Dump memory region
116sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "x/100x 0x7fff12345678"
117
118# List all threads
119sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "info threads"
120
121# Show loaded shared libraries
122sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "info sharedlibrary"
123
124# Get register state
125sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "info registers"
126
127# Set breakpoint and continue until hit
128sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> \
129 -ex "break function_name" \
130 -ex "continue" \
131 -ex "bt" \
132 -ex "info locals"
133
134# Multiple commands
135sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> \
136 -ex "info threads" \
137 -ex "thread apply all bt" \
138 -ex "info registers"
139```
140
141### GDB with binary (not attached)
142
143```bash
144# Run with arguments
145nix shell nixpkgs#gdb -c gdb -batch -ex "run" -ex "bt" --args ./binary arg1 arg2
146
147# Run until crash, get backtrace
148nix shell nixpkgs#gdb -c gdb -batch -ex "run" -ex "bt full" -ex "info registers" --args ./binary
149
150# Set breakpoint before running
151nix shell nixpkgs#gdb -c gdb -batch \
152 -ex "break main" \
153 -ex "run" \
154 -ex "step 10" \
155 -ex "info locals" \
156 -ex "bt" \
157 --args ./binary
158```
159
160### GDB Python scripting
161
162For complex analysis, use GDB's Python API:
163
164```bash
165sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "python
166import gdb
167for thread in gdb.inferiors()[0].threads():
168 thread.switch()
169 frame = gdb.newest_frame()
170 print(f'Thread {thread.num}: {frame.name()} at {frame.pc():#x}')
171"
172```
173
174### Workflow: Debug a running process
175
1761. Find the process: `ps aux | grep process_name` or `pidof process_name`
1772. Get overview: `sudo nix shell nixpkgs#gdb -c gdb -batch -p <PID> -ex "info threads" -ex "thread apply all bt"`
1783. Check specific state: inspect variables, registers, memory
1794. Set breakpoints if needed for dynamic analysis
1805. Combine with Ghidra: decompile the binary to understand what functions do, then use GDB to observe runtime behavior
181
182## Combining Ghidra + GDB
183
1841. Find the binary path: `readlink -f /proc/<PID>/exe`
1852. Import into Ghidra for static analysis: understand the code structure
1863. Use GDB to observe runtime behavior: set breakpoints at interesting functions found in Ghidra
1874. Cross-reference: Ghidra gives you function names and decompiled code, GDB shows you actual runtime values
188
189## Tips
190
191- Ghidra headless output goes to scriptlog; use `-scriptlog /dev/stdout` to capture it
192- Use `-noanalysis -readOnly` when running scripts on already-analyzed projects
193- GDB `-batch` mode is essential for non-interactive use — it runs commands and exits
194- `sudo` is typically needed for GDB to attach to processes you don't own
195- Check `/proc/sys/kernel/yama/ptrace_scope` if attach fails (set to 0 for debugging)