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.
- package/CODEX_INSTALLATION.md +69 -0
- package/COPILOT_INSTALLATION.md +77 -0
- package/LICENSE +21 -0
- package/README.md +314 -0
- package/bin/windows-exe-decompiler-mcp-server.js +3 -0
- package/dist/analysis-provenance.d.ts +184 -0
- package/dist/analysis-provenance.js +74 -0
- package/dist/analysis-task-runner.d.ts +31 -0
- package/dist/analysis-task-runner.js +160 -0
- package/dist/artifact-inventory.d.ts +23 -0
- package/dist/artifact-inventory.js +175 -0
- package/dist/cache-manager.d.ts +128 -0
- package/dist/cache-manager.js +454 -0
- package/dist/confidence-semantics.d.ts +66 -0
- package/dist/confidence-semantics.js +122 -0
- package/dist/config.d.ts +335 -0
- package/dist/config.js +193 -0
- package/dist/database.d.ts +227 -0
- package/dist/database.js +601 -0
- package/dist/decompiler-worker.d.ts +441 -0
- package/dist/decompiler-worker.js +1962 -0
- package/dist/dynamic-trace.d.ts +95 -0
- package/dist/dynamic-trace.js +629 -0
- package/dist/env-validator.d.ts +15 -0
- package/dist/env-validator.js +249 -0
- package/dist/error-handler.d.ts +28 -0
- package/dist/error-handler.example.d.ts +22 -0
- package/dist/error-handler.example.js +141 -0
- package/dist/error-handler.js +139 -0
- package/dist/ghidra-analysis-status.d.ts +49 -0
- package/dist/ghidra-analysis-status.js +178 -0
- package/dist/ghidra-config.d.ts +134 -0
- package/dist/ghidra-config.js +464 -0
- package/dist/index.d.ts +9 -0
- package/dist/index.js +200 -0
- package/dist/job-queue.d.ts +169 -0
- package/dist/job-queue.js +407 -0
- package/dist/logger.d.ts +106 -0
- package/dist/logger.js +176 -0
- package/dist/policy-guard.d.ts +115 -0
- package/dist/policy-guard.js +243 -0
- package/dist/process-output.d.ts +15 -0
- package/dist/process-output.js +90 -0
- package/dist/prompts/function-explanation-review.d.ts +5 -0
- package/dist/prompts/function-explanation-review.js +64 -0
- package/dist/prompts/semantic-name-review.d.ts +5 -0
- package/dist/prompts/semantic-name-review.js +63 -0
- package/dist/runtime-correlation.d.ts +34 -0
- package/dist/runtime-correlation.js +279 -0
- package/dist/runtime-paths.d.ts +3 -0
- package/dist/runtime-paths.js +11 -0
- package/dist/selection-diff.d.ts +667 -0
- package/dist/selection-diff.js +53 -0
- package/dist/semantic-name-suggestion-artifacts.d.ts +116 -0
- package/dist/semantic-name-suggestion-artifacts.js +314 -0
- package/dist/server.d.ts +129 -0
- package/dist/server.js +578 -0
- package/dist/tools/artifact-read.d.ts +235 -0
- package/dist/tools/artifact-read.js +317 -0
- package/dist/tools/artifacts-diff.d.ts +728 -0
- package/dist/tools/artifacts-diff.js +304 -0
- package/dist/tools/artifacts-list.d.ts +515 -0
- package/dist/tools/artifacts-list.js +389 -0
- package/dist/tools/attack-map.d.ts +290 -0
- package/dist/tools/attack-map.js +519 -0
- package/dist/tools/cache-observability.d.ts +4 -0
- package/dist/tools/cache-observability.js +36 -0
- package/dist/tools/code-function-cfg.d.ts +50 -0
- package/dist/tools/code-function-cfg.js +102 -0
- package/dist/tools/code-function-decompile.d.ts +55 -0
- package/dist/tools/code-function-decompile.js +103 -0
- package/dist/tools/code-function-disassemble.d.ts +43 -0
- package/dist/tools/code-function-disassemble.js +185 -0
- package/dist/tools/code-function-explain-apply.d.ts +255 -0
- package/dist/tools/code-function-explain-apply.js +225 -0
- package/dist/tools/code-function-explain-prepare.d.ts +535 -0
- package/dist/tools/code-function-explain-prepare.js +276 -0
- package/dist/tools/code-function-explain-review.d.ts +397 -0
- package/dist/tools/code-function-explain-review.js +589 -0
- package/dist/tools/code-function-rename-apply.d.ts +248 -0
- package/dist/tools/code-function-rename-apply.js +220 -0
- package/dist/tools/code-function-rename-prepare.d.ts +506 -0
- package/dist/tools/code-function-rename-prepare.js +279 -0
- package/dist/tools/code-function-rename-review.d.ts +574 -0
- package/dist/tools/code-function-rename-review.js +761 -0
- package/dist/tools/code-functions-list.d.ts +37 -0
- package/dist/tools/code-functions-list.js +91 -0
- package/dist/tools/code-functions-rank.d.ts +34 -0
- package/dist/tools/code-functions-rank.js +90 -0
- package/dist/tools/code-functions-reconstruct.d.ts +2725 -0
- package/dist/tools/code-functions-reconstruct.js +2807 -0
- package/dist/tools/code-functions-search.d.ts +39 -0
- package/dist/tools/code-functions-search.js +90 -0
- package/dist/tools/code-reconstruct-export.d.ts +1212 -0
- package/dist/tools/code-reconstruct-export.js +4002 -0
- package/dist/tools/code-reconstruct-plan.d.ts +274 -0
- package/dist/tools/code-reconstruct-plan.js +342 -0
- package/dist/tools/dotnet-metadata-extract.d.ts +541 -0
- package/dist/tools/dotnet-metadata-extract.js +355 -0
- package/dist/tools/dotnet-reconstruct-export.d.ts +567 -0
- package/dist/tools/dotnet-reconstruct-export.js +1151 -0
- package/dist/tools/dotnet-types-list.d.ts +325 -0
- package/dist/tools/dotnet-types-list.js +201 -0
- package/dist/tools/dynamic-dependencies.d.ts +115 -0
- package/dist/tools/dynamic-dependencies.js +213 -0
- package/dist/tools/dynamic-memory-import.d.ts +10 -0
- package/dist/tools/dynamic-memory-import.js +567 -0
- package/dist/tools/dynamic-trace-import.d.ts +10 -0
- package/dist/tools/dynamic-trace-import.js +235 -0
- package/dist/tools/entrypoint-fallback-disasm.d.ts +30 -0
- package/dist/tools/entrypoint-fallback-disasm.js +89 -0
- package/dist/tools/ghidra-analyze.d.ts +88 -0
- package/dist/tools/ghidra-analyze.js +208 -0
- package/dist/tools/ghidra-health.d.ts +37 -0
- package/dist/tools/ghidra-health.js +212 -0
- package/dist/tools/ioc-export.d.ts +209 -0
- package/dist/tools/ioc-export.js +542 -0
- package/dist/tools/packer-detect.d.ts +165 -0
- package/dist/tools/packer-detect.js +284 -0
- package/dist/tools/pe-exports-extract.d.ts +175 -0
- package/dist/tools/pe-exports-extract.js +253 -0
- package/dist/tools/pe-fingerprint.d.ts +234 -0
- package/dist/tools/pe-fingerprint.js +269 -0
- package/dist/tools/pe-imports-extract.d.ts +105 -0
- package/dist/tools/pe-imports-extract.js +245 -0
- package/dist/tools/report-generate.d.ts +157 -0
- package/dist/tools/report-generate.js +457 -0
- package/dist/tools/report-summarize.d.ts +2131 -0
- package/dist/tools/report-summarize.js +596 -0
- package/dist/tools/runtime-detect.d.ts +135 -0
- package/dist/tools/runtime-detect.js +247 -0
- package/dist/tools/sample-ingest.d.ts +94 -0
- package/dist/tools/sample-ingest.js +327 -0
- package/dist/tools/sample-profile-get.d.ts +183 -0
- package/dist/tools/sample-profile-get.js +121 -0
- package/dist/tools/sandbox-execute.d.ts +441 -0
- package/dist/tools/sandbox-execute.js +392 -0
- package/dist/tools/strings-extract.d.ts +375 -0
- package/dist/tools/strings-extract.js +314 -0
- package/dist/tools/strings-floss-decode.d.ts +143 -0
- package/dist/tools/strings-floss-decode.js +259 -0
- package/dist/tools/system-health.d.ts +434 -0
- package/dist/tools/system-health.js +446 -0
- package/dist/tools/task-cancel.d.ts +21 -0
- package/dist/tools/task-cancel.js +70 -0
- package/dist/tools/task-status.d.ts +27 -0
- package/dist/tools/task-status.js +106 -0
- package/dist/tools/task-sweep.d.ts +22 -0
- package/dist/tools/task-sweep.js +77 -0
- package/dist/tools/tool-help.d.ts +340 -0
- package/dist/tools/tool-help.js +261 -0
- package/dist/tools/yara-scan.d.ts +554 -0
- package/dist/tools/yara-scan.js +313 -0
- package/dist/types.d.ts +266 -0
- package/dist/types.js +41 -0
- package/dist/worker-pool.d.ts +204 -0
- package/dist/worker-pool.js +650 -0
- package/dist/workflows/deep-static.d.ts +104 -0
- package/dist/workflows/deep-static.js +276 -0
- package/dist/workflows/function-explanation-review.d.ts +655 -0
- package/dist/workflows/function-explanation-review.js +440 -0
- package/dist/workflows/reconstruct.d.ts +2053 -0
- package/dist/workflows/reconstruct.js +666 -0
- package/dist/workflows/semantic-name-review.d.ts +2418 -0
- package/dist/workflows/semantic-name-review.js +521 -0
- package/dist/workflows/triage.d.ts +659 -0
- package/dist/workflows/triage.js +1374 -0
- package/dist/workspace-manager.d.ts +150 -0
- package/dist/workspace-manager.js +411 -0
- package/ghidra_scripts/DecompileFunction.java +487 -0
- package/ghidra_scripts/DecompileFunction.py +150 -0
- package/ghidra_scripts/ExtractCFG.java +256 -0
- package/ghidra_scripts/ExtractCFG.py +233 -0
- package/ghidra_scripts/ExtractFunctions.java +442 -0
- package/ghidra_scripts/ExtractFunctions.py +101 -0
- package/ghidra_scripts/README.md +125 -0
- package/ghidra_scripts/SearchFunctionReferences.java +380 -0
- package/helpers/DotNetMetadataProbe/DotNetMetadataProbe.csproj +9 -0
- package/helpers/DotNetMetadataProbe/Program.cs +566 -0
- package/install-to-codex.ps1 +178 -0
- package/install-to-copilot.ps1 +303 -0
- package/package.json +101 -0
- package/requirements.txt +9 -0
- package/workers/requirements-dynamic.txt +11 -0
- package/workers/requirements.txt +8 -0
- package/workers/speakeasy_compat.py +175 -0
- package/workers/static_worker.py +5183 -0
- package/workers/yara_rules/default.yar +33 -0
- package/workers/yara_rules/malware_families.yar +93 -0
- package/workers/yara_rules/packers.yar +80 -0
|
@@ -0,0 +1,274 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* code.reconstruct.plan tool implementation
|
|
3
|
+
* Builds a practical source-reconstruction plan from current static/decompiler signals.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import type { ToolDefinition, ToolArgs, WorkerResult } from '../types.js';
|
|
7
|
+
import type { WorkspaceManager } from '../workspace-manager.js';
|
|
8
|
+
import type { DatabaseManager } from '../database.js';
|
|
9
|
+
import type { CacheManager } from '../cache-manager.js';
|
|
10
|
+
export declare const CodeReconstructPlanInputSchema: z.ZodObject<{
|
|
11
|
+
sample_id: z.ZodString;
|
|
12
|
+
target_language: z.ZodDefault<z.ZodEnum<["auto", "csharp", "c", "cpp", "rust", "go"]>>;
|
|
13
|
+
depth: z.ZodDefault<z.ZodEnum<["quick", "standard", "deep"]>>;
|
|
14
|
+
include_decompiler: z.ZodDefault<z.ZodBoolean>;
|
|
15
|
+
include_strings: z.ZodDefault<z.ZodBoolean>;
|
|
16
|
+
}, "strip", z.ZodTypeAny, {
|
|
17
|
+
sample_id: string;
|
|
18
|
+
target_language: "rust" | "go" | "auto" | "csharp" | "c" | "cpp";
|
|
19
|
+
depth: "quick" | "standard" | "deep";
|
|
20
|
+
include_decompiler: boolean;
|
|
21
|
+
include_strings: boolean;
|
|
22
|
+
}, {
|
|
23
|
+
sample_id: string;
|
|
24
|
+
target_language?: "rust" | "go" | "auto" | "csharp" | "c" | "cpp" | undefined;
|
|
25
|
+
depth?: "quick" | "standard" | "deep" | undefined;
|
|
26
|
+
include_decompiler?: boolean | undefined;
|
|
27
|
+
include_strings?: boolean | undefined;
|
|
28
|
+
}>;
|
|
29
|
+
export type CodeReconstructPlanInput = z.infer<typeof CodeReconstructPlanInputSchema>;
|
|
30
|
+
export declare const CodeReconstructPlanOutputSchema: z.ZodObject<{
|
|
31
|
+
ok: z.ZodBoolean;
|
|
32
|
+
data: z.ZodOptional<z.ZodObject<{
|
|
33
|
+
feasibility: z.ZodEnum<["high", "medium", "low"]>;
|
|
34
|
+
confidence: z.ZodNumber;
|
|
35
|
+
restoration_expectation: z.ZodString;
|
|
36
|
+
runtime_summary: z.ZodObject<{
|
|
37
|
+
primary_runtime: z.ZodString;
|
|
38
|
+
suspected: z.ZodArray<z.ZodObject<{
|
|
39
|
+
runtime: z.ZodString;
|
|
40
|
+
confidence: z.ZodNumber;
|
|
41
|
+
evidence: z.ZodArray<z.ZodString, "many">;
|
|
42
|
+
}, "strip", z.ZodTypeAny, {
|
|
43
|
+
confidence: number;
|
|
44
|
+
evidence: string[];
|
|
45
|
+
runtime: string;
|
|
46
|
+
}, {
|
|
47
|
+
confidence: number;
|
|
48
|
+
evidence: string[];
|
|
49
|
+
runtime: string;
|
|
50
|
+
}>, "many">;
|
|
51
|
+
}, "strip", z.ZodTypeAny, {
|
|
52
|
+
suspected: {
|
|
53
|
+
confidence: number;
|
|
54
|
+
evidence: string[];
|
|
55
|
+
runtime: string;
|
|
56
|
+
}[];
|
|
57
|
+
primary_runtime: string;
|
|
58
|
+
}, {
|
|
59
|
+
suspected: {
|
|
60
|
+
confidence: number;
|
|
61
|
+
evidence: string[];
|
|
62
|
+
runtime: string;
|
|
63
|
+
}[];
|
|
64
|
+
primary_runtime: string;
|
|
65
|
+
}>;
|
|
66
|
+
packing_summary: z.ZodObject<{
|
|
67
|
+
packed: z.ZodBoolean;
|
|
68
|
+
confidence: z.ZodNumber;
|
|
69
|
+
}, "strip", z.ZodTypeAny, {
|
|
70
|
+
confidence: number;
|
|
71
|
+
packed: boolean;
|
|
72
|
+
}, {
|
|
73
|
+
confidence: number;
|
|
74
|
+
packed: boolean;
|
|
75
|
+
}>;
|
|
76
|
+
blockers: z.ZodArray<z.ZodString, "many">;
|
|
77
|
+
recommendations: z.ZodArray<z.ZodString, "many">;
|
|
78
|
+
phases: z.ZodArray<z.ZodObject<{
|
|
79
|
+
phase: z.ZodString;
|
|
80
|
+
title: z.ZodString;
|
|
81
|
+
objective: z.ZodString;
|
|
82
|
+
actions: z.ZodArray<z.ZodString, "many">;
|
|
83
|
+
estimated_effort: z.ZodEnum<["low", "medium", "high"]>;
|
|
84
|
+
confidence: z.ZodNumber;
|
|
85
|
+
}, "strip", z.ZodTypeAny, {
|
|
86
|
+
confidence: number;
|
|
87
|
+
title: string;
|
|
88
|
+
phase: string;
|
|
89
|
+
objective: string;
|
|
90
|
+
actions: string[];
|
|
91
|
+
estimated_effort: "high" | "low" | "medium";
|
|
92
|
+
}, {
|
|
93
|
+
confidence: number;
|
|
94
|
+
title: string;
|
|
95
|
+
phase: string;
|
|
96
|
+
objective: string;
|
|
97
|
+
actions: string[];
|
|
98
|
+
estimated_effort: "high" | "low" | "medium";
|
|
99
|
+
}>, "many">;
|
|
100
|
+
}, "strip", z.ZodTypeAny, {
|
|
101
|
+
confidence: number;
|
|
102
|
+
feasibility: "high" | "low" | "medium";
|
|
103
|
+
restoration_expectation: string;
|
|
104
|
+
runtime_summary: {
|
|
105
|
+
suspected: {
|
|
106
|
+
confidence: number;
|
|
107
|
+
evidence: string[];
|
|
108
|
+
runtime: string;
|
|
109
|
+
}[];
|
|
110
|
+
primary_runtime: string;
|
|
111
|
+
};
|
|
112
|
+
packing_summary: {
|
|
113
|
+
confidence: number;
|
|
114
|
+
packed: boolean;
|
|
115
|
+
};
|
|
116
|
+
blockers: string[];
|
|
117
|
+
recommendations: string[];
|
|
118
|
+
phases: {
|
|
119
|
+
confidence: number;
|
|
120
|
+
title: string;
|
|
121
|
+
phase: string;
|
|
122
|
+
objective: string;
|
|
123
|
+
actions: string[];
|
|
124
|
+
estimated_effort: "high" | "low" | "medium";
|
|
125
|
+
}[];
|
|
126
|
+
}, {
|
|
127
|
+
confidence: number;
|
|
128
|
+
feasibility: "high" | "low" | "medium";
|
|
129
|
+
restoration_expectation: string;
|
|
130
|
+
runtime_summary: {
|
|
131
|
+
suspected: {
|
|
132
|
+
confidence: number;
|
|
133
|
+
evidence: string[];
|
|
134
|
+
runtime: string;
|
|
135
|
+
}[];
|
|
136
|
+
primary_runtime: string;
|
|
137
|
+
};
|
|
138
|
+
packing_summary: {
|
|
139
|
+
confidence: number;
|
|
140
|
+
packed: boolean;
|
|
141
|
+
};
|
|
142
|
+
blockers: string[];
|
|
143
|
+
recommendations: string[];
|
|
144
|
+
phases: {
|
|
145
|
+
confidence: number;
|
|
146
|
+
title: string;
|
|
147
|
+
phase: string;
|
|
148
|
+
objective: string;
|
|
149
|
+
actions: string[];
|
|
150
|
+
estimated_effort: "high" | "low" | "medium";
|
|
151
|
+
}[];
|
|
152
|
+
}>>;
|
|
153
|
+
warnings: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
154
|
+
errors: z.ZodOptional<z.ZodArray<z.ZodString, "many">>;
|
|
155
|
+
metrics: z.ZodOptional<z.ZodObject<{
|
|
156
|
+
elapsed_ms: z.ZodNumber;
|
|
157
|
+
tool: z.ZodString;
|
|
158
|
+
cached: z.ZodOptional<z.ZodBoolean>;
|
|
159
|
+
cache_key: z.ZodOptional<z.ZodString>;
|
|
160
|
+
cache_tier: z.ZodOptional<z.ZodString>;
|
|
161
|
+
cache_created_at: z.ZodOptional<z.ZodString>;
|
|
162
|
+
cache_expires_at: z.ZodOptional<z.ZodString>;
|
|
163
|
+
cache_hit_at: z.ZodOptional<z.ZodString>;
|
|
164
|
+
}, "strip", z.ZodTypeAny, {
|
|
165
|
+
elapsed_ms: number;
|
|
166
|
+
tool: string;
|
|
167
|
+
cached?: boolean | undefined;
|
|
168
|
+
cache_key?: string | undefined;
|
|
169
|
+
cache_tier?: string | undefined;
|
|
170
|
+
cache_created_at?: string | undefined;
|
|
171
|
+
cache_expires_at?: string | undefined;
|
|
172
|
+
cache_hit_at?: string | undefined;
|
|
173
|
+
}, {
|
|
174
|
+
elapsed_ms: number;
|
|
175
|
+
tool: string;
|
|
176
|
+
cached?: boolean | undefined;
|
|
177
|
+
cache_key?: string | undefined;
|
|
178
|
+
cache_tier?: string | undefined;
|
|
179
|
+
cache_created_at?: string | undefined;
|
|
180
|
+
cache_expires_at?: string | undefined;
|
|
181
|
+
cache_hit_at?: string | undefined;
|
|
182
|
+
}>>;
|
|
183
|
+
}, "strip", z.ZodTypeAny, {
|
|
184
|
+
ok: boolean;
|
|
185
|
+
metrics?: {
|
|
186
|
+
elapsed_ms: number;
|
|
187
|
+
tool: string;
|
|
188
|
+
cached?: boolean | undefined;
|
|
189
|
+
cache_key?: string | undefined;
|
|
190
|
+
cache_tier?: string | undefined;
|
|
191
|
+
cache_created_at?: string | undefined;
|
|
192
|
+
cache_expires_at?: string | undefined;
|
|
193
|
+
cache_hit_at?: string | undefined;
|
|
194
|
+
} | undefined;
|
|
195
|
+
data?: {
|
|
196
|
+
confidence: number;
|
|
197
|
+
feasibility: "high" | "low" | "medium";
|
|
198
|
+
restoration_expectation: string;
|
|
199
|
+
runtime_summary: {
|
|
200
|
+
suspected: {
|
|
201
|
+
confidence: number;
|
|
202
|
+
evidence: string[];
|
|
203
|
+
runtime: string;
|
|
204
|
+
}[];
|
|
205
|
+
primary_runtime: string;
|
|
206
|
+
};
|
|
207
|
+
packing_summary: {
|
|
208
|
+
confidence: number;
|
|
209
|
+
packed: boolean;
|
|
210
|
+
};
|
|
211
|
+
blockers: string[];
|
|
212
|
+
recommendations: string[];
|
|
213
|
+
phases: {
|
|
214
|
+
confidence: number;
|
|
215
|
+
title: string;
|
|
216
|
+
phase: string;
|
|
217
|
+
objective: string;
|
|
218
|
+
actions: string[];
|
|
219
|
+
estimated_effort: "high" | "low" | "medium";
|
|
220
|
+
}[];
|
|
221
|
+
} | undefined;
|
|
222
|
+
warnings?: string[] | undefined;
|
|
223
|
+
errors?: string[] | undefined;
|
|
224
|
+
}, {
|
|
225
|
+
ok: boolean;
|
|
226
|
+
metrics?: {
|
|
227
|
+
elapsed_ms: number;
|
|
228
|
+
tool: string;
|
|
229
|
+
cached?: boolean | undefined;
|
|
230
|
+
cache_key?: string | undefined;
|
|
231
|
+
cache_tier?: string | undefined;
|
|
232
|
+
cache_created_at?: string | undefined;
|
|
233
|
+
cache_expires_at?: string | undefined;
|
|
234
|
+
cache_hit_at?: string | undefined;
|
|
235
|
+
} | undefined;
|
|
236
|
+
data?: {
|
|
237
|
+
confidence: number;
|
|
238
|
+
feasibility: "high" | "low" | "medium";
|
|
239
|
+
restoration_expectation: string;
|
|
240
|
+
runtime_summary: {
|
|
241
|
+
suspected: {
|
|
242
|
+
confidence: number;
|
|
243
|
+
evidence: string[];
|
|
244
|
+
runtime: string;
|
|
245
|
+
}[];
|
|
246
|
+
primary_runtime: string;
|
|
247
|
+
};
|
|
248
|
+
packing_summary: {
|
|
249
|
+
confidence: number;
|
|
250
|
+
packed: boolean;
|
|
251
|
+
};
|
|
252
|
+
blockers: string[];
|
|
253
|
+
recommendations: string[];
|
|
254
|
+
phases: {
|
|
255
|
+
confidence: number;
|
|
256
|
+
title: string;
|
|
257
|
+
phase: string;
|
|
258
|
+
objective: string;
|
|
259
|
+
actions: string[];
|
|
260
|
+
estimated_effort: "high" | "low" | "medium";
|
|
261
|
+
}[];
|
|
262
|
+
} | undefined;
|
|
263
|
+
warnings?: string[] | undefined;
|
|
264
|
+
errors?: string[] | undefined;
|
|
265
|
+
}>;
|
|
266
|
+
export type CodeReconstructPlanOutput = z.infer<typeof CodeReconstructPlanOutputSchema>;
|
|
267
|
+
export declare const codeReconstructPlanToolDefinition: ToolDefinition;
|
|
268
|
+
interface ReconstructPlanDependencies {
|
|
269
|
+
runtimeDetectHandler?: (args: ToolArgs) => Promise<WorkerResult>;
|
|
270
|
+
packerDetectHandler?: (args: ToolArgs) => Promise<WorkerResult>;
|
|
271
|
+
}
|
|
272
|
+
export declare function createCodeReconstructPlanHandler(workspaceManager: WorkspaceManager, database: DatabaseManager, cacheManager: CacheManager, dependencies?: ReconstructPlanDependencies): (args: ToolArgs) => Promise<WorkerResult>;
|
|
273
|
+
export {};
|
|
274
|
+
//# sourceMappingURL=code-reconstruct-plan.d.ts.map
|
|
@@ -0,0 +1,342 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* code.reconstruct.plan tool implementation
|
|
3
|
+
* Builds a practical source-reconstruction plan from current static/decompiler signals.
|
|
4
|
+
*/
|
|
5
|
+
import { z } from 'zod';
|
|
6
|
+
import { generateCacheKey } from '../cache-manager.js';
|
|
7
|
+
import { lookupCachedResult, formatCacheWarning } from './cache-observability.js';
|
|
8
|
+
import { createRuntimeDetectHandler } from './runtime-detect.js';
|
|
9
|
+
import { createPackerDetectHandler } from './packer-detect.js';
|
|
10
|
+
const TOOL_NAME = 'code.reconstruct.plan';
|
|
11
|
+
const TOOL_VERSION = '0.1.0';
|
|
12
|
+
const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
13
|
+
export const CodeReconstructPlanInputSchema = z.object({
|
|
14
|
+
sample_id: z.string().describe('Sample ID (format: sha256:<hex>)'),
|
|
15
|
+
target_language: z
|
|
16
|
+
.enum(['auto', 'csharp', 'c', 'cpp', 'rust', 'go'])
|
|
17
|
+
.default('auto')
|
|
18
|
+
.describe('Preferred reconstruction language'),
|
|
19
|
+
depth: z
|
|
20
|
+
.enum(['quick', 'standard', 'deep'])
|
|
21
|
+
.default('standard')
|
|
22
|
+
.describe('Planning depth'),
|
|
23
|
+
include_decompiler: z
|
|
24
|
+
.boolean()
|
|
25
|
+
.default(true)
|
|
26
|
+
.describe('Whether to include decompiler-based phases'),
|
|
27
|
+
include_strings: z
|
|
28
|
+
.boolean()
|
|
29
|
+
.default(true)
|
|
30
|
+
.describe('Whether to include string/IOC enrichment phases'),
|
|
31
|
+
});
|
|
32
|
+
const ReconstructionPhaseSchema = z.object({
|
|
33
|
+
phase: z.string(),
|
|
34
|
+
title: z.string(),
|
|
35
|
+
objective: z.string(),
|
|
36
|
+
actions: z.array(z.string()),
|
|
37
|
+
estimated_effort: z.enum(['low', 'medium', 'high']),
|
|
38
|
+
confidence: z.number().min(0).max(1),
|
|
39
|
+
});
|
|
40
|
+
export const CodeReconstructPlanOutputSchema = z.object({
|
|
41
|
+
ok: z.boolean(),
|
|
42
|
+
data: z
|
|
43
|
+
.object({
|
|
44
|
+
feasibility: z.enum(['high', 'medium', 'low']),
|
|
45
|
+
confidence: z.number().min(0).max(1),
|
|
46
|
+
restoration_expectation: z.string(),
|
|
47
|
+
runtime_summary: z.object({
|
|
48
|
+
primary_runtime: z.string(),
|
|
49
|
+
suspected: z.array(z.object({
|
|
50
|
+
runtime: z.string(),
|
|
51
|
+
confidence: z.number(),
|
|
52
|
+
evidence: z.array(z.string()),
|
|
53
|
+
})),
|
|
54
|
+
}),
|
|
55
|
+
packing_summary: z.object({
|
|
56
|
+
packed: z.boolean(),
|
|
57
|
+
confidence: z.number(),
|
|
58
|
+
}),
|
|
59
|
+
blockers: z.array(z.string()),
|
|
60
|
+
recommendations: z.array(z.string()),
|
|
61
|
+
phases: z.array(ReconstructionPhaseSchema),
|
|
62
|
+
})
|
|
63
|
+
.optional(),
|
|
64
|
+
warnings: z.array(z.string()).optional(),
|
|
65
|
+
errors: z.array(z.string()).optional(),
|
|
66
|
+
metrics: z
|
|
67
|
+
.object({
|
|
68
|
+
elapsed_ms: z.number(),
|
|
69
|
+
tool: z.string(),
|
|
70
|
+
cached: z.boolean().optional(),
|
|
71
|
+
cache_key: z.string().optional(),
|
|
72
|
+
cache_tier: z.string().optional(),
|
|
73
|
+
cache_created_at: z.string().optional(),
|
|
74
|
+
cache_expires_at: z.string().optional(),
|
|
75
|
+
cache_hit_at: z.string().optional(),
|
|
76
|
+
})
|
|
77
|
+
.optional(),
|
|
78
|
+
});
|
|
79
|
+
export const codeReconstructPlanToolDefinition = {
|
|
80
|
+
name: TOOL_NAME,
|
|
81
|
+
description: 'Assess source-reconstruction feasibility and produce a phased reverse-engineering plan with confidence.',
|
|
82
|
+
inputSchema: CodeReconstructPlanInputSchema,
|
|
83
|
+
outputSchema: CodeReconstructPlanOutputSchema,
|
|
84
|
+
};
|
|
85
|
+
function clamp(value, min, max) {
|
|
86
|
+
return Math.max(min, Math.min(max, value));
|
|
87
|
+
}
|
|
88
|
+
function pickPrimaryRuntime(runtimeData) {
|
|
89
|
+
const suspected = runtimeData?.suspected || [];
|
|
90
|
+
if (suspected.length === 0) {
|
|
91
|
+
return 'unknown';
|
|
92
|
+
}
|
|
93
|
+
const sorted = [...suspected].sort((a, b) => b.confidence - a.confidence);
|
|
94
|
+
return sorted[0].runtime || 'unknown';
|
|
95
|
+
}
|
|
96
|
+
function assessReconstructability(runtimeData, packerData) {
|
|
97
|
+
const primaryRuntime = pickPrimaryRuntime(runtimeData).toLowerCase();
|
|
98
|
+
const isDotNet = runtimeData?.is_dotnet === true || primaryRuntime.includes('dotnet');
|
|
99
|
+
const packed = packerData?.packed === true;
|
|
100
|
+
const packingConfidence = clamp(packerData?.confidence ?? 0, 0, 1);
|
|
101
|
+
let score = 0.5;
|
|
102
|
+
const blockers = [];
|
|
103
|
+
if (isDotNet) {
|
|
104
|
+
score += 0.3;
|
|
105
|
+
}
|
|
106
|
+
else if (primaryRuntime.includes('rust')) {
|
|
107
|
+
score -= 0.15;
|
|
108
|
+
}
|
|
109
|
+
else if (primaryRuntime.includes('go')) {
|
|
110
|
+
score -= 0.1;
|
|
111
|
+
}
|
|
112
|
+
else if (primaryRuntime.includes('c++') || primaryRuntime.includes('cpp')) {
|
|
113
|
+
score -= 0.05;
|
|
114
|
+
}
|
|
115
|
+
if (packed) {
|
|
116
|
+
score -= 0.35 * (packingConfidence || 0.8);
|
|
117
|
+
blockers.push('Sample appears packed/obfuscated; unpacking is needed before reliable reconstruction.');
|
|
118
|
+
}
|
|
119
|
+
if (primaryRuntime === 'unknown') {
|
|
120
|
+
score -= 0.2;
|
|
121
|
+
blockers.push('Primary runtime is uncertain; detection confidence is currently low.');
|
|
122
|
+
}
|
|
123
|
+
const confidenceSignals = (runtimeData ? 1 : 0) + (packerData ? 1 : 0) + ((runtimeData?.suspected?.length || 0) > 0 ? 1 : 0);
|
|
124
|
+
const confidence = clamp(0.35 + confidenceSignals * 0.2, 0.35, 0.95);
|
|
125
|
+
score = clamp(score, 0, 1);
|
|
126
|
+
let feasibility = 'low';
|
|
127
|
+
if (score >= 0.75) {
|
|
128
|
+
feasibility = 'high';
|
|
129
|
+
}
|
|
130
|
+
else if (score >= 0.5) {
|
|
131
|
+
feasibility = 'medium';
|
|
132
|
+
}
|
|
133
|
+
let restorationExpectation = 'Behavioral reconstruction is possible; exact original source text is not recoverable.';
|
|
134
|
+
if (isDotNet && !packed) {
|
|
135
|
+
restorationExpectation =
|
|
136
|
+
'High-confidence C# structural restoration is feasible, but comments/symbol intent still requires manual review.';
|
|
137
|
+
}
|
|
138
|
+
else if (isDotNet && packed) {
|
|
139
|
+
restorationExpectation =
|
|
140
|
+
'Partial C# restoration is feasible after unpacking/deobfuscation; fidelity depends on recovered metadata.';
|
|
141
|
+
}
|
|
142
|
+
else if (!isDotNet) {
|
|
143
|
+
restorationExpectation =
|
|
144
|
+
'Native binaries support semantic reconstruction (C-like pseudocode), not exact original source restoration.';
|
|
145
|
+
}
|
|
146
|
+
return {
|
|
147
|
+
feasibility,
|
|
148
|
+
confidence,
|
|
149
|
+
restorationExpectation,
|
|
150
|
+
blockers,
|
|
151
|
+
};
|
|
152
|
+
}
|
|
153
|
+
function buildPhases(input, runtimeData, packerData, confidence) {
|
|
154
|
+
const primaryRuntime = pickPrimaryRuntime(runtimeData).toLowerCase();
|
|
155
|
+
const isDotNet = runtimeData?.is_dotnet === true || primaryRuntime.includes('dotnet');
|
|
156
|
+
const packed = packerData?.packed === true;
|
|
157
|
+
const phases = [
|
|
158
|
+
{
|
|
159
|
+
phase: 'phase_1',
|
|
160
|
+
title: 'Assess & Baseline',
|
|
161
|
+
objective: 'Establish runtime profile, packing state, and reconstruction boundary.',
|
|
162
|
+
actions: [
|
|
163
|
+
'Run runtime.detect and packer.detect with evidence capture.',
|
|
164
|
+
'Lock sample hash and workspace snapshot for reproducibility.',
|
|
165
|
+
'Define target output: semantic reconstruction vs source-like project.',
|
|
166
|
+
],
|
|
167
|
+
estimated_effort: 'low',
|
|
168
|
+
confidence: clamp(confidence, 0.3, 0.95),
|
|
169
|
+
},
|
|
170
|
+
];
|
|
171
|
+
if (packed) {
|
|
172
|
+
phases.push({
|
|
173
|
+
phase: 'phase_2',
|
|
174
|
+
title: 'Unpack & Normalize',
|
|
175
|
+
objective: 'Remove packing/obfuscation artifacts before deep reconstruction.',
|
|
176
|
+
actions: [
|
|
177
|
+
'Correlate packer signatures with imports/calls to reduce false positives.',
|
|
178
|
+
'Extract clean image and rerun static fingerprinting.',
|
|
179
|
+
'Rebuild string corpus with IOC-priority filtering.',
|
|
180
|
+
],
|
|
181
|
+
estimated_effort: 'high',
|
|
182
|
+
confidence: clamp(confidence - 0.1, 0.2, 0.85),
|
|
183
|
+
});
|
|
184
|
+
}
|
|
185
|
+
if (input.include_decompiler) {
|
|
186
|
+
phases.push({
|
|
187
|
+
phase: packed ? 'phase_3' : 'phase_2',
|
|
188
|
+
title: 'Function Recovery',
|
|
189
|
+
objective: 'Recover function-level semantics and prioritize high-value logic.',
|
|
190
|
+
actions: [
|
|
191
|
+
'Run ghidra.analyze and build per-function confidence map.',
|
|
192
|
+
'Use code.functions.rank to focus on entry points and sensitive APIs.',
|
|
193
|
+
'Pair code.function.decompile with disassembly for mismatch review.',
|
|
194
|
+
],
|
|
195
|
+
estimated_effort: input.depth === 'deep' ? 'high' : 'medium',
|
|
196
|
+
confidence: clamp(confidence - (packed ? 0.15 : 0.05), 0.2, 0.9),
|
|
197
|
+
});
|
|
198
|
+
}
|
|
199
|
+
phases.push({
|
|
200
|
+
phase: packed ? (input.include_decompiler ? 'phase_4' : 'phase_3') : (input.include_decompiler ? 'phase_3' : 'phase_2'),
|
|
201
|
+
title: isDotNet ? '.NET Structure Rebuild' : 'Module Recomposition',
|
|
202
|
+
objective: isDotNet
|
|
203
|
+
? 'Recover assembly/type/method structure and generate maintainable C# project skeleton.'
|
|
204
|
+
: 'Cluster functions into modules and produce source-like pseudocode packages.',
|
|
205
|
+
actions: isDotNet
|
|
206
|
+
? [
|
|
207
|
+
'Extract namespace/type graph and identify business-critical methods.',
|
|
208
|
+
'Reconstruct method bodies with IL fallback when C# decompilation is uncertain.',
|
|
209
|
+
'Export project skeleton with unresolved gaps documented.',
|
|
210
|
+
]
|
|
211
|
+
: [
|
|
212
|
+
'Group functions by call graph and shared constants/strings.',
|
|
213
|
+
'Promote stable symbols and infer interfaces/data structures.',
|
|
214
|
+
'Export source-like files with confidence annotations and TODO gaps.',
|
|
215
|
+
],
|
|
216
|
+
estimated_effort: 'high',
|
|
217
|
+
confidence: clamp(confidence - 0.1, 0.2, 0.85),
|
|
218
|
+
});
|
|
219
|
+
return phases;
|
|
220
|
+
}
|
|
221
|
+
export function createCodeReconstructPlanHandler(workspaceManager, database, cacheManager, dependencies) {
|
|
222
|
+
const runtimeDetectHandler = dependencies?.runtimeDetectHandler ||
|
|
223
|
+
createRuntimeDetectHandler(workspaceManager, database, cacheManager);
|
|
224
|
+
const packerDetectHandler = dependencies?.packerDetectHandler ||
|
|
225
|
+
createPackerDetectHandler(workspaceManager, database, cacheManager);
|
|
226
|
+
return async (args) => {
|
|
227
|
+
const input = args;
|
|
228
|
+
const startTime = Date.now();
|
|
229
|
+
try {
|
|
230
|
+
const sample = database.findSample(input.sample_id);
|
|
231
|
+
if (!sample) {
|
|
232
|
+
return {
|
|
233
|
+
ok: false,
|
|
234
|
+
errors: [`Sample not found: ${input.sample_id}`],
|
|
235
|
+
};
|
|
236
|
+
}
|
|
237
|
+
const cacheKey = generateCacheKey({
|
|
238
|
+
sampleSha256: sample.sha256,
|
|
239
|
+
toolName: TOOL_NAME,
|
|
240
|
+
toolVersion: TOOL_VERSION,
|
|
241
|
+
args: {
|
|
242
|
+
target_language: input.target_language,
|
|
243
|
+
depth: input.depth,
|
|
244
|
+
include_decompiler: input.include_decompiler,
|
|
245
|
+
include_strings: input.include_strings,
|
|
246
|
+
},
|
|
247
|
+
});
|
|
248
|
+
const cachedLookup = await lookupCachedResult(cacheManager, cacheKey);
|
|
249
|
+
if (cachedLookup) {
|
|
250
|
+
return {
|
|
251
|
+
ok: true,
|
|
252
|
+
data: cachedLookup.data,
|
|
253
|
+
warnings: ['Result from cache', formatCacheWarning(cachedLookup.metadata)],
|
|
254
|
+
metrics: {
|
|
255
|
+
elapsed_ms: Date.now() - startTime,
|
|
256
|
+
tool: TOOL_NAME,
|
|
257
|
+
cached: true,
|
|
258
|
+
cache_key: cachedLookup.metadata.key,
|
|
259
|
+
cache_tier: cachedLookup.metadata.tier,
|
|
260
|
+
cache_created_at: cachedLookup.metadata.createdAt,
|
|
261
|
+
cache_expires_at: cachedLookup.metadata.expiresAt,
|
|
262
|
+
cache_hit_at: cachedLookup.metadata.fetchedAt,
|
|
263
|
+
},
|
|
264
|
+
};
|
|
265
|
+
}
|
|
266
|
+
const warnings = [];
|
|
267
|
+
const runtimeResult = await runtimeDetectHandler({ sample_id: input.sample_id });
|
|
268
|
+
let runtimeData;
|
|
269
|
+
if (runtimeResult.ok && runtimeResult.data) {
|
|
270
|
+
runtimeData = runtimeResult.data;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
warnings.push(`runtime.detect unavailable: ${(runtimeResult.errors || ['unknown error']).join('; ')}`);
|
|
274
|
+
}
|
|
275
|
+
const packerResult = await packerDetectHandler({
|
|
276
|
+
sample_id: input.sample_id,
|
|
277
|
+
engines: ['yara', 'entropy', 'entrypoint'],
|
|
278
|
+
});
|
|
279
|
+
let packerData;
|
|
280
|
+
if (packerResult.ok && packerResult.data) {
|
|
281
|
+
packerData = packerResult.data;
|
|
282
|
+
}
|
|
283
|
+
else {
|
|
284
|
+
warnings.push(`packer.detect unavailable: ${(packerResult.errors || ['unknown error']).join('; ')}`);
|
|
285
|
+
}
|
|
286
|
+
const assessment = assessReconstructability(runtimeData, packerData);
|
|
287
|
+
const phases = buildPhases(input, runtimeData, packerData, assessment.confidence);
|
|
288
|
+
const recommendations = [
|
|
289
|
+
'Treat reconstruction as semantic recovery, not literal source restoration.',
|
|
290
|
+
'Prioritize top-ranked functions and entry points before broad decompilation.',
|
|
291
|
+
'Keep a confidence map and flag low-confidence blocks for manual review.',
|
|
292
|
+
];
|
|
293
|
+
const primaryRuntime = pickPrimaryRuntime(runtimeData).toLowerCase();
|
|
294
|
+
if (primaryRuntime.includes('dotnet') || runtimeData?.is_dotnet) {
|
|
295
|
+
recommendations.push('Use .NET-oriented extraction first (types/method metadata) to maximize readable source output.');
|
|
296
|
+
}
|
|
297
|
+
else {
|
|
298
|
+
recommendations.push('For native binaries, export C-like pseudocode modules with explicit TODOs for unresolved semantics.');
|
|
299
|
+
}
|
|
300
|
+
if (packerData?.packed) {
|
|
301
|
+
recommendations.push('Complete unpacking/deobfuscation before claiming source-level conclusions.');
|
|
302
|
+
}
|
|
303
|
+
const outputData = {
|
|
304
|
+
feasibility: assessment.feasibility,
|
|
305
|
+
confidence: assessment.confidence,
|
|
306
|
+
restoration_expectation: assessment.restorationExpectation,
|
|
307
|
+
runtime_summary: {
|
|
308
|
+
primary_runtime: pickPrimaryRuntime(runtimeData),
|
|
309
|
+
suspected: runtimeData?.suspected || [],
|
|
310
|
+
},
|
|
311
|
+
packing_summary: {
|
|
312
|
+
packed: packerData?.packed === true,
|
|
313
|
+
confidence: clamp(packerData?.confidence ?? 0, 0, 1),
|
|
314
|
+
},
|
|
315
|
+
blockers: assessment.blockers,
|
|
316
|
+
recommendations,
|
|
317
|
+
phases,
|
|
318
|
+
};
|
|
319
|
+
await cacheManager.setCachedResult(cacheKey, outputData, CACHE_TTL_MS, sample.sha256);
|
|
320
|
+
return {
|
|
321
|
+
ok: true,
|
|
322
|
+
data: outputData,
|
|
323
|
+
warnings: warnings.length > 0 ? warnings : undefined,
|
|
324
|
+
metrics: {
|
|
325
|
+
elapsed_ms: Date.now() - startTime,
|
|
326
|
+
tool: TOOL_NAME,
|
|
327
|
+
},
|
|
328
|
+
};
|
|
329
|
+
}
|
|
330
|
+
catch (error) {
|
|
331
|
+
return {
|
|
332
|
+
ok: false,
|
|
333
|
+
errors: [error.message],
|
|
334
|
+
metrics: {
|
|
335
|
+
elapsed_ms: Date.now() - startTime,
|
|
336
|
+
tool: TOOL_NAME,
|
|
337
|
+
},
|
|
338
|
+
};
|
|
339
|
+
}
|
|
340
|
+
};
|
|
341
|
+
}
|
|
342
|
+
//# sourceMappingURL=code-reconstruct-plan.js.map
|