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
|
@@ -20,10 +20,10 @@ import { ghidraConfig } from '../ghidra-config.js';
|
|
|
20
20
|
import { loadDynamicTraceEvidence } from '../dynamic-trace.js';
|
|
21
21
|
import { getPackageRoot } from '../runtime-paths.js';
|
|
22
22
|
import { correlateFunctionWithRuntimeEvidence, modulesSuggestedByRuntimeStages, } from '../runtime-correlation.js';
|
|
23
|
-
import { findSemanticFunctionExplanation, loadSemanticFunctionExplanationIndex, loadSemanticNameSuggestionIndex, SEMANTIC_FUNCTION_EXPLANATIONS_ARTIFACT_TYPE, SEMANTIC_NAME_SUGGESTIONS_ARTIFACT_TYPE, } from '../semantic-name-suggestion-artifacts.js';
|
|
23
|
+
import { findSemanticFunctionExplanation, findSemanticModuleReview, loadSemanticFunctionExplanationIndex, loadSemanticModuleReviewIndex, loadSemanticNameSuggestionIndex, SEMANTIC_FUNCTION_EXPLANATIONS_ARTIFACT_TYPE, SEMANTIC_NAME_SUGGESTIONS_ARTIFACT_TYPE, } from '../semantic-name-suggestion-artifacts.js';
|
|
24
24
|
import { AnalysisProvenanceSchema, buildRuntimeArtifactProvenance, buildSemanticArtifactProvenance, } from '../analysis-provenance.js';
|
|
25
25
|
const TOOL_NAME = 'code.reconstruct.export';
|
|
26
|
-
const TOOL_VERSION = '0.2.
|
|
26
|
+
const TOOL_VERSION = '0.2.15';
|
|
27
27
|
const CACHE_TTL_MS = 7 * 24 * 60 * 60 * 1000; // 7 days
|
|
28
28
|
export const CodeReconstructExportInputSchema = z.object({
|
|
29
29
|
sample_id: z.string().describe('Sample ID (format: sha256:<hex>)'),
|
|
@@ -106,6 +106,22 @@ export const CodeReconstructExportInputSchema = z.object({
|
|
|
106
106
|
.string()
|
|
107
107
|
.optional()
|
|
108
108
|
.describe('Optional semantic review session selector used when semantic_scope=session or to narrow all/latest results'),
|
|
109
|
+
role_target: z
|
|
110
|
+
.string()
|
|
111
|
+
.min(1)
|
|
112
|
+
.max(64)
|
|
113
|
+
.optional()
|
|
114
|
+
.describe('Optional high-level binary role hint from workflow preflight, such as native_rust_executable, dll_library, or com_server'),
|
|
115
|
+
role_focus_areas: z
|
|
116
|
+
.array(z.string().min(1).max(96))
|
|
117
|
+
.max(16)
|
|
118
|
+
.default([])
|
|
119
|
+
.describe('Optional role-aware focus areas that bias module grouping and rewrite prioritization'),
|
|
120
|
+
role_priority_order: z
|
|
121
|
+
.array(z.string().min(1).max(96))
|
|
122
|
+
.max(24)
|
|
123
|
+
.default([])
|
|
124
|
+
.describe('Optional priority-order hints from role-aware planning that influence module ordering and preservation'),
|
|
109
125
|
reuse_cached: z
|
|
110
126
|
.boolean()
|
|
111
127
|
.default(true)
|
|
@@ -139,6 +155,11 @@ const ModuleSchema = z.object({
|
|
|
139
155
|
name: z.string(),
|
|
140
156
|
confidence: z.number().min(0).max(1),
|
|
141
157
|
function_count: z.number().int().nonnegative(),
|
|
158
|
+
role_hint: z.string().nullable().optional(),
|
|
159
|
+
focus_matches: z.array(z.string()).optional(),
|
|
160
|
+
refined_name: z.string().nullable().optional(),
|
|
161
|
+
review_summary: z.string().nullable().optional(),
|
|
162
|
+
review_confidence: z.number().min(0).max(1).nullable().optional(),
|
|
142
163
|
import_hints: z.array(z.string()),
|
|
143
164
|
string_hints: z.array(z.string()),
|
|
144
165
|
runtime_apis: z.array(z.string()),
|
|
@@ -216,7 +237,11 @@ export const CodeReconstructExportOutputSchema = z.object({
|
|
|
216
237
|
stage_count: z.number().int().nonnegative(),
|
|
217
238
|
observed_apis: z.array(z.string()),
|
|
218
239
|
region_types: z.array(z.string()).optional(),
|
|
240
|
+
protections: z.array(z.string()).optional(),
|
|
241
|
+
address_ranges: z.array(z.string()).optional(),
|
|
242
|
+
region_owners: z.array(z.string()).optional(),
|
|
219
243
|
observed_modules: z.array(z.string()).optional(),
|
|
244
|
+
segment_names: z.array(z.string()).optional(),
|
|
220
245
|
observed_strings: z.array(z.string()).optional(),
|
|
221
246
|
stages: z.array(z.string()),
|
|
222
247
|
summary: z.string(),
|
|
@@ -248,6 +273,54 @@ export const codeReconstructExportToolDefinition = {
|
|
|
248
273
|
inputSchema: CodeReconstructExportInputSchema,
|
|
249
274
|
outputSchema: CodeReconstructExportOutputSchema,
|
|
250
275
|
};
|
|
276
|
+
function collectRoleFocusMatchesForModule(moduleName, roleOptions) {
|
|
277
|
+
if (!roleOptions) {
|
|
278
|
+
return [];
|
|
279
|
+
}
|
|
280
|
+
const normalized = sanitizeModuleName(moduleName);
|
|
281
|
+
const matches = new Set();
|
|
282
|
+
if (roleOptions.targetRole &&
|
|
283
|
+
mapRoleSignalToModules(roleOptions.targetRole).some((item) => sanitizeModuleName(item) === normalized)) {
|
|
284
|
+
matches.add(`target:${roleOptions.targetRole}`);
|
|
285
|
+
}
|
|
286
|
+
for (const focus of roleOptions.focusAreas) {
|
|
287
|
+
if (mapRoleSignalToModules(focus).some((item) => sanitizeModuleName(item) === normalized)) {
|
|
288
|
+
matches.add(`focus:${focus}`);
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
for (const priority of roleOptions.priorityOrder) {
|
|
292
|
+
if (mapRoleSignalToModules(priority).some((item) => sanitizeModuleName(item) === normalized)) {
|
|
293
|
+
matches.add(`priority:${priority}`);
|
|
294
|
+
}
|
|
295
|
+
}
|
|
296
|
+
return Array.from(matches);
|
|
297
|
+
}
|
|
298
|
+
function inferRoleHintForModule(moduleName, roleOptions) {
|
|
299
|
+
const normalized = sanitizeModuleName(moduleName);
|
|
300
|
+
const focusMatches = collectRoleFocusMatchesForModule(normalized, roleOptions);
|
|
301
|
+
if (focusMatches.length === 0) {
|
|
302
|
+
return null;
|
|
303
|
+
}
|
|
304
|
+
if (normalized === 'dll_lifecycle') {
|
|
305
|
+
return 'Role-aware focus on DLL entry, attach/detach, and lifecycle side effects.';
|
|
306
|
+
}
|
|
307
|
+
if (normalized === 'com_activation') {
|
|
308
|
+
return 'Role-aware focus on COM activation, registration, and class factory flow.';
|
|
309
|
+
}
|
|
310
|
+
if (normalized === 'export_dispatch') {
|
|
311
|
+
return 'Role-aware focus on exported command dispatch and externally reachable entrypoints.';
|
|
312
|
+
}
|
|
313
|
+
if (normalized === 'callback_surface') {
|
|
314
|
+
return 'Role-aware focus on callback, plugin, and host interaction surfaces.';
|
|
315
|
+
}
|
|
316
|
+
if (normalized === 'service_ops') {
|
|
317
|
+
return 'Role-aware focus on service control, hook, and hosted callback paths.';
|
|
318
|
+
}
|
|
319
|
+
if (normalized === 'process_ops') {
|
|
320
|
+
return 'Role-aware focus on runtime wrappers, process manipulation, and execution-transfer paths.';
|
|
321
|
+
}
|
|
322
|
+
return `Role-aware focus derived from ${focusMatches.join(', ')}.`;
|
|
323
|
+
}
|
|
251
324
|
const BEHAVIOR_TO_MODULE = {
|
|
252
325
|
process_injection: 'process_ops',
|
|
253
326
|
process_spawn: 'process_ops',
|
|
@@ -257,6 +330,10 @@ const BEHAVIOR_TO_MODULE = {
|
|
|
257
330
|
crypto: 'crypto_ops',
|
|
258
331
|
anti_debug: 'anti_analysis',
|
|
259
332
|
service_control: 'service_ops',
|
|
333
|
+
dll_lifecycle: 'dll_lifecycle',
|
|
334
|
+
export_dispatch: 'export_dispatch',
|
|
335
|
+
com_activation: 'com_activation',
|
|
336
|
+
callback_surface: 'callback_surface',
|
|
260
337
|
};
|
|
261
338
|
const IMPORT_TO_MODULE_HINT = [
|
|
262
339
|
{ module: 'network_ops', matcher: /^(ws2_32|wininet|winhttp|dnsapi)\.dll$/i },
|
|
@@ -290,6 +367,22 @@ const API_TO_MODULE_HINT = [
|
|
|
290
367
|
module: 'service_ops',
|
|
291
368
|
matcher: /\b(OpenSCManager|CreateService|StartService|ControlService|DeleteService)\b/i,
|
|
292
369
|
},
|
|
370
|
+
{
|
|
371
|
+
module: 'dll_lifecycle',
|
|
372
|
+
matcher: /\b(DllMain|DisableThreadLibraryCalls|LdrRegisterDllNotification|DLL_(PROCESS|THREAD)_(ATTACH|DETACH)|ProcessAttach|ThreadAttach|ProcessDetach|ThreadDetach)\b/i,
|
|
373
|
+
},
|
|
374
|
+
{
|
|
375
|
+
module: 'com_activation',
|
|
376
|
+
matcher: /\b(DllGetClassObject|DllCanUnloadNow|CoCreateInstance|CLSIDFromProgID|ProgIDFromCLSID|IClassFactory|IUnknown|IDispatch)\b/i,
|
|
377
|
+
},
|
|
378
|
+
{
|
|
379
|
+
module: 'export_dispatch',
|
|
380
|
+
matcher: /\b(InvokeCommand|Dispatch(Command|Export)?|HandleCommand|ExecuteCommand|RunCommand|DispatchTable|ForwardedExport)\b/i,
|
|
381
|
+
},
|
|
382
|
+
{
|
|
383
|
+
module: 'callback_surface',
|
|
384
|
+
matcher: /\b(InitializePlugin|RegisterCallback|SetCallback|Notify|OnEvent|EventSink|HookProc|Observer|Callback)\b/i,
|
|
385
|
+
},
|
|
293
386
|
{
|
|
294
387
|
module: 'anti_analysis',
|
|
295
388
|
matcher: /\b(IsDebuggerPresent|CheckRemoteDebuggerPresent|NtQuerySystemInformation|NtQueryInformationProcess|OutputDebugString)\b/i,
|
|
@@ -342,6 +435,96 @@ function sanitizeModuleName(name) {
|
|
|
342
435
|
const cleaned = name.toLowerCase().replace(/[^a-z0-9_]+/g, '_').replace(/^_+|_+$/g, '');
|
|
343
436
|
return cleaned.length > 0 ? cleaned : 'core';
|
|
344
437
|
}
|
|
438
|
+
function dedupeLower(values) {
|
|
439
|
+
return Array.from(new Set(values.map((item) => item.trim()).filter((item) => item.length > 0)));
|
|
440
|
+
}
|
|
441
|
+
function addRoleModules(target, values) {
|
|
442
|
+
for (const value of values) {
|
|
443
|
+
target.add(sanitizeModuleName(value));
|
|
444
|
+
}
|
|
445
|
+
}
|
|
446
|
+
function mapRoleSignalToModules(signal) {
|
|
447
|
+
const lowered = signal.toLowerCase();
|
|
448
|
+
if (/class_factory|registration|com_activation|com_server|dllgetclassobject|dllcanunloadnow|inprocserver32|localserver32/.test(lowered)) {
|
|
449
|
+
return ['com_activation', 'export_dispatch', 'dll_lifecycle'];
|
|
450
|
+
}
|
|
451
|
+
if (/dllmain|attach_detach|dll_entry|dllmain_and_export_surface|lifecycle/.test(lowered)) {
|
|
452
|
+
return ['dll_lifecycle'];
|
|
453
|
+
}
|
|
454
|
+
if (/export_dispatch|dispatch_model|review_exported_command_dispatch_surface/.test(lowered)) {
|
|
455
|
+
return ['export_dispatch'];
|
|
456
|
+
}
|
|
457
|
+
if (/host_callback|plugin|extension_contract|callback/.test(lowered)) {
|
|
458
|
+
return ['callback_surface'];
|
|
459
|
+
}
|
|
460
|
+
if (/service/.test(lowered)) {
|
|
461
|
+
return ['service_ops', 'callback_surface'];
|
|
462
|
+
}
|
|
463
|
+
if (/runtime_wrappers|process_manipulation/.test(lowered)) {
|
|
464
|
+
return ['process_ops'];
|
|
465
|
+
}
|
|
466
|
+
if (/network/.test(lowered)) {
|
|
467
|
+
return ['network_ops'];
|
|
468
|
+
}
|
|
469
|
+
return [];
|
|
470
|
+
}
|
|
471
|
+
function buildRoleAwareModuleOptions(input) {
|
|
472
|
+
const preferredModules = new Set();
|
|
473
|
+
const stickyModules = new Set();
|
|
474
|
+
const moduleOrder = new Map();
|
|
475
|
+
const targetRole = input.role_target?.trim() || null;
|
|
476
|
+
const focusAreas = dedupeLower(input.role_focus_areas || []);
|
|
477
|
+
const priorityOrder = dedupeLower(input.role_priority_order || []);
|
|
478
|
+
if (targetRole) {
|
|
479
|
+
addRoleModules(preferredModules, mapRoleSignalToModules(targetRole));
|
|
480
|
+
}
|
|
481
|
+
for (const focus of focusAreas) {
|
|
482
|
+
addRoleModules(preferredModules, mapRoleSignalToModules(focus));
|
|
483
|
+
if (/class_factory|registration|com_activation|dllmain|lifecycle|host_callback|plugin|callback/.test(focus)) {
|
|
484
|
+
addRoleModules(stickyModules, mapRoleSignalToModules(focus));
|
|
485
|
+
}
|
|
486
|
+
}
|
|
487
|
+
for (const priority of priorityOrder) {
|
|
488
|
+
addRoleModules(preferredModules, mapRoleSignalToModules(priority));
|
|
489
|
+
if (/trace_com_activation|review_dllmain|identify_host_callbacks|extension_contract|exported_command_dispatch_surface/.test(priority)) {
|
|
490
|
+
addRoleModules(stickyModules, mapRoleSignalToModules(priority));
|
|
491
|
+
}
|
|
492
|
+
}
|
|
493
|
+
if (targetRole === 'com_server') {
|
|
494
|
+
addRoleModules(stickyModules, ['com_activation', 'dll_lifecycle', 'export_dispatch']);
|
|
495
|
+
}
|
|
496
|
+
else if (targetRole === 'export_dispatch_dll') {
|
|
497
|
+
addRoleModules(stickyModules, ['export_dispatch', 'dll_lifecycle']);
|
|
498
|
+
}
|
|
499
|
+
else if (targetRole === 'hosted_plugin_or_service_dll') {
|
|
500
|
+
addRoleModules(stickyModules, ['callback_surface', 'dll_lifecycle', 'service_ops']);
|
|
501
|
+
}
|
|
502
|
+
else if (targetRole === 'dll_library') {
|
|
503
|
+
addRoleModules(stickyModules, ['dll_lifecycle']);
|
|
504
|
+
}
|
|
505
|
+
let order = 0;
|
|
506
|
+
for (const priority of priorityOrder) {
|
|
507
|
+
for (const moduleName of mapRoleSignalToModules(priority)) {
|
|
508
|
+
const normalized = sanitizeModuleName(moduleName);
|
|
509
|
+
if (!moduleOrder.has(normalized)) {
|
|
510
|
+
moduleOrder.set(normalized, order++);
|
|
511
|
+
}
|
|
512
|
+
}
|
|
513
|
+
}
|
|
514
|
+
for (const moduleName of preferredModules) {
|
|
515
|
+
if (!moduleOrder.has(moduleName)) {
|
|
516
|
+
moduleOrder.set(moduleName, order++);
|
|
517
|
+
}
|
|
518
|
+
}
|
|
519
|
+
return {
|
|
520
|
+
targetRole,
|
|
521
|
+
focusAreas,
|
|
522
|
+
priorityOrder,
|
|
523
|
+
preferredModules,
|
|
524
|
+
stickyModules,
|
|
525
|
+
moduleOrder,
|
|
526
|
+
};
|
|
527
|
+
}
|
|
345
528
|
function sanitizeSymbolForHeader(symbol) {
|
|
346
529
|
const cleaned = symbol.replace(/[^a-zA-Z0-9_]/g, '_');
|
|
347
530
|
if (cleaned.length === 0) {
|
|
@@ -374,6 +557,37 @@ async function attachFunctionExplanations(workspaceManager, database, sampleId,
|
|
|
374
557
|
}
|
|
375
558
|
return explanationIndex;
|
|
376
559
|
}
|
|
560
|
+
async function attachModuleReviews(workspaceManager, database, sampleId, modules, options) {
|
|
561
|
+
const reviewIndex = await loadSemanticModuleReviewIndex(workspaceManager, database, sampleId, {
|
|
562
|
+
scope: options?.scope,
|
|
563
|
+
sessionTag: options?.sessionTag,
|
|
564
|
+
});
|
|
565
|
+
for (const module of modules) {
|
|
566
|
+
const review = findSemanticModuleReview(reviewIndex, module.name);
|
|
567
|
+
if (!review) {
|
|
568
|
+
continue;
|
|
569
|
+
}
|
|
570
|
+
module.reviewResolution = {
|
|
571
|
+
refined_name: review.refined_name,
|
|
572
|
+
summary: review.summary,
|
|
573
|
+
role_hint: review.role_hint,
|
|
574
|
+
confidence: review.confidence,
|
|
575
|
+
assumptions: review.assumptions,
|
|
576
|
+
evidence_used: review.evidence_used,
|
|
577
|
+
rewrite_guidance: review.rewrite_guidance,
|
|
578
|
+
focus_areas: review.focus_areas,
|
|
579
|
+
priority_functions: review.priority_functions,
|
|
580
|
+
source: 'llm',
|
|
581
|
+
};
|
|
582
|
+
if (review.role_hint && (!module.roleHint || module.roleHint.trim().length === 0)) {
|
|
583
|
+
module.roleHint = review.role_hint || module.roleHint;
|
|
584
|
+
}
|
|
585
|
+
for (const focus of review.focus_areas || []) {
|
|
586
|
+
module.focusMatches.add(`review:${focus}`);
|
|
587
|
+
}
|
|
588
|
+
}
|
|
589
|
+
return reviewIndex;
|
|
590
|
+
}
|
|
377
591
|
function addHint(hints, module, value) {
|
|
378
592
|
const normalized = normalizeReadableHint(value);
|
|
379
593
|
if (!isReadableTextCandidate(normalized)) {
|
|
@@ -385,7 +599,7 @@ function addHint(hints, module, value) {
|
|
|
385
599
|
hints.set(module, current);
|
|
386
600
|
}
|
|
387
601
|
}
|
|
388
|
-
function inferModulesFromText(text, categories = []) {
|
|
602
|
+
function inferModulesFromText(text, categories = [], roleOptions) {
|
|
389
603
|
const modules = new Set();
|
|
390
604
|
const lowered = text.toLowerCase();
|
|
391
605
|
if (categories.includes('network') || categories.includes('url')) {
|
|
@@ -414,9 +628,35 @@ function inferModulesFromText(text, categories = []) {
|
|
|
414
628
|
if (/\b(pack(er)? detection|protection|entropy|section|signature)\b/i.test(lowered)) {
|
|
415
629
|
modules.add('packer_analysis');
|
|
416
630
|
}
|
|
631
|
+
if (/\b(dllmain|disablethreadlibrarycalls|dll_process_attach|dll_thread_attach|processattach|threadattach|processdetach|threaddetach|attach\/detach)\b/i.test(lowered)) {
|
|
632
|
+
modules.add('dll_lifecycle');
|
|
633
|
+
}
|
|
634
|
+
if (/\b(dllgetclassobject|dllcanunloadnow|iclassfactory|cocreateinstance|clsid|progid|inprocserver32|localserver32|class factory)\b/i.test(lowered)) {
|
|
635
|
+
modules.add('com_activation');
|
|
636
|
+
}
|
|
637
|
+
if (/\b(export dispatch|dispatch table|invokecommand|handlecommand|executecommand|runcommand|forwarded export|ordinal export|export surface)\b/i.test(lowered)) {
|
|
638
|
+
modules.add('export_dispatch');
|
|
639
|
+
}
|
|
640
|
+
if (/\b(callback|event sink|observer|notify|plugin|addin|extension point|initializeplugin|registercallback|setcallback|hook proc)\b/i.test(lowered)) {
|
|
641
|
+
modules.add('callback_surface');
|
|
642
|
+
}
|
|
643
|
+
if (roleOptions) {
|
|
644
|
+
if (roleOptions.preferredModules.has('dll_lifecycle') && /\b(dll|attach|detach|module handle|dllmain)\b/i.test(lowered)) {
|
|
645
|
+
modules.add('dll_lifecycle');
|
|
646
|
+
}
|
|
647
|
+
if (roleOptions.preferredModules.has('com_activation') && /\b(class factory|registerserver|clsid|progid|activation)\b/i.test(lowered)) {
|
|
648
|
+
modules.add('com_activation');
|
|
649
|
+
}
|
|
650
|
+
if (roleOptions.preferredModules.has('export_dispatch') && /\b(dispatch|export|command|invoke)\b/i.test(lowered)) {
|
|
651
|
+
modules.add('export_dispatch');
|
|
652
|
+
}
|
|
653
|
+
if (roleOptions.preferredModules.has('callback_surface') && /\b(callback|plugin|notify|hook|host)\b/i.test(lowered)) {
|
|
654
|
+
modules.add('callback_surface');
|
|
655
|
+
}
|
|
656
|
+
}
|
|
417
657
|
return Array.from(modules);
|
|
418
658
|
}
|
|
419
|
-
function detectModuleByNameOrReasons(func) {
|
|
659
|
+
function detectModuleByNameOrReasons(func, roleOptions) {
|
|
420
660
|
const xrefApis = (func.xref_signals || []).map((item) => item.api).join(' ');
|
|
421
661
|
const callContext = [
|
|
422
662
|
...(func.call_context?.callers || []),
|
|
@@ -431,6 +671,18 @@ function detectModuleByNameOrReasons(func) {
|
|
|
431
671
|
callContext,
|
|
432
672
|
].join(' ');
|
|
433
673
|
const lowered = corpus.toLowerCase();
|
|
674
|
+
if (/dllmain|disablethreadlibrarycalls|dll_process_attach|dll_thread_attach|processattach|threadattach|processdetach|threaddetach/.test(lowered)) {
|
|
675
|
+
return 'dll_lifecycle';
|
|
676
|
+
}
|
|
677
|
+
if (/dllgetclassobject|dllcanunloadnow|iclassfactory|cocreateinstance|clsid|progid|inprocserver32|localserver32/.test(lowered)) {
|
|
678
|
+
return 'com_activation';
|
|
679
|
+
}
|
|
680
|
+
if (/initializeplugin|registercallback|setcallback|event sink|notify|hook proc|observer|plugin host/.test(lowered)) {
|
|
681
|
+
return 'callback_surface';
|
|
682
|
+
}
|
|
683
|
+
if (/export dispatch|dispatch table|invokecommand|handlecommand|executecommand|runcommand|forwarded export/.test(lowered)) {
|
|
684
|
+
return 'export_dispatch';
|
|
685
|
+
}
|
|
434
686
|
if (/socket|http|internet|dns|connect|send|recv/.test(lowered)) {
|
|
435
687
|
return 'network_ops';
|
|
436
688
|
}
|
|
@@ -455,6 +707,18 @@ function detectModuleByNameOrReasons(func) {
|
|
|
455
707
|
if (/packer|entropy|section|signature|goblin|iced-x86|recon|analysis/.test(lowered)) {
|
|
456
708
|
return 'packer_analysis';
|
|
457
709
|
}
|
|
710
|
+
if (roleOptions?.preferredModules.has('dll_lifecycle') && /\bdll\b/.test(lowered)) {
|
|
711
|
+
return 'dll_lifecycle';
|
|
712
|
+
}
|
|
713
|
+
if (roleOptions?.preferredModules.has('com_activation') && /\b(class factory|registration|activation)\b/.test(lowered)) {
|
|
714
|
+
return 'com_activation';
|
|
715
|
+
}
|
|
716
|
+
if (roleOptions?.preferredModules.has('export_dispatch') && /\b(dispatch|export|command)\b/.test(lowered)) {
|
|
717
|
+
return 'export_dispatch';
|
|
718
|
+
}
|
|
719
|
+
if (roleOptions?.preferredModules.has('callback_surface') && /\b(callback|plugin|host)\b/.test(lowered)) {
|
|
720
|
+
return 'callback_surface';
|
|
721
|
+
}
|
|
458
722
|
return 'core';
|
|
459
723
|
}
|
|
460
724
|
function computeImportModuleHints(importsData) {
|
|
@@ -658,6 +922,26 @@ function enrichFunctionsWithRuntimeContext(functions, dynamicEvidence) {
|
|
|
658
922
|
...(func.runtime_context.matched_memory_regions || []),
|
|
659
923
|
...(runtimeContext.matched_memory_regions || []),
|
|
660
924
|
]).slice(0, 6),
|
|
925
|
+
matched_protections: dedupe([
|
|
926
|
+
...(func.runtime_context.matched_protections || []),
|
|
927
|
+
...(runtimeContext.matched_protections || []),
|
|
928
|
+
]).slice(0, 6),
|
|
929
|
+
matched_address_ranges: dedupe([
|
|
930
|
+
...(func.runtime_context.matched_address_ranges || []),
|
|
931
|
+
...(runtimeContext.matched_address_ranges || []),
|
|
932
|
+
]).slice(0, 6),
|
|
933
|
+
matched_region_owners: dedupe([
|
|
934
|
+
...(func.runtime_context.matched_region_owners || []),
|
|
935
|
+
...(runtimeContext.matched_region_owners || []),
|
|
936
|
+
]).slice(0, 6),
|
|
937
|
+
matched_observed_modules: dedupe([
|
|
938
|
+
...(func.runtime_context.matched_observed_modules || []),
|
|
939
|
+
...(runtimeContext.matched_observed_modules || []),
|
|
940
|
+
]).slice(0, 6),
|
|
941
|
+
matched_segment_names: dedupe([
|
|
942
|
+
...(func.runtime_context.matched_segment_names || []),
|
|
943
|
+
...(runtimeContext.matched_segment_names || []),
|
|
944
|
+
]).slice(0, 6),
|
|
661
945
|
suggested_modules: dedupe([
|
|
662
946
|
...(func.runtime_context.suggested_modules || []),
|
|
663
947
|
...(runtimeContext.suggested_modules || []),
|
|
@@ -670,7 +954,7 @@ function enrichFunctionsWithRuntimeContext(functions, dynamicEvidence) {
|
|
|
670
954
|
};
|
|
671
955
|
});
|
|
672
956
|
}
|
|
673
|
-
function chooseModuleForFunctionWithScoring(func, functionStringHints) {
|
|
957
|
+
function chooseModuleForFunctionWithScoring(func, functionStringHints, roleOptions) {
|
|
674
958
|
const scores = new Map();
|
|
675
959
|
const importHints = new Map();
|
|
676
960
|
const stringHints = new Map();
|
|
@@ -696,7 +980,7 @@ function chooseModuleForFunctionWithScoring(func, functionStringHints) {
|
|
|
696
980
|
...((func.call_context?.callers || []).slice(0, 3)),
|
|
697
981
|
...((func.call_context?.callees || []).slice(0, 5)),
|
|
698
982
|
].join(' ');
|
|
699
|
-
for (const module of inferModulesFromText(textCorpus)) {
|
|
983
|
+
for (const module of inferModulesFromText(textCorpus, [], roleOptions)) {
|
|
700
984
|
addScore(module, 3);
|
|
701
985
|
}
|
|
702
986
|
for (const signal of func.xref_signals || []) {
|
|
@@ -765,26 +1049,95 @@ function chooseModuleForFunctionWithScoring(func, functionStringHints) {
|
|
|
765
1049
|
addScore('network_ops', 3, region, stringHints);
|
|
766
1050
|
}
|
|
767
1051
|
}
|
|
1052
|
+
for (const protection of runtimeContext.matched_protections || []) {
|
|
1053
|
+
if (/read_write|write|execute|rwx/i.test(protection)) {
|
|
1054
|
+
addScore('process_ops', 2, protection, stringHints);
|
|
1055
|
+
}
|
|
1056
|
+
if (/file|container/i.test(protection)) {
|
|
1057
|
+
addScore('file_ops', 1, protection, stringHints);
|
|
1058
|
+
}
|
|
1059
|
+
if (/image|r-x|read/i.test(protection) && roleOptions?.preferredModules.has('export_dispatch')) {
|
|
1060
|
+
addScore('export_dispatch', 2, protection, stringHints);
|
|
1061
|
+
}
|
|
1062
|
+
if (/image|r-x|read/i.test(protection) && roleOptions?.preferredModules.has('dll_lifecycle')) {
|
|
1063
|
+
addScore('dll_lifecycle', 2, protection, stringHints);
|
|
1064
|
+
}
|
|
1065
|
+
}
|
|
1066
|
+
for (const owner of [
|
|
1067
|
+
...(runtimeContext.matched_region_owners || []),
|
|
1068
|
+
...(runtimeContext.matched_observed_modules || []),
|
|
1069
|
+
]) {
|
|
1070
|
+
if (/ole32|oleaut32|combase|rpcrt4/i.test(owner)) {
|
|
1071
|
+
addScore('com_activation', 4, owner, stringHints);
|
|
1072
|
+
}
|
|
1073
|
+
if (/plugin|host|extension|addin/i.test(owner)) {
|
|
1074
|
+
addScore('callback_surface', 3, owner, stringHints);
|
|
1075
|
+
}
|
|
1076
|
+
if (/\.dll$|\.ocx$|\.cpl$/i.test(owner) && roleOptions?.preferredModules.has('dll_lifecycle')) {
|
|
1077
|
+
addScore('dll_lifecycle', 2, owner, stringHints);
|
|
1078
|
+
}
|
|
1079
|
+
}
|
|
1080
|
+
for (const segment of runtimeContext.matched_segment_names || []) {
|
|
1081
|
+
if (/\.edata|export|dispatch/i.test(segment)) {
|
|
1082
|
+
addScore('export_dispatch', 4, segment, stringHints);
|
|
1083
|
+
}
|
|
1084
|
+
if (/\.tls|\.crt|init/i.test(segment)) {
|
|
1085
|
+
addScore('dll_lifecycle', 4, segment, stringHints);
|
|
1086
|
+
}
|
|
1087
|
+
if (/class|factory|\.idata/i.test(segment)) {
|
|
1088
|
+
addScore('com_activation', 3, segment, stringHints);
|
|
1089
|
+
}
|
|
1090
|
+
if (/callback|hook|event|notify/i.test(segment)) {
|
|
1091
|
+
addScore('callback_surface', 3, segment, stringHints);
|
|
1092
|
+
}
|
|
1093
|
+
}
|
|
1094
|
+
}
|
|
1095
|
+
if (roleOptions) {
|
|
1096
|
+
for (const module of roleOptions.preferredModules) {
|
|
1097
|
+
if (scores.has(module)) {
|
|
1098
|
+
addScore(module, roleOptions.stickyModules.has(module) ? 4 : 2);
|
|
1099
|
+
}
|
|
1100
|
+
}
|
|
1101
|
+
if (roleOptions.preferredModules.has('export_dispatch') &&
|
|
1102
|
+
/\b(export|dispatch|invoke|command)\b/i.test(textCorpus)) {
|
|
1103
|
+
addScore('export_dispatch', 3);
|
|
1104
|
+
}
|
|
1105
|
+
if (roleOptions.preferredModules.has('com_activation') &&
|
|
1106
|
+
/\b(class factory|dllgetclassobject|registerserver|activation|clsid|progid)\b/i.test(textCorpus)) {
|
|
1107
|
+
addScore('com_activation', 4);
|
|
1108
|
+
}
|
|
1109
|
+
if (roleOptions.preferredModules.has('dll_lifecycle') &&
|
|
1110
|
+
/\b(dllmain|attach|detach|disablethreadlibrarycalls|module handle)\b/i.test(textCorpus)) {
|
|
1111
|
+
addScore('dll_lifecycle', 4);
|
|
1112
|
+
}
|
|
1113
|
+
if (roleOptions.preferredModules.has('callback_surface') &&
|
|
1114
|
+
/\b(callback|notify|plugin|hook|host)\b/i.test(textCorpus)) {
|
|
1115
|
+
addScore('callback_surface', 3);
|
|
1116
|
+
}
|
|
768
1117
|
}
|
|
769
1118
|
const top = Array.from(scores.entries()).sort((a, b) => b[1] - a[1])[0];
|
|
770
|
-
const moduleName = top && top[1] >= 3
|
|
1119
|
+
const moduleName = top && top[1] >= 3
|
|
1120
|
+
? sanitizeModuleName(top[0])
|
|
1121
|
+
: sanitizeModuleName(detectModuleByNameOrReasons(func, roleOptions));
|
|
771
1122
|
return {
|
|
772
1123
|
moduleName,
|
|
773
1124
|
importHints: Array.from(importHints.get(moduleName) || []).slice(0, 8),
|
|
774
1125
|
stringHints: Array.from(stringHints.get(moduleName) || []).slice(0, 8),
|
|
775
1126
|
};
|
|
776
1127
|
}
|
|
777
|
-
function regroupModules(functions, moduleLimit, minModuleSize, importsData, stringsData, functionStringHints) {
|
|
1128
|
+
function regroupModules(functions, moduleLimit, minModuleSize, importsData, stringsData, functionStringHints, roleOptions) {
|
|
778
1129
|
const moduleMap = new Map();
|
|
779
1130
|
const importHints = computeImportModuleHints(importsData);
|
|
780
1131
|
const stringHints = computeStringModuleHints(stringsData);
|
|
781
1132
|
for (const func of functions) {
|
|
782
|
-
const decision = chooseModuleForFunctionWithScoring(func, functionStringHints || new Map());
|
|
1133
|
+
const decision = chooseModuleForFunctionWithScoring(func, functionStringHints || new Map(), roleOptions);
|
|
783
1134
|
const moduleName = sanitizeModuleName(decision.moduleName);
|
|
784
1135
|
if (!moduleMap.has(moduleName)) {
|
|
785
1136
|
moduleMap.set(moduleName, {
|
|
786
1137
|
name: moduleName,
|
|
787
1138
|
functions: [],
|
|
1139
|
+
roleHint: inferRoleHintForModule(moduleName, roleOptions),
|
|
1140
|
+
focusMatches: new Set(collectRoleFocusMatchesForModule(moduleName, roleOptions)),
|
|
788
1141
|
importHints: new Set(importHints.get(moduleName) || []),
|
|
789
1142
|
stringHints: new Set((stringHints.get(moduleName) || []).slice(0, 8)),
|
|
790
1143
|
runtimeApis: new Set(),
|
|
@@ -810,13 +1163,39 @@ function regroupModules(functions, moduleLimit, minModuleSize, importsData, stri
|
|
|
810
1163
|
bucket.runtimeNotes.add(note);
|
|
811
1164
|
}
|
|
812
1165
|
}
|
|
813
|
-
|
|
1166
|
+
const modulePriority = (module) => {
|
|
1167
|
+
if (!roleOptions) {
|
|
1168
|
+
return 0;
|
|
1169
|
+
}
|
|
1170
|
+
return roleOptions.moduleOrder.has(module.name)
|
|
1171
|
+
? 100 - (roleOptions.moduleOrder.get(module.name) || 0)
|
|
1172
|
+
: 0;
|
|
1173
|
+
};
|
|
1174
|
+
let modules = Array.from(moduleMap.values()).sort((a, b) => {
|
|
1175
|
+
const priorityDelta = modulePriority(b) - modulePriority(a);
|
|
1176
|
+
if (priorityDelta !== 0) {
|
|
1177
|
+
return priorityDelta;
|
|
1178
|
+
}
|
|
1179
|
+
return b.functions.length - a.functions.length;
|
|
1180
|
+
});
|
|
814
1181
|
if (modules.length > moduleLimit) {
|
|
815
|
-
const
|
|
816
|
-
|
|
1182
|
+
const sticky = roleOptions
|
|
1183
|
+
? modules.filter((module) => roleOptions.stickyModules.has(module.name))
|
|
1184
|
+
: [];
|
|
1185
|
+
const nonSticky = roleOptions
|
|
1186
|
+
? modules.filter((module) => !roleOptions.stickyModules.has(module.name))
|
|
1187
|
+
: modules;
|
|
1188
|
+
const keepCount = Math.max(1, moduleLimit - 1);
|
|
1189
|
+
const stickyKept = sticky.slice(0, Math.max(0, keepCount));
|
|
1190
|
+
const remainingSlots = Math.max(0, keepCount - stickyKept.length);
|
|
1191
|
+
const kept = [...stickyKept, ...nonSticky.slice(0, remainingSlots)];
|
|
1192
|
+
const keptNames = new Set(kept.map((module) => module.name));
|
|
1193
|
+
const overflow = modules.filter((module) => !keptNames.has(module.name));
|
|
817
1194
|
const mergedCore = {
|
|
818
1195
|
name: 'core',
|
|
819
1196
|
functions: overflow.flatMap((module) => module.functions),
|
|
1197
|
+
roleHint: inferRoleHintForModule('core', roleOptions),
|
|
1198
|
+
focusMatches: new Set(overflow.flatMap((module) => Array.from(module.focusMatches || []))),
|
|
820
1199
|
importHints: new Set(overflow.flatMap((module) => Array.from(module.importHints))),
|
|
821
1200
|
stringHints: new Set(overflow.flatMap((module) => Array.from(module.stringHints))),
|
|
822
1201
|
runtimeApis: new Set(overflow.flatMap((module) => Array.from(module.runtimeApis))),
|
|
@@ -827,17 +1206,23 @@ function regroupModules(functions, moduleLimit, minModuleSize, importsData, stri
|
|
|
827
1206
|
}
|
|
828
1207
|
const small = modules.filter((module) => module.functions.length < minModuleSize);
|
|
829
1208
|
if (small.length > 0 && modules.length > 1) {
|
|
830
|
-
const
|
|
1209
|
+
const smallMergeable = roleOptions
|
|
1210
|
+
? small.filter((module) => !roleOptions.stickyModules.has(module.name))
|
|
1211
|
+
: small;
|
|
1212
|
+
const large = modules.filter((module) => module.functions.length >= minModuleSize ||
|
|
1213
|
+
Boolean(roleOptions?.stickyModules.has(module.name)));
|
|
831
1214
|
const core = large.find((module) => module.name === 'core') || {
|
|
832
1215
|
name: 'core',
|
|
833
1216
|
functions: [],
|
|
1217
|
+
roleHint: inferRoleHintForModule('core', roleOptions),
|
|
1218
|
+
focusMatches: new Set(),
|
|
834
1219
|
importHints: new Set(),
|
|
835
1220
|
stringHints: new Set(),
|
|
836
1221
|
runtimeApis: new Set(),
|
|
837
1222
|
runtimeStages: new Set(),
|
|
838
1223
|
runtimeNotes: new Set(),
|
|
839
1224
|
};
|
|
840
|
-
for (const module of
|
|
1225
|
+
for (const module of smallMergeable) {
|
|
841
1226
|
core.functions.push(...module.functions);
|
|
842
1227
|
for (const hint of module.importHints) {
|
|
843
1228
|
core.importHints.add(hint);
|
|
@@ -854,13 +1239,26 @@ function regroupModules(functions, moduleLimit, minModuleSize, importsData, stri
|
|
|
854
1239
|
for (const note of module.runtimeNotes) {
|
|
855
1240
|
core.runtimeNotes.add(note);
|
|
856
1241
|
}
|
|
1242
|
+
for (const match of module.focusMatches) {
|
|
1243
|
+
core.focusMatches.add(match);
|
|
1244
|
+
}
|
|
1245
|
+
if (!core.roleHint && module.roleHint) {
|
|
1246
|
+
core.roleHint = module.roleHint;
|
|
1247
|
+
}
|
|
857
1248
|
}
|
|
858
|
-
modules = large.filter((module) => module.functions.length >= minModuleSize
|
|
1249
|
+
modules = large.filter((module) => module.functions.length >= minModuleSize ||
|
|
1250
|
+
Boolean(roleOptions?.stickyModules.has(module.name)));
|
|
859
1251
|
if (!modules.find((module) => module.name === 'core')) {
|
|
860
1252
|
modules.push(core);
|
|
861
1253
|
}
|
|
862
1254
|
}
|
|
863
|
-
return modules.sort((a, b) =>
|
|
1255
|
+
return modules.sort((a, b) => {
|
|
1256
|
+
const priorityDelta = modulePriority(b) - modulePriority(a);
|
|
1257
|
+
if (priorityDelta !== 0) {
|
|
1258
|
+
return priorityDelta;
|
|
1259
|
+
}
|
|
1260
|
+
return b.functions.length - a.functions.length;
|
|
1261
|
+
});
|
|
864
1262
|
}
|
|
865
1263
|
const RESERVED_C_WRAPPER_NAMES = new Set([
|
|
866
1264
|
'main',
|
|
@@ -1062,6 +1460,30 @@ function humanizeModuleName(value) {
|
|
|
1062
1460
|
}
|
|
1063
1461
|
function deriveSemanticCliDefaults(module) {
|
|
1064
1462
|
const features = collectModuleFeatureSnapshot(module);
|
|
1463
|
+
if (module.name === 'dll_lifecycle') {
|
|
1464
|
+
return {
|
|
1465
|
+
toolName: 'DLL Lifecycle Surface',
|
|
1466
|
+
helpBanner: 'Review DllMain attach/detach behavior, library initialization, and module-lifetime side effects.',
|
|
1467
|
+
};
|
|
1468
|
+
}
|
|
1469
|
+
if (module.name === 'com_activation') {
|
|
1470
|
+
return {
|
|
1471
|
+
toolName: 'COM Activation Surface',
|
|
1472
|
+
helpBanner: 'Trace class-factory exports, registration paths, and COM activation routines.',
|
|
1473
|
+
};
|
|
1474
|
+
}
|
|
1475
|
+
if (module.name === 'export_dispatch') {
|
|
1476
|
+
return {
|
|
1477
|
+
toolName: 'Export Dispatch Surface',
|
|
1478
|
+
helpBanner: 'Recover exported command handlers, dispatch tables, and forwarded-export routing.',
|
|
1479
|
+
};
|
|
1480
|
+
}
|
|
1481
|
+
if (module.name === 'callback_surface') {
|
|
1482
|
+
return {
|
|
1483
|
+
toolName: 'Host Callback Surface',
|
|
1484
|
+
helpBanner: 'Recover host-driven callbacks, plugin entrypoints, and extension notification paths.',
|
|
1485
|
+
};
|
|
1486
|
+
}
|
|
1065
1487
|
if (module.name === 'packer_analysis' || features.hasPackerScan) {
|
|
1066
1488
|
return {
|
|
1067
1489
|
toolName: 'Packer/Protector Detection',
|
|
@@ -1157,6 +1579,12 @@ function collectDisplayStringHints(module, limit = 8) {
|
|
|
1157
1579
|
return [semanticDefaults.helpBanner].filter(Boolean).slice(0, limit);
|
|
1158
1580
|
}
|
|
1159
1581
|
function describeModuleRole(module) {
|
|
1582
|
+
if (module.reviewResolution?.role_hint) {
|
|
1583
|
+
return module.reviewResolution.role_hint;
|
|
1584
|
+
}
|
|
1585
|
+
if (module.roleHint) {
|
|
1586
|
+
return module.roleHint;
|
|
1587
|
+
}
|
|
1160
1588
|
const defaults = deriveSemanticCliDefaults(module);
|
|
1161
1589
|
return defaults.helpBanner;
|
|
1162
1590
|
}
|
|
@@ -1692,6 +2120,13 @@ function summarizeRewriteParameterRoles(func) {
|
|
|
1692
2120
|
.map((item) => `${item.slot}=>${item.role}<${item.inferred_type}>`)
|
|
1693
2121
|
.join('; ');
|
|
1694
2122
|
}
|
|
2123
|
+
function summarizeRewriteReturnRole(func) {
|
|
2124
|
+
const role = func.return_role || func.semantic_evidence?.return_role || null;
|
|
2125
|
+
if (!role) {
|
|
2126
|
+
return 'none';
|
|
2127
|
+
}
|
|
2128
|
+
return `${role.role}<${role.inferred_type}>`;
|
|
2129
|
+
}
|
|
1695
2130
|
function summarizeRewriteStateRoles(func) {
|
|
1696
2131
|
const roles = func.state_roles || func.semantic_evidence?.state_roles || [];
|
|
1697
2132
|
if (roles.length === 0) {
|
|
@@ -2446,6 +2881,7 @@ function buildRewriteSteps(func) {
|
|
|
2446
2881
|
}
|
|
2447
2882
|
function buildAnnotatedRewriteContent(module) {
|
|
2448
2883
|
const lines = [];
|
|
2884
|
+
const orderedFunctions = orderModuleFunctionsForPresentation(module);
|
|
2449
2885
|
const displayStringHints = collectDisplayStringHints(module);
|
|
2450
2886
|
lines.push(`/* module: ${module.name} | annotated rewrite */`);
|
|
2451
2887
|
lines.push(`#include "${sanitizeModuleName(module.name)}.interface.h"`);
|
|
@@ -2454,16 +2890,33 @@ function buildAnnotatedRewriteContent(module) {
|
|
|
2454
2890
|
lines.push(` * Analyst summary:`);
|
|
2455
2891
|
lines.push(` * - function_count: ${module.functions.length}`);
|
|
2456
2892
|
lines.push(` * - recovered_role: ${describeModuleRole(module)}`);
|
|
2893
|
+
lines.push(` * - role_focus: ${Array.from(module.focusMatches).join(', ') || 'none'}`);
|
|
2894
|
+
if (module.reviewResolution?.refined_name) {
|
|
2895
|
+
lines.push(` * - module_review_name: ${module.reviewResolution.refined_name}`);
|
|
2896
|
+
}
|
|
2897
|
+
if (module.reviewResolution?.summary) {
|
|
2898
|
+
lines.push(` * - module_review_summary: ${normalizeExplanationText(module.reviewResolution.summary) || 'none'}`);
|
|
2899
|
+
}
|
|
2900
|
+
if (typeof module.reviewResolution?.confidence === 'number') {
|
|
2901
|
+
lines.push(` * - module_review_confidence: ${Number(module.reviewResolution.confidence).toFixed(2)}`);
|
|
2902
|
+
}
|
|
2903
|
+
lines.push(` * - prioritized_functions: ${orderedFunctions
|
|
2904
|
+
.slice(0, 3)
|
|
2905
|
+
.map((func) => getValidatedSemanticName(func) || func.function)
|
|
2906
|
+
.join(', ') || 'none'}`);
|
|
2457
2907
|
lines.push(` * - import_hints: ${Array.from(module.importHints).slice(0, 8).join(', ') || 'none'}`);
|
|
2458
2908
|
lines.push(` * - string_hints: ${displayStringHints.join(' | ') || 'none'}`);
|
|
2459
2909
|
lines.push(` * - runtime_apis: ${Array.from(module.runtimeApis).slice(0, 8).join(', ') || 'none'}`);
|
|
2460
2910
|
lines.push(` * - runtime_stages: ${Array.from(module.runtimeStages).slice(0, 6).join(', ') || 'none'}`);
|
|
2461
2911
|
lines.push(` * - runtime_notes: ${Array.from(module.runtimeNotes).slice(0, 4).join(' | ') || 'none'}`);
|
|
2912
|
+
if ((module.reviewResolution?.rewrite_guidance || []).length > 0) {
|
|
2913
|
+
lines.push(` * - module_rewrite_guidance: ${(module.reviewResolution?.rewrite_guidance || []).join(' | ')}`);
|
|
2914
|
+
}
|
|
2462
2915
|
lines.push(' * - This file is a human-readable rewrite scaffold, not original source.');
|
|
2463
2916
|
lines.push(' */');
|
|
2464
2917
|
lines.push('');
|
|
2465
2918
|
lines.push(...buildModuleRewritePrelude(module));
|
|
2466
|
-
for (const func of
|
|
2919
|
+
for (const func of orderedFunctions) {
|
|
2467
2920
|
const names = deriveRewriteEntryNames(func, module);
|
|
2468
2921
|
const validatedSemanticName = getValidatedSemanticName(func);
|
|
2469
2922
|
lines.push(`int ${names.implementationName}(AkRuntimeContext *runtime_ctx, const AkSemanticInputs *inputs, AkSemanticOutputs *outputs)`);
|
|
@@ -2502,12 +2955,17 @@ function buildAnnotatedRewriteContent(module) {
|
|
|
2502
2955
|
lines.push(` /* call_context: callers=${func.call_context?.callers?.slice(0, 4).join(', ') || 'none'} callees=${func.call_context?.callees?.slice(0, 6).join(', ') || 'none'} */`);
|
|
2503
2956
|
lines.push(` /* relation_hints: callers=${summarizeRelationshipEntries(func.call_relationships?.callers)} callees=${summarizeRelationshipEntries(func.call_relationships?.callees)} */`);
|
|
2504
2957
|
lines.push(` /* parameter_roles: ${summarizeRewriteParameterRoles(func)} */`);
|
|
2958
|
+
lines.push(` /* return_role: ${summarizeRewriteReturnRole(func)} */`);
|
|
2505
2959
|
lines.push(` /* state_roles: ${summarizeRewriteStateRoles(func)} */`);
|
|
2506
2960
|
lines.push(` /* struct_inference: ${summarizeRewriteStructInference(func)} */`);
|
|
2507
2961
|
if ((func.runtime_context?.corroborated_apis || []).length > 0 ||
|
|
2508
2962
|
(func.runtime_context?.corroborated_stages || []).length > 0 ||
|
|
2509
|
-
(func.runtime_context?.matched_memory_regions || []).length > 0
|
|
2510
|
-
|
|
2963
|
+
(func.runtime_context?.matched_memory_regions || []).length > 0 ||
|
|
2964
|
+
(func.runtime_context?.matched_protections || []).length > 0 ||
|
|
2965
|
+
(func.runtime_context?.matched_region_owners || []).length > 0 ||
|
|
2966
|
+
(func.runtime_context?.matched_observed_modules || []).length > 0 ||
|
|
2967
|
+
(func.runtime_context?.matched_segment_names || []).length > 0) {
|
|
2968
|
+
lines.push(` /* runtime_context: apis=${(func.runtime_context?.corroborated_apis || []).join(', ') || 'none'} stages=${(func.runtime_context?.corroborated_stages || []).join(', ') || 'none'} regions=${(func.runtime_context?.matched_memory_regions || []).join(', ') || 'none'} protections=${(func.runtime_context?.matched_protections || []).join(', ') || 'none'} owners=${(func.runtime_context?.matched_region_owners || []).join(', ') || 'none'} observed_modules=${(func.runtime_context?.matched_observed_modules || []).join(', ') || 'none'} segments=${(func.runtime_context?.matched_segment_names || []).join(', ') || 'none'} ranges=${(func.runtime_context?.matched_address_ranges || []).join(', ') || 'none'} modules=${(func.runtime_context?.suggested_modules || []).join(', ') || 'none'} confidence=${Number(func.runtime_context?.confidence || 0).toFixed(2)} executed=${func.runtime_context?.executed ? 'yes' : 'no'} sources=${(func.runtime_context?.evidence_sources || []).join(', ') || 'unknown'} names=${(func.runtime_context?.source_names || []).join(', ') || 'unknown'} matched_by=${(func.runtime_context?.matched_by || []).join(', ') || 'unknown'} artifacts=${func.runtime_context?.executed_artifact_count || 0}/${func.runtime_context?.artifact_count || 0} */`);
|
|
2511
2969
|
}
|
|
2512
2970
|
if ((func.runtime_context?.notes || []).length > 0) {
|
|
2513
2971
|
lines.push(` /* runtime_notes: ${(func.runtime_context?.notes || []).join(' || ')} */`);
|
|
@@ -2632,6 +3090,58 @@ function scoreFunctionForDedup(func) {
|
|
|
2632
3090
|
(func.runtime_context?.matched_memory_regions?.length || 0) * 2 -
|
|
2633
3091
|
(func.gaps?.length || 0) * 3);
|
|
2634
3092
|
}
|
|
3093
|
+
function scoreFunctionForRewritePresentation(func, module) {
|
|
3094
|
+
const corpus = [
|
|
3095
|
+
func.function,
|
|
3096
|
+
func.semantic_summary || '',
|
|
3097
|
+
func.source_like_snippet || '',
|
|
3098
|
+
...(func.behavior_tags || []),
|
|
3099
|
+
...(func.rank_reasons || []),
|
|
3100
|
+
...(func.runtime_context?.corroborated_stages || []),
|
|
3101
|
+
...(func.runtime_context?.matched_memory_regions || []),
|
|
3102
|
+
].join(' ');
|
|
3103
|
+
let score = func.confidence * 100 +
|
|
3104
|
+
(func.xref_signals?.length || 0) * 6 +
|
|
3105
|
+
(func.runtime_context?.corroborated_apis?.length || 0) * 5 +
|
|
3106
|
+
(func.runtime_context?.matched_memory_regions?.length || 0) * 4 +
|
|
3107
|
+
(func.parameter_roles?.length || 0) * 2 +
|
|
3108
|
+
(func.struct_inference?.length || 0) * 3;
|
|
3109
|
+
if (func.name_resolution?.validated_name) {
|
|
3110
|
+
score += 10;
|
|
3111
|
+
}
|
|
3112
|
+
if (func.explanation_resolution?.summary) {
|
|
3113
|
+
score += 8;
|
|
3114
|
+
}
|
|
3115
|
+
const lowered = corpus.toLowerCase();
|
|
3116
|
+
if (module.name === 'com_activation' && /\b(dllgetclassobject|class factory|iclassfactory|cocreateinstance|inprocserver32)\b/.test(lowered)) {
|
|
3117
|
+
score += 30;
|
|
3118
|
+
}
|
|
3119
|
+
if (module.name === 'dll_lifecycle' && /\b(dllmain|disablethreadlibrarycalls|attach|detach)\b/.test(lowered)) {
|
|
3120
|
+
score += 30;
|
|
3121
|
+
}
|
|
3122
|
+
if (module.name === 'export_dispatch' && /\b(dispatch|invokecommand|handlecommand|runcommand|export)\b/.test(lowered)) {
|
|
3123
|
+
score += 24;
|
|
3124
|
+
}
|
|
3125
|
+
if (module.name === 'callback_surface' && /\b(callback|plugin|notify|hook|host)\b/.test(lowered)) {
|
|
3126
|
+
score += 24;
|
|
3127
|
+
}
|
|
3128
|
+
if (module.name === 'process_ops' && /\b(writeprocessmemory|openprocess|createprocess|setthreadcontext|resumethread)\b/.test(lowered)) {
|
|
3129
|
+
score += 20;
|
|
3130
|
+
}
|
|
3131
|
+
if (module.name === 'packer_analysis' && /\b(packer|protector|entropy|section|signature|layout)\b/.test(lowered)) {
|
|
3132
|
+
score += 20;
|
|
3133
|
+
}
|
|
3134
|
+
return score;
|
|
3135
|
+
}
|
|
3136
|
+
function orderModuleFunctionsForPresentation(module) {
|
|
3137
|
+
return [...module.functions].sort((left, right) => {
|
|
3138
|
+
const scoreDelta = scoreFunctionForRewritePresentation(right, module) - scoreFunctionForRewritePresentation(left, module);
|
|
3139
|
+
if (scoreDelta !== 0) {
|
|
3140
|
+
return scoreDelta;
|
|
3141
|
+
}
|
|
3142
|
+
return left.address.localeCompare(right.address);
|
|
3143
|
+
});
|
|
3144
|
+
}
|
|
2635
3145
|
function dedupeReconstructedFunctions(functions) {
|
|
2636
3146
|
const orderedKeys = [];
|
|
2637
3147
|
const byKey = new Map();
|
|
@@ -3067,6 +3577,8 @@ function buildBinaryProfile(sampleFileType, originalFilename, exportsData, packe
|
|
|
3067
3577
|
buildReconstructCliProfile(modules.map((module) => ({
|
|
3068
3578
|
name: module.name,
|
|
3069
3579
|
functions: [],
|
|
3580
|
+
roleHint: module.role_hint || null,
|
|
3581
|
+
focusMatches: new Set(module.focus_matches || []),
|
|
3070
3582
|
importHints: new Set(module.import_hints || []),
|
|
3071
3583
|
stringHints: new Set(module.string_hints || []),
|
|
3072
3584
|
runtimeApis: new Set(module.runtime_apis || []),
|
|
@@ -3155,6 +3667,22 @@ function buildReverseNotesMarkdown(profile, modules, warnings, runtimeEvidence,
|
|
|
3155
3667
|
const moduleBucket = {
|
|
3156
3668
|
name: module.name,
|
|
3157
3669
|
functions: [],
|
|
3670
|
+
roleHint: module.role_hint || null,
|
|
3671
|
+
focusMatches: new Set(module.focus_matches || []),
|
|
3672
|
+
reviewResolution: module.review_summary || module.refined_name || module.role_hint
|
|
3673
|
+
? {
|
|
3674
|
+
refined_name: module.refined_name || null,
|
|
3675
|
+
summary: module.review_summary || null,
|
|
3676
|
+
role_hint: module.role_hint || null,
|
|
3677
|
+
confidence: typeof module.review_confidence === 'number' ? module.review_confidence : null,
|
|
3678
|
+
assumptions: [],
|
|
3679
|
+
evidence_used: [],
|
|
3680
|
+
rewrite_guidance: [],
|
|
3681
|
+
focus_areas: module.focus_matches || [],
|
|
3682
|
+
priority_functions: [],
|
|
3683
|
+
source: 'llm',
|
|
3684
|
+
}
|
|
3685
|
+
: undefined,
|
|
3158
3686
|
importHints: new Set(module.import_hints || []),
|
|
3159
3687
|
stringHints: new Set(module.string_hints || []),
|
|
3160
3688
|
runtimeApis: new Set(module.runtime_apis || []),
|
|
@@ -3163,7 +3691,7 @@ function buildReverseNotesMarkdown(profile, modules, warnings, runtimeEvidence,
|
|
|
3163
3691
|
};
|
|
3164
3692
|
const displayHints = collectDisplayStringHints(moduleBucket).slice(0, 3);
|
|
3165
3693
|
const semanticRole = describeModuleRole(moduleBucket);
|
|
3166
|
-
lines.push(`- ${module.name}: role=${semanticRole} confidence=${module.confidence.toFixed(2)}, functions=${module.function_count}, strings=${displayHints.join(' | ') || 'none'}, runtime=${module.runtime_stages.slice(0, 2).join(', ') || 'none'}`);
|
|
3694
|
+
lines.push(`- ${module.name}${module.refined_name ? ` [${module.refined_name}]` : ''}: role=${semanticRole} confidence=${module.confidence.toFixed(2)}, focus=${(module.focus_matches || []).join(', ') || 'none'}, functions=${module.function_count}, strings=${displayHints.join(' | ') || 'none'}, runtime=${module.runtime_stages.slice(0, 2).join(', ') || 'none'}${module.review_summary ? `, review=${normalizeExplanationText(module.review_summary)}` : ''}`);
|
|
3167
3695
|
}
|
|
3168
3696
|
lines.push('');
|
|
3169
3697
|
if (runtimeEvidence) {
|
|
@@ -3288,6 +3816,9 @@ export function createCodeReconstructExportHandler(workspaceManager, database, c
|
|
|
3288
3816
|
evidence_session_tag: input.evidence_session_tag || null,
|
|
3289
3817
|
semantic_scope: input.semantic_scope,
|
|
3290
3818
|
semantic_session_tag: input.semantic_session_tag || null,
|
|
3819
|
+
role_target: input.role_target || null,
|
|
3820
|
+
role_focus_areas: input.role_focus_areas,
|
|
3821
|
+
role_priority_order: input.role_priority_order,
|
|
3291
3822
|
analysis_marker: analysisMarker,
|
|
3292
3823
|
runtime_marker: runtimeMarker,
|
|
3293
3824
|
semantic_name_marker: semanticNameMarker,
|
|
@@ -3453,7 +3984,13 @@ export function createCodeReconstructExportHandler(workspaceManager, database, c
|
|
|
3453
3984
|
semantic_names: buildSemanticArtifactProvenance('semantic naming artifacts', semanticNameIndex, input.semantic_scope, input.semantic_session_tag),
|
|
3454
3985
|
semantic_explanations: buildSemanticArtifactProvenance('semantic explanation artifacts', explanationIndex, input.semantic_scope, input.semantic_session_tag),
|
|
3455
3986
|
};
|
|
3456
|
-
const
|
|
3987
|
+
const roleAwareModules = buildRoleAwareModuleOptions(input);
|
|
3988
|
+
const modules = regroupModules(normalizedFunctions, input.module_limit, input.min_module_size, importsData, stringsData, functionStringHints, roleAwareModules);
|
|
3989
|
+
const moduleReviewIndex = await attachModuleReviews(workspaceManager, database, input.sample_id, modules, {
|
|
3990
|
+
scope: input.semantic_scope,
|
|
3991
|
+
sessionTag: input.semantic_session_tag,
|
|
3992
|
+
});
|
|
3993
|
+
provenance.semantic_module_reviews = buildSemanticArtifactProvenance('semantic module review artifacts', moduleReviewIndex, input.semantic_scope, input.semantic_session_tag);
|
|
3457
3994
|
const workspace = await workspaceManager.getWorkspace(input.sample_id);
|
|
3458
3995
|
const originalEntries = await fs.readdir(workspace.original);
|
|
3459
3996
|
const originalFilename = originalEntries.length > 0 ? originalEntries[0] : null;
|
|
@@ -3483,6 +4020,13 @@ export function createCodeReconstructExportHandler(workspaceManager, database, c
|
|
|
3483
4020
|
name: safeName,
|
|
3484
4021
|
confidence: averageConfidence(module.functions),
|
|
3485
4022
|
function_count: module.functions.length,
|
|
4023
|
+
role_hint: module.reviewResolution?.role_hint || module.roleHint,
|
|
4024
|
+
focus_matches: Array.from(module.focusMatches),
|
|
4025
|
+
refined_name: module.reviewResolution?.refined_name || null,
|
|
4026
|
+
review_summary: module.reviewResolution?.summary || null,
|
|
4027
|
+
review_confidence: typeof module.reviewResolution?.confidence === 'number'
|
|
4028
|
+
? module.reviewResolution.confidence
|
|
4029
|
+
: null,
|
|
3486
4030
|
import_hints: Array.from(module.importHints).slice(0, 10),
|
|
3487
4031
|
string_hints: Array.from(module.stringHints).slice(0, 10),
|
|
3488
4032
|
runtime_apis: Array.from(module.runtimeApis).slice(0, 10),
|
|
@@ -3658,7 +4202,11 @@ export function createCodeReconstructExportHandler(workspaceManager, database, c
|
|
|
3658
4202
|
stage_count: dynamicEvidence.stage_count,
|
|
3659
4203
|
observed_apis: dynamicEvidence.observed_apis.slice(0, 12),
|
|
3660
4204
|
region_types: (dynamicEvidence.region_types || []).slice(0, 12),
|
|
4205
|
+
protections: (dynamicEvidence.protections || []).slice(0, 12),
|
|
4206
|
+
address_ranges: (dynamicEvidence.address_ranges || []).slice(0, 8),
|
|
4207
|
+
region_owners: (dynamicEvidence.region_owners || []).slice(0, 8),
|
|
3661
4208
|
observed_modules: (dynamicEvidence.observed_modules || []).slice(0, 8),
|
|
4209
|
+
segment_names: (dynamicEvidence.segment_names || []).slice(0, 8),
|
|
3662
4210
|
observed_strings: (dynamicEvidence.observed_strings || []).slice(0, 8),
|
|
3663
4211
|
stages: dynamicEvidence.stages.slice(0, 12),
|
|
3664
4212
|
summary: dynamicEvidence.summary,
|
|
@@ -3669,6 +4217,11 @@ export function createCodeReconstructExportHandler(workspaceManager, database, c
|
|
|
3669
4217
|
name: module.name,
|
|
3670
4218
|
confidence: module.confidence,
|
|
3671
4219
|
function_count: module.function_count,
|
|
4220
|
+
role_hint: module.role_hint || null,
|
|
4221
|
+
focus_matches: module.focus_matches || [],
|
|
4222
|
+
refined_name: module.refined_name || null,
|
|
4223
|
+
review_summary: module.review_summary || null,
|
|
4224
|
+
review_confidence: typeof module.review_confidence === 'number' ? module.review_confidence : null,
|
|
3672
4225
|
interface_path: module.interface_path,
|
|
3673
4226
|
pseudocode_path: module.pseudocode_path,
|
|
3674
4227
|
rewrite_path: module.rewrite_path,
|
|
@@ -3966,7 +4519,11 @@ export function createCodeReconstructExportHandler(workspaceManager, database, c
|
|
|
3966
4519
|
stage_count: dynamicEvidence.stage_count,
|
|
3967
4520
|
observed_apis: dynamicEvidence.observed_apis.slice(0, 12),
|
|
3968
4521
|
region_types: (dynamicEvidence.region_types || []).slice(0, 12),
|
|
4522
|
+
protections: (dynamicEvidence.protections || []).slice(0, 12),
|
|
4523
|
+
address_ranges: (dynamicEvidence.address_ranges || []).slice(0, 8),
|
|
4524
|
+
region_owners: (dynamicEvidence.region_owners || []).slice(0, 8),
|
|
3969
4525
|
observed_modules: (dynamicEvidence.observed_modules || []).slice(0, 8),
|
|
4526
|
+
segment_names: (dynamicEvidence.segment_names || []).slice(0, 8),
|
|
3970
4527
|
observed_strings: (dynamicEvidence.observed_strings || []).slice(0, 8),
|
|
3971
4528
|
stages: dynamicEvidence.stages.slice(0, 12),
|
|
3972
4529
|
summary: dynamicEvidence.summary,
|