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.
- package/CLAUDE_INSTALLATION.md +129 -0
- package/CODEX_INSTALLATION.md +25 -1
- package/COPILOT_INSTALLATION.md +29 -1
- package/LICENSE +21 -21
- package/README.md +232 -110
- package/dist/analysis-provenance.d.ts +50 -2
- package/dist/analysis-provenance.js +1 -0
- package/dist/analysis-task-runner.js +92 -0
- package/dist/config.d.ts +35 -16
- package/dist/config.js +37 -3
- package/dist/database.js +115 -115
- package/dist/decompiler-worker.d.ts +10 -5
- package/dist/decompiler-worker.js +240 -58
- package/dist/dynamic-trace.d.ts +6 -0
- package/dist/dynamic-trace.js +52 -1
- package/dist/ghidra-config.js +17 -1
- package/dist/index.js +38 -8
- package/dist/pe-runtime-functions.d.ts +90 -0
- package/dist/pe-runtime-functions.js +452 -0
- package/dist/prompts/module-reconstruction-review.d.ts +5 -0
- package/dist/prompts/module-reconstruction-review.js +65 -0
- package/dist/runtime-correlation.d.ts +5 -0
- package/dist/runtime-correlation.js +179 -2
- package/dist/sample-workspace.d.ts +28 -0
- package/dist/sample-workspace.js +186 -0
- package/dist/semantic-name-suggestion-artifacts.d.ts +56 -0
- package/dist/semantic-name-suggestion-artifacts.js +87 -0
- package/dist/server.js +1 -1
- package/dist/setup-guidance.d.ts +73 -0
- package/dist/setup-guidance.js +211 -0
- package/dist/tools/artifact-read.d.ts +10 -10
- package/dist/tools/artifacts-diff.d.ts +8 -8
- package/dist/tools/artifacts-list.d.ts +16 -16
- package/dist/tools/attack-map.d.ts +8 -8
- package/dist/tools/binary-role-profile.d.ts +1197 -0
- package/dist/tools/binary-role-profile.js +575 -0
- package/dist/tools/code-function-explain-apply.d.ts +12 -12
- package/dist/tools/code-function-explain-prepare.d.ts +12 -12
- package/dist/tools/code-function-explain-review.d.ts +58 -58
- package/dist/tools/code-function-rename-apply.d.ts +12 -12
- package/dist/tools/code-function-rename-prepare.d.ts +14 -14
- package/dist/tools/code-function-rename-review.d.ts +66 -66
- package/dist/tools/code-functions-define.d.ts +337 -0
- package/dist/tools/code-functions-define.js +337 -0
- package/dist/tools/code-functions-list.js +1 -1
- package/dist/tools/code-functions-rank.js +1 -1
- package/dist/tools/code-functions-reconstruct.d.ts +368 -58
- package/dist/tools/code-functions-reconstruct.js +130 -10
- package/dist/tools/code-functions-smart-recover.d.ts +352 -0
- package/dist/tools/code-functions-smart-recover.js +190 -0
- package/dist/tools/code-module-review-apply.d.ts +233 -0
- package/dist/tools/code-module-review-apply.js +209 -0
- package/dist/tools/code-module-review-prepare.d.ts +756 -0
- package/dist/tools/code-module-review-prepare.js +343 -0
- package/dist/tools/code-module-review.d.ts +474 -0
- package/dist/tools/code-module-review.js +566 -0
- package/dist/tools/code-reconstruct-export.d.ts +193 -21
- package/dist/tools/code-reconstruct-export.js +578 -21
- package/dist/tools/code-reconstruct-plan.d.ts +20 -20
- package/dist/tools/com-role-profile.d.ts +353 -0
- package/dist/tools/com-role-profile.js +186 -0
- package/dist/tools/dll-export-profile.d.ts +625 -0
- package/dist/tools/dll-export-profile.js +230 -0
- package/dist/tools/dotnet-metadata-extract.d.ts +122 -122
- package/dist/tools/dotnet-reconstruct-export.d.ts +49 -49
- package/dist/tools/dotnet-types-list.d.ts +66 -66
- package/dist/tools/dynamic-dependencies.d.ts +144 -8
- package/dist/tools/dynamic-dependencies.js +20 -1
- package/dist/tools/dynamic-memory-import.js +105 -2
- package/dist/tools/ghidra-analyze.d.ts +20 -0
- package/dist/tools/ghidra-analyze.js +10 -2
- package/dist/tools/ghidra-health.d.ts +177 -0
- package/dist/tools/ghidra-health.js +28 -0
- package/dist/tools/ioc-export.d.ts +8 -8
- package/dist/tools/packer-detect.d.ts +14 -14
- package/dist/tools/packer-detect.js +6 -9
- package/dist/tools/pe-exports-extract.d.ts +8 -8
- package/dist/tools/pe-exports-extract.js +6 -9
- package/dist/tools/pe-fingerprint.d.ts +36 -36
- package/dist/tools/pe-imports-extract.d.ts +8 -8
- package/dist/tools/pe-imports-extract.js +6 -9
- package/dist/tools/pe-pdata-extract.d.ts +448 -0
- package/dist/tools/pe-pdata-extract.js +219 -0
- package/dist/tools/pe-symbols-recover.d.ts +227 -0
- package/dist/tools/pe-symbols-recover.js +316 -0
- package/dist/tools/report-generate.d.ts +15 -1
- package/dist/tools/report-generate.js +139 -16
- package/dist/tools/report-summarize.d.ts +2242 -8
- package/dist/tools/report-summarize.js +246 -10
- package/dist/tools/runtime-detect.d.ts +8 -8
- package/dist/tools/runtime-detect.js +2 -12
- package/dist/tools/rust-binary-analyze.d.ts +2047 -0
- package/dist/tools/rust-binary-analyze.js +443 -0
- package/dist/tools/sample-profile-get.d.ts +135 -16
- package/dist/tools/sample-profile-get.js +35 -32
- package/dist/tools/sandbox-execute.d.ts +10 -10
- package/dist/tools/strings-extract.d.ts +8 -8
- package/dist/tools/strings-extract.js +2 -12
- package/dist/tools/strings-floss-decode.d.ts +8 -8
- package/dist/tools/system-health.d.ts +172 -36
- package/dist/tools/system-health.js +14 -0
- package/dist/tools/system-setup-guide.d.ts +179 -0
- package/dist/tools/system-setup-guide.js +62 -0
- package/dist/tools/tool-help.d.ts +16 -16
- package/dist/tools/tool-help.js +172 -0
- package/dist/tools/yara-scan.d.ts +8 -8
- package/dist/types.d.ts +2 -0
- package/dist/workflows/function-explanation-review.d.ts +3034 -76
- package/dist/workflows/function-explanation-review.js +172 -42
- package/dist/workflows/function-index-recover.d.ts +333 -0
- package/dist/workflows/function-index-recover.js +291 -0
- package/dist/workflows/module-reconstruction-review.d.ts +3537 -0
- package/dist/workflows/module-reconstruction-review.js +354 -0
- package/dist/workflows/reconstruct.d.ts +2182 -223
- package/dist/workflows/reconstruct.js +575 -32
- package/dist/workflows/semantic-name-review.d.ts +1436 -85
- package/dist/workflows/semantic-name-review.js +150 -58
- package/dist/workflows/triage.d.ts +8 -8
- package/ghidra_scripts/DecompileFunction.java +487 -487
- package/ghidra_scripts/ExtractCFG.java +256 -256
- package/ghidra_scripts/ExtractFunctions.java +442 -442
- package/ghidra_scripts/README.md +112 -112
- package/ghidra_scripts/SearchFunctionReferences.java +380 -380
- package/helpers/DotNetMetadataProbe/DotNetMetadataProbe.csproj +9 -9
- package/helpers/DotNetMetadataProbe/Program.cs +566 -566
- package/install-to-claude.ps1 +432 -0
- package/install-to-codex.ps1 +256 -178
- package/install-to-copilot.ps1 +389 -303
- package/package.json +4 -2
- package/requirements.txt +9 -9
- package/workers/requirements-dynamic.txt +11 -11
- package/workers/requirements.txt +8 -8
- package/workers/speakeasy_compat.py +175 -175
- package/workers/static_worker.py +3474 -3474
|
@@ -0,0 +1,575 @@
|
|
|
1
|
+
import path from 'path';
|
|
2
|
+
import { z } from 'zod';
|
|
3
|
+
import { generateCacheKey } from '../cache-manager.js';
|
|
4
|
+
import { lookupCachedResult, formatCacheWarning } from './cache-observability.js';
|
|
5
|
+
import { createPEExportsExtractHandler } from './pe-exports-extract.js';
|
|
6
|
+
import { createPEImportsExtractHandler } from './pe-imports-extract.js';
|
|
7
|
+
import { createStringsExtractHandler } from './strings-extract.js';
|
|
8
|
+
import { createRuntimeDetectHandler } from './runtime-detect.js';
|
|
9
|
+
import { createPackerDetectHandler } from './packer-detect.js';
|
|
10
|
+
import { inspectSampleWorkspace, formatMissingOriginalError, resolvePrimarySamplePath, } from '../sample-workspace.js';
|
|
11
|
+
const TOOL_NAME = 'binary.role.profile';
|
|
12
|
+
const TOOL_VERSION = '0.2.0';
|
|
13
|
+
const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000;
|
|
14
|
+
export const BinaryRoleProfileInputSchema = z.object({
|
|
15
|
+
sample_id: z.string().describe('Sample ID (format: sha256:<hex>)'),
|
|
16
|
+
max_exports: z
|
|
17
|
+
.number()
|
|
18
|
+
.int()
|
|
19
|
+
.min(1)
|
|
20
|
+
.max(32)
|
|
21
|
+
.default(12)
|
|
22
|
+
.describe('Maximum notable exports returned in the summarized export surface'),
|
|
23
|
+
max_strings: z
|
|
24
|
+
.number()
|
|
25
|
+
.int()
|
|
26
|
+
.min(20)
|
|
27
|
+
.max(400)
|
|
28
|
+
.default(120)
|
|
29
|
+
.describe('Maximum strings inspected for COM/service/plugin role heuristics'),
|
|
30
|
+
force_refresh: z
|
|
31
|
+
.boolean()
|
|
32
|
+
.default(false)
|
|
33
|
+
.describe('Bypass cache lookup and recompute from source sample'),
|
|
34
|
+
});
|
|
35
|
+
export const ExportSurfaceSchema = z.object({
|
|
36
|
+
total_exports: z.number().int().nonnegative(),
|
|
37
|
+
total_forwarders: z.number().int().nonnegative(),
|
|
38
|
+
notable_exports: z.array(z.string()),
|
|
39
|
+
com_related_exports: z.array(z.string()),
|
|
40
|
+
service_related_exports: z.array(z.string()),
|
|
41
|
+
plugin_related_exports: z.array(z.string()),
|
|
42
|
+
forwarded_exports: z.array(z.string()),
|
|
43
|
+
});
|
|
44
|
+
export const ImportSurfaceSchema = z.object({
|
|
45
|
+
dll_count: z.number().int().nonnegative(),
|
|
46
|
+
notable_dlls: z.array(z.string()),
|
|
47
|
+
com_related_imports: z.array(z.string()),
|
|
48
|
+
service_related_imports: z.array(z.string()),
|
|
49
|
+
network_related_imports: z.array(z.string()),
|
|
50
|
+
process_related_imports: z.array(z.string()),
|
|
51
|
+
});
|
|
52
|
+
export const RoleIndicatorSchema = z.object({
|
|
53
|
+
likely: z.boolean(),
|
|
54
|
+
confidence: z.number().min(0).max(1),
|
|
55
|
+
evidence: z.array(z.string()),
|
|
56
|
+
});
|
|
57
|
+
export const ExportDispatchProfileSchema = z.object({
|
|
58
|
+
command_like_exports: z.array(z.string()),
|
|
59
|
+
callback_like_exports: z.array(z.string()),
|
|
60
|
+
registration_exports: z.array(z.string()),
|
|
61
|
+
ordinal_only_exports: z.number().int().nonnegative(),
|
|
62
|
+
likely_dispatch_model: z.string(),
|
|
63
|
+
confidence: z.number().min(0).max(1),
|
|
64
|
+
});
|
|
65
|
+
export const ComProfileSchema = z.object({
|
|
66
|
+
clsid_strings: z.array(z.string()),
|
|
67
|
+
progid_strings: z.array(z.string()),
|
|
68
|
+
interface_hints: z.array(z.string()),
|
|
69
|
+
registration_strings: z.array(z.string()),
|
|
70
|
+
class_factory_exports: z.array(z.string()),
|
|
71
|
+
class_factory_surface: z.array(z.string()).default([]),
|
|
72
|
+
confidence: z.number().min(0).max(1),
|
|
73
|
+
});
|
|
74
|
+
export const HostInteractionProfileSchema = z.object({
|
|
75
|
+
likely_hosted: z.boolean(),
|
|
76
|
+
host_hints: z.array(z.string()),
|
|
77
|
+
callback_exports: z.array(z.string()),
|
|
78
|
+
callback_surface: z.array(z.string()).default([]),
|
|
79
|
+
callback_strings: z.array(z.string()),
|
|
80
|
+
service_hooks: z.array(z.string()),
|
|
81
|
+
confidence: z.number().min(0).max(1),
|
|
82
|
+
});
|
|
83
|
+
export const BinaryRoleProfileDataSchema = z.object({
|
|
84
|
+
sample_id: z.string(),
|
|
85
|
+
original_filename: z.string().nullable(),
|
|
86
|
+
binary_role: z.string(),
|
|
87
|
+
role_confidence: z.number().min(0).max(1),
|
|
88
|
+
runtime_hint: z.object({
|
|
89
|
+
is_dotnet: z.boolean().nullable(),
|
|
90
|
+
dotnet_version: z.string().nullable(),
|
|
91
|
+
target_framework: z.string().nullable(),
|
|
92
|
+
primary_runtime: z.string().nullable(),
|
|
93
|
+
}),
|
|
94
|
+
export_surface: ExportSurfaceSchema,
|
|
95
|
+
import_surface: ImportSurfaceSchema,
|
|
96
|
+
packed: z.boolean(),
|
|
97
|
+
packing_confidence: z.number().min(0).max(1),
|
|
98
|
+
indicators: z.object({
|
|
99
|
+
com_server: RoleIndicatorSchema,
|
|
100
|
+
service_binary: RoleIndicatorSchema,
|
|
101
|
+
plugin_binary: RoleIndicatorSchema,
|
|
102
|
+
driver_binary: RoleIndicatorSchema,
|
|
103
|
+
}),
|
|
104
|
+
export_dispatch_profile: ExportDispatchProfileSchema,
|
|
105
|
+
lifecycle_surface: z.array(z.string()).default([]),
|
|
106
|
+
com_profile: ComProfileSchema,
|
|
107
|
+
host_interaction_profile: HostInteractionProfileSchema,
|
|
108
|
+
analysis_priorities: z.array(z.string()),
|
|
109
|
+
strings_considered: z.number().int().nonnegative(),
|
|
110
|
+
});
|
|
111
|
+
export const BinaryRoleProfileOutputSchema = z.object({
|
|
112
|
+
ok: z.boolean(),
|
|
113
|
+
data: BinaryRoleProfileDataSchema.optional(),
|
|
114
|
+
warnings: z.array(z.string()).optional(),
|
|
115
|
+
errors: z.array(z.string()).optional(),
|
|
116
|
+
metrics: z
|
|
117
|
+
.object({
|
|
118
|
+
elapsed_ms: z.number(),
|
|
119
|
+
tool: z.string(),
|
|
120
|
+
cached: z.boolean().optional(),
|
|
121
|
+
cache_key: z.string().optional(),
|
|
122
|
+
cache_tier: z.string().optional(),
|
|
123
|
+
cache_created_at: z.string().optional(),
|
|
124
|
+
cache_expires_at: z.string().optional(),
|
|
125
|
+
cache_hit_at: z.string().optional(),
|
|
126
|
+
})
|
|
127
|
+
.optional(),
|
|
128
|
+
});
|
|
129
|
+
export const binaryRoleProfileToolDefinition = {
|
|
130
|
+
name: TOOL_NAME,
|
|
131
|
+
description: 'Summarize Windows PE role, export surface, DLL/COM/service/plugin indicators, and analysis priorities for EXE/DLL-like samples.',
|
|
132
|
+
inputSchema: BinaryRoleProfileInputSchema,
|
|
133
|
+
outputSchema: BinaryRoleProfileOutputSchema,
|
|
134
|
+
};
|
|
135
|
+
function clamp(value, min = 0, max = 1) {
|
|
136
|
+
if (Number.isNaN(value)) {
|
|
137
|
+
return min;
|
|
138
|
+
}
|
|
139
|
+
return Math.min(max, Math.max(min, value));
|
|
140
|
+
}
|
|
141
|
+
function uniqueStrings(values) {
|
|
142
|
+
const seen = new Set();
|
|
143
|
+
const output = [];
|
|
144
|
+
for (const value of values) {
|
|
145
|
+
const trimmed = (value || '').trim();
|
|
146
|
+
if (!trimmed) {
|
|
147
|
+
continue;
|
|
148
|
+
}
|
|
149
|
+
if (seen.has(trimmed)) {
|
|
150
|
+
continue;
|
|
151
|
+
}
|
|
152
|
+
seen.add(trimmed);
|
|
153
|
+
output.push(trimmed);
|
|
154
|
+
}
|
|
155
|
+
return output;
|
|
156
|
+
}
|
|
157
|
+
async function getOriginalFilename(workspaceManager, sampleId) {
|
|
158
|
+
const { samplePath: primarySamplePath } = await resolvePrimarySamplePath(workspaceManager, sampleId);
|
|
159
|
+
if (!primarySamplePath) {
|
|
160
|
+
return null;
|
|
161
|
+
}
|
|
162
|
+
return path.basename(primarySamplePath);
|
|
163
|
+
}
|
|
164
|
+
function inferBinaryRole(originalFilename, sampleFileType, exportCount, importsData, runtimeData) {
|
|
165
|
+
const loweredName = (originalFilename || '').toLowerCase();
|
|
166
|
+
const loweredType = (sampleFileType || '').toLowerCase();
|
|
167
|
+
const importDlls = Object.keys(importsData?.imports || {}).map((item) => item.toLowerCase());
|
|
168
|
+
const evidence = [];
|
|
169
|
+
if (loweredName.endsWith('.sys') ||
|
|
170
|
+
loweredType.includes('driver') ||
|
|
171
|
+
importDlls.some((item) => item.includes('ntoskrnl') || item.includes('fltmgr'))) {
|
|
172
|
+
evidence.push('driver filename/type/import pattern');
|
|
173
|
+
return { binaryRole: 'driver', roleConfidence: 0.96, roleEvidence: evidence };
|
|
174
|
+
}
|
|
175
|
+
if (runtimeData?.is_dotnet) {
|
|
176
|
+
evidence.push('runtime.detect is_dotnet=true');
|
|
177
|
+
if (loweredName.endsWith('.dll') || loweredType.includes('dll')) {
|
|
178
|
+
evidence.push('dll filename/type');
|
|
179
|
+
return { binaryRole: '.net_library', roleConfidence: 0.95, roleEvidence: evidence };
|
|
180
|
+
}
|
|
181
|
+
return { binaryRole: '.net_executable', roleConfidence: 0.94, roleEvidence: evidence };
|
|
182
|
+
}
|
|
183
|
+
if (loweredName.endsWith('.dll') ||
|
|
184
|
+
loweredName.endsWith('.ocx') ||
|
|
185
|
+
loweredName.endsWith('.cpl') ||
|
|
186
|
+
loweredType.includes('dll')) {
|
|
187
|
+
evidence.push('dll-like filename/type');
|
|
188
|
+
return { binaryRole: 'dll', roleConfidence: exportCount > 0 ? 0.92 : 0.84, roleEvidence: evidence };
|
|
189
|
+
}
|
|
190
|
+
if (loweredName.endsWith('.exe') || loweredType.includes('exe') || loweredType.includes('pe32')) {
|
|
191
|
+
evidence.push('executable filename/type');
|
|
192
|
+
return {
|
|
193
|
+
binaryRole: exportCount > 0 ? 'executable_with_exports' : 'executable',
|
|
194
|
+
roleConfidence: exportCount > 0 ? 0.8 : 0.88,
|
|
195
|
+
roleEvidence: evidence,
|
|
196
|
+
};
|
|
197
|
+
}
|
|
198
|
+
if (exportCount > 0) {
|
|
199
|
+
evidence.push('exports present without clear filename/type');
|
|
200
|
+
return { binaryRole: 'library_like_pe', roleConfidence: 0.73, roleEvidence: evidence };
|
|
201
|
+
}
|
|
202
|
+
return { binaryRole: 'pe_image', roleConfidence: 0.62, roleEvidence: ['generic PE image'] };
|
|
203
|
+
}
|
|
204
|
+
function buildRoleIndicator(confidence, evidence) {
|
|
205
|
+
return {
|
|
206
|
+
likely: confidence >= 0.55,
|
|
207
|
+
confidence: clamp(confidence),
|
|
208
|
+
evidence: uniqueStrings(evidence),
|
|
209
|
+
};
|
|
210
|
+
}
|
|
211
|
+
function flattenImportFunctions(importsData) {
|
|
212
|
+
return uniqueStrings(Object.values(importsData?.imports || {})
|
|
213
|
+
.flatMap((items) => items || [])
|
|
214
|
+
.map((item) => item.trim()));
|
|
215
|
+
}
|
|
216
|
+
export function createBinaryRoleProfileHandler(workspaceManager, database, cacheManager, dependencies) {
|
|
217
|
+
const exportsHandler = dependencies?.exportsHandler ||
|
|
218
|
+
createPEExportsExtractHandler(workspaceManager, database, cacheManager);
|
|
219
|
+
const importsHandler = dependencies?.importsHandler ||
|
|
220
|
+
createPEImportsExtractHandler(workspaceManager, database, cacheManager);
|
|
221
|
+
const stringsHandler = dependencies?.stringsHandler ||
|
|
222
|
+
createStringsExtractHandler(workspaceManager, database, cacheManager);
|
|
223
|
+
const runtimeHandler = dependencies?.runtimeHandler ||
|
|
224
|
+
createRuntimeDetectHandler(workspaceManager, database, cacheManager);
|
|
225
|
+
const packerHandler = dependencies?.packerHandler ||
|
|
226
|
+
createPackerDetectHandler(workspaceManager, database, cacheManager);
|
|
227
|
+
return async (args) => {
|
|
228
|
+
const input = BinaryRoleProfileInputSchema.parse(args);
|
|
229
|
+
const startTime = Date.now();
|
|
230
|
+
try {
|
|
231
|
+
const sample = database.findSample(input.sample_id);
|
|
232
|
+
if (!sample) {
|
|
233
|
+
return {
|
|
234
|
+
ok: false,
|
|
235
|
+
errors: [`Sample not found: ${input.sample_id}`],
|
|
236
|
+
metrics: {
|
|
237
|
+
elapsed_ms: Date.now() - startTime,
|
|
238
|
+
tool: TOOL_NAME,
|
|
239
|
+
},
|
|
240
|
+
};
|
|
241
|
+
}
|
|
242
|
+
const originalFilename = await getOriginalFilename(workspaceManager, input.sample_id);
|
|
243
|
+
if (!originalFilename) {
|
|
244
|
+
const integrity = await inspectSampleWorkspace(workspaceManager, input.sample_id);
|
|
245
|
+
return {
|
|
246
|
+
ok: false,
|
|
247
|
+
errors: [formatMissingOriginalError(input.sample_id, integrity)],
|
|
248
|
+
metrics: {
|
|
249
|
+
elapsed_ms: Date.now() - startTime,
|
|
250
|
+
tool: TOOL_NAME,
|
|
251
|
+
},
|
|
252
|
+
};
|
|
253
|
+
}
|
|
254
|
+
const cacheKey = generateCacheKey({
|
|
255
|
+
sampleSha256: sample.sha256,
|
|
256
|
+
toolName: TOOL_NAME,
|
|
257
|
+
toolVersion: TOOL_VERSION,
|
|
258
|
+
args: {
|
|
259
|
+
max_exports: input.max_exports,
|
|
260
|
+
max_strings: input.max_strings,
|
|
261
|
+
original_filename: originalFilename,
|
|
262
|
+
},
|
|
263
|
+
});
|
|
264
|
+
if (!input.force_refresh) {
|
|
265
|
+
const cachedLookup = await lookupCachedResult(cacheManager, cacheKey);
|
|
266
|
+
if (cachedLookup) {
|
|
267
|
+
return {
|
|
268
|
+
ok: true,
|
|
269
|
+
data: cachedLookup.data,
|
|
270
|
+
warnings: ['Result from cache', formatCacheWarning(cachedLookup.metadata)],
|
|
271
|
+
metrics: {
|
|
272
|
+
elapsed_ms: Date.now() - startTime,
|
|
273
|
+
tool: TOOL_NAME,
|
|
274
|
+
cached: true,
|
|
275
|
+
cache_key: cachedLookup.metadata.key,
|
|
276
|
+
cache_tier: cachedLookup.metadata.tier,
|
|
277
|
+
cache_created_at: cachedLookup.metadata.createdAt,
|
|
278
|
+
cache_expires_at: cachedLookup.metadata.expiresAt,
|
|
279
|
+
cache_hit_at: cachedLookup.metadata.fetchedAt,
|
|
280
|
+
},
|
|
281
|
+
};
|
|
282
|
+
}
|
|
283
|
+
}
|
|
284
|
+
const [exportsResult, importsResult, stringsResult, runtimeResult, packerResult] = await Promise.all([
|
|
285
|
+
exportsHandler({ sample_id: input.sample_id, force_refresh: input.force_refresh }),
|
|
286
|
+
importsHandler({
|
|
287
|
+
sample_id: input.sample_id,
|
|
288
|
+
group_by_dll: true,
|
|
289
|
+
force_refresh: input.force_refresh,
|
|
290
|
+
}),
|
|
291
|
+
stringsHandler({
|
|
292
|
+
sample_id: input.sample_id,
|
|
293
|
+
category_filter: 'all',
|
|
294
|
+
max_strings: input.max_strings,
|
|
295
|
+
force_refresh: input.force_refresh,
|
|
296
|
+
}),
|
|
297
|
+
runtimeHandler({ sample_id: input.sample_id, force_refresh: input.force_refresh }),
|
|
298
|
+
packerHandler({ sample_id: input.sample_id, force_refresh: input.force_refresh }),
|
|
299
|
+
]);
|
|
300
|
+
const warnings = [
|
|
301
|
+
...(exportsResult.warnings || []).map((item) => `exports: ${item}`),
|
|
302
|
+
...(importsResult.warnings || []).map((item) => `imports: ${item}`),
|
|
303
|
+
...(stringsResult.warnings || []).map((item) => `strings: ${item}`),
|
|
304
|
+
...(runtimeResult.warnings || []).map((item) => `runtime: ${item}`),
|
|
305
|
+
...(packerResult.warnings || []).map((item) => `packer: ${item}`),
|
|
306
|
+
];
|
|
307
|
+
const exportsData = (exportsResult.ok ? exportsResult.data : undefined);
|
|
308
|
+
const importsData = (importsResult.ok ? importsResult.data : undefined);
|
|
309
|
+
const stringsData = (stringsResult.ok ? stringsResult.data : undefined);
|
|
310
|
+
const runtimeData = (runtimeResult.ok ? runtimeResult.data : undefined);
|
|
311
|
+
const packerData = (packerResult.ok ? packerResult.data : undefined);
|
|
312
|
+
const exportEntries = exportsData?.exports || [];
|
|
313
|
+
const forwarders = exportsData?.forwarders || [];
|
|
314
|
+
const importDlls = Object.keys(importsData?.imports || {});
|
|
315
|
+
const importFunctions = flattenImportFunctions(importsData);
|
|
316
|
+
const stringValues = (stringsData?.strings || []).map((item) => item.string);
|
|
317
|
+
const loweredStrings = stringValues.map((item) => item.toLowerCase());
|
|
318
|
+
const exportNames = exportEntries.map((item) => item.name).filter(Boolean);
|
|
319
|
+
const loweredExports = exportNames.map((item) => item.toLowerCase());
|
|
320
|
+
const loweredImportDlls = importDlls.map((item) => item.toLowerCase());
|
|
321
|
+
const loweredImportFunctions = importFunctions.map((item) => item.toLowerCase());
|
|
322
|
+
const { binaryRole, roleConfidence, roleEvidence } = inferBinaryRole(originalFilename, sample.file_type, exportsData?.total_exports ?? exportEntries.length, importsData, runtimeData);
|
|
323
|
+
const clsidStrings = uniqueStrings(stringValues.filter((item) => /\{[0-9a-f]{8}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{4}-[0-9a-f]{12}\}/i.test(item))).slice(0, 6);
|
|
324
|
+
const progIdStrings = uniqueStrings(stringValues.filter((item) => /progid|classfactory|iclassfactory|cocreateinstance|dllgetclassobject/i.test(item))).slice(0, 6);
|
|
325
|
+
const comExports = uniqueStrings(exportNames.filter((item) => /dll(getclassobject|canunloadnow|registerserver|unregisterserver)/i.test(item)));
|
|
326
|
+
const serviceExports = uniqueStrings(exportNames.filter((item) => /servicemain|svcmain/i.test(item)));
|
|
327
|
+
const pluginExports = uniqueStrings(exportNames.filter((item) => /plugin|addin|extension|initialize/i.test(item)));
|
|
328
|
+
const commandLikeExports = uniqueStrings(exportNames.filter((item) => /dispatch|command|execute|handle|invoke|run|process|query/i.test(item)));
|
|
329
|
+
const callbackLikeExports = uniqueStrings(exportNames.filter((item) => /callback|hook|notify|event|factory|attach|detach/i.test(item)));
|
|
330
|
+
const registrationExports = uniqueStrings(exportNames.filter((item) => /dll(registerserver|unregisterserver|install)|register/i.test(item)));
|
|
331
|
+
const forwardedExports = uniqueStrings(forwarders.map((item) => `${item.name || `ordinal_${item.ordinal}`} -> ${item.forwarder}`)).slice(0, input.max_exports);
|
|
332
|
+
const comImports = uniqueStrings(importDlls.filter((item) => /ole32|oleaut32|combase|rpcrt4/i.test(item)));
|
|
333
|
+
const serviceImports = uniqueStrings(importDlls.filter((item) => /advapi32/i.test(item)));
|
|
334
|
+
const networkImports = uniqueStrings(importDlls.filter((item) => /winhttp|wininet|ws2_32|dnsapi|urlmon/i.test(item)));
|
|
335
|
+
const processImports = uniqueStrings(importDlls.filter((item) => /kernel32|ntdll|psapi|dbghelp/i.test(item)));
|
|
336
|
+
const comEvidence = [
|
|
337
|
+
...roleEvidence.filter((item) => item.includes('dll')),
|
|
338
|
+
...comExports.map((item) => `export:${item}`),
|
|
339
|
+
...comImports.map((item) => `import:${item}`),
|
|
340
|
+
...clsidStrings.map((item) => `clsid:${item}`),
|
|
341
|
+
...progIdStrings.map((item) => `string:${item}`),
|
|
342
|
+
];
|
|
343
|
+
let comScore = 0;
|
|
344
|
+
if (comExports.length > 0)
|
|
345
|
+
comScore += 0.38;
|
|
346
|
+
if (comImports.length > 0)
|
|
347
|
+
comScore += 0.18;
|
|
348
|
+
if (clsidStrings.length > 0)
|
|
349
|
+
comScore += 0.22;
|
|
350
|
+
if (progIdStrings.length > 0)
|
|
351
|
+
comScore += 0.18;
|
|
352
|
+
if (binaryRole === 'dll' || binaryRole === '.net_library')
|
|
353
|
+
comScore += 0.08;
|
|
354
|
+
const interfaceHints = uniqueStrings(stringValues.filter((item) => /iunknown|idispatch|iclassfactory|ipropertypage|iprovid(e|er)|interface/i.test(item))).slice(0, 8);
|
|
355
|
+
const registrationStrings = uniqueStrings(stringValues.filter((item) => /inprocserver32|localserver32|typelib|appid|clsid|progid|treatas/i.test(item))).slice(0, 8);
|
|
356
|
+
const serviceStrings = uniqueStrings(stringValues.filter((item) => /services\\|registerservicectrlhandler|startservicectrldispatcher|setservicestatus|servicemain/i.test(item))).slice(0, 6);
|
|
357
|
+
const serviceEvidence = [
|
|
358
|
+
...serviceImports.map((item) => `import:${item}`),
|
|
359
|
+
...serviceExports.map((item) => `export:${item}`),
|
|
360
|
+
...serviceStrings.map((item) => `string:${item}`),
|
|
361
|
+
];
|
|
362
|
+
let serviceScore = 0;
|
|
363
|
+
if (serviceImports.length > 0)
|
|
364
|
+
serviceScore += 0.28;
|
|
365
|
+
if (serviceStrings.length > 0)
|
|
366
|
+
serviceScore += 0.24;
|
|
367
|
+
if (serviceExports.length > 0)
|
|
368
|
+
serviceScore += 0.18;
|
|
369
|
+
if (loweredStrings.some((item) => item.includes('currentcontrolset\\services')))
|
|
370
|
+
serviceScore += 0.16;
|
|
371
|
+
const pluginStrings = uniqueStrings(stringValues.filter((item) => /plugin|extension|addin|host application|register plugin/i.test(item))).slice(0, 6);
|
|
372
|
+
const pluginEvidence = [
|
|
373
|
+
...pluginExports.map((item) => `export:${item}`),
|
|
374
|
+
...pluginStrings.map((item) => `string:${item}`),
|
|
375
|
+
];
|
|
376
|
+
let pluginScore = 0;
|
|
377
|
+
if (pluginExports.length > 0)
|
|
378
|
+
pluginScore += 0.34;
|
|
379
|
+
if (pluginStrings.length > 0)
|
|
380
|
+
pluginScore += 0.22;
|
|
381
|
+
if ((binaryRole === 'dll' || binaryRole === '.net_library') && (pluginExports.length > 0 || pluginStrings.length > 0)) {
|
|
382
|
+
pluginScore += 0.16;
|
|
383
|
+
}
|
|
384
|
+
if (loweredExports.some((item) => item.includes('initialize')))
|
|
385
|
+
pluginScore += 0.1;
|
|
386
|
+
const hostHints = uniqueStrings([
|
|
387
|
+
...stringValues.filter((item) => /plugin host|host application|shell extension|addin|extension point|loaded by/i.test(item)),
|
|
388
|
+
...importDlls.filter((item) => /shell32|explorerframe|office|vbscript|jscript/i.test(item)),
|
|
389
|
+
]).slice(0, 8);
|
|
390
|
+
const callbackStrings = uniqueStrings(stringValues.filter((item) => /callback|event sink|notification|hook chain|observer/i.test(item))).slice(0, 8);
|
|
391
|
+
const serviceHooks = uniqueStrings([
|
|
392
|
+
...serviceExports,
|
|
393
|
+
...importFunctions.filter((item) => /startservicectrldispatcher|registerservicectrlhandler|setservicestatus/i.test(item)),
|
|
394
|
+
]).slice(0, 8);
|
|
395
|
+
let hostInteractionScore = 0;
|
|
396
|
+
if (pluginScore >= 0.4)
|
|
397
|
+
hostInteractionScore += 0.25;
|
|
398
|
+
if (callbackLikeExports.length > 0)
|
|
399
|
+
hostInteractionScore += 0.18;
|
|
400
|
+
if (callbackStrings.length > 0)
|
|
401
|
+
hostInteractionScore += 0.16;
|
|
402
|
+
if (hostHints.length > 0)
|
|
403
|
+
hostInteractionScore += 0.18;
|
|
404
|
+
if (serviceHooks.length > 0)
|
|
405
|
+
hostInteractionScore += 0.12;
|
|
406
|
+
let exportDispatchScore = 0;
|
|
407
|
+
if (commandLikeExports.length > 0)
|
|
408
|
+
exportDispatchScore += 0.34;
|
|
409
|
+
if (callbackLikeExports.length > 0)
|
|
410
|
+
exportDispatchScore += 0.18;
|
|
411
|
+
if (forwardedExports.length > 0)
|
|
412
|
+
exportDispatchScore += 0.08;
|
|
413
|
+
if (registrationExports.length > 0)
|
|
414
|
+
exportDispatchScore += 0.14;
|
|
415
|
+
if ((exportsData?.total_exports ?? exportEntries.length) >= 8)
|
|
416
|
+
exportDispatchScore += 0.12;
|
|
417
|
+
const ordinalOnlyExports = Math.max(0, (exportsData?.total_exports ?? exportEntries.length) - exportNames.length);
|
|
418
|
+
let likelyDispatchModel = 'none';
|
|
419
|
+
if (registrationExports.length > 0 && comScore >= 0.55) {
|
|
420
|
+
likelyDispatchModel = 'com_registration_and_class_factory';
|
|
421
|
+
}
|
|
422
|
+
else if (pluginScore >= 0.55 && hostInteractionScore >= 0.45) {
|
|
423
|
+
likelyDispatchModel = 'plugin_initialization_and_host_callbacks';
|
|
424
|
+
}
|
|
425
|
+
else if (commandLikeExports.length > 0) {
|
|
426
|
+
likelyDispatchModel = 'exported_command_dispatch';
|
|
427
|
+
}
|
|
428
|
+
else if (forwardedExports.length > 0) {
|
|
429
|
+
likelyDispatchModel = 'forwarded_export_surface';
|
|
430
|
+
}
|
|
431
|
+
const driverEvidence = uniqueStrings([
|
|
432
|
+
...roleEvidence.filter((item) => item.includes('driver')),
|
|
433
|
+
...loweredImportDlls.filter((item) => item.includes('ntoskrnl') || item.includes('fltmgr')).map((item) => `import:${item}`),
|
|
434
|
+
]);
|
|
435
|
+
let driverScore = 0;
|
|
436
|
+
if (binaryRole === 'driver')
|
|
437
|
+
driverScore += 0.62;
|
|
438
|
+
if (driverEvidence.length > 1)
|
|
439
|
+
driverScore += 0.2;
|
|
440
|
+
const priorities = [];
|
|
441
|
+
if (binaryRole === 'driver')
|
|
442
|
+
priorities.push('review_driver_entrypoints_and_ioctl_surface');
|
|
443
|
+
if (comScore >= 0.55)
|
|
444
|
+
priorities.push('trace_com_activation_and_class_factory_flow');
|
|
445
|
+
if (registrationExports.length > 0)
|
|
446
|
+
priorities.push('review_registration_exports_and_inprocserver_paths');
|
|
447
|
+
if (serviceScore >= 0.55)
|
|
448
|
+
priorities.push('trace_service_entrypoint_and_scm_lifecycle');
|
|
449
|
+
if (pluginScore >= 0.55)
|
|
450
|
+
priorities.push('trace_host_plugin_exports_and_callback_model');
|
|
451
|
+
if (exportDispatchScore >= 0.5)
|
|
452
|
+
priorities.push('review_exported_command_dispatch_surface');
|
|
453
|
+
if (hostInteractionScore >= 0.5)
|
|
454
|
+
priorities.push('identify_host_callbacks_and_extension_contract');
|
|
455
|
+
if (loweredImportFunctions.some((item) => item.includes('disablethreadlibrarycalls'))) {
|
|
456
|
+
priorities.push('review_dllmain_lifecycle_and_attach_detach_side_effects');
|
|
457
|
+
}
|
|
458
|
+
if ((exportsData?.total_exports ?? exportEntries.length) > 0)
|
|
459
|
+
priorities.push('trace_export_surface_first');
|
|
460
|
+
if ((exportsData?.total_forwarders ?? forwarders.length) > 0)
|
|
461
|
+
priorities.push('inspect_forwarded_exports');
|
|
462
|
+
if (runtimeData?.is_dotnet)
|
|
463
|
+
priorities.push('prefer_managed_metadata_and_il_recovery');
|
|
464
|
+
if (packerData?.packed || (packerData?.confidence || 0) >= 0.45)
|
|
465
|
+
priorities.push('unpack_or_stage_memory_import_before_deep_reconstruct');
|
|
466
|
+
if (networkImports.length > 0)
|
|
467
|
+
priorities.push('review_network_session_setup_and_remote_endpoints');
|
|
468
|
+
if (processImports.length > 0)
|
|
469
|
+
priorities.push('review_process_manipulation_and_dynamic_resolution_paths');
|
|
470
|
+
const lifecycleSurface = uniqueStrings([
|
|
471
|
+
...exportNames.filter((item) => /dllmain|dllentry|initialize/i.test(item)),
|
|
472
|
+
...importFunctions.filter((item) => /disablethreadlibrarycalls|getmodulehandle|freelibrary/i.test(item)),
|
|
473
|
+
...stringValues.filter((item) => /dllmain|dll_process_attach|dll_process_detach|thread_attach|thread_detach/i.test(item)),
|
|
474
|
+
]).slice(0, input.max_exports);
|
|
475
|
+
const classFactorySurface = uniqueStrings([
|
|
476
|
+
...comExports,
|
|
477
|
+
...interfaceHints.filter((item) => /iclassfactory|iunknown|idispatch/i.test(item)),
|
|
478
|
+
...stringValues.filter((item) => /createinstance|lockserver|dllgetclassobject|cocreateinstance/i.test(item)),
|
|
479
|
+
]).slice(0, input.max_exports);
|
|
480
|
+
const callbackSurface = uniqueStrings([
|
|
481
|
+
...callbackLikeExports,
|
|
482
|
+
...callbackStrings,
|
|
483
|
+
...hostHints.filter((item) => /plugin|extension|host/i.test(item)),
|
|
484
|
+
]).slice(0, input.max_exports);
|
|
485
|
+
const payload = {
|
|
486
|
+
sample_id: input.sample_id,
|
|
487
|
+
original_filename: originalFilename,
|
|
488
|
+
binary_role: binaryRole,
|
|
489
|
+
role_confidence: clamp(roleConfidence),
|
|
490
|
+
runtime_hint: {
|
|
491
|
+
is_dotnet: runtimeData?.is_dotnet ?? null,
|
|
492
|
+
dotnet_version: runtimeData?.dotnet_version ?? null,
|
|
493
|
+
target_framework: runtimeData?.target_framework ?? null,
|
|
494
|
+
primary_runtime: [...(runtimeData?.suspected || [])].sort((a, b) => b.confidence - a.confidence)[0]?.runtime ||
|
|
495
|
+
null,
|
|
496
|
+
},
|
|
497
|
+
export_surface: {
|
|
498
|
+
total_exports: exportsData?.total_exports ?? exportEntries.length,
|
|
499
|
+
total_forwarders: exportsData?.total_forwarders ?? forwarders.length,
|
|
500
|
+
notable_exports: uniqueStrings(exportNames).slice(0, input.max_exports),
|
|
501
|
+
com_related_exports: comExports.slice(0, input.max_exports),
|
|
502
|
+
service_related_exports: serviceExports.slice(0, input.max_exports),
|
|
503
|
+
plugin_related_exports: pluginExports.slice(0, input.max_exports),
|
|
504
|
+
forwarded_exports: forwardedExports,
|
|
505
|
+
},
|
|
506
|
+
import_surface: {
|
|
507
|
+
dll_count: importDlls.length,
|
|
508
|
+
notable_dlls: uniqueStrings(importDlls).slice(0, input.max_exports),
|
|
509
|
+
com_related_imports: comImports,
|
|
510
|
+
service_related_imports: serviceImports,
|
|
511
|
+
network_related_imports: networkImports,
|
|
512
|
+
process_related_imports: processImports,
|
|
513
|
+
},
|
|
514
|
+
packed: packerData?.packed === true,
|
|
515
|
+
packing_confidence: clamp(packerData?.confidence || 0),
|
|
516
|
+
indicators: {
|
|
517
|
+
com_server: buildRoleIndicator(comScore, comEvidence),
|
|
518
|
+
service_binary: buildRoleIndicator(serviceScore, serviceEvidence),
|
|
519
|
+
plugin_binary: buildRoleIndicator(pluginScore, pluginEvidence),
|
|
520
|
+
driver_binary: buildRoleIndicator(driverScore, driverEvidence),
|
|
521
|
+
},
|
|
522
|
+
export_dispatch_profile: {
|
|
523
|
+
command_like_exports: commandLikeExports.slice(0, input.max_exports),
|
|
524
|
+
callback_like_exports: callbackLikeExports.slice(0, input.max_exports),
|
|
525
|
+
registration_exports: registrationExports.slice(0, input.max_exports),
|
|
526
|
+
ordinal_only_exports: ordinalOnlyExports,
|
|
527
|
+
likely_dispatch_model: likelyDispatchModel,
|
|
528
|
+
confidence: clamp(exportDispatchScore),
|
|
529
|
+
},
|
|
530
|
+
lifecycle_surface: lifecycleSurface,
|
|
531
|
+
com_profile: {
|
|
532
|
+
clsid_strings: clsidStrings,
|
|
533
|
+
progid_strings: progIdStrings,
|
|
534
|
+
interface_hints: interfaceHints,
|
|
535
|
+
registration_strings: registrationStrings,
|
|
536
|
+
class_factory_exports: comExports.slice(0, input.max_exports),
|
|
537
|
+
class_factory_surface: classFactorySurface,
|
|
538
|
+
confidence: clamp(comScore),
|
|
539
|
+
},
|
|
540
|
+
host_interaction_profile: {
|
|
541
|
+
likely_hosted: hostInteractionScore >= 0.55,
|
|
542
|
+
host_hints: hostHints,
|
|
543
|
+
callback_exports: callbackLikeExports.slice(0, input.max_exports),
|
|
544
|
+
callback_surface: callbackSurface,
|
|
545
|
+
callback_strings: callbackStrings,
|
|
546
|
+
service_hooks: serviceHooks,
|
|
547
|
+
confidence: clamp(hostInteractionScore),
|
|
548
|
+
},
|
|
549
|
+
analysis_priorities: uniqueStrings(priorities).slice(0, 8),
|
|
550
|
+
strings_considered: stringValues.length,
|
|
551
|
+
};
|
|
552
|
+
await cacheManager.setCachedResult(cacheKey, payload, CACHE_TTL_MS, sample.sha256);
|
|
553
|
+
return {
|
|
554
|
+
ok: true,
|
|
555
|
+
data: payload,
|
|
556
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
557
|
+
metrics: {
|
|
558
|
+
elapsed_ms: Date.now() - startTime,
|
|
559
|
+
tool: TOOL_NAME,
|
|
560
|
+
},
|
|
561
|
+
};
|
|
562
|
+
}
|
|
563
|
+
catch (error) {
|
|
564
|
+
return {
|
|
565
|
+
ok: false,
|
|
566
|
+
errors: [error instanceof Error ? error.message : String(error)],
|
|
567
|
+
metrics: {
|
|
568
|
+
elapsed_ms: Date.now() - startTime,
|
|
569
|
+
tool: TOOL_NAME,
|
|
570
|
+
},
|
|
571
|
+
};
|
|
572
|
+
}
|
|
573
|
+
};
|
|
574
|
+
}
|
|
575
|
+
//# sourceMappingURL=binary-role-profile.js.map
|
|
@@ -148,9 +148,9 @@ export declare const codeFunctionExplainApplyOutputSchema: z.ZodObject<{
|
|
|
148
148
|
sha256: string;
|
|
149
149
|
mime?: string | undefined;
|
|
150
150
|
};
|
|
151
|
+
next_steps: string[];
|
|
151
152
|
accepted_count: number;
|
|
152
153
|
rejected_count: number;
|
|
153
|
-
next_steps: string[];
|
|
154
154
|
accepted_explanations: {
|
|
155
155
|
function: string | null;
|
|
156
156
|
address: string | null;
|
|
@@ -167,9 +167,9 @@ export declare const codeFunctionExplainApplyOutputSchema: z.ZodObject<{
|
|
|
167
167
|
sha256: string;
|
|
168
168
|
mime?: string | undefined;
|
|
169
169
|
};
|
|
170
|
+
next_steps: string[];
|
|
170
171
|
accepted_count: number;
|
|
171
172
|
rejected_count: number;
|
|
172
|
-
next_steps: string[];
|
|
173
173
|
accepted_explanations: {
|
|
174
174
|
function: string | null;
|
|
175
175
|
address: string | null;
|
|
@@ -193,10 +193,6 @@ export declare const codeFunctionExplainApplyOutputSchema: z.ZodObject<{
|
|
|
193
193
|
}>>;
|
|
194
194
|
}, "strip", z.ZodTypeAny, {
|
|
195
195
|
ok: boolean;
|
|
196
|
-
metrics?: {
|
|
197
|
-
elapsed_ms: number;
|
|
198
|
-
tool: string;
|
|
199
|
-
} | undefined;
|
|
200
196
|
data?: {
|
|
201
197
|
sample_id: string;
|
|
202
198
|
artifact: {
|
|
@@ -206,9 +202,9 @@ export declare const codeFunctionExplainApplyOutputSchema: z.ZodObject<{
|
|
|
206
202
|
sha256: string;
|
|
207
203
|
mime?: string | undefined;
|
|
208
204
|
};
|
|
205
|
+
next_steps: string[];
|
|
209
206
|
accepted_count: number;
|
|
210
207
|
rejected_count: number;
|
|
211
|
-
next_steps: string[];
|
|
212
208
|
accepted_explanations: {
|
|
213
209
|
function: string | null;
|
|
214
210
|
address: string | null;
|
|
@@ -217,15 +213,15 @@ export declare const codeFunctionExplainApplyOutputSchema: z.ZodObject<{
|
|
|
217
213
|
rewrite_guidance_count: number;
|
|
218
214
|
}[];
|
|
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;
|
|
223
223
|
}, {
|
|
224
224
|
ok: boolean;
|
|
225
|
-
metrics?: {
|
|
226
|
-
elapsed_ms: number;
|
|
227
|
-
tool: string;
|
|
228
|
-
} | undefined;
|
|
229
225
|
data?: {
|
|
230
226
|
sample_id: string;
|
|
231
227
|
artifact: {
|
|
@@ -235,9 +231,9 @@ export declare const codeFunctionExplainApplyOutputSchema: z.ZodObject<{
|
|
|
235
231
|
sha256: string;
|
|
236
232
|
mime?: string | undefined;
|
|
237
233
|
};
|
|
234
|
+
next_steps: string[];
|
|
238
235
|
accepted_count: number;
|
|
239
236
|
rejected_count: number;
|
|
240
|
-
next_steps: string[];
|
|
241
237
|
accepted_explanations: {
|
|
242
238
|
function: string | null;
|
|
243
239
|
address: string | null;
|
|
@@ -246,6 +242,10 @@ export declare const codeFunctionExplainApplyOutputSchema: z.ZodObject<{
|
|
|
246
242
|
rewrite_guidance_count: number;
|
|
247
243
|
}[];
|
|
248
244
|
} | undefined;
|
|
245
|
+
metrics?: {
|
|
246
|
+
elapsed_ms: number;
|
|
247
|
+
tool: string;
|
|
248
|
+
} | undefined;
|
|
249
249
|
warnings?: string[] | undefined;
|
|
250
250
|
errors?: string[] | undefined;
|
|
251
251
|
artifacts?: any[] | undefined;
|