mitsupi 1.0.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (77) hide show
  1. package/LICENSE +201 -0
  2. package/README.md +95 -0
  3. package/TODO.md +11 -0
  4. package/commands/handoff.md +100 -0
  5. package/commands/make-release.md +75 -0
  6. package/commands/pickup.md +30 -0
  7. package/commands/update-changelog.md +78 -0
  8. package/package.json +22 -0
  9. package/pi-extensions/answer.ts +527 -0
  10. package/pi-extensions/codex-tuning.ts +632 -0
  11. package/pi-extensions/commit.ts +248 -0
  12. package/pi-extensions/cwd-history.ts +237 -0
  13. package/pi-extensions/issues.ts +548 -0
  14. package/pi-extensions/loop.ts +446 -0
  15. package/pi-extensions/qna.ts +167 -0
  16. package/pi-extensions/reveal.ts +689 -0
  17. package/pi-extensions/review.ts +807 -0
  18. package/pi-themes/armin.json +81 -0
  19. package/pi-themes/nightowl.json +82 -0
  20. package/skills/anachb/SKILL.md +183 -0
  21. package/skills/anachb/departures.sh +79 -0
  22. package/skills/anachb/disruptions.sh +53 -0
  23. package/skills/anachb/route.sh +87 -0
  24. package/skills/anachb/search.sh +43 -0
  25. package/skills/ghidra/SKILL.md +254 -0
  26. package/skills/ghidra/scripts/find-ghidra.sh +54 -0
  27. package/skills/ghidra/scripts/ghidra-analyze.sh +239 -0
  28. package/skills/ghidra/scripts/ghidra_scripts/ExportAll.java +278 -0
  29. package/skills/ghidra/scripts/ghidra_scripts/ExportCalls.java +148 -0
  30. package/skills/ghidra/scripts/ghidra_scripts/ExportDecompiled.java +84 -0
  31. package/skills/ghidra/scripts/ghidra_scripts/ExportFunctions.java +114 -0
  32. package/skills/ghidra/scripts/ghidra_scripts/ExportStrings.java +123 -0
  33. package/skills/ghidra/scripts/ghidra_scripts/ExportSymbols.java +135 -0
  34. package/skills/github/SKILL.md +47 -0
  35. package/skills/improve-skill/SKILL.md +155 -0
  36. package/skills/improve-skill/scripts/extract-session.js +349 -0
  37. package/skills/oebb-scotty/SKILL.md +429 -0
  38. package/skills/oebb-scotty/arrivals.sh +83 -0
  39. package/skills/oebb-scotty/departures.sh +83 -0
  40. package/skills/oebb-scotty/disruptions.sh +33 -0
  41. package/skills/oebb-scotty/search-station.sh +36 -0
  42. package/skills/oebb-scotty/trip.sh +119 -0
  43. package/skills/openscad/SKILL.md +232 -0
  44. package/skills/openscad/examples/parametric_box.scad +92 -0
  45. package/skills/openscad/examples/phone_stand.scad +95 -0
  46. package/skills/openscad/tools/common.sh +50 -0
  47. package/skills/openscad/tools/export-stl.sh +56 -0
  48. package/skills/openscad/tools/extract-params.sh +147 -0
  49. package/skills/openscad/tools/multi-preview.sh +68 -0
  50. package/skills/openscad/tools/preview.sh +74 -0
  51. package/skills/openscad/tools/render-with-params.sh +91 -0
  52. package/skills/openscad/tools/validate.sh +46 -0
  53. package/skills/pi-share/SKILL.md +105 -0
  54. package/skills/pi-share/fetch-session.mjs +322 -0
  55. package/skills/sentry/SKILL.md +239 -0
  56. package/skills/sentry/lib/auth.js +99 -0
  57. package/skills/sentry/scripts/fetch-event.js +329 -0
  58. package/skills/sentry/scripts/fetch-issue.js +356 -0
  59. package/skills/sentry/scripts/list-issues.js +239 -0
  60. package/skills/sentry/scripts/search-events.js +291 -0
  61. package/skills/sentry/scripts/search-logs.js +240 -0
  62. package/skills/tmux/SKILL.md +105 -0
  63. package/skills/tmux/scripts/find-sessions.sh +112 -0
  64. package/skills/tmux/scripts/wait-for-text.sh +83 -0
  65. package/skills/web-browser/SKILL.md +91 -0
  66. package/skills/web-browser/scripts/cdp.js +210 -0
  67. package/skills/web-browser/scripts/dismiss-cookies.js +373 -0
  68. package/skills/web-browser/scripts/eval.js +68 -0
  69. package/skills/web-browser/scripts/logs-tail.js +69 -0
  70. package/skills/web-browser/scripts/nav.js +65 -0
  71. package/skills/web-browser/scripts/net-summary.js +94 -0
  72. package/skills/web-browser/scripts/package-lock.json +33 -0
  73. package/skills/web-browser/scripts/package.json +6 -0
  74. package/skills/web-browser/scripts/pick.js +165 -0
  75. package/skills/web-browser/scripts/screenshot.js +52 -0
  76. package/skills/web-browser/scripts/start.js +80 -0
  77. package/skills/web-browser/scripts/watch.js +266 -0
@@ -0,0 +1,254 @@
1
+ ---
2
+ name: ghidra
3
+ description: "Reverse engineer binaries using Ghidra's headless analyzer. Decompile executables, extract functions, strings, symbols, and analyze call graphs without GUI."
4
+ ---
5
+
6
+ # Ghidra Headless Analysis Skill
7
+
8
+ Perform automated reverse engineering using Ghidra's `analyzeHeadless` tool. Import binaries, run analysis, decompile to C code, and extract useful information.
9
+
10
+ ## Quick Reference
11
+
12
+ | Task | Command |
13
+ |------|---------|
14
+ | Full analysis with all exports | `ghidra-analyze.sh -s ExportAll.java -o ./output binary` |
15
+ | Decompile to C code | `ghidra-analyze.sh -s ExportDecompiled.java -o ./output binary` |
16
+ | List functions | `ghidra-analyze.sh -s ExportFunctions.java -o ./output binary` |
17
+ | Extract strings | `ghidra-analyze.sh -s ExportStrings.java -o ./output binary` |
18
+ | Get call graph | `ghidra-analyze.sh -s ExportCalls.java -o ./output binary` |
19
+ | Export symbols | `ghidra-analyze.sh -s ExportSymbols.java -o ./output binary` |
20
+ | Find Ghidra path | `find-ghidra.sh` |
21
+
22
+ ## Prerequisites
23
+
24
+ - **Ghidra** must be installed. On macOS: `brew install --cask ghidra`
25
+ - **Java** (OpenJDK 17+) must be available
26
+
27
+ The skill automatically locates Ghidra in common installation paths. Set `GHIDRA_HOME` environment variable if Ghidra is installed in a non-standard location.
28
+
29
+ ---
30
+
31
+ ## Main Wrapper Script
32
+
33
+ ```bash
34
+ ./scripts/ghidra-analyze.sh [options] <binary>
35
+ ```
36
+
37
+ Wrapper that handles project creation/cleanup and provides a simpler interface to `analyzeHeadless`.
38
+
39
+ **Options:**
40
+ - `-o, --output <dir>` - Output directory for results (default: current dir)
41
+ - `-s, --script <name>` - Post-analysis script to run (can be repeated)
42
+ - `-a, --script-args <args>` - Arguments for the last specified script
43
+ - `--script-path <path>` - Additional script search path
44
+ - `-p, --processor <id>` - Processor/architecture (e.g., `x86:LE:32:default`)
45
+ - `-c, --cspec <id>` - Compiler spec (e.g., `gcc`, `windows`)
46
+ - `--no-analysis` - Skip auto-analysis (faster, but less info)
47
+ - `--timeout <seconds>` - Analysis timeout per file
48
+ - `--keep-project` - Keep the Ghidra project after analysis
49
+ - `--project-dir <dir>` - Directory for Ghidra project (default: /tmp)
50
+ - `--project-name <name>` - Project name (default: auto-generated)
51
+ - `-v, --verbose` - Verbose output
52
+
53
+ ---
54
+
55
+ ## Built-in Export Scripts
56
+
57
+ ### ExportAll.java
58
+ Comprehensive export - runs all other exports and creates a summary. Best for initial analysis.
59
+
60
+ **Output files:**
61
+ - `{name}_summary.txt` - Overview: architecture, memory sections, function counts
62
+ - `{name}_decompiled.c` - All functions decompiled to C
63
+ - `{name}_functions.json` - Function list with signatures and calls
64
+ - `{name}_strings.txt` - All strings found
65
+ - `{name}_interesting.txt` - Functions matching security-relevant patterns
66
+
67
+ ```bash
68
+ ./scripts/ghidra-analyze.sh -s ExportAll.java -o ./analysis firmware.bin
69
+ ```
70
+
71
+ ### ExportDecompiled.java
72
+ Decompile all functions to C pseudocode.
73
+
74
+ **Output:** `{name}_decompiled.c`
75
+
76
+ ```bash
77
+ ./scripts/ghidra-analyze.sh -s ExportDecompiled.java -o ./output program.exe
78
+ ```
79
+
80
+ ### ExportFunctions.java
81
+ Export function list as JSON with addresses, signatures, parameters, and call relationships.
82
+
83
+ **Output:** `{name}_functions.json`
84
+
85
+ ```json
86
+ {
87
+ "program": "example.exe",
88
+ "architecture": "x86",
89
+ "functions": [
90
+ {
91
+ "name": "main",
92
+ "address": "0x00401000",
93
+ "size": 256,
94
+ "signature": "int main(int argc, char **argv)",
95
+ "returnType": "int",
96
+ "callingConvention": "cdecl",
97
+ "isExternal": false,
98
+ "parameters": [{"name": "argc", "type": "int"}, ...],
99
+ "calls": ["printf", "malloc", "process_data"],
100
+ "calledBy": ["_start"]
101
+ }
102
+ ]
103
+ }
104
+ ```
105
+
106
+ ### ExportStrings.java
107
+ Extract all strings (ASCII, Unicode) with addresses.
108
+
109
+ **Output:** `{name}_strings.json`
110
+
111
+ ```bash
112
+ ./scripts/ghidra-analyze.sh -s ExportStrings.java -o ./output malware.exe
113
+ ```
114
+
115
+ ### ExportCalls.java
116
+ Export function call graph showing caller/callee relationships.
117
+
118
+ **Output:** `{name}_calls.json`
119
+
120
+ Includes:
121
+ - Full call graph
122
+ - Potential entry points (functions with no callers)
123
+ - Most frequently called functions
124
+
125
+ ### ExportSymbols.java
126
+ Export all symbols: imports, exports, and internal symbols.
127
+
128
+ **Output:** `{name}_symbols.json`
129
+
130
+ ---
131
+
132
+ ## Common Workflows
133
+
134
+ ### Analyze an Unknown Binary
135
+
136
+ ```bash
137
+ # Create output directory
138
+ mkdir -p ./analysis
139
+
140
+ # Run comprehensive analysis
141
+ ./scripts/ghidra-analyze.sh -s ExportAll.java -o ./analysis unknown_binary
142
+
143
+ # Review the summary first
144
+ cat ./analysis/unknown_binary_summary.txt
145
+
146
+ # Look at interesting patterns (crypto, network, dangerous functions)
147
+ cat ./analysis/unknown_binary_interesting.txt
148
+
149
+ # Check specific decompiled functions
150
+ grep -A 50 "encrypt" ./analysis/unknown_binary_decompiled.c
151
+ ```
152
+
153
+ ### Analyze Firmware
154
+
155
+ ```bash
156
+ # Specify ARM architecture for firmware
157
+ ./scripts/ghidra-analyze.sh \
158
+ -p "ARM:LE:32:v7" \
159
+ -s ExportAll.java \
160
+ -o ./firmware_analysis \
161
+ firmware.bin
162
+ ```
163
+
164
+ ### Quick Function Listing
165
+
166
+ ```bash
167
+ # Just get function names and addresses (faster)
168
+ ./scripts/ghidra-analyze.sh --no-analysis -s ExportFunctions.java -o . program
169
+
170
+ # Parse with jq
171
+ cat program_functions.json | jq '.functions[] | "\(.address): \(.name)"'
172
+ ```
173
+
174
+ ### Find Specific Patterns
175
+
176
+ ```bash
177
+ # After running ExportDecompiled, search for patterns
178
+ grep -n "password\|secret\|key" output_decompiled.c
179
+ grep -n "strcpy\|sprintf\|gets" output_decompiled.c
180
+ ```
181
+
182
+ ### Analyze Multiple Binaries
183
+
184
+ ```bash
185
+ for bin in ./samples/*; do
186
+ name=$(basename "$bin")
187
+ ./scripts/ghidra-analyze.sh -s ExportAll.java -o "./results/$name" "$bin"
188
+ done
189
+ ```
190
+
191
+ ---
192
+
193
+ ## Architecture/Processor IDs
194
+
195
+ Common processor IDs for the `-p` option:
196
+
197
+ | Architecture | Processor ID |
198
+ |-------------|--------------|
199
+ | x86 32-bit | `x86:LE:32:default` |
200
+ | x86 64-bit | `x86:LE:64:default` |
201
+ | ARM 32-bit | `ARM:LE:32:v7` |
202
+ | ARM 64-bit | `AARCH64:LE:64:v8A` |
203
+ | MIPS 32-bit | `MIPS:BE:32:default` or `MIPS:LE:32:default` |
204
+ | PowerPC | `PowerPC:BE:32:default` |
205
+
206
+ Find all available processors:
207
+ ```bash
208
+ ls "$(dirname $(./scripts/find-ghidra.sh))/../Ghidra/Processors/"
209
+ ```
210
+
211
+ ---
212
+
213
+ ## Troubleshooting
214
+
215
+ ### Ghidra Not Found
216
+ ```bash
217
+ # Check if Ghidra is installed
218
+ ./scripts/find-ghidra.sh
219
+
220
+ # Set GHIDRA_HOME if in non-standard location
221
+ export GHIDRA_HOME=/path/to/ghidra_11.x_PUBLIC
222
+ ./scripts/ghidra-analyze.sh ...
223
+ ```
224
+
225
+ ### Analysis Takes Too Long
226
+ ```bash
227
+ # Set a timeout (seconds)
228
+ ./scripts/ghidra-analyze.sh --timeout 300 -s ExportAll.java binary
229
+
230
+ # Skip analysis for quick export
231
+ ./scripts/ghidra-analyze.sh --no-analysis -s ExportSymbols.java binary
232
+ ```
233
+
234
+ ### Out of Memory
235
+ Edit the `analyzeHeadless` script or set:
236
+ ```bash
237
+ export MAXMEM=4G
238
+ ```
239
+
240
+ ### Wrong Architecture Detected
241
+ Explicitly specify the processor:
242
+ ```bash
243
+ ./scripts/ghidra-analyze.sh -p "ARM:LE:32:v7" -s ExportAll.java firmware.bin
244
+ ```
245
+
246
+ ---
247
+
248
+ ## Tips
249
+
250
+ 1. **Start with ExportAll.java** - It gives you everything and the summary helps orient you
251
+ 2. **Check the interesting.txt file** - It highlights security-relevant functions automatically
252
+ 3. **Use jq for JSON parsing** - The JSON exports are designed to be machine-readable
253
+ 4. **Decompilation isn't perfect** - Use it as a guide, cross-reference with disassembly
254
+ 5. **Large binaries take time** - Use `--timeout` and consider `--no-analysis` for quick scans
@@ -0,0 +1,54 @@
1
+ #!/bin/bash
2
+ # Locate Ghidra installation and analyzeHeadless script
3
+ # Searches common installation paths and outputs the path to analyzeHeadless
4
+
5
+ set -e
6
+
7
+ # Common locations to search for Ghidra
8
+ SEARCH_PATHS=(
9
+ # Homebrew on Apple Silicon
10
+ "/opt/homebrew/Caskroom/ghidra"
11
+ # Homebrew on Intel
12
+ "/usr/local/Caskroom/ghidra"
13
+ # Manual installation locations
14
+ "/opt/ghidra"
15
+ "/usr/local/ghidra"
16
+ "$HOME/ghidra"
17
+ "$HOME/Applications/ghidra"
18
+ "/Applications/ghidra"
19
+ # Linux common paths
20
+ "/usr/share/ghidra"
21
+ "/usr/local/share/ghidra"
22
+ )
23
+
24
+ # Check GHIDRA_HOME environment variable first
25
+ if [[ -n "$GHIDRA_HOME" ]]; then
26
+ HEADLESS="$GHIDRA_HOME/support/analyzeHeadless"
27
+ if [[ -x "$HEADLESS" ]]; then
28
+ echo "$HEADLESS"
29
+ exit 0
30
+ fi
31
+ fi
32
+
33
+ # Search through common paths
34
+ for base_path in "${SEARCH_PATHS[@]}"; do
35
+ if [[ -d "$base_path" ]]; then
36
+ # Find analyzeHeadless in the directory tree (handles versioned paths)
37
+ HEADLESS=$(find "$base_path" -name "analyzeHeadless" -type f 2>/dev/null | head -n 1)
38
+ if [[ -n "$HEADLESS" && -x "$HEADLESS" ]]; then
39
+ echo "$HEADLESS"
40
+ exit 0
41
+ fi
42
+ fi
43
+ done
44
+
45
+ # Try to find it anywhere on the system as a last resort
46
+ HEADLESS=$(find /opt /usr/local /Applications "$HOME" -name "analyzeHeadless" -type f 2>/dev/null | head -n 1)
47
+ if [[ -n "$HEADLESS" && -x "$HEADLESS" ]]; then
48
+ echo "$HEADLESS"
49
+ exit 0
50
+ fi
51
+
52
+ echo "ERROR: Could not find Ghidra's analyzeHeadless script." >&2
53
+ echo "Please set GHIDRA_HOME environment variable or install Ghidra." >&2
54
+ exit 1
@@ -0,0 +1,239 @@
1
+ #!/bin/bash
2
+ # Wrapper script for Ghidra headless analysis
3
+ # Handles project creation/cleanup and provides a simpler interface
4
+
5
+ set -e
6
+
7
+ SCRIPT_DIR="$(cd "$(dirname "${BASH_SOURCE[0]}")" && pwd)"
8
+
9
+ # Find analyzeHeadless
10
+ ANALYZE_HEADLESS=$("$SCRIPT_DIR/find-ghidra.sh")
11
+ GHIDRA_HOME=$(dirname "$(dirname "$ANALYZE_HEADLESS")")
12
+
13
+ show_help() {
14
+ cat << 'EOF'
15
+ Usage: ghidra-analyze.sh [options] <binary>
16
+
17
+ Analyze a binary file using Ghidra's headless analyzer.
18
+
19
+ Options:
20
+ -o, --output <dir> Output directory for results (default: current dir)
21
+ -s, --script <name> Post-analysis script to run (can be repeated)
22
+ -a, --script-args <args> Arguments for the last specified script
23
+ --script-path <path> Additional script search path
24
+ -p, --processor <id> Processor/architecture (e.g., x86:LE:32:default)
25
+ -c, --cspec <id> Compiler spec (e.g., gcc, windows)
26
+ --no-analysis Skip auto-analysis
27
+ --timeout <seconds> Analysis timeout per file
28
+ --keep-project Keep the Ghidra project after analysis
29
+ --project-dir <dir> Directory for Ghidra project (default: /tmp)
30
+ --project-name <name> Project name (default: auto-generated)
31
+ -v, --verbose Verbose output
32
+ -h, --help Show this help
33
+
34
+ Built-in Scripts (use with -s):
35
+ ExportDecompiled.java Export all functions as decompiled C code
36
+ ExportFunctions.java Export function list with addresses and signatures
37
+ ExportStrings.java Export all strings found in the binary
38
+ ExportCalls.java Export function call graph
39
+ ExportSymbols.java Export all symbols and their addresses
40
+
41
+ Examples:
42
+ # Basic analysis with decompilation output
43
+ ghidra-analyze.sh -s ExportDecompiled.java -o ./output myprogram
44
+
45
+ # Analyze with specific architecture
46
+ ghidra-analyze.sh -p ARM:LE:32:v7 firmware.bin
47
+
48
+ # Run multiple scripts
49
+ ghidra-analyze.sh -s ExportFunctions.java -s ExportStrings.java binary
50
+
51
+ # Keep project for later use
52
+ ghidra-analyze.sh --keep-project --project-name MyProject binary
53
+ EOF
54
+ }
55
+
56
+ # Default values
57
+ OUTPUT_DIR="."
58
+ SCRIPTS=()
59
+ SCRIPT_ARGS=()
60
+ SCRIPT_PATH=""
61
+ PROCESSOR=""
62
+ CSPEC=""
63
+ NO_ANALYSIS=""
64
+ TIMEOUT=""
65
+ KEEP_PROJECT=false
66
+ PROJECT_DIR="/tmp"
67
+ PROJECT_NAME=""
68
+ VERBOSE=false
69
+ BINARY=""
70
+
71
+ # Parse arguments
72
+ while [[ $# -gt 0 ]]; do
73
+ case $1 in
74
+ -o|--output)
75
+ OUTPUT_DIR="$2"
76
+ shift 2
77
+ ;;
78
+ -s|--script)
79
+ SCRIPTS+=("$2")
80
+ shift 2
81
+ ;;
82
+ -a|--script-args)
83
+ # Associate args with the last script
84
+ if [[ ${#SCRIPTS[@]} -gt 0 ]]; then
85
+ SCRIPT_ARGS+=("${#SCRIPTS[@]}:$2")
86
+ fi
87
+ shift 2
88
+ ;;
89
+ --script-path)
90
+ SCRIPT_PATH="$2"
91
+ shift 2
92
+ ;;
93
+ -p|--processor)
94
+ PROCESSOR="$2"
95
+ shift 2
96
+ ;;
97
+ -c|--cspec)
98
+ CSPEC="$2"
99
+ shift 2
100
+ ;;
101
+ --no-analysis)
102
+ NO_ANALYSIS="-noanalysis"
103
+ shift
104
+ ;;
105
+ --timeout)
106
+ TIMEOUT="$2"
107
+ shift 2
108
+ ;;
109
+ --keep-project)
110
+ KEEP_PROJECT=true
111
+ shift
112
+ ;;
113
+ --project-dir)
114
+ PROJECT_DIR="$2"
115
+ shift 2
116
+ ;;
117
+ --project-name)
118
+ PROJECT_NAME="$2"
119
+ shift 2
120
+ ;;
121
+ -v|--verbose)
122
+ VERBOSE=true
123
+ shift
124
+ ;;
125
+ -h|--help)
126
+ show_help
127
+ exit 0
128
+ ;;
129
+ -*)
130
+ echo "Unknown option: $1" >&2
131
+ exit 1
132
+ ;;
133
+ *)
134
+ BINARY="$1"
135
+ shift
136
+ ;;
137
+ esac
138
+ done
139
+
140
+ if [[ -z "$BINARY" ]]; then
141
+ echo "Error: No binary file specified" >&2
142
+ show_help
143
+ exit 1
144
+ fi
145
+
146
+ if [[ ! -f "$BINARY" ]]; then
147
+ echo "Error: Binary file not found: $BINARY" >&2
148
+ exit 1
149
+ fi
150
+
151
+ # Create output directory if needed
152
+ mkdir -p "$OUTPUT_DIR"
153
+
154
+ # Generate project name if not specified
155
+ if [[ -z "$PROJECT_NAME" ]]; then
156
+ PROJECT_NAME="ghidra_$(basename "$BINARY" | tr '.' '_')_$$"
157
+ fi
158
+
159
+ # Build script path including our built-in scripts
160
+ BUILTIN_SCRIPTS="$SCRIPT_DIR/ghidra_scripts"
161
+ if [[ -n "$SCRIPT_PATH" ]]; then
162
+ FULL_SCRIPT_PATH="$BUILTIN_SCRIPTS;$SCRIPT_PATH"
163
+ else
164
+ FULL_SCRIPT_PATH="$BUILTIN_SCRIPTS"
165
+ fi
166
+
167
+ # Build command
168
+ CMD=("$ANALYZE_HEADLESS" "$PROJECT_DIR" "$PROJECT_NAME" -import "$BINARY")
169
+
170
+ # Add script path
171
+ CMD+=(-scriptPath "$FULL_SCRIPT_PATH")
172
+
173
+ # Add scripts
174
+ for i in "${!SCRIPTS[@]}"; do
175
+ script="${SCRIPTS[$i]}"
176
+ CMD+=(-postScript "$script")
177
+
178
+ # Check if there are args for this script
179
+ for arg_entry in "${SCRIPT_ARGS[@]}"; do
180
+ idx="${arg_entry%%:*}"
181
+ args="${arg_entry#*:}"
182
+ if [[ "$idx" -eq $((i + 1)) ]]; then
183
+ # Append script arguments
184
+ CMD+=($args)
185
+ fi
186
+ done
187
+ done
188
+
189
+ # Add output directory as environment variable for scripts
190
+ export GHIDRA_OUTPUT_DIR="$OUTPUT_DIR"
191
+
192
+ # Add processor if specified
193
+ if [[ -n "$PROCESSOR" ]]; then
194
+ CMD+=(-processor "$PROCESSOR")
195
+ fi
196
+
197
+ # Add compiler spec if specified
198
+ if [[ -n "$CSPEC" ]]; then
199
+ CMD+=(-cspec "$CSPEC")
200
+ fi
201
+
202
+ # Add no-analysis flag if specified
203
+ if [[ -n "$NO_ANALYSIS" ]]; then
204
+ CMD+=($NO_ANALYSIS)
205
+ fi
206
+
207
+ # Add timeout if specified
208
+ if [[ -n "$TIMEOUT" ]]; then
209
+ CMD+=(-analysisTimeoutPerFile "$TIMEOUT")
210
+ fi
211
+
212
+ # Delete project after analysis unless keeping it
213
+ if [[ "$KEEP_PROJECT" != true ]]; then
214
+ CMD+=(-deleteProject)
215
+ fi
216
+
217
+ # Add log file
218
+ LOG_FILE="$OUTPUT_DIR/ghidra_analysis.log"
219
+ CMD+=(-log "$LOG_FILE")
220
+
221
+ # Run the analysis
222
+ if [[ "$VERBOSE" == true ]]; then
223
+ echo "Running: ${CMD[*]}"
224
+ fi
225
+
226
+ "${CMD[@]}" 2>&1 | tee "$OUTPUT_DIR/ghidra_output.log"
227
+
228
+ exit_code=${PIPESTATUS[0]}
229
+
230
+ if [[ $exit_code -eq 0 ]]; then
231
+ echo ""
232
+ echo "Analysis complete. Output files in: $OUTPUT_DIR"
233
+ ls -la "$OUTPUT_DIR"
234
+ else
235
+ echo "Analysis failed with exit code: $exit_code" >&2
236
+ echo "Check log file: $LOG_FILE" >&2
237
+ fi
238
+
239
+ exit $exit_code