windows-exe-decompiler-mcp-server 0.1.0 → 0.1.3

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 (134) hide show
  1. package/CLAUDE_INSTALLATION.md +129 -0
  2. package/CODEX_INSTALLATION.md +25 -1
  3. package/COPILOT_INSTALLATION.md +29 -1
  4. package/LICENSE +21 -21
  5. package/README.md +232 -110
  6. package/dist/analysis-provenance.d.ts +50 -2
  7. package/dist/analysis-provenance.js +1 -0
  8. package/dist/analysis-task-runner.js +92 -0
  9. package/dist/config.d.ts +35 -16
  10. package/dist/config.js +37 -3
  11. package/dist/database.js +115 -115
  12. package/dist/decompiler-worker.d.ts +10 -5
  13. package/dist/decompiler-worker.js +240 -58
  14. package/dist/dynamic-trace.d.ts +6 -0
  15. package/dist/dynamic-trace.js +52 -1
  16. package/dist/ghidra-config.js +17 -1
  17. package/dist/index.js +38 -8
  18. package/dist/pe-runtime-functions.d.ts +90 -0
  19. package/dist/pe-runtime-functions.js +452 -0
  20. package/dist/prompts/module-reconstruction-review.d.ts +5 -0
  21. package/dist/prompts/module-reconstruction-review.js +65 -0
  22. package/dist/runtime-correlation.d.ts +5 -0
  23. package/dist/runtime-correlation.js +179 -2
  24. package/dist/sample-workspace.d.ts +28 -0
  25. package/dist/sample-workspace.js +186 -0
  26. package/dist/semantic-name-suggestion-artifacts.d.ts +56 -0
  27. package/dist/semantic-name-suggestion-artifacts.js +87 -0
  28. package/dist/server.js +1 -1
  29. package/dist/setup-guidance.d.ts +73 -0
  30. package/dist/setup-guidance.js +211 -0
  31. package/dist/tools/artifact-read.d.ts +10 -10
  32. package/dist/tools/artifacts-diff.d.ts +8 -8
  33. package/dist/tools/artifacts-list.d.ts +16 -16
  34. package/dist/tools/attack-map.d.ts +8 -8
  35. package/dist/tools/binary-role-profile.d.ts +1197 -0
  36. package/dist/tools/binary-role-profile.js +575 -0
  37. package/dist/tools/code-function-explain-apply.d.ts +12 -12
  38. package/dist/tools/code-function-explain-prepare.d.ts +12 -12
  39. package/dist/tools/code-function-explain-review.d.ts +58 -58
  40. package/dist/tools/code-function-rename-apply.d.ts +12 -12
  41. package/dist/tools/code-function-rename-prepare.d.ts +14 -14
  42. package/dist/tools/code-function-rename-review.d.ts +66 -66
  43. package/dist/tools/code-functions-define.d.ts +337 -0
  44. package/dist/tools/code-functions-define.js +337 -0
  45. package/dist/tools/code-functions-list.js +1 -1
  46. package/dist/tools/code-functions-rank.js +1 -1
  47. package/dist/tools/code-functions-reconstruct.d.ts +368 -58
  48. package/dist/tools/code-functions-reconstruct.js +130 -10
  49. package/dist/tools/code-functions-smart-recover.d.ts +352 -0
  50. package/dist/tools/code-functions-smart-recover.js +190 -0
  51. package/dist/tools/code-module-review-apply.d.ts +233 -0
  52. package/dist/tools/code-module-review-apply.js +209 -0
  53. package/dist/tools/code-module-review-prepare.d.ts +756 -0
  54. package/dist/tools/code-module-review-prepare.js +343 -0
  55. package/dist/tools/code-module-review.d.ts +474 -0
  56. package/dist/tools/code-module-review.js +566 -0
  57. package/dist/tools/code-reconstruct-export.d.ts +193 -21
  58. package/dist/tools/code-reconstruct-export.js +578 -21
  59. package/dist/tools/code-reconstruct-plan.d.ts +20 -20
  60. package/dist/tools/com-role-profile.d.ts +353 -0
  61. package/dist/tools/com-role-profile.js +186 -0
  62. package/dist/tools/dll-export-profile.d.ts +625 -0
  63. package/dist/tools/dll-export-profile.js +230 -0
  64. package/dist/tools/dotnet-metadata-extract.d.ts +122 -122
  65. package/dist/tools/dotnet-reconstruct-export.d.ts +49 -49
  66. package/dist/tools/dotnet-types-list.d.ts +66 -66
  67. package/dist/tools/dynamic-dependencies.d.ts +144 -8
  68. package/dist/tools/dynamic-dependencies.js +20 -1
  69. package/dist/tools/dynamic-memory-import.js +105 -2
  70. package/dist/tools/ghidra-analyze.d.ts +20 -0
  71. package/dist/tools/ghidra-analyze.js +10 -2
  72. package/dist/tools/ghidra-health.d.ts +177 -0
  73. package/dist/tools/ghidra-health.js +28 -0
  74. package/dist/tools/ioc-export.d.ts +8 -8
  75. package/dist/tools/packer-detect.d.ts +14 -14
  76. package/dist/tools/packer-detect.js +6 -9
  77. package/dist/tools/pe-exports-extract.d.ts +8 -8
  78. package/dist/tools/pe-exports-extract.js +6 -9
  79. package/dist/tools/pe-fingerprint.d.ts +36 -36
  80. package/dist/tools/pe-imports-extract.d.ts +8 -8
  81. package/dist/tools/pe-imports-extract.js +6 -9
  82. package/dist/tools/pe-pdata-extract.d.ts +448 -0
  83. package/dist/tools/pe-pdata-extract.js +219 -0
  84. package/dist/tools/pe-symbols-recover.d.ts +227 -0
  85. package/dist/tools/pe-symbols-recover.js +316 -0
  86. package/dist/tools/report-generate.d.ts +15 -1
  87. package/dist/tools/report-generate.js +139 -16
  88. package/dist/tools/report-summarize.d.ts +2242 -8
  89. package/dist/tools/report-summarize.js +246 -10
  90. package/dist/tools/runtime-detect.d.ts +8 -8
  91. package/dist/tools/runtime-detect.js +2 -12
  92. package/dist/tools/rust-binary-analyze.d.ts +2047 -0
  93. package/dist/tools/rust-binary-analyze.js +443 -0
  94. package/dist/tools/sample-profile-get.d.ts +135 -16
  95. package/dist/tools/sample-profile-get.js +35 -32
  96. package/dist/tools/sandbox-execute.d.ts +10 -10
  97. package/dist/tools/strings-extract.d.ts +8 -8
  98. package/dist/tools/strings-extract.js +2 -12
  99. package/dist/tools/strings-floss-decode.d.ts +8 -8
  100. package/dist/tools/system-health.d.ts +172 -36
  101. package/dist/tools/system-health.js +14 -0
  102. package/dist/tools/system-setup-guide.d.ts +179 -0
  103. package/dist/tools/system-setup-guide.js +62 -0
  104. package/dist/tools/tool-help.d.ts +16 -16
  105. package/dist/tools/tool-help.js +172 -0
  106. package/dist/tools/yara-scan.d.ts +8 -8
  107. package/dist/types.d.ts +2 -0
  108. package/dist/workflows/function-explanation-review.d.ts +3034 -76
  109. package/dist/workflows/function-explanation-review.js +172 -42
  110. package/dist/workflows/function-index-recover.d.ts +333 -0
  111. package/dist/workflows/function-index-recover.js +291 -0
  112. package/dist/workflows/module-reconstruction-review.d.ts +3537 -0
  113. package/dist/workflows/module-reconstruction-review.js +354 -0
  114. package/dist/workflows/reconstruct.d.ts +2182 -223
  115. package/dist/workflows/reconstruct.js +575 -32
  116. package/dist/workflows/semantic-name-review.d.ts +1436 -85
  117. package/dist/workflows/semantic-name-review.js +150 -58
  118. package/dist/workflows/triage.d.ts +8 -8
  119. package/ghidra_scripts/DecompileFunction.java +487 -487
  120. package/ghidra_scripts/ExtractCFG.java +256 -256
  121. package/ghidra_scripts/ExtractFunctions.java +442 -442
  122. package/ghidra_scripts/README.md +112 -112
  123. package/ghidra_scripts/SearchFunctionReferences.java +380 -380
  124. package/helpers/DotNetMetadataProbe/DotNetMetadataProbe.csproj +9 -9
  125. package/helpers/DotNetMetadataProbe/Program.cs +566 -566
  126. package/install-to-claude.ps1 +432 -0
  127. package/install-to-codex.ps1 +256 -178
  128. package/install-to-copilot.ps1 +389 -303
  129. package/package.json +4 -2
  130. package/requirements.txt +9 -9
  131. package/workers/requirements-dynamic.txt +11 -11
  132. package/workers/requirements.txt +8 -8
  133. package/workers/speakeasy_compat.py +175 -175
  134. package/workers/static_worker.py +3474 -3474
@@ -8,6 +8,7 @@ import { z } from 'zod';
8
8
  import { checkGhidraHealth, } from '../ghidra-config.js';
9
9
  import { findBestGhidraAnalysis, getGhidraReadiness, parseGhidraAnalysisMetadata, } from '../ghidra-analysis-status.js';
10
10
  import { DecompilerWorker } from '../decompiler-worker.js';
11
+ import { RequiredUserInputSchema, SetupActionSchema, buildGhidraRequiredUserInputs, buildGhidraSetupActions, buildPyGhidraSetupActions, mergeRequiredUserInputs, mergeSetupActions, } from '../setup-guidance.js';
11
12
  export const ghidraHealthInputSchema = z.object({
12
13
  timeout_ms: z
13
14
  .number()
@@ -34,10 +35,26 @@ export const ghidraHealthInputSchema = z.object({
34
35
  .optional()
35
36
  .describe('Optional stale-analysis reap threshold in milliseconds. Omit or null to disable auto-reaping.'),
36
37
  });
38
+ export const ghidraHealthOutputSchema = z.object({
39
+ ok: z.boolean(),
40
+ data: z
41
+ .object({
42
+ environment: z.any(),
43
+ downstream: z.record(z.any()).optional(),
44
+ reaped_persisted_analysis_ids: z.array(z.string()),
45
+ reaped_persisted_analysis_count: z.number().int().nonnegative(),
46
+ setup_actions: z.array(SetupActionSchema),
47
+ required_user_inputs: z.array(RequiredUserInputSchema),
48
+ })
49
+ .optional(),
50
+ errors: z.array(z.string()).optional(),
51
+ warnings: z.array(z.string()).optional(),
52
+ });
37
53
  export const ghidraHealthToolDefinition = {
38
54
  name: 'ghidra.health',
39
55
  description: 'Run a Ghidra environment health check plus optional end-to-end downstream probes using a real analyzed sample/project.',
40
56
  inputSchema: ghidraHealthInputSchema,
57
+ outputSchema: ghidraHealthOutputSchema,
41
58
  };
42
59
  function jsonResult(payload, isError) {
43
60
  return {
@@ -88,6 +105,15 @@ export function createGhidraHealthHandler(workspaceManager, database, dependenci
88
105
  const result = runHealthCheck(input.timeout_ms);
89
106
  const warnings = [...result.warnings];
90
107
  const errors = [...result.errors];
108
+ let setupActions = [];
109
+ let requiredUserInputs = [];
110
+ if (!result.ok) {
111
+ setupActions = mergeSetupActions(setupActions, buildGhidraSetupActions());
112
+ requiredUserInputs = mergeRequiredUserInputs(requiredUserInputs, buildGhidraRequiredUserInputs());
113
+ }
114
+ if (result.checks?.pyghidra_available === false) {
115
+ setupActions = mergeSetupActions(setupActions, buildPyGhidraSetupActions());
116
+ }
91
117
  let reapedAnalyses = [];
92
118
  if (database && typeof input.stale_running_ms === 'number') {
93
119
  reapedAnalyses = database
@@ -196,6 +222,8 @@ export function createGhidraHealthHandler(workspaceManager, database, dependenci
196
222
  downstream,
197
223
  reaped_persisted_analysis_ids: reapedAnalyses,
198
224
  reaped_persisted_analysis_count: reapedAnalyses.length,
225
+ setup_actions: setupActions,
226
+ required_user_inputs: requiredUserInputs,
199
227
  },
200
228
  errors: errors.length > 0 ? errors : undefined,
201
229
  warnings: warnings.length > 0 ? warnings : undefined,
@@ -141,10 +141,6 @@ export declare const IOCExportOutputSchema: z.ZodObject<{
141
141
  }>>;
142
142
  }, "strip", z.ZodTypeAny, {
143
143
  ok: boolean;
144
- metrics?: {
145
- elapsed_ms: number;
146
- tool: string;
147
- } | undefined;
148
144
  data?: {
149
145
  sample_id: string;
150
146
  tool_version: string;
@@ -168,15 +164,15 @@ export declare const IOCExportOutputSchema: z.ZodObject<{
168
164
  mime: string;
169
165
  } | undefined;
170
166
  } | undefined;
167
+ metrics?: {
168
+ elapsed_ms: number;
169
+ tool: string;
170
+ } | undefined;
171
171
  warnings?: string[] | undefined;
172
172
  errors?: string[] | undefined;
173
173
  artifacts?: any[] | undefined;
174
174
  }, {
175
175
  ok: boolean;
176
- metrics?: {
177
- elapsed_ms: number;
178
- tool: string;
179
- } | undefined;
180
176
  data?: {
181
177
  sample_id: string;
182
178
  tool_version: string;
@@ -200,6 +196,10 @@ export declare const IOCExportOutputSchema: z.ZodObject<{
200
196
  mime: string;
201
197
  } | undefined;
202
198
  } | undefined;
199
+ metrics?: {
200
+ elapsed_ms: number;
201
+ tool: string;
202
+ } | undefined;
203
203
  warnings?: string[] | undefined;
204
204
  errors?: string[] | undefined;
205
205
  artifacts?: any[] | undefined;
@@ -58,7 +58,6 @@ export declare const PackerDetectOutputSchema: z.ZodObject<{
58
58
  inference: z.ZodOptional<z.ZodRecord<z.ZodString, z.ZodAny>>;
59
59
  }, "strip", z.ZodTypeAny, {
60
60
  confidence: number;
61
- methods: string[];
62
61
  packed: boolean;
63
62
  detections: {
64
63
  name: string;
@@ -66,13 +65,13 @@ export declare const PackerDetectOutputSchema: z.ZodObject<{
66
65
  method: string;
67
66
  details: Record<string, any>;
68
67
  }[];
68
+ methods: string[];
69
69
  evidence?: Record<string, any> | undefined;
70
70
  inference?: Record<string, any> | undefined;
71
71
  confidence_breakdown?: Record<string, number> | undefined;
72
72
  feature_fusion?: Record<string, any> | undefined;
73
73
  }, {
74
74
  confidence: number;
75
- methods: string[];
76
75
  packed: boolean;
77
76
  detections: {
78
77
  name: string;
@@ -80,6 +79,7 @@ export declare const PackerDetectOutputSchema: z.ZodObject<{
80
79
  method: string;
81
80
  details: Record<string, any>;
82
81
  }[];
82
+ methods: string[];
83
83
  evidence?: Record<string, any> | undefined;
84
84
  inference?: Record<string, any> | undefined;
85
85
  confidence_breakdown?: Record<string, number> | undefined;
@@ -103,14 +103,8 @@ export declare const PackerDetectOutputSchema: z.ZodObject<{
103
103
  }>>;
104
104
  }, "strip", z.ZodTypeAny, {
105
105
  ok: boolean;
106
- metrics?: {
107
- elapsed_ms: number;
108
- tool: string;
109
- engines_used?: string[] | undefined;
110
- } | undefined;
111
106
  data?: {
112
107
  confidence: number;
113
- methods: string[];
114
108
  packed: boolean;
115
109
  detections: {
116
110
  name: string;
@@ -118,24 +112,24 @@ export declare const PackerDetectOutputSchema: z.ZodObject<{
118
112
  method: string;
119
113
  details: Record<string, any>;
120
114
  }[];
115
+ methods: string[];
121
116
  evidence?: Record<string, any> | undefined;
122
117
  inference?: Record<string, any> | undefined;
123
118
  confidence_breakdown?: Record<string, number> | undefined;
124
119
  feature_fusion?: Record<string, any> | undefined;
125
120
  } | undefined;
126
- warnings?: string[] | undefined;
127
- errors?: string[] | undefined;
128
- artifacts?: any[] | undefined;
129
- }, {
130
- ok: boolean;
131
121
  metrics?: {
132
122
  elapsed_ms: number;
133
123
  tool: string;
134
124
  engines_used?: string[] | undefined;
135
125
  } | undefined;
126
+ warnings?: string[] | undefined;
127
+ errors?: string[] | undefined;
128
+ artifacts?: any[] | undefined;
129
+ }, {
130
+ ok: boolean;
136
131
  data?: {
137
132
  confidence: number;
138
- methods: string[];
139
133
  packed: boolean;
140
134
  detections: {
141
135
  name: string;
@@ -143,11 +137,17 @@ export declare const PackerDetectOutputSchema: z.ZodObject<{
143
137
  method: string;
144
138
  details: Record<string, any>;
145
139
  }[];
140
+ methods: string[];
146
141
  evidence?: Record<string, any> | undefined;
147
142
  inference?: Record<string, any> | undefined;
148
143
  confidence_breakdown?: Record<string, number> | undefined;
149
144
  feature_fusion?: Record<string, any> | undefined;
150
145
  } | undefined;
146
+ metrics?: {
147
+ elapsed_ms: number;
148
+ tool: string;
149
+ engines_used?: string[] | undefined;
150
+ } | undefined;
151
151
  warnings?: string[] | undefined;
152
152
  errors?: string[] | undefined;
153
153
  artifacts?: any[] | undefined;
@@ -5,11 +5,11 @@
5
5
  */
6
6
  import { z } from 'zod';
7
7
  import { spawn } from 'child_process';
8
- import path from 'path';
9
8
  import { v4 as uuidv4 } from 'uuid';
10
9
  import { generateCacheKey } from '../cache-manager.js';
11
10
  import { resolvePackagePath } from '../runtime-paths.js';
12
11
  import { lookupCachedResult, formatCacheWarning } from './cache-observability.js';
12
+ import { inspectSampleWorkspace, formatMissingOriginalError, resolvePrimarySamplePath } from '../sample-workspace.js';
13
13
  // ============================================================================
14
14
  // Constants
15
15
  // ============================================================================
@@ -201,18 +201,15 @@ export function createPackerDetectHandler(workspaceManager, database, cacheManag
201
201
  };
202
202
  }
203
203
  }
204
- // 4. Get sample path from workspace
205
- const workspace = await workspaceManager.getWorkspace(input.sample_id);
206
- // Find the sample file in the original directory
207
- const fs = await import('fs/promises');
208
- const files = await fs.readdir(workspace.original);
209
- if (files.length === 0) {
204
+ // 4. Get sample path from workspace, allowing legacy sibling workspace fallback
205
+ const { samplePath } = await resolvePrimarySamplePath(workspaceManager, input.sample_id);
206
+ if (!samplePath) {
207
+ const integrity = await inspectSampleWorkspace(workspaceManager, input.sample_id);
210
208
  return {
211
209
  ok: false,
212
- errors: ['Sample file not found in workspace'],
210
+ errors: [formatMissingOriginalError(input.sample_id, integrity)],
213
211
  };
214
212
  }
215
- const samplePath = path.join(workspace.original, files[0]);
216
213
  // 5. Prepare worker request
217
214
  const workerRequest = {
218
215
  job_id: uuidv4(),
@@ -111,10 +111,6 @@ export declare const PEExportsExtractOutputSchema: z.ZodObject<{
111
111
  }>>;
112
112
  }, "strip", z.ZodTypeAny, {
113
113
  ok: boolean;
114
- metrics?: {
115
- elapsed_ms: number;
116
- tool: string;
117
- } | undefined;
118
114
  data?: {
119
115
  exports: {
120
116
  address: number;
@@ -132,15 +128,15 @@ export declare const PEExportsExtractOutputSchema: z.ZodObject<{
132
128
  _parser?: string | undefined;
133
129
  _pefile_error?: string | undefined;
134
130
  } | undefined;
131
+ metrics?: {
132
+ elapsed_ms: number;
133
+ tool: string;
134
+ } | undefined;
135
135
  warnings?: string[] | undefined;
136
136
  errors?: string[] | undefined;
137
137
  artifacts?: any[] | undefined;
138
138
  }, {
139
139
  ok: boolean;
140
- metrics?: {
141
- elapsed_ms: number;
142
- tool: string;
143
- } | undefined;
144
140
  data?: {
145
141
  exports: {
146
142
  address: number;
@@ -158,6 +154,10 @@ export declare const PEExportsExtractOutputSchema: z.ZodObject<{
158
154
  _parser?: string | undefined;
159
155
  _pefile_error?: string | undefined;
160
156
  } | undefined;
157
+ metrics?: {
158
+ elapsed_ms: number;
159
+ tool: string;
160
+ } | undefined;
161
161
  warnings?: string[] | undefined;
162
162
  errors?: string[] | undefined;
163
163
  artifacts?: any[] | undefined;
@@ -5,11 +5,11 @@
5
5
  */
6
6
  import { z } from 'zod';
7
7
  import { spawn } from 'child_process';
8
- import path from 'path';
9
8
  import { v4 as uuidv4 } from 'uuid';
10
9
  import { generateCacheKey } from '../cache-manager.js';
11
10
  import { resolvePackagePath } from '../runtime-paths.js';
12
11
  import { lookupCachedResult, formatCacheWarning } from './cache-observability.js';
12
+ import { inspectSampleWorkspace, formatMissingOriginalError, resolvePrimarySamplePath } from '../sample-workspace.js';
13
13
  // ============================================================================
14
14
  // Constants
15
15
  // ============================================================================
@@ -179,18 +179,15 @@ export function createPEExportsExtractHandler(workspaceManager, database, cacheM
179
179
  };
180
180
  }
181
181
  }
182
- // 3. Get sample path from workspace
183
- const workspace = await workspaceManager.getWorkspace(input.sample_id);
184
- // Find the sample file in the original directory
185
- const fs = await import('fs/promises');
186
- const files = await fs.readdir(workspace.original);
187
- if (files.length === 0) {
182
+ // 3. Get sample path from workspace, allowing legacy sibling workspace fallback
183
+ const { samplePath } = await resolvePrimarySamplePath(workspaceManager, input.sample_id);
184
+ if (!samplePath) {
185
+ const integrity = await inspectSampleWorkspace(workspaceManager, input.sample_id);
188
186
  return {
189
187
  ok: false,
190
- errors: ['Sample file not found in workspace'],
188
+ errors: [formatMissingOriginalError(input.sample_id, integrity)],
191
189
  };
192
190
  }
193
- const samplePath = path.join(workspace.original, files[0]);
194
191
  // 4. Prepare worker request
195
192
  const workerRequest = {
196
193
  job_id: uuidv4(),
@@ -86,18 +86,12 @@ export declare const PEFingerprintOutputSchema: z.ZodObject<{
86
86
  entry_point: number;
87
87
  machine: number;
88
88
  machine_name: string;
89
+ image_base: number;
89
90
  subsystem: number;
90
91
  subsystem_name: string;
91
92
  timestamp: number;
92
93
  timestamp_iso: string | null;
93
94
  imphash: string | null;
94
- image_base: number;
95
- signature?: {
96
- present: boolean;
97
- address?: number | undefined;
98
- size?: number | undefined;
99
- verified?: boolean | undefined;
100
- } | undefined;
101
95
  sections?: {
102
96
  name: string;
103
97
  virtual_address: number;
@@ -106,24 +100,24 @@ export declare const PEFingerprintOutputSchema: z.ZodObject<{
106
100
  entropy: number;
107
101
  characteristics: number;
108
102
  }[] | undefined;
103
+ signature?: {
104
+ present: boolean;
105
+ address?: number | undefined;
106
+ size?: number | undefined;
107
+ verified?: boolean | undefined;
108
+ } | undefined;
109
109
  _parser?: string | undefined;
110
110
  _pefile_error?: string | undefined;
111
111
  }, {
112
112
  entry_point: number;
113
113
  machine: number;
114
114
  machine_name: string;
115
+ image_base: number;
115
116
  subsystem: number;
116
117
  subsystem_name: string;
117
118
  timestamp: number;
118
119
  timestamp_iso: string | null;
119
120
  imphash: string | null;
120
- image_base: number;
121
- signature?: {
122
- present: boolean;
123
- address?: number | undefined;
124
- size?: number | undefined;
125
- verified?: boolean | undefined;
126
- } | undefined;
127
121
  sections?: {
128
122
  name: string;
129
123
  virtual_address: number;
@@ -132,6 +126,12 @@ export declare const PEFingerprintOutputSchema: z.ZodObject<{
132
126
  entropy: number;
133
127
  characteristics: number;
134
128
  }[] | undefined;
129
+ signature?: {
130
+ present: boolean;
131
+ address?: number | undefined;
132
+ size?: number | undefined;
133
+ verified?: boolean | undefined;
134
+ } | undefined;
135
135
  _parser?: string | undefined;
136
136
  _pefile_error?: string | undefined;
137
137
  }>>;
@@ -150,26 +150,16 @@ export declare const PEFingerprintOutputSchema: z.ZodObject<{
150
150
  }>>;
151
151
  }, "strip", z.ZodTypeAny, {
152
152
  ok: boolean;
153
- metrics?: {
154
- elapsed_ms: number;
155
- tool: string;
156
- } | undefined;
157
153
  data?: {
158
154
  entry_point: number;
159
155
  machine: number;
160
156
  machine_name: string;
157
+ image_base: number;
161
158
  subsystem: number;
162
159
  subsystem_name: string;
163
160
  timestamp: number;
164
161
  timestamp_iso: string | null;
165
162
  imphash: string | null;
166
- image_base: number;
167
- signature?: {
168
- present: boolean;
169
- address?: number | undefined;
170
- size?: number | undefined;
171
- verified?: boolean | undefined;
172
- } | undefined;
173
163
  sections?: {
174
164
  name: string;
175
165
  virtual_address: number;
@@ -178,34 +168,34 @@ export declare const PEFingerprintOutputSchema: z.ZodObject<{
178
168
  entropy: number;
179
169
  characteristics: number;
180
170
  }[] | undefined;
171
+ signature?: {
172
+ present: boolean;
173
+ address?: number | undefined;
174
+ size?: number | undefined;
175
+ verified?: boolean | undefined;
176
+ } | undefined;
181
177
  _parser?: string | undefined;
182
178
  _pefile_error?: string | undefined;
183
179
  } | undefined;
180
+ metrics?: {
181
+ elapsed_ms: number;
182
+ tool: string;
183
+ } | undefined;
184
184
  warnings?: string[] | undefined;
185
185
  errors?: string[] | undefined;
186
186
  artifacts?: any[] | undefined;
187
187
  }, {
188
188
  ok: boolean;
189
- metrics?: {
190
- elapsed_ms: number;
191
- tool: string;
192
- } | undefined;
193
189
  data?: {
194
190
  entry_point: number;
195
191
  machine: number;
196
192
  machine_name: string;
193
+ image_base: number;
197
194
  subsystem: number;
198
195
  subsystem_name: string;
199
196
  timestamp: number;
200
197
  timestamp_iso: string | null;
201
198
  imphash: string | null;
202
- image_base: number;
203
- signature?: {
204
- present: boolean;
205
- address?: number | undefined;
206
- size?: number | undefined;
207
- verified?: boolean | undefined;
208
- } | undefined;
209
199
  sections?: {
210
200
  name: string;
211
201
  virtual_address: number;
@@ -214,9 +204,19 @@ export declare const PEFingerprintOutputSchema: z.ZodObject<{
214
204
  entropy: number;
215
205
  characteristics: number;
216
206
  }[] | undefined;
207
+ signature?: {
208
+ present: boolean;
209
+ address?: number | undefined;
210
+ size?: number | undefined;
211
+ verified?: boolean | undefined;
212
+ } | undefined;
217
213
  _parser?: string | undefined;
218
214
  _pefile_error?: string | undefined;
219
215
  } | undefined;
216
+ metrics?: {
217
+ elapsed_ms: number;
218
+ tool: string;
219
+ } | undefined;
220
220
  warnings?: string[] | undefined;
221
221
  errors?: string[] | undefined;
222
222
  artifacts?: any[] | undefined;
@@ -63,31 +63,31 @@ export declare const PEImportsExtractOutputSchema: z.ZodObject<{
63
63
  }>>;
64
64
  }, "strip", z.ZodTypeAny, {
65
65
  ok: boolean;
66
- metrics?: {
67
- elapsed_ms: number;
68
- tool: string;
69
- } | undefined;
70
66
  data?: {
71
67
  _parser?: string | undefined;
72
68
  _pefile_error?: string | undefined;
73
69
  imports?: Record<string, string[]> | undefined;
74
70
  delay_imports?: Record<string, string[]> | undefined;
75
71
  } | undefined;
72
+ metrics?: {
73
+ elapsed_ms: number;
74
+ tool: string;
75
+ } | undefined;
76
76
  warnings?: string[] | undefined;
77
77
  errors?: string[] | undefined;
78
78
  artifacts?: any[] | undefined;
79
79
  }, {
80
80
  ok: boolean;
81
- metrics?: {
82
- elapsed_ms: number;
83
- tool: string;
84
- } | undefined;
85
81
  data?: {
86
82
  _parser?: string | undefined;
87
83
  _pefile_error?: string | undefined;
88
84
  imports?: Record<string, string[]> | undefined;
89
85
  delay_imports?: Record<string, string[]> | undefined;
90
86
  } | undefined;
87
+ metrics?: {
88
+ elapsed_ms: number;
89
+ tool: string;
90
+ } | undefined;
91
91
  warnings?: string[] | undefined;
92
92
  errors?: string[] | undefined;
93
93
  artifacts?: any[] | undefined;
@@ -5,11 +5,11 @@
5
5
  */
6
6
  import { z } from 'zod';
7
7
  import { spawn } from 'child_process';
8
- import path from 'path';
9
8
  import { v4 as uuidv4 } from 'uuid';
10
9
  import { generateCacheKey } from '../cache-manager.js';
11
10
  import { resolvePackagePath } from '../runtime-paths.js';
12
11
  import { lookupCachedResult, formatCacheWarning } from './cache-observability.js';
12
+ import { inspectSampleWorkspace, formatMissingOriginalError, resolvePrimarySamplePath } from '../sample-workspace.js';
13
13
  // ============================================================================
14
14
  // Constants
15
15
  // ============================================================================
@@ -169,18 +169,15 @@ export function createPEImportsExtractHandler(workspaceManager, database, cacheM
169
169
  };
170
170
  }
171
171
  }
172
- // 3. Get sample path from workspace
173
- const workspace = await workspaceManager.getWorkspace(input.sample_id);
174
- // Find the sample file in the original directory
175
- const fs = await import('fs/promises');
176
- const files = await fs.readdir(workspace.original);
177
- if (files.length === 0) {
172
+ // 3. Get sample path from workspace, allowing legacy sibling workspace fallback
173
+ const { samplePath } = await resolvePrimarySamplePath(workspaceManager, input.sample_id);
174
+ if (!samplePath) {
175
+ const integrity = await inspectSampleWorkspace(workspaceManager, input.sample_id);
178
176
  return {
179
177
  ok: false,
180
- errors: ['Sample file not found in workspace'],
178
+ errors: [formatMissingOriginalError(input.sample_id, integrity)],
181
179
  };
182
180
  }
183
- const samplePath = path.join(workspace.original, files[0]);
184
181
  // 4. Prepare worker request
185
182
  const workerRequest = {
186
183
  job_id: uuidv4(),