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,115 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Guard Component
|
|
3
|
+
* Enforces authorization rules for dangerous operations
|
|
4
|
+
* Requirements: 18.1, 18.2, 18.3, 18.4
|
|
5
|
+
*/
|
|
6
|
+
/**
|
|
7
|
+
* Operation types that can be checked by Policy Guard
|
|
8
|
+
*/
|
|
9
|
+
export type OperationType = 'static_analysis' | 'decompile' | 'dynamic_execution' | 'network_access' | 'external_upload' | 'bulk_decompile';
|
|
10
|
+
/**
|
|
11
|
+
* Operation to be checked
|
|
12
|
+
*/
|
|
13
|
+
export interface Operation {
|
|
14
|
+
type: OperationType;
|
|
15
|
+
tool: string;
|
|
16
|
+
args: Record<string, unknown>;
|
|
17
|
+
}
|
|
18
|
+
/**
|
|
19
|
+
* Context for policy decision
|
|
20
|
+
*/
|
|
21
|
+
export interface PolicyContext {
|
|
22
|
+
user?: string;
|
|
23
|
+
sampleId?: string;
|
|
24
|
+
timestamp?: string;
|
|
25
|
+
}
|
|
26
|
+
/**
|
|
27
|
+
* Policy decision result
|
|
28
|
+
*/
|
|
29
|
+
export interface PolicyDecision {
|
|
30
|
+
allowed: boolean;
|
|
31
|
+
reason?: string;
|
|
32
|
+
requiresApproval?: boolean;
|
|
33
|
+
}
|
|
34
|
+
/**
|
|
35
|
+
* Dangerous operation requiring approval
|
|
36
|
+
*/
|
|
37
|
+
export interface DangerousOperation {
|
|
38
|
+
type: string;
|
|
39
|
+
description: string;
|
|
40
|
+
risks: string[];
|
|
41
|
+
sampleId: string;
|
|
42
|
+
}
|
|
43
|
+
/**
|
|
44
|
+
* Audit event for logging
|
|
45
|
+
*/
|
|
46
|
+
export interface AuditEvent {
|
|
47
|
+
timestamp: string;
|
|
48
|
+
operation: string;
|
|
49
|
+
user?: string;
|
|
50
|
+
sampleId: string;
|
|
51
|
+
decision: 'allow' | 'deny';
|
|
52
|
+
reason?: string;
|
|
53
|
+
metadata?: Record<string, unknown>;
|
|
54
|
+
}
|
|
55
|
+
/**
|
|
56
|
+
* Policy rule configuration
|
|
57
|
+
*/
|
|
58
|
+
export interface PolicyRule {
|
|
59
|
+
defaultAllow: boolean;
|
|
60
|
+
requiresApproval: boolean;
|
|
61
|
+
requiresIsolation?: boolean;
|
|
62
|
+
auditLevel: 'info' | 'warning' | 'critical';
|
|
63
|
+
maxLimit?: number;
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* Policy rules for different operation types
|
|
67
|
+
* Requirements: 18.1, 18.2, 18.3, 18.4
|
|
68
|
+
*/
|
|
69
|
+
export declare const POLICY_RULES: Record<string, PolicyRule>;
|
|
70
|
+
/**
|
|
71
|
+
* Policy Guard class for enforcing authorization rules
|
|
72
|
+
*/
|
|
73
|
+
export declare class PolicyGuard {
|
|
74
|
+
private auditLogPath;
|
|
75
|
+
constructor(auditLogPath?: string);
|
|
76
|
+
/**
|
|
77
|
+
* Ensure audit log file exists
|
|
78
|
+
*/
|
|
79
|
+
private ensureAuditLogExists;
|
|
80
|
+
/**
|
|
81
|
+
* Check permission for an operation
|
|
82
|
+
* Requirements: 18.1, 18.2
|
|
83
|
+
*/
|
|
84
|
+
checkPermission(operation: Operation, _context: PolicyContext): Promise<PolicyDecision>;
|
|
85
|
+
/**
|
|
86
|
+
* Detect if operation is dangerous based on tool and arguments
|
|
87
|
+
* Requirements: 18.1, 18.3, 18.4
|
|
88
|
+
*/
|
|
89
|
+
private detectDangerousOperation;
|
|
90
|
+
/**
|
|
91
|
+
* Check if approval was provided in operation arguments
|
|
92
|
+
*/
|
|
93
|
+
private checkApprovalProvided;
|
|
94
|
+
/**
|
|
95
|
+
* Check if operation exceeds limit
|
|
96
|
+
*/
|
|
97
|
+
private checkLimitExceeded;
|
|
98
|
+
/**
|
|
99
|
+
* Require user approval for dangerous operation (placeholder)
|
|
100
|
+
* Requirements: 18.1
|
|
101
|
+
* Note: This is a placeholder for V0.5 when human-in-the-loop is implemented
|
|
102
|
+
*/
|
|
103
|
+
requireUserApproval(_operation: DangerousOperation): Promise<boolean>;
|
|
104
|
+
/**
|
|
105
|
+
* Record audit log event
|
|
106
|
+
* Requirements: 18.5, 18.6, 23.1, 23.2, 23.4, 23.5
|
|
107
|
+
*/
|
|
108
|
+
auditLog(event: AuditEvent): Promise<void>;
|
|
109
|
+
/**
|
|
110
|
+
* Get audit log path
|
|
111
|
+
*/
|
|
112
|
+
getAuditLogPath(): string;
|
|
113
|
+
}
|
|
114
|
+
export default PolicyGuard;
|
|
115
|
+
//# sourceMappingURL=policy-guard.d.ts.map
|
|
@@ -0,0 +1,243 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Policy Guard Component
|
|
3
|
+
* Enforces authorization rules for dangerous operations
|
|
4
|
+
* Requirements: 18.1, 18.2, 18.3, 18.4
|
|
5
|
+
*/
|
|
6
|
+
import fs from 'fs';
|
|
7
|
+
import path from 'path';
|
|
8
|
+
// ============================================================================
|
|
9
|
+
// Policy Rules Configuration
|
|
10
|
+
// ============================================================================
|
|
11
|
+
/**
|
|
12
|
+
* Policy rules for different operation types
|
|
13
|
+
* Requirements: 18.1, 18.2, 18.3, 18.4
|
|
14
|
+
*/
|
|
15
|
+
export const POLICY_RULES = {
|
|
16
|
+
// Requirement 18.1: Dynamic execution requires approval
|
|
17
|
+
dynamic_execution: {
|
|
18
|
+
defaultAllow: false,
|
|
19
|
+
requiresApproval: true,
|
|
20
|
+
requiresIsolation: true,
|
|
21
|
+
auditLevel: 'critical',
|
|
22
|
+
},
|
|
23
|
+
// Requirement 18.3: External upload requires approval
|
|
24
|
+
external_upload: {
|
|
25
|
+
defaultAllow: false,
|
|
26
|
+
requiresApproval: true,
|
|
27
|
+
auditLevel: 'critical',
|
|
28
|
+
},
|
|
29
|
+
// Requirement 18.4: Bulk decompilation requires approval
|
|
30
|
+
bulk_decompile: {
|
|
31
|
+
defaultAllow: false,
|
|
32
|
+
requiresApproval: true,
|
|
33
|
+
auditLevel: 'warning',
|
|
34
|
+
maxLimit: 100,
|
|
35
|
+
},
|
|
36
|
+
// Static analysis is generally allowed
|
|
37
|
+
static_analysis: {
|
|
38
|
+
defaultAllow: true,
|
|
39
|
+
requiresApproval: false,
|
|
40
|
+
auditLevel: 'info',
|
|
41
|
+
},
|
|
42
|
+
// Regular decompilation is allowed
|
|
43
|
+
decompile: {
|
|
44
|
+
defaultAllow: true,
|
|
45
|
+
requiresApproval: false,
|
|
46
|
+
auditLevel: 'info',
|
|
47
|
+
},
|
|
48
|
+
// Network access requires approval
|
|
49
|
+
network_access: {
|
|
50
|
+
defaultAllow: false,
|
|
51
|
+
requiresApproval: true,
|
|
52
|
+
requiresIsolation: true,
|
|
53
|
+
auditLevel: 'critical',
|
|
54
|
+
},
|
|
55
|
+
};
|
|
56
|
+
// ============================================================================
|
|
57
|
+
// Policy Guard Implementation
|
|
58
|
+
// ============================================================================
|
|
59
|
+
/**
|
|
60
|
+
* Policy Guard class for enforcing authorization rules
|
|
61
|
+
*/
|
|
62
|
+
export class PolicyGuard {
|
|
63
|
+
auditLogPath;
|
|
64
|
+
constructor(auditLogPath = './audit.log') {
|
|
65
|
+
this.auditLogPath = auditLogPath;
|
|
66
|
+
this.ensureAuditLogExists();
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Ensure audit log file exists
|
|
70
|
+
*/
|
|
71
|
+
ensureAuditLogExists() {
|
|
72
|
+
const dir = path.dirname(this.auditLogPath);
|
|
73
|
+
if (!fs.existsSync(dir)) {
|
|
74
|
+
fs.mkdirSync(dir, { recursive: true });
|
|
75
|
+
}
|
|
76
|
+
if (!fs.existsSync(this.auditLogPath)) {
|
|
77
|
+
fs.writeFileSync(this.auditLogPath, '', 'utf-8');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Check permission for an operation
|
|
82
|
+
* Requirements: 18.1, 18.2
|
|
83
|
+
*/
|
|
84
|
+
async checkPermission(operation, _context) {
|
|
85
|
+
// Detect dangerous operations
|
|
86
|
+
const dangerousType = this.detectDangerousOperation(operation);
|
|
87
|
+
// Get policy rule for the operation type
|
|
88
|
+
const rule = POLICY_RULES[dangerousType] || POLICY_RULES[operation.type];
|
|
89
|
+
if (!rule) {
|
|
90
|
+
// Unknown operation type - deny by default
|
|
91
|
+
return {
|
|
92
|
+
allowed: false,
|
|
93
|
+
reason: `Unknown operation type: ${operation.type}`,
|
|
94
|
+
};
|
|
95
|
+
}
|
|
96
|
+
// Check specific limits FIRST (e.g., bulk decompile limit)
|
|
97
|
+
if (rule.maxLimit !== undefined) {
|
|
98
|
+
const limitExceeded = this.checkLimitExceeded(operation, rule.maxLimit);
|
|
99
|
+
if (limitExceeded) {
|
|
100
|
+
return {
|
|
101
|
+
allowed: false,
|
|
102
|
+
reason: `Operation exceeds maximum limit of ${rule.maxLimit}`,
|
|
103
|
+
requiresApproval: true,
|
|
104
|
+
};
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
// Check if operation requires approval
|
|
108
|
+
if (rule.requiresApproval) {
|
|
109
|
+
// Check if approval was explicitly provided
|
|
110
|
+
const hasApproval = this.checkApprovalProvided(operation);
|
|
111
|
+
if (!hasApproval) {
|
|
112
|
+
return {
|
|
113
|
+
allowed: false,
|
|
114
|
+
reason: `Operation '${operation.type}' requires explicit approval`,
|
|
115
|
+
requiresApproval: true,
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
// Operation is allowed
|
|
120
|
+
return {
|
|
121
|
+
allowed: rule.defaultAllow || this.checkApprovalProvided(operation),
|
|
122
|
+
reason: rule.defaultAllow ? undefined : 'Approved by user',
|
|
123
|
+
};
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Detect if operation is dangerous based on tool and arguments
|
|
127
|
+
* Requirements: 18.1, 18.3, 18.4
|
|
128
|
+
*/
|
|
129
|
+
detectDangerousOperation(operation) {
|
|
130
|
+
// Check for dynamic execution
|
|
131
|
+
if (operation.tool === 'sandbox.execute' ||
|
|
132
|
+
operation.type === 'dynamic_execution') {
|
|
133
|
+
return 'dynamic_execution';
|
|
134
|
+
}
|
|
135
|
+
// Check for external upload
|
|
136
|
+
if (operation.tool.includes('upload') ||
|
|
137
|
+
operation.args.backend === 'online_sandbox' ||
|
|
138
|
+
operation.args.external === true) {
|
|
139
|
+
return 'external_upload';
|
|
140
|
+
}
|
|
141
|
+
// Check for bulk decompilation - check multiple parameters
|
|
142
|
+
if (operation.type === 'decompile') {
|
|
143
|
+
// Check count parameter
|
|
144
|
+
if (typeof operation.args.count === 'number' && operation.args.count > 100) {
|
|
145
|
+
return 'bulk_decompile';
|
|
146
|
+
}
|
|
147
|
+
// Check topk parameter
|
|
148
|
+
if (typeof operation.args.topk === 'number' && operation.args.topk > 100) {
|
|
149
|
+
return 'bulk_decompile';
|
|
150
|
+
}
|
|
151
|
+
// Check addresses array
|
|
152
|
+
if (Array.isArray(operation.args.addresses) && operation.args.addresses.length > 100) {
|
|
153
|
+
return 'bulk_decompile';
|
|
154
|
+
}
|
|
155
|
+
// Check functions array
|
|
156
|
+
if (Array.isArray(operation.args.functions) && operation.args.functions.length > 100) {
|
|
157
|
+
return 'bulk_decompile';
|
|
158
|
+
}
|
|
159
|
+
}
|
|
160
|
+
// Check for network access
|
|
161
|
+
if (operation.args.network === 'enabled' ||
|
|
162
|
+
operation.args.network === 'fake') {
|
|
163
|
+
return 'network_access';
|
|
164
|
+
}
|
|
165
|
+
return operation.type;
|
|
166
|
+
}
|
|
167
|
+
/**
|
|
168
|
+
* Check if approval was provided in operation arguments
|
|
169
|
+
*/
|
|
170
|
+
checkApprovalProvided(operation) {
|
|
171
|
+
// Check for explicit approval flag
|
|
172
|
+
if (operation.args.require_user_approval === true) {
|
|
173
|
+
return true;
|
|
174
|
+
}
|
|
175
|
+
if (operation.args.approved === true) {
|
|
176
|
+
return true;
|
|
177
|
+
}
|
|
178
|
+
return false;
|
|
179
|
+
}
|
|
180
|
+
/**
|
|
181
|
+
* Check if operation exceeds limit
|
|
182
|
+
*/
|
|
183
|
+
checkLimitExceeded(operation, maxLimit) {
|
|
184
|
+
// Check count parameter
|
|
185
|
+
if (typeof operation.args.count === 'number') {
|
|
186
|
+
return operation.args.count > maxLimit;
|
|
187
|
+
}
|
|
188
|
+
// Check topk parameter (for bulk operations)
|
|
189
|
+
if (typeof operation.args.topk === 'number') {
|
|
190
|
+
return operation.args.topk > maxLimit;
|
|
191
|
+
}
|
|
192
|
+
// Check array length parameters
|
|
193
|
+
if (Array.isArray(operation.args.addresses)) {
|
|
194
|
+
return operation.args.addresses.length > maxLimit;
|
|
195
|
+
}
|
|
196
|
+
if (Array.isArray(operation.args.functions)) {
|
|
197
|
+
return operation.args.functions.length > maxLimit;
|
|
198
|
+
}
|
|
199
|
+
return false;
|
|
200
|
+
}
|
|
201
|
+
/**
|
|
202
|
+
* Require user approval for dangerous operation (placeholder)
|
|
203
|
+
* Requirements: 18.1
|
|
204
|
+
* Note: This is a placeholder for V0.5 when human-in-the-loop is implemented
|
|
205
|
+
*/
|
|
206
|
+
async requireUserApproval(_operation) {
|
|
207
|
+
// Placeholder implementation - always returns false
|
|
208
|
+
// In V0.5, this will implement actual human approval mechanism
|
|
209
|
+
return false;
|
|
210
|
+
}
|
|
211
|
+
/**
|
|
212
|
+
* Record audit log event
|
|
213
|
+
* Requirements: 18.5, 18.6, 23.1, 23.2, 23.4, 23.5
|
|
214
|
+
*/
|
|
215
|
+
async auditLog(event) {
|
|
216
|
+
// Ensure timestamp is set
|
|
217
|
+
if (!event.timestamp) {
|
|
218
|
+
event.timestamp = new Date().toISOString();
|
|
219
|
+
}
|
|
220
|
+
// Format as JSON Lines (one JSON object per line)
|
|
221
|
+
const logLine = JSON.stringify(event) + '\n';
|
|
222
|
+
// Append to audit log file
|
|
223
|
+
try {
|
|
224
|
+
fs.appendFileSync(this.auditLogPath, logLine, 'utf-8');
|
|
225
|
+
}
|
|
226
|
+
catch (error) {
|
|
227
|
+
// Log to console if file write fails
|
|
228
|
+
console.error('Failed to write audit log:', error);
|
|
229
|
+
console.error('Audit event:', event);
|
|
230
|
+
}
|
|
231
|
+
}
|
|
232
|
+
/**
|
|
233
|
+
* Get audit log path
|
|
234
|
+
*/
|
|
235
|
+
getAuditLogPath() {
|
|
236
|
+
return this.auditLogPath;
|
|
237
|
+
}
|
|
238
|
+
}
|
|
239
|
+
// ============================================================================
|
|
240
|
+
// Exports
|
|
241
|
+
// ============================================================================
|
|
242
|
+
export default PolicyGuard;
|
|
243
|
+
//# sourceMappingURL=policy-guard.js.map
|
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for decoding process output and rendering raw command lines.
|
|
3
|
+
*/
|
|
4
|
+
export interface DecodedProcessText {
|
|
5
|
+
text: string;
|
|
6
|
+
encoding: string;
|
|
7
|
+
}
|
|
8
|
+
export interface DecodedProcessStreams {
|
|
9
|
+
stdout: DecodedProcessText;
|
|
10
|
+
stderr: DecodedProcessText;
|
|
11
|
+
}
|
|
12
|
+
export declare function decodeProcessText(input: Buffer | string | null | undefined, platform?: NodeJS.Platform): DecodedProcessText;
|
|
13
|
+
export declare function decodeProcessStreams(stdout: Buffer | string | null | undefined, stderr: Buffer | string | null | undefined, platform?: NodeJS.Platform): DecodedProcessStreams;
|
|
14
|
+
export declare function buildRawCommandLine(command: string, args: string[]): string;
|
|
15
|
+
//# sourceMappingURL=process-output.d.ts.map
|
|
@@ -0,0 +1,90 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Helpers for decoding process output and rendering raw command lines.
|
|
3
|
+
*/
|
|
4
|
+
const WINDOWS_CANDIDATE_ENCODINGS = ['utf-8', 'gb18030', 'gbk', 'cp936', 'utf-16le', 'latin1'];
|
|
5
|
+
const DEFAULT_CANDIDATE_ENCODINGS = ['utf-8', 'utf-16le', 'latin1'];
|
|
6
|
+
function toBuffer(input) {
|
|
7
|
+
if (input === undefined || input === null) {
|
|
8
|
+
return Buffer.alloc(0);
|
|
9
|
+
}
|
|
10
|
+
if (Buffer.isBuffer(input)) {
|
|
11
|
+
return input;
|
|
12
|
+
}
|
|
13
|
+
return Buffer.from(input);
|
|
14
|
+
}
|
|
15
|
+
function scoreDecodedText(text) {
|
|
16
|
+
if (!text) {
|
|
17
|
+
return 0;
|
|
18
|
+
}
|
|
19
|
+
let replacementCount = 0;
|
|
20
|
+
let controlCount = 0;
|
|
21
|
+
for (const char of text) {
|
|
22
|
+
const code = char.charCodeAt(0);
|
|
23
|
+
if (code === 0xfffd) {
|
|
24
|
+
replacementCount += 1;
|
|
25
|
+
continue;
|
|
26
|
+
}
|
|
27
|
+
if (code < 32 && char !== '\r' && char !== '\n' && char !== '\t') {
|
|
28
|
+
controlCount += 1;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return text.length - replacementCount * 8 - controlCount * 2;
|
|
32
|
+
}
|
|
33
|
+
function tryDecode(buffer, encoding) {
|
|
34
|
+
try {
|
|
35
|
+
const decoder = new TextDecoder(encoding);
|
|
36
|
+
return decoder.decode(buffer);
|
|
37
|
+
}
|
|
38
|
+
catch {
|
|
39
|
+
return null;
|
|
40
|
+
}
|
|
41
|
+
}
|
|
42
|
+
export function decodeProcessText(input, platform = process.platform) {
|
|
43
|
+
if (typeof input === 'string') {
|
|
44
|
+
return {
|
|
45
|
+
text: input,
|
|
46
|
+
encoding: 'utf-8',
|
|
47
|
+
};
|
|
48
|
+
}
|
|
49
|
+
const buffer = toBuffer(input);
|
|
50
|
+
if (buffer.length === 0) {
|
|
51
|
+
return {
|
|
52
|
+
text: '',
|
|
53
|
+
encoding: 'utf-8',
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
const candidateEncodings = platform === 'win32' ? WINDOWS_CANDIDATE_ENCODINGS : DEFAULT_CANDIDATE_ENCODINGS;
|
|
57
|
+
let best = null;
|
|
58
|
+
let bestScore = Number.NEGATIVE_INFINITY;
|
|
59
|
+
for (const encoding of candidateEncodings) {
|
|
60
|
+
const decoded = tryDecode(buffer, encoding);
|
|
61
|
+
if (decoded === null) {
|
|
62
|
+
continue;
|
|
63
|
+
}
|
|
64
|
+
const score = scoreDecodedText(decoded);
|
|
65
|
+
if (score > bestScore) {
|
|
66
|
+
bestScore = score;
|
|
67
|
+
best = {
|
|
68
|
+
text: decoded,
|
|
69
|
+
encoding,
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
if (best) {
|
|
74
|
+
return best;
|
|
75
|
+
}
|
|
76
|
+
return {
|
|
77
|
+
text: buffer.toString('utf8'),
|
|
78
|
+
encoding: 'utf-8',
|
|
79
|
+
};
|
|
80
|
+
}
|
|
81
|
+
export function decodeProcessStreams(stdout, stderr, platform = process.platform) {
|
|
82
|
+
return {
|
|
83
|
+
stdout: decodeProcessText(stdout, platform),
|
|
84
|
+
stderr: decodeProcessText(stderr, platform),
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
export function buildRawCommandLine(command, args) {
|
|
88
|
+
return [command, ...args].join(' ').trim();
|
|
89
|
+
}
|
|
90
|
+
//# sourceMappingURL=process-output.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PromptArgs, PromptDefinition, PromptResult } from '../types.js';
|
|
2
|
+
export declare const functionExplanationReviewPromptDefinition: PromptDefinition;
|
|
3
|
+
export declare function buildFunctionExplanationReviewPromptText(preparedBundleJson: string, analysisGoal?: string): string;
|
|
4
|
+
export declare function createFunctionExplanationReviewPromptHandler(): (args: PromptArgs) => Promise<PromptResult>;
|
|
5
|
+
//# sourceMappingURL=function-explanation-review.d.ts.map
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
export const functionExplanationReviewPromptDefinition = {
|
|
2
|
+
name: 'reverse.function_explanation_review',
|
|
3
|
+
title: 'Function Explanation Review',
|
|
4
|
+
description: 'Guide an external LLM to explain structured reverse-engineering evidence and return strict JSON explanations grounded in MCP evidence.',
|
|
5
|
+
arguments: [
|
|
6
|
+
{
|
|
7
|
+
name: 'prepared_bundle_json',
|
|
8
|
+
description: 'JSON bundle produced by code.function.explain.prepare',
|
|
9
|
+
required: true,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'analysis_goal',
|
|
13
|
+
description: 'Optional analysis goal to bias the explanation toward malware, tooling, or library semantics',
|
|
14
|
+
required: false,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
export function buildFunctionExplanationReviewPromptText(preparedBundleJson, analysisGoal) {
|
|
19
|
+
const goal = analysisGoal?.trim() ||
|
|
20
|
+
'Explain the supplied functions in plain language and propose evidence-grounded rewrite guidance.';
|
|
21
|
+
return [
|
|
22
|
+
goal,
|
|
23
|
+
'',
|
|
24
|
+
'You are reviewing structured reverse-engineering evidence from an MCP server.',
|
|
25
|
+
'Use only the supplied evidence bundle. Do not invent APIs, data structures, or behaviors that do not appear in the evidence.',
|
|
26
|
+
'',
|
|
27
|
+
'Explanation policy:',
|
|
28
|
+
'- Prefer behavior-first summaries such as "resolves dynamic imports", "dispatches exported commands", or "checks service control state".',
|
|
29
|
+
'- Treat all confidence values as heuristic evidence strength, not calibrated probability.',
|
|
30
|
+
'- Explicitly preserve uncertainty. If a behavior depends on an assumption, state the assumption rather than overstating certainty.',
|
|
31
|
+
'- Keep rewrite guidance implementation-oriented but evidence-grounded. Avoid pretending you recovered the original source code.',
|
|
32
|
+
'',
|
|
33
|
+
'Output contract:',
|
|
34
|
+
'Return strict JSON only, with the shape {"explanations":[...]}',
|
|
35
|
+
'Each explanation item must contain:',
|
|
36
|
+
'- address_or_function, or separate address / function fields',
|
|
37
|
+
'- summary',
|
|
38
|
+
'- behavior',
|
|
39
|
+
'- confidence',
|
|
40
|
+
'- assumptions',
|
|
41
|
+
'- evidence_used',
|
|
42
|
+
'- rewrite_guidance',
|
|
43
|
+
'',
|
|
44
|
+
'The client can use your JSON output as a post-processing explanation layer over reconstruct/export results.',
|
|
45
|
+
'',
|
|
46
|
+
'Prepared bundle JSON:',
|
|
47
|
+
preparedBundleJson,
|
|
48
|
+
].join('\n');
|
|
49
|
+
}
|
|
50
|
+
export function createFunctionExplanationReviewPromptHandler() {
|
|
51
|
+
return async (args) => ({
|
|
52
|
+
description: 'Prompt template for evidence-grounded function explanation and rewrite guidance.',
|
|
53
|
+
messages: [
|
|
54
|
+
{
|
|
55
|
+
role: 'user',
|
|
56
|
+
content: {
|
|
57
|
+
type: 'text',
|
|
58
|
+
text: buildFunctionExplanationReviewPromptText(args.prepared_bundle_json || '', args.analysis_goal),
|
|
59
|
+
},
|
|
60
|
+
},
|
|
61
|
+
],
|
|
62
|
+
});
|
|
63
|
+
}
|
|
64
|
+
//# sourceMappingURL=function-explanation-review.js.map
|
|
@@ -0,0 +1,5 @@
|
|
|
1
|
+
import type { PromptArgs, PromptDefinition, PromptResult } from '../types.js';
|
|
2
|
+
export declare const semanticNameReviewPromptDefinition: PromptDefinition;
|
|
3
|
+
export declare function buildSemanticNameReviewPromptText(preparedBundleJson: string, analysisGoal?: string): string;
|
|
4
|
+
export declare function createSemanticNameReviewPromptHandler(): (args: PromptArgs) => Promise<PromptResult>;
|
|
5
|
+
//# sourceMappingURL=semantic-name-review.d.ts.map
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
export const semanticNameReviewPromptDefinition = {
|
|
2
|
+
name: 'reverse.semantic_name_review',
|
|
3
|
+
title: 'Semantic Name Review',
|
|
4
|
+
description: 'Guide an external LLM to review structured reverse-engineering evidence and return JSON name suggestions.',
|
|
5
|
+
arguments: [
|
|
6
|
+
{
|
|
7
|
+
name: 'prepared_bundle_json',
|
|
8
|
+
description: 'JSON bundle produced by code.function.rename.prepare',
|
|
9
|
+
required: true,
|
|
10
|
+
},
|
|
11
|
+
{
|
|
12
|
+
name: 'analysis_goal',
|
|
13
|
+
description: 'Optional analysis goal to bias the review toward a malware/operator-tooling objective',
|
|
14
|
+
required: false,
|
|
15
|
+
},
|
|
16
|
+
],
|
|
17
|
+
};
|
|
18
|
+
export function buildSemanticNameReviewPromptText(preparedBundleJson, analysisGoal) {
|
|
19
|
+
const goal = analysisGoal?.trim() ||
|
|
20
|
+
'Review the supplied function evidence bundle and propose precise, human-readable semantic names.';
|
|
21
|
+
return [
|
|
22
|
+
goal,
|
|
23
|
+
'',
|
|
24
|
+
'You are reviewing structured reverse-engineering evidence from an MCP server.',
|
|
25
|
+
'Use only the supplied evidence. Do not invent APIs, data structures, or behaviors that are not present in the bundle.',
|
|
26
|
+
'',
|
|
27
|
+
'Naming policy:',
|
|
28
|
+
'- Preserve any existing rule_based_name unless the bundle explicitly marks the function unresolved.',
|
|
29
|
+
'- Prefer snake_case names that describe observable behavior, such as read_remote_memory, write_remote_memory, or parse_pe_sections.',
|
|
30
|
+
'- Return no suggestion when evidence is too weak. Weak evidence is better represented as a lower confidence candidate than as a hallucinated precise name.',
|
|
31
|
+
'- Keep suggestions implementation-agnostic. Avoid compiler, thunk, or framework noise unless it is the dominant behavior.',
|
|
32
|
+
'',
|
|
33
|
+
'Output contract:',
|
|
34
|
+
'Return strict JSON only, with the shape {"suggestions":[...]}',
|
|
35
|
+
'Each suggestion item must contain:',
|
|
36
|
+
'- address_or_function, or separate address / function fields',
|
|
37
|
+
'- candidate_name',
|
|
38
|
+
'- confidence',
|
|
39
|
+
'- why',
|
|
40
|
+
'- required_assumptions',
|
|
41
|
+
'- evidence_used',
|
|
42
|
+
'',
|
|
43
|
+
'The client should pass your JSON result to code.function.rename.apply.',
|
|
44
|
+
'',
|
|
45
|
+
'Prepared bundle JSON:',
|
|
46
|
+
preparedBundleJson,
|
|
47
|
+
].join('\n');
|
|
48
|
+
}
|
|
49
|
+
export function createSemanticNameReviewPromptHandler() {
|
|
50
|
+
return async (args) => ({
|
|
51
|
+
description: 'Prompt template for evidence-grounded semantic renaming of reconstructed functions.',
|
|
52
|
+
messages: [
|
|
53
|
+
{
|
|
54
|
+
role: 'user',
|
|
55
|
+
content: {
|
|
56
|
+
type: 'text',
|
|
57
|
+
text: buildSemanticNameReviewPromptText(args.prepared_bundle_json || '', args.analysis_goal),
|
|
58
|
+
},
|
|
59
|
+
},
|
|
60
|
+
],
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=semantic-name-review.js.map
|
|
@@ -0,0 +1,34 @@
|
|
|
1
|
+
import type { DynamicTraceSummary } from './dynamic-trace.js';
|
|
2
|
+
export interface RuntimeCorrelationInput {
|
|
3
|
+
functionName?: string;
|
|
4
|
+
moduleName?: string;
|
|
5
|
+
behaviorTags?: string[];
|
|
6
|
+
xrefApis?: string[];
|
|
7
|
+
rankReasons?: string[];
|
|
8
|
+
semanticSummary?: string;
|
|
9
|
+
stringHints?: string[];
|
|
10
|
+
callTargets?: string[];
|
|
11
|
+
}
|
|
12
|
+
export interface RuntimeCorrelation {
|
|
13
|
+
corroborated_apis: string[];
|
|
14
|
+
corroborated_stages: string[];
|
|
15
|
+
notes: string[];
|
|
16
|
+
confidence: number;
|
|
17
|
+
executed?: boolean;
|
|
18
|
+
evidence_sources?: string[];
|
|
19
|
+
source_names?: string[];
|
|
20
|
+
artifact_count?: number;
|
|
21
|
+
executed_artifact_count?: number;
|
|
22
|
+
matched_memory_regions?: string[];
|
|
23
|
+
suggested_modules?: string[];
|
|
24
|
+
matched_by?: string[];
|
|
25
|
+
provenance_layers?: string[];
|
|
26
|
+
latest_artifact_at?: string | null;
|
|
27
|
+
scope_note?: string;
|
|
28
|
+
}
|
|
29
|
+
export declare function normalizeRuntimeApiName(value: string): string;
|
|
30
|
+
export declare function extractSensitiveApisFromReasons(rankReasons?: string[]): string[];
|
|
31
|
+
export declare function deriveRuntimeStageCandidates(input: RuntimeCorrelationInput): string[];
|
|
32
|
+
export declare function correlateFunctionWithRuntimeEvidence(input: RuntimeCorrelationInput, dynamicEvidence: DynamicTraceSummary | null | undefined): RuntimeCorrelation | undefined;
|
|
33
|
+
export declare function modulesSuggestedByRuntimeStages(stages?: string[]): string[];
|
|
34
|
+
//# sourceMappingURL=runtime-correlation.d.ts.map
|