windows-exe-decompiler-mcp-server 0.1.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 (190) hide show
  1. package/CODEX_INSTALLATION.md +69 -0
  2. package/COPILOT_INSTALLATION.md +77 -0
  3. package/LICENSE +21 -0
  4. package/README.md +314 -0
  5. package/bin/windows-exe-decompiler-mcp-server.js +3 -0
  6. package/dist/analysis-provenance.d.ts +184 -0
  7. package/dist/analysis-provenance.js +74 -0
  8. package/dist/analysis-task-runner.d.ts +31 -0
  9. package/dist/analysis-task-runner.js +160 -0
  10. package/dist/artifact-inventory.d.ts +23 -0
  11. package/dist/artifact-inventory.js +175 -0
  12. package/dist/cache-manager.d.ts +128 -0
  13. package/dist/cache-manager.js +454 -0
  14. package/dist/confidence-semantics.d.ts +66 -0
  15. package/dist/confidence-semantics.js +122 -0
  16. package/dist/config.d.ts +335 -0
  17. package/dist/config.js +193 -0
  18. package/dist/database.d.ts +227 -0
  19. package/dist/database.js +601 -0
  20. package/dist/decompiler-worker.d.ts +441 -0
  21. package/dist/decompiler-worker.js +1962 -0
  22. package/dist/dynamic-trace.d.ts +95 -0
  23. package/dist/dynamic-trace.js +629 -0
  24. package/dist/env-validator.d.ts +15 -0
  25. package/dist/env-validator.js +249 -0
  26. package/dist/error-handler.d.ts +28 -0
  27. package/dist/error-handler.example.d.ts +22 -0
  28. package/dist/error-handler.example.js +141 -0
  29. package/dist/error-handler.js +139 -0
  30. package/dist/ghidra-analysis-status.d.ts +49 -0
  31. package/dist/ghidra-analysis-status.js +178 -0
  32. package/dist/ghidra-config.d.ts +134 -0
  33. package/dist/ghidra-config.js +464 -0
  34. package/dist/index.d.ts +9 -0
  35. package/dist/index.js +200 -0
  36. package/dist/job-queue.d.ts +169 -0
  37. package/dist/job-queue.js +407 -0
  38. package/dist/logger.d.ts +106 -0
  39. package/dist/logger.js +176 -0
  40. package/dist/policy-guard.d.ts +115 -0
  41. package/dist/policy-guard.js +243 -0
  42. package/dist/process-output.d.ts +15 -0
  43. package/dist/process-output.js +90 -0
  44. package/dist/prompts/function-explanation-review.d.ts +5 -0
  45. package/dist/prompts/function-explanation-review.js +64 -0
  46. package/dist/prompts/semantic-name-review.d.ts +5 -0
  47. package/dist/prompts/semantic-name-review.js +63 -0
  48. package/dist/runtime-correlation.d.ts +34 -0
  49. package/dist/runtime-correlation.js +279 -0
  50. package/dist/runtime-paths.d.ts +3 -0
  51. package/dist/runtime-paths.js +11 -0
  52. package/dist/selection-diff.d.ts +667 -0
  53. package/dist/selection-diff.js +53 -0
  54. package/dist/semantic-name-suggestion-artifacts.d.ts +116 -0
  55. package/dist/semantic-name-suggestion-artifacts.js +314 -0
  56. package/dist/server.d.ts +129 -0
  57. package/dist/server.js +578 -0
  58. package/dist/tools/artifact-read.d.ts +235 -0
  59. package/dist/tools/artifact-read.js +317 -0
  60. package/dist/tools/artifacts-diff.d.ts +728 -0
  61. package/dist/tools/artifacts-diff.js +304 -0
  62. package/dist/tools/artifacts-list.d.ts +515 -0
  63. package/dist/tools/artifacts-list.js +389 -0
  64. package/dist/tools/attack-map.d.ts +290 -0
  65. package/dist/tools/attack-map.js +519 -0
  66. package/dist/tools/cache-observability.d.ts +4 -0
  67. package/dist/tools/cache-observability.js +36 -0
  68. package/dist/tools/code-function-cfg.d.ts +50 -0
  69. package/dist/tools/code-function-cfg.js +102 -0
  70. package/dist/tools/code-function-decompile.d.ts +55 -0
  71. package/dist/tools/code-function-decompile.js +103 -0
  72. package/dist/tools/code-function-disassemble.d.ts +43 -0
  73. package/dist/tools/code-function-disassemble.js +185 -0
  74. package/dist/tools/code-function-explain-apply.d.ts +255 -0
  75. package/dist/tools/code-function-explain-apply.js +225 -0
  76. package/dist/tools/code-function-explain-prepare.d.ts +535 -0
  77. package/dist/tools/code-function-explain-prepare.js +276 -0
  78. package/dist/tools/code-function-explain-review.d.ts +397 -0
  79. package/dist/tools/code-function-explain-review.js +589 -0
  80. package/dist/tools/code-function-rename-apply.d.ts +248 -0
  81. package/dist/tools/code-function-rename-apply.js +220 -0
  82. package/dist/tools/code-function-rename-prepare.d.ts +506 -0
  83. package/dist/tools/code-function-rename-prepare.js +279 -0
  84. package/dist/tools/code-function-rename-review.d.ts +574 -0
  85. package/dist/tools/code-function-rename-review.js +761 -0
  86. package/dist/tools/code-functions-list.d.ts +37 -0
  87. package/dist/tools/code-functions-list.js +91 -0
  88. package/dist/tools/code-functions-rank.d.ts +34 -0
  89. package/dist/tools/code-functions-rank.js +90 -0
  90. package/dist/tools/code-functions-reconstruct.d.ts +2725 -0
  91. package/dist/tools/code-functions-reconstruct.js +2807 -0
  92. package/dist/tools/code-functions-search.d.ts +39 -0
  93. package/dist/tools/code-functions-search.js +90 -0
  94. package/dist/tools/code-reconstruct-export.d.ts +1212 -0
  95. package/dist/tools/code-reconstruct-export.js +4002 -0
  96. package/dist/tools/code-reconstruct-plan.d.ts +274 -0
  97. package/dist/tools/code-reconstruct-plan.js +342 -0
  98. package/dist/tools/dotnet-metadata-extract.d.ts +541 -0
  99. package/dist/tools/dotnet-metadata-extract.js +355 -0
  100. package/dist/tools/dotnet-reconstruct-export.d.ts +567 -0
  101. package/dist/tools/dotnet-reconstruct-export.js +1151 -0
  102. package/dist/tools/dotnet-types-list.d.ts +325 -0
  103. package/dist/tools/dotnet-types-list.js +201 -0
  104. package/dist/tools/dynamic-dependencies.d.ts +115 -0
  105. package/dist/tools/dynamic-dependencies.js +213 -0
  106. package/dist/tools/dynamic-memory-import.d.ts +10 -0
  107. package/dist/tools/dynamic-memory-import.js +567 -0
  108. package/dist/tools/dynamic-trace-import.d.ts +10 -0
  109. package/dist/tools/dynamic-trace-import.js +235 -0
  110. package/dist/tools/entrypoint-fallback-disasm.d.ts +30 -0
  111. package/dist/tools/entrypoint-fallback-disasm.js +89 -0
  112. package/dist/tools/ghidra-analyze.d.ts +88 -0
  113. package/dist/tools/ghidra-analyze.js +208 -0
  114. package/dist/tools/ghidra-health.d.ts +37 -0
  115. package/dist/tools/ghidra-health.js +212 -0
  116. package/dist/tools/ioc-export.d.ts +209 -0
  117. package/dist/tools/ioc-export.js +542 -0
  118. package/dist/tools/packer-detect.d.ts +165 -0
  119. package/dist/tools/packer-detect.js +284 -0
  120. package/dist/tools/pe-exports-extract.d.ts +175 -0
  121. package/dist/tools/pe-exports-extract.js +253 -0
  122. package/dist/tools/pe-fingerprint.d.ts +234 -0
  123. package/dist/tools/pe-fingerprint.js +269 -0
  124. package/dist/tools/pe-imports-extract.d.ts +105 -0
  125. package/dist/tools/pe-imports-extract.js +245 -0
  126. package/dist/tools/report-generate.d.ts +157 -0
  127. package/dist/tools/report-generate.js +457 -0
  128. package/dist/tools/report-summarize.d.ts +2131 -0
  129. package/dist/tools/report-summarize.js +596 -0
  130. package/dist/tools/runtime-detect.d.ts +135 -0
  131. package/dist/tools/runtime-detect.js +247 -0
  132. package/dist/tools/sample-ingest.d.ts +94 -0
  133. package/dist/tools/sample-ingest.js +327 -0
  134. package/dist/tools/sample-profile-get.d.ts +183 -0
  135. package/dist/tools/sample-profile-get.js +121 -0
  136. package/dist/tools/sandbox-execute.d.ts +441 -0
  137. package/dist/tools/sandbox-execute.js +392 -0
  138. package/dist/tools/strings-extract.d.ts +375 -0
  139. package/dist/tools/strings-extract.js +314 -0
  140. package/dist/tools/strings-floss-decode.d.ts +143 -0
  141. package/dist/tools/strings-floss-decode.js +259 -0
  142. package/dist/tools/system-health.d.ts +434 -0
  143. package/dist/tools/system-health.js +446 -0
  144. package/dist/tools/task-cancel.d.ts +21 -0
  145. package/dist/tools/task-cancel.js +70 -0
  146. package/dist/tools/task-status.d.ts +27 -0
  147. package/dist/tools/task-status.js +106 -0
  148. package/dist/tools/task-sweep.d.ts +22 -0
  149. package/dist/tools/task-sweep.js +77 -0
  150. package/dist/tools/tool-help.d.ts +340 -0
  151. package/dist/tools/tool-help.js +261 -0
  152. package/dist/tools/yara-scan.d.ts +554 -0
  153. package/dist/tools/yara-scan.js +313 -0
  154. package/dist/types.d.ts +266 -0
  155. package/dist/types.js +41 -0
  156. package/dist/worker-pool.d.ts +204 -0
  157. package/dist/worker-pool.js +650 -0
  158. package/dist/workflows/deep-static.d.ts +104 -0
  159. package/dist/workflows/deep-static.js +276 -0
  160. package/dist/workflows/function-explanation-review.d.ts +655 -0
  161. package/dist/workflows/function-explanation-review.js +440 -0
  162. package/dist/workflows/reconstruct.d.ts +2053 -0
  163. package/dist/workflows/reconstruct.js +666 -0
  164. package/dist/workflows/semantic-name-review.d.ts +2418 -0
  165. package/dist/workflows/semantic-name-review.js +521 -0
  166. package/dist/workflows/triage.d.ts +659 -0
  167. package/dist/workflows/triage.js +1374 -0
  168. package/dist/workspace-manager.d.ts +150 -0
  169. package/dist/workspace-manager.js +411 -0
  170. package/ghidra_scripts/DecompileFunction.java +487 -0
  171. package/ghidra_scripts/DecompileFunction.py +150 -0
  172. package/ghidra_scripts/ExtractCFG.java +256 -0
  173. package/ghidra_scripts/ExtractCFG.py +233 -0
  174. package/ghidra_scripts/ExtractFunctions.java +442 -0
  175. package/ghidra_scripts/ExtractFunctions.py +101 -0
  176. package/ghidra_scripts/README.md +125 -0
  177. package/ghidra_scripts/SearchFunctionReferences.java +380 -0
  178. package/helpers/DotNetMetadataProbe/DotNetMetadataProbe.csproj +9 -0
  179. package/helpers/DotNetMetadataProbe/Program.cs +566 -0
  180. package/install-to-codex.ps1 +178 -0
  181. package/install-to-copilot.ps1 +303 -0
  182. package/package.json +101 -0
  183. package/requirements.txt +9 -0
  184. package/workers/requirements-dynamic.txt +11 -0
  185. package/workers/requirements.txt +8 -0
  186. package/workers/speakeasy_compat.py +175 -0
  187. package/workers/static_worker.py +5183 -0
  188. package/workers/yara_rules/default.yar +33 -0
  189. package/workers/yara_rules/malware_families.yar +93 -0
  190. package/workers/yara_rules/packers.yar +80 -0
@@ -0,0 +1,178 @@
1
+ /**
2
+ * Shared helpers for interpreting persisted Ghidra analysis states.
3
+ */
4
+ export const GHIDRA_READY_STATUSES = new Set(['done', 'partial_success']);
5
+ export const GHIDRA_STRICT_READY_STATUSES = new Set(['done']);
6
+ function normalizeCapabilityStatus(raw, fallback) {
7
+ if (!raw || typeof raw !== 'object') {
8
+ return fallback;
9
+ }
10
+ const candidate = raw;
11
+ const statusRaw = String(candidate.status || fallback.status || 'missing').toLowerCase();
12
+ const status = statusRaw === 'ready'
13
+ ? 'ready'
14
+ : statusRaw === 'degraded'
15
+ ? 'degraded'
16
+ : 'missing';
17
+ return {
18
+ available: typeof candidate.available === 'boolean' ? candidate.available : status === 'ready',
19
+ status,
20
+ reason: typeof candidate.reason === 'string'
21
+ ? candidate.reason
22
+ : typeof fallback.reason === 'string'
23
+ ? fallback.reason
24
+ : undefined,
25
+ warnings: Array.isArray(candidate.warnings)
26
+ ? candidate.warnings.filter((item) => typeof item === 'string')
27
+ : fallback.warnings,
28
+ checked_at: typeof candidate.checked_at === 'string'
29
+ ? candidate.checked_at
30
+ : fallback.checked_at,
31
+ target: typeof candidate.target === 'string'
32
+ ? candidate.target
33
+ : fallback.target,
34
+ details: candidate.details && typeof candidate.details === 'object'
35
+ ? candidate.details
36
+ : fallback.details,
37
+ };
38
+ }
39
+ function buildLegacyCapabilityFallback(capability, analysis, metadata) {
40
+ const hasProject = Boolean(metadata.project_path && metadata.project_key);
41
+ const functionCount = typeof metadata.function_count === 'number'
42
+ ? metadata.function_count
43
+ : 0;
44
+ const extractionStatus = String(metadata.function_extraction?.status || '').toLowerCase();
45
+ const extractionWarnings = Array.isArray(metadata.function_extraction?.warnings)
46
+ ? metadata.function_extraction?.warnings
47
+ : undefined;
48
+ const strictReady = isStrictGhidraReadyStatus(analysis.status);
49
+ const looseReady = isGhidraReadyStatus(analysis.status);
50
+ if (capability === 'function_index') {
51
+ if (functionCount > 0) {
52
+ return {
53
+ available: true,
54
+ status: 'ready',
55
+ warnings: extractionWarnings,
56
+ };
57
+ }
58
+ if (looseReady && extractionStatus === 'failed') {
59
+ return {
60
+ available: false,
61
+ status: 'missing',
62
+ reason: 'Function extraction failed after headless analysis completed.',
63
+ warnings: extractionWarnings,
64
+ };
65
+ }
66
+ if (looseReady) {
67
+ return {
68
+ available: false,
69
+ status: 'missing',
70
+ reason: 'Legacy Ghidra record has no extracted function index.',
71
+ warnings: extractionWarnings,
72
+ };
73
+ }
74
+ return {
75
+ available: false,
76
+ status: 'missing',
77
+ reason: 'No completed function-index extraction recorded.',
78
+ };
79
+ }
80
+ if (hasProject && strictReady) {
81
+ return {
82
+ available: true,
83
+ status: 'ready',
84
+ warnings: extractionWarnings,
85
+ };
86
+ }
87
+ if (hasProject && looseReady) {
88
+ return {
89
+ available: false,
90
+ status: 'degraded',
91
+ reason: capability === 'decompile'
92
+ ? 'Project metadata exists, but decompile readiness was not validated.'
93
+ : 'Project metadata exists, but CFG readiness was not validated.',
94
+ warnings: extractionWarnings,
95
+ };
96
+ }
97
+ return {
98
+ available: false,
99
+ status: 'missing',
100
+ reason: capability === 'decompile'
101
+ ? 'No decompile-capable Ghidra project metadata found.'
102
+ : 'No CFG-capable Ghidra project metadata found.',
103
+ warnings: extractionWarnings,
104
+ };
105
+ }
106
+ export function parseGhidraAnalysisMetadata(outputJson) {
107
+ if (!outputJson) {
108
+ return {};
109
+ }
110
+ try {
111
+ const parsed = JSON.parse(outputJson);
112
+ if (!parsed || typeof parsed !== 'object') {
113
+ return {};
114
+ }
115
+ return parsed;
116
+ }
117
+ catch {
118
+ return {};
119
+ }
120
+ }
121
+ export function isGhidraReadyStatus(status) {
122
+ if (!status) {
123
+ return false;
124
+ }
125
+ return GHIDRA_READY_STATUSES.has(status);
126
+ }
127
+ export function isStrictGhidraReadyStatus(status) {
128
+ if (!status) {
129
+ return false;
130
+ }
131
+ return GHIDRA_STRICT_READY_STATUSES.has(status);
132
+ }
133
+ export function getGhidraReadiness(analysis) {
134
+ const metadata = parseGhidraAnalysisMetadata(analysis.output_json);
135
+ const readiness = metadata.readiness || {};
136
+ return {
137
+ function_index: normalizeCapabilityStatus(readiness.function_index, buildLegacyCapabilityFallback('function_index', analysis, metadata)),
138
+ decompile: normalizeCapabilityStatus(readiness.decompile, buildLegacyCapabilityFallback('decompile', analysis, metadata)),
139
+ cfg: normalizeCapabilityStatus(readiness.cfg, buildLegacyCapabilityFallback('cfg', analysis, metadata)),
140
+ };
141
+ }
142
+ export function getGhidraCapabilityStatus(analysis, capability) {
143
+ return getGhidraReadiness(analysis)[capability];
144
+ }
145
+ export function isGhidraCapabilityReady(analysis, capability) {
146
+ const state = getGhidraCapabilityStatus(analysis, capability);
147
+ return state.available === true && state.status === 'ready';
148
+ }
149
+ function analysisSortKey(analysis) {
150
+ const candidates = [analysis.finished_at, analysis.started_at];
151
+ for (const candidate of candidates) {
152
+ if (!candidate) {
153
+ continue;
154
+ }
155
+ const ts = new Date(candidate).getTime();
156
+ if (Number.isFinite(ts)) {
157
+ return ts;
158
+ }
159
+ }
160
+ return 0;
161
+ }
162
+ export function findBestGhidraAnalysis(analyses, capability) {
163
+ const sorted = [...analyses]
164
+ .filter((analysis) => analysis.backend === 'ghidra')
165
+ .sort((left, right) => analysisSortKey(right) - analysisSortKey(left));
166
+ if (!capability) {
167
+ return sorted[0];
168
+ }
169
+ const ready = sorted.find((analysis) => isGhidraCapabilityReady(analysis, capability));
170
+ if (ready) {
171
+ return ready;
172
+ }
173
+ return sorted.find((analysis) => {
174
+ const status = getGhidraCapabilityStatus(analysis, capability);
175
+ return status.status === 'degraded';
176
+ });
177
+ }
178
+ //# sourceMappingURL=ghidra-analysis-status.js.map
@@ -0,0 +1,134 @@
1
+ /**
2
+ * Ghidra Headless configuration and validation
3
+ * Handles detection, validation, and configuration of Ghidra installation
4
+ */
5
+ export interface GhidraConfig {
6
+ installDir: string;
7
+ analyzeHeadlessPath: string;
8
+ scriptsDir: string;
9
+ version?: string;
10
+ isValid: boolean;
11
+ }
12
+ export interface GhidraHealthStatus {
13
+ ok: boolean;
14
+ checked_at: string;
15
+ install_dir: string;
16
+ analyze_headless_path: string;
17
+ scripts_dir: string;
18
+ version?: string;
19
+ checks: {
20
+ install_dir_exists: boolean;
21
+ analyze_headless_exists: boolean;
22
+ scripts_dir_exists: boolean;
23
+ launch_ok: boolean;
24
+ pyghidra_available: boolean;
25
+ };
26
+ launch_probe?: {
27
+ raw_cmd: string;
28
+ exit_code: number | null;
29
+ timed_out: boolean;
30
+ stdout: string;
31
+ stderr: string;
32
+ stdout_encoding: string;
33
+ stderr_encoding: string;
34
+ };
35
+ pyghidra_probe?: {
36
+ command: string;
37
+ available: boolean;
38
+ version?: string;
39
+ error?: string;
40
+ };
41
+ errors: string[];
42
+ warnings: string[];
43
+ }
44
+ export interface ProcessInvocation {
45
+ command: string;
46
+ args: string[];
47
+ windowsVerbatimArguments?: boolean;
48
+ }
49
+ export declare function probePyGhidraAvailability(timeoutMs?: number): {
50
+ command: string;
51
+ available: boolean;
52
+ version?: string;
53
+ error?: string;
54
+ };
55
+ /**
56
+ * Quote argument for Windows cmd.exe command line.
57
+ * Keeps special characters literal, including &, (), and spaces.
58
+ */
59
+ export declare function quoteForWindowsCmd(value: string): string;
60
+ /**
61
+ * Build explicit cmd.exe invocation for .bat/.cmd entry points on Windows.
62
+ * Avoids `shell: true` and path-splitting issues on special characters.
63
+ */
64
+ export declare function buildWindowsBatchInvocation(command: string, args: string[]): ProcessInvocation;
65
+ /**
66
+ * Build portable process invocation.
67
+ * On Windows batch scripts we explicitly route through cmd.exe.
68
+ */
69
+ export declare function buildProcessInvocation(command: string, args: string[], platform?: NodeJS.Platform): ProcessInvocation;
70
+ /**
71
+ * Detect Ghidra installation from environment variable or common paths
72
+ */
73
+ export declare function detectGhidraInstallation(): string | null;
74
+ /**
75
+ * Validate Ghidra installation directory
76
+ */
77
+ export declare function validateGhidraInstallation(installDir: string): boolean;
78
+ /**
79
+ * Get path to analyzeHeadless script based on platform
80
+ */
81
+ export declare function getAnalyzeHeadlessPath(installDir: string): string;
82
+ /**
83
+ * Get Ghidra version from installation
84
+ */
85
+ export declare function getGhidraVersion(installDir: string): string | null;
86
+ /**
87
+ * Ensure Ghidra scripts directory exists
88
+ */
89
+ export declare function ensureScriptsDirectory(baseDir?: string): string;
90
+ /**
91
+ * Initialize Ghidra configuration
92
+ */
93
+ export declare function initializeGhidraConfig(installDir?: string): GhidraConfig;
94
+ /**
95
+ * Generate unique project key for Ghidra project
96
+ * Format: <timestamp>_<random>
97
+ * Ensures uniqueness for concurrent analyses
98
+ *
99
+ * Requirements: 8.1, 8.7
100
+ */
101
+ export declare function generateProjectKey(): string;
102
+ /**
103
+ * Create Ghidra project directory
104
+ * Creates isolated project space to avoid concurrent conflicts
105
+ *
106
+ * Requirements: 8.1, 8.7
107
+ *
108
+ * @param ghidraWorkspaceDir - Base Ghidra workspace directory (from workspace manager)
109
+ * @param projectKey - Unique project key (optional, will be generated if not provided)
110
+ * @returns Object with project path and project key
111
+ */
112
+ export declare function createGhidraProject(ghidraWorkspaceDir: string, projectKey?: string): {
113
+ projectPath: string;
114
+ projectKey: string;
115
+ };
116
+ /**
117
+ * Clean up old Ghidra projects
118
+ * Removes project directories older than specified age
119
+ *
120
+ * @param ghidraWorkspaceDir - Base Ghidra workspace directory
121
+ * @param maxAgeMs - Maximum age in milliseconds (default: 7 days)
122
+ * @returns Number of projects cleaned up
123
+ */
124
+ export declare function cleanupOldGhidraProjects(ghidraWorkspaceDir: string, maxAgeMs?: number): number;
125
+ /**
126
+ * Perform a lightweight Ghidra environment health check.
127
+ * This verifies path resolution and attempts a short `analyzeHeadless -help` launch.
128
+ */
129
+ export declare function checkGhidraHealth(timeoutMs?: number): GhidraHealthStatus;
130
+ /**
131
+ * Global Ghidra configuration instance
132
+ */
133
+ export declare const ghidraConfig: GhidraConfig;
134
+ //# sourceMappingURL=ghidra-config.d.ts.map