Loading...
Loading...
Reverse engineer binaries using Ghidra's headless analyzer. Decompile executables, extract functions, strings, symbols, and analyze call graphs without GUI.
npx skill4agent add mitsuhiko/agent-stuff ghidraanalyzeHeadless| Task | Command |
|---|---|
| Full analysis with all exports | |
| Decompile to C code | |
| List functions | |
| Extract strings | |
| Get call graph | |
| Export symbols | |
| Find Ghidra path | |
brew install --cask ghidraGHIDRA_HOME./scripts/ghidra-analyze.sh [options] <binary>analyzeHeadless-o, --output <dir>-s, --script <name>-a, --script-args <args>--script-path <path>-p, --processor <id>x86:LE:32:default-c, --cspec <id>gccwindows--no-analysis--timeout <seconds>--keep-project--project-dir <dir>--project-name <name>-v, --verbose{name}_summary.txt{name}_decompiled.c{name}_functions.json{name}_strings.txt{name}_interesting.txt./scripts/ghidra-analyze.sh -s ExportAll.java -o ./analysis firmware.bin{name}_decompiled.c./scripts/ghidra-analyze.sh -s ExportDecompiled.java -o ./output program.exe{name}_functions.json{
"program": "example.exe",
"architecture": "x86",
"functions": [
{
"name": "main",
"address": "0x00401000",
"size": 256,
"signature": "int main(int argc, char **argv)",
"returnType": "int",
"callingConvention": "cdecl",
"isExternal": false,
"parameters": [{"name": "argc", "type": "int"}, ...],
"calls": ["printf", "malloc", "process_data"],
"calledBy": ["_start"]
}
]
}{name}_strings.json./scripts/ghidra-analyze.sh -s ExportStrings.java -o ./output malware.exe{name}_calls.json{name}_symbols.json# Create output directory
mkdir -p ./analysis
# Run comprehensive analysis
./scripts/ghidra-analyze.sh -s ExportAll.java -o ./analysis unknown_binary
# Review the summary first
cat ./analysis/unknown_binary_summary.txt
# Look at interesting patterns (crypto, network, dangerous functions)
cat ./analysis/unknown_binary_interesting.txt
# Check specific decompiled functions
grep -A 50 "encrypt" ./analysis/unknown_binary_decompiled.c# Specify ARM architecture for firmware
./scripts/ghidra-analyze.sh \
-p "ARM:LE:32:v7" \
-s ExportAll.java \
-o ./firmware_analysis \
firmware.bin# Just get function names and addresses (faster)
./scripts/ghidra-analyze.sh --no-analysis -s ExportFunctions.java -o . program
# Parse with jq
cat program_functions.json | jq '.functions[] | "\(.address): \(.name)"'# After running ExportDecompiled, search for patterns
grep -n "password\|secret\|key" output_decompiled.c
grep -n "strcpy\|sprintf\|gets" output_decompiled.cfor bin in ./samples/*; do
name=$(basename "$bin")
./scripts/ghidra-analyze.sh -s ExportAll.java -o "./results/$name" "$bin"
done-p| Architecture | Processor ID |
|---|---|
| x86 32-bit | |
| x86 64-bit | |
| ARM 32-bit | |
| ARM 64-bit | |
| MIPS 32-bit | |
| PowerPC | |
ls "$(dirname $(./scripts/find-ghidra.sh))/../Ghidra/Processors/"# Check if Ghidra is installed
./scripts/find-ghidra.sh
# Set GHIDRA_HOME if in non-standard location
export GHIDRA_HOME=/path/to/ghidra_11.x_PUBLIC
./scripts/ghidra-analyze.sh ...# Set a timeout (seconds)
./scripts/ghidra-analyze.sh --timeout 300 -s ExportAll.java binary
# Skip analysis for quick export
./scripts/ghidra-analyze.sh --no-analysis -s ExportSymbols.java binaryanalyzeHeadlessexport MAXMEM=4G./scripts/ghidra-analyze.sh -p "ARM:LE:32:v7" -s ExportAll.java firmware.bin--timeout--no-analysis