@remnux/mcp-server 0.1.53 → 0.1.55

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (72) hide show
  1. package/README.md +7 -1
  2. package/dist/analysis/behavior-prerequisites.d.ts +65 -0
  3. package/dist/analysis/behavior-prerequisites.d.ts.map +1 -0
  4. package/dist/analysis/behavior-prerequisites.js +186 -0
  5. package/dist/analysis/behavior-prerequisites.js.map +1 -0
  6. package/dist/analysis/file-diff.d.ts +59 -0
  7. package/dist/analysis/file-diff.d.ts.map +1 -0
  8. package/dist/analysis/file-diff.js +55 -0
  9. package/dist/analysis/file-diff.js.map +1 -0
  10. package/dist/analysis/index.d.ts +1 -1
  11. package/dist/analysis/index.d.ts.map +1 -1
  12. package/dist/analysis/index.js +1 -1
  13. package/dist/analysis/index.js.map +1 -1
  14. package/dist/analysis/string-usage.d.ts +77 -0
  15. package/dist/analysis/string-usage.d.ts.map +1 -0
  16. package/dist/analysis/string-usage.js +130 -0
  17. package/dist/analysis/string-usage.js.map +1 -0
  18. package/dist/analysis/summarizer.d.ts +22 -0
  19. package/dist/analysis/summarizer.d.ts.map +1 -1
  20. package/dist/analysis/summarizer.js +41 -0
  21. package/dist/analysis/summarizer.js.map +1 -1
  22. package/dist/connectors/local.d.ts.map +1 -1
  23. package/dist/connectors/local.js +14 -1
  24. package/dist/connectors/local.js.map +1 -1
  25. package/dist/connectors/ssh.d.ts +1 -0
  26. package/dist/connectors/ssh.d.ts.map +1 -1
  27. package/dist/connectors/ssh.js +14 -6
  28. package/dist/connectors/ssh.js.map +1 -1
  29. package/dist/handlers/analyze-file.d.ts.map +1 -1
  30. package/dist/handlers/analyze-file.js +14 -2
  31. package/dist/handlers/analyze-file.js.map +1 -1
  32. package/dist/handlers/check-behavior-prerequisites.d.ts +16 -0
  33. package/dist/handlers/check-behavior-prerequisites.d.ts.map +1 -0
  34. package/dist/handlers/check-behavior-prerequisites.js +132 -0
  35. package/dist/handlers/check-behavior-prerequisites.js.map +1 -0
  36. package/dist/handlers/compare-files.d.ts +10 -0
  37. package/dist/handlers/compare-files.d.ts.map +1 -0
  38. package/dist/handlers/compare-files.js +147 -0
  39. package/dist/handlers/compare-files.js.map +1 -0
  40. package/dist/handlers/report.d.ts.map +1 -1
  41. package/dist/handlers/report.js +11 -0
  42. package/dist/handlers/report.js.map +1 -1
  43. package/dist/handlers/verify-string-usage.d.ts +10 -0
  44. package/dist/handlers/verify-string-usage.d.ts.map +1 -0
  45. package/dist/handlers/verify-string-usage.js +166 -0
  46. package/dist/handlers/verify-string-usage.js.map +1 -0
  47. package/dist/index.d.ts.map +1 -1
  48. package/dist/index.js +47 -8
  49. package/dist/index.js.map +1 -1
  50. package/dist/parsers/capa.d.ts +8 -1
  51. package/dist/parsers/capa.d.ts.map +1 -1
  52. package/dist/parsers/capa.js +138 -0
  53. package/dist/parsers/capa.js.map +1 -1
  54. package/dist/parsers/imports.d.ts +36 -0
  55. package/dist/parsers/imports.d.ts.map +1 -0
  56. package/dist/parsers/imports.js +67 -0
  57. package/dist/parsers/imports.js.map +1 -0
  58. package/dist/parsers/r2.d.ts +73 -0
  59. package/dist/parsers/r2.d.ts.map +1 -0
  60. package/dist/parsers/r2.js +161 -0
  61. package/dist/parsers/r2.js.map +1 -0
  62. package/dist/parsers/types.d.ts +19 -0
  63. package/dist/parsers/types.d.ts.map +1 -1
  64. package/dist/report/triage-discipline.d.ts +28 -0
  65. package/dist/report/triage-discipline.d.ts.map +1 -0
  66. package/dist/report/triage-discipline.js +49 -0
  67. package/dist/report/triage-discipline.js.map +1 -0
  68. package/dist/schemas/tools.d.ts +45 -3
  69. package/dist/schemas/tools.d.ts.map +1 -1
  70. package/dist/schemas/tools.js +22 -2
  71. package/dist/schemas/tools.js.map +1 -1
  72. package/package.json +1 -1
@@ -0,0 +1,132 @@
1
+ import { validateFilePath } from "../security/blocklist.js";
2
+ import { formatResponse, formatError } from "../response.js";
3
+ import { REMnuxError } from "../errors/remnux-error.js";
4
+ import { toREMnuxError } from "../errors/error-mapper.js";
5
+ import { resolveSamplePath } from "../utils/resolve-sample-path.js";
6
+ import { checkFileExists } from "../utils/check-file-exists.js";
7
+ import { parsePeImports } from "../parsers/imports.js";
8
+ import { BEHAVIOR_PREREQUISITES, classifyPrerequisite, hasDynamicResolution, } from "../analysis/behavior-prerequisites.js";
9
+ /** Packer/protector families whose names in diec output indicate an obscured import table. */
10
+ const PACKER_KEYWORDS = /\b(UPX|ASPack|MPRESS|Themida|VMProtect|Enigma|PECompact|FSG|MEW|Petite|NSPack|Armadillo|Obsidium|ASProtect|MoleBox|Yoda|kkrunchy|nspack)\b/i;
11
+ /**
12
+ * Decide whether the import table is unreliable (packed/protected). Tries diec's
13
+ * JSON (`detects[].values[].type` of Packer/Protector), then falls back to a
14
+ * keyword scan of the raw output. Conservative: any signal → obscured.
15
+ */
16
+ export function looksObscured(diecOutput) {
17
+ const raw = diecOutput.trim();
18
+ if (!raw)
19
+ return false;
20
+ try {
21
+ const data = JSON.parse(raw);
22
+ if (Array.isArray(data.detects)) {
23
+ for (const d of data.detects) {
24
+ for (const v of d.values ?? []) {
25
+ if (typeof v.type === "string" && /pack|protect/i.test(v.type))
26
+ return true;
27
+ if (typeof v.name === "string" && PACKER_KEYWORDS.test(v.name))
28
+ return true;
29
+ }
30
+ }
31
+ return false; // valid diec JSON with no packer/protector detect
32
+ }
33
+ }
34
+ catch {
35
+ // not JSON — fall through to keyword scan
36
+ }
37
+ return PACKER_KEYWORDS.test(raw);
38
+ }
39
+ const BASIS = "Static PE import table (readpe) plus packer detection (diec). This is a STATIC capability check: it reports " +
40
+ "whether the binary can call the APIs a behavior requires, NOT whether the behavior runs. Static capability is " +
41
+ "necessary but not sufficient — confirm any behavior with dynamic analysis.";
42
+ export async function handleCheckBehaviorPrerequisites(deps, args) {
43
+ const startTime = Date.now();
44
+ try {
45
+ const { connector, config } = deps;
46
+ // Validate the requested behavior up front (clear error beats a vague result).
47
+ const behaviorKeys = Object.keys(BEHAVIOR_PREREQUISITES);
48
+ if (args.behavior && !(args.behavior in BEHAVIOR_PREREQUISITES)) {
49
+ return formatError("check_behavior_prerequisites", new REMnuxError(`Unknown behavior "${args.behavior}".`, "INVALID_ARGUMENT", "validation", `Use one of: ${behaviorKeys.join(", ")} — or omit 'behavior' to scan all.`), startTime);
50
+ }
51
+ if (!config.noSandbox) {
52
+ const validation = validateFilePath(args.file, config.samplesDir);
53
+ if (!validation.safe) {
54
+ return formatError("check_behavior_prerequisites", new REMnuxError(validation.error || "Invalid file path", "INVALID_PATH", "validation", "Use a relative path within the samples directory"), startTime);
55
+ }
56
+ }
57
+ const { filePath } = resolveSamplePath(args.file, config.samplesDir, config.mode);
58
+ const fileError = await checkFileExists(connector, filePath);
59
+ if (fileError)
60
+ return formatError("check_behavior_prerequisites", fileError, startTime);
61
+ // Confirm this is a Windows PE — the check is meaningless otherwise.
62
+ let fileType = "";
63
+ try {
64
+ const r = await connector.execute(["file", filePath], { timeout: 30000 });
65
+ fileType = r.stdout?.trim() ?? "";
66
+ }
67
+ catch (error) {
68
+ const mapped = toREMnuxError(error, config.mode);
69
+ if (mapped.code === "CONNECTION_FAILED") {
70
+ return formatError("check_behavior_prerequisites", mapped, startTime);
71
+ }
72
+ }
73
+ const isPe = /\bPE32\+?\b|MS Windows|for MS Windows|\.Net assembly|PE executable/i.test(fileType);
74
+ if (!isPe) {
75
+ return formatResponse("check_behavior_prerequisites", {
76
+ file: args.file,
77
+ file_type: fileType,
78
+ is_pe: false,
79
+ basis: BASIS,
80
+ results: (args.behavior ? [args.behavior] : behaviorKeys).map((b) => ({
81
+ behavior: b,
82
+ description: BEHAVIOR_PREREQUISITES[b].description,
83
+ static_capability: "not_applicable",
84
+ rationale: "Not a Windows PE file; the import-based prerequisite check does not apply.",
85
+ recommended_followup: "Use the analysis tools appropriate for this file type.",
86
+ })),
87
+ }, startTime);
88
+ }
89
+ // Read the import table (readpe -i -f json) and detect packing (diec -j).
90
+ let imports = parsePeImports("");
91
+ try {
92
+ const r = await connector.execute(["readpe", "-i", "-f", "json", filePath], { timeout: 60000 });
93
+ imports = parsePeImports(r.stdout ?? "");
94
+ }
95
+ catch {
96
+ // imports stays unparsed → analysis_incomplete downstream
97
+ }
98
+ let obscured = false;
99
+ try {
100
+ const r = await connector.execute(["diec", "-j", filePath], { timeout: 60000 });
101
+ obscured = looksObscured(r.stdout ?? "");
102
+ }
103
+ catch {
104
+ // best effort — absence of diec is not proof of no packer
105
+ }
106
+ // A PE that parses but imports nothing is itself a strong obscured signal.
107
+ if (imports.parsed && imports.count === 0)
108
+ obscured = true;
109
+ // Managed/.NET: the native import table doesn't reflect managed-code
110
+ // capability, so we must not emit a clean negative from it.
111
+ const managed = /\.net assembly|mono\/\.net/i.test(fileType) ||
112
+ imports.dlls.some((d) => /^mscoree\.dll$/i.test(d.dll));
113
+ const ctx = { obscured, importsParsed: imports.parsed && imports.count > 0, managed };
114
+ const keysToCheck = args.behavior ? [args.behavior] : behaviorKeys;
115
+ const results = keysToCheck.map((b) => classifyPrerequisite(b, BEHAVIOR_PREREQUISITES[b], imports.functionSet, ctx));
116
+ return formatResponse("check_behavior_prerequisites", {
117
+ file: args.file,
118
+ file_type: fileType,
119
+ is_pe: true,
120
+ managed,
121
+ packer_detected: obscured,
122
+ import_count: imports.count,
123
+ dynamic_resolution_present: hasDynamicResolution(imports.functionSet),
124
+ basis: BASIS,
125
+ results,
126
+ }, startTime);
127
+ }
128
+ catch (error) {
129
+ return formatError("check_behavior_prerequisites", toREMnuxError(error, deps.config.mode), startTime);
130
+ }
131
+ }
132
+ //# sourceMappingURL=check-behavior-prerequisites.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"check-behavior-prerequisites.js","sourceRoot":"","sources":["../../src/handlers/check-behavior-prerequisites.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { HandlerDeps } from "./types.js";
2
+ import type { CompareFilesArgs } from "../schemas/tools.js";
3
+ export declare function handleCompareFiles(deps: HandlerDeps, args: CompareFilesArgs): Promise<{
4
+ content: Array<{
5
+ type: "text";
6
+ text: string;
7
+ }>;
8
+ isError?: boolean;
9
+ }>;
10
+ //# sourceMappingURL=compare-files.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-files.d.ts","sourceRoot":"","sources":["../../src/handlers/compare-files.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,qBAAqB,CAAC;AAwH5D,wBAAsB,kBAAkB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,gBAAgB;;;;;;GA8CjF"}
@@ -0,0 +1,147 @@
1
+ import { validateFilePath } from "../security/blocklist.js";
2
+ import { formatResponse, formatError } from "../response.js";
3
+ import { REMnuxError } from "../errors/remnux-error.js";
4
+ import { toREMnuxError } from "../errors/error-mapper.js";
5
+ import { resolveSamplePath } from "../utils/resolve-sample-path.js";
6
+ import { checkFileExists } from "../utils/check-file-exists.js";
7
+ import { parsePeImports } from "../parsers/imports.js";
8
+ import { parseDiecOutput } from "../parsers/diec.js";
9
+ import { parseCapaOutput } from "../parsers/capa.js";
10
+ import { parseR2Sections } from "../parsers/r2.js";
11
+ import { diffFileMeta } from "../analysis/file-diff.js";
12
+ /** Shannon entropy of the file's bytes, via a one-shot python helper. */
13
+ const ENTROPY_PY = "import sys,math,collections\n" +
14
+ "b=open(sys.argv[1],'rb').read()\n" +
15
+ "n=len(b) or 1\n" +
16
+ "c=collections.Counter(b)\n" +
17
+ "print(round(-sum((v/n)*math.log2(v/n) for v in c.values()),4))";
18
+ function archFromFileType(ft) {
19
+ if (/PE32\+|x86-64|x86_64|64-bit/i.test(ft))
20
+ return "x64";
21
+ if (/PE32\b|Intel 80386|80386|32-bit/i.test(ft))
22
+ return "x86";
23
+ return undefined;
24
+ }
25
+ /** Pull the value after "Type: name" from a diec finding for a given category. */
26
+ function diecValue(diecRaw, category) {
27
+ const parsed = parseDiecOutput(diecRaw);
28
+ const f = parsed.findings.find((x) => x.category === category);
29
+ if (!f)
30
+ return undefined;
31
+ const idx = f.description.indexOf(": ");
32
+ return idx >= 0 ? f.description.slice(idx + 2) : f.description;
33
+ }
34
+ async function num(connector, cmd) {
35
+ try {
36
+ const r = await connector.execute(cmd, { timeout: 30000 });
37
+ const n = parseFloat((r.stdout || "").trim().split(/\s+/)[0]);
38
+ return Number.isFinite(n) ? n : undefined;
39
+ }
40
+ catch {
41
+ return undefined;
42
+ }
43
+ }
44
+ async function gatherFileMeta(connector, filePath, fileArg, runCapa) {
45
+ let fileType = "";
46
+ let sha256 = "";
47
+ try {
48
+ fileType = (await connector.execute(["file", filePath], { timeout: 30000 })).stdout?.trim() ?? "";
49
+ }
50
+ catch { /* best effort */ }
51
+ try {
52
+ sha256 = ((await connector.execute(["sha256sum", filePath], { timeout: 30000 })).stdout || "").trim().split(/\s+/)[0] || "";
53
+ }
54
+ catch { /* best effort */ }
55
+ const size_bytes = (await num(connector, ["stat", "-c", "%s", filePath])) ?? 0;
56
+ const entropy = await (async () => {
57
+ try {
58
+ const r = await connector.execute(["python3", "-c", ENTROPY_PY, filePath], { timeout: 30000 });
59
+ const n = parseFloat((r.stdout || "").trim());
60
+ return Number.isFinite(n) ? n : undefined;
61
+ }
62
+ catch {
63
+ return undefined;
64
+ }
65
+ })();
66
+ let compiler;
67
+ let packer;
68
+ try {
69
+ const diec = (await connector.execute(["diec", "-j", filePath], { timeout: 60000 })).stdout || "";
70
+ compiler = diecValue(diec, "compiler");
71
+ packer = diecValue(diec, "packer") ?? diecValue(diec, "protector");
72
+ }
73
+ catch { /* best effort */ }
74
+ let imports = [];
75
+ try {
76
+ const imp = parsePeImports((await connector.execute(["readpe", "-i", "-f", "json", filePath], { timeout: 60000 })).stdout || "");
77
+ imports = imp.dlls.flatMap((d) => d.functions);
78
+ }
79
+ catch { /* non-PE or failure */ }
80
+ let sections = [];
81
+ try {
82
+ const sec = parseR2Sections((await connector.execute(["r2", "-2", "-q", "-N", "-e", "scr.color=0", "-c", "iSj", filePath], { timeout: 30000 })).stdout || "");
83
+ sections = sec.map((s) => s.name).filter((n) => n.length > 0);
84
+ }
85
+ catch { /* best effort */ }
86
+ let capabilities = [];
87
+ if (runCapa) {
88
+ try {
89
+ const capa = parseCapaOutput((await connector.execute(["capa", "-j", filePath], { timeout: 300000 })).stdout || "");
90
+ capabilities = capa.findings.map((f) => f.description);
91
+ }
92
+ catch { /* best effort */ }
93
+ }
94
+ return {
95
+ file: fileArg,
96
+ file_type: fileType,
97
+ sha256,
98
+ size_bytes,
99
+ arch: archFromFileType(fileType),
100
+ entropy,
101
+ compiler,
102
+ packer,
103
+ imports,
104
+ import_count: imports.length,
105
+ capabilities,
106
+ capa_run: runCapa,
107
+ sections,
108
+ };
109
+ }
110
+ export async function handleCompareFiles(deps, args) {
111
+ const startTime = Date.now();
112
+ try {
113
+ const { connector, config } = deps;
114
+ const depth = args.depth ?? "standard";
115
+ for (const f of [args.file_a, args.file_b]) {
116
+ if (!config.noSandbox) {
117
+ const v = validateFilePath(f, config.samplesDir);
118
+ if (!v.safe) {
119
+ return formatError("compare_files", new REMnuxError(v.error || "Invalid file path", "INVALID_PATH", "validation", "Use a relative path within the samples directory"), startTime);
120
+ }
121
+ }
122
+ }
123
+ const pa = resolveSamplePath(args.file_a, config.samplesDir, config.mode);
124
+ const pb = resolveSamplePath(args.file_b, config.samplesDir, config.mode);
125
+ const ea = await checkFileExists(connector, pa.filePath);
126
+ if (ea)
127
+ return formatError("compare_files", ea, startTime);
128
+ const eb = await checkFileExists(connector, pb.filePath);
129
+ if (eb)
130
+ return formatError("compare_files", eb, startTime);
131
+ const runCapa = depth === "standard";
132
+ const metaA = await gatherFileMeta(connector, pa.filePath, args.file_a, runCapa);
133
+ const metaB = await gatherFileMeta(connector, pb.filePath, args.file_b, runCapa);
134
+ const diff = diffFileMeta(metaA, metaB);
135
+ return formatResponse("compare_files", {
136
+ depth,
137
+ basis: "Structured diff of two files' static properties (size, entropy, architecture, compiler, packer, imports, capabilities, sections). Reuses readpe/diec/capa/radare2; capability diff requires depth='standard'.",
138
+ file_a: { ...diff.file_a, file_type: metaA.file_type, size_bytes: metaA.size_bytes, import_count: metaA.import_count },
139
+ file_b: { ...diff.file_b, file_type: metaB.file_type, size_bytes: metaB.size_bytes, import_count: metaB.import_count },
140
+ diff,
141
+ }, startTime);
142
+ }
143
+ catch (error) {
144
+ return formatError("compare_files", toREMnuxError(error, deps.config.mode), startTime);
145
+ }
146
+ }
147
+ //# sourceMappingURL=compare-files.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"compare-files.js","sourceRoot":"","sources":["../../src/handlers/compare-files.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/handlers/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AAyCjE,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,WAAW;;;;;;GAgB/D;AAED,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB;;;;;;GAkB5F"}
1
+ {"version":3,"file":"report.d.ts","sourceRoot":"","sources":["../../src/handlers/report.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AA0CjE,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,WAAW;;;;;;GAgB/D;AAED,wBAAsB,uBAAuB,CAAC,KAAK,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB;;;;;;GAmC5F"}
@@ -1,6 +1,7 @@
1
1
  import { formatResponse, formatError } from "../response.js";
2
2
  import { toREMnuxError } from "../errors/error-mapper.js";
3
3
  import { REPORT_TEMPLATE, GUIDELINES_DIGEST, ATTRIBUTION, SOURCE_META, } from "../report/content.generated.js";
4
+ import { TRIAGE_DISCIPLINE } from "../report/triage-discipline.js";
4
5
  const NOTES = "This report template and writing guidance are bundled with the server and work offline — no network required. " +
5
6
  `The canonical, continuously updated source is ${SOURCE_META.fallbackArticleUrl}. ` +
6
7
  "When online, the zeltser-website MCP server offers richer tools — malware_get_template, malware_get_guidelines, " +
@@ -47,6 +48,16 @@ export async function handleGetReportGuidance(_deps, args) {
47
48
  const startTime = Date.now();
48
49
  try {
49
50
  const topic = args.topic ?? "all";
51
+ // The triage-discipline checklist is server-authored operational guidance,
52
+ // not part of the synced report-writing digest — return it on its own.
53
+ if (topic === "triage_checklist") {
54
+ return formatResponse("get_report_guidance", {
55
+ topic,
56
+ triage_discipline: TRIAGE_DISCIPLINE,
57
+ notes: "Server-authored, bundled, offline operational guidance — distinct from the report-writing " +
58
+ "guidelines (use any other topic, or 'all', for those).",
59
+ }, startTime);
60
+ }
50
61
  return formatResponse("get_report_guidance", {
51
62
  topic,
52
63
  guidelines: selectGuidelines(topic),
@@ -1 +1 @@
1
- {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/handlers/report.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,cAAc,EAAE,WAAW,EAAE,MAAM,gBAAgB,CAAC;AAC7D,OAAO,EAAE,aAAa,EAAE,MAAM,2BAA2B,CAAC;AAC1D,OAAO,EACL,eAAe,EACf,iBAAiB,EACjB,WAAW,EACX,WAAW,GACZ,MAAM,gCAAgC,CAAC;AAExC,MAAM,KAAK,GACT,gHAAgH;IAChH,iDAAiD,WAAW,CAAC,kBAAkB,IAAI;IACnF,kHAAkH;IAClH,uFAAuF,CAAC;AAE1F,0FAA0F;AAC1F,MAAM,UAAU,GAA6B;IAC3C,QAAQ,EAAE,CAAC,oBAAoB,EAAE,gBAAgB,EAAE,eAAe,EAAE,qBAAqB,CAAC;IAC1F,UAAU,EAAE,CAAC,YAAY,CAAC;IAC1B,YAAY,EAAE,CAAC,iBAAiB,CAAC;IACjC,eAAe,EAAE,CAAC,eAAe,CAAC;IAClC,aAAa,EAAE,CAAC,cAAc,CAAC;IAC/B,MAAM,EAAE,CAAC,gBAAgB,EAAE,gBAAgB,EAAE,sBAAsB,EAAE,0BAA0B,CAAC;IAChG,OAAO,EAAE,CAAC,YAAY,EAAE,iBAAiB,EAAE,kBAAkB,EAAE,gBAAgB,EAAE,iBAAiB,CAAC;IACnG,UAAU,EAAE,CAAC,YAAY,CAAC;IAC1B,QAAQ,EAAE,CAAC,uBAAuB,CAAC;CACpC,CAAC;AAEF,+GAA+G;AAC/G,SAAS,gBAAgB,CAAC,KAAa;IACrC,IAAI,KAAK,KAAK,KAAK,IAAI,CAAC,UAAU,CAAC,KAAK,CAAC,EAAE,CAAC;QAC1C,OAAO,iBAAiB,CAAC;IAC3B,CAAC;IACD,MAAM,MAAM,GAA4B,EAAE,CAAC;IAC3C,KAAK,MAAM,GAAG,IAAI,CAAC,OAAO,EAAE,YAAY,EAAE,GAAG,UAAU,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC;QAChE,IAAI,GAAG,IAAI,iBAAiB;YAAE,MAAM,CAAC,GAAG,CAAC,GAAG,iBAAiB,CAAC,GAAG,CAAC,CAAC;IACrE,CAAC;IACD,OAAO,MAAM,CAAC;AAChB,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAAkB;IAC9D,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,OAAO,cAAc,CACnB,qBAAqB,EACrB;YACE,QAAQ,EAAE,eAAe;YACzB,WAAW,EAAE,WAAW,CAAC,QAAQ;YACjC,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,KAAK;SACb,EACD,SAAS,CACV,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,qBAAqB,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC;AAED,MAAM,CAAC,KAAK,UAAU,uBAAuB,CAAC,KAAkB,EAAE,IAA2B;IAC3F,MAAM,SAAS,GAAG,IAAI,CAAC,GAAG,EAAE,CAAC;IAC7B,IAAI,CAAC;QACH,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,IAAI,KAAK,CAAC;QAClC,OAAO,cAAc,CACnB,qBAAqB,EACrB;YACE,KAAK;YACL,UAAU,EAAE,gBAAgB,CAAC,KAAK,CAAC;YACnC,WAAW,EAAE,WAAW,CAAC,UAAU;YACnC,MAAM,EAAE,WAAW;YACnB,KAAK,EAAE,KAAK;SACb,EACD,SAAS,CACV,CAAC;IACJ,CAAC;IAAC,OAAO,KAAK,EAAE,CAAC;QACf,OAAO,WAAW,CAAC,qBAAqB,EAAE,aAAa,CAAC,KAAK,CAAC,EAAE,SAAS,CAAC,CAAC;IAC7E,CAAC;AACH,CAAC"}
1
+ {"version":3,"file":"report.js","sourceRoot":"","sources":["../../src/handlers/report.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,10 @@
1
+ import type { HandlerDeps } from "./types.js";
2
+ import type { VerifyStringUsageArgs } from "../schemas/tools.js";
3
+ export declare function handleVerifyStringUsage(deps: HandlerDeps, args: VerifyStringUsageArgs): Promise<{
4
+ content: Array<{
5
+ type: "text";
6
+ text: string;
7
+ }>;
8
+ isError?: boolean;
9
+ }>;
10
+ //# sourceMappingURL=verify-string-usage.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-string-usage.d.ts","sourceRoot":"","sources":["../../src/handlers/verify-string-usage.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAC9C,OAAO,KAAK,EAAE,qBAAqB,EAAE,MAAM,qBAAqB,CAAC;AA+BjE,wBAAsB,uBAAuB,CAAC,IAAI,EAAE,WAAW,EAAE,IAAI,EAAE,qBAAqB;;;;;;GAuL3F"}
@@ -0,0 +1,166 @@
1
+ import { validateFilePath } from "../security/blocklist.js";
2
+ import { formatResponse, formatError } from "../response.js";
3
+ import { REMnuxError } from "../errors/remnux-error.js";
4
+ import { toREMnuxError } from "../errors/error-mapper.js";
5
+ import { resolveSamplePath } from "../utils/resolve-sample-path.js";
6
+ import { checkFileExists } from "../utils/check-file-exists.js";
7
+ import { looksObscured } from "./check-behavior-prerequisites.js";
8
+ import { parseR2Strings, parseR2Sections, parseR2Functions, parseR2Xrefs, splitMarkedR2Output, R2_MARKERS, } from "../parsers/r2.js";
9
+ import { selectMatches, classifyMatch } from "../analysis/string-usage.js";
10
+ const BASIS = "Static string enumeration (radare2 izj) plus code cross-reference analysis (aa; aar; axt). 'referenced_from_code' " +
11
+ "means an instruction references the string; 'no_code_xrefs_detected' is a complete-analysis null result and is " +
12
+ "NOT proof the string is unused; 'unknown' means analysis was incomplete/unreliable (packed, timed out, version " +
13
+ "drift) and is never a negative. This is a static check — confirm runtime behavior dynamically.";
14
+ /** Base, non-interactive, hermetic r2 invocation flags. */
15
+ const R2_FLAGS = ["-2", "-q", "-N", "-e", "scr.color=0", "-e", "log.quiet=true"];
16
+ /** Total distinct string addresses fed to the (expensive) xref pass. */
17
+ const VADDR_CAP = 40;
18
+ export async function handleVerifyStringUsage(deps, args) {
19
+ const startTime = Date.now();
20
+ try {
21
+ const { connector, config } = deps;
22
+ if (!args.query) {
23
+ return formatError("verify_string_usage", new REMnuxError("A non-empty 'query' string is required.", "INVALID_ARGUMENT", "validation", "Pass the string to look for."), startTime);
24
+ }
25
+ if (!config.noSandbox) {
26
+ const validation = validateFilePath(args.file, config.samplesDir);
27
+ if (!validation.safe) {
28
+ return formatError("verify_string_usage", new REMnuxError(validation.error || "Invalid file path", "INVALID_PATH", "validation", "Use a relative path within the samples directory"), startTime);
29
+ }
30
+ }
31
+ const { filePath } = resolveSamplePath(args.file, config.samplesDir, config.mode);
32
+ const fileError = await checkFileExists(connector, filePath);
33
+ if (fileError)
34
+ return formatError("verify_string_usage", fileError, startTime);
35
+ let fileType = "";
36
+ try {
37
+ const r = await connector.execute(["file", filePath], { timeout: 30000 });
38
+ fileType = r.stdout?.trim() ?? "";
39
+ }
40
+ catch (error) {
41
+ const mapped = toREMnuxError(error, config.mode);
42
+ if (mapped.code === "CONNECTION_FAILED")
43
+ return formatError("verify_string_usage", mapped, startTime);
44
+ }
45
+ const isCodeFile = /\bPE32\+?\b|\bELF\b|Mach-O|MS Windows|executable/i.test(fileType);
46
+ // Pass 1 — enumerate strings (cheap, no analysis). Try izj (mapped sections),
47
+ // fall back to izzj (whole file). r2 absence is detected here.
48
+ let r2Available = true;
49
+ let strings = parseR2Strings("");
50
+ try {
51
+ const r = await connector.execute([...["r2"], ...R2_FLAGS, "-c", "izj", filePath], { timeout: 30000 });
52
+ if (r.exitCode === 127 || /not found|No such file/i.test(r.stderr || "")) {
53
+ r2Available = false;
54
+ }
55
+ else {
56
+ strings = parseR2Strings(r.stdout || "");
57
+ if (strings.length === 0) {
58
+ const rz = await connector.execute([...["r2"], ...R2_FLAGS, "-c", "izzj", filePath], { timeout: 30000 });
59
+ strings = parseR2Strings(rz.stdout || "");
60
+ }
61
+ }
62
+ }
63
+ catch {
64
+ r2Available = false;
65
+ }
66
+ if (!r2Available) {
67
+ return formatResponse("verify_string_usage", {
68
+ file: args.file, query: args.query, file_type: fileType, engine: "radare2", engine_available: false, basis: BASIS,
69
+ match_count: 0, matches: [],
70
+ note: "radare2 is unavailable on this system; string cross-reference analysis could not run. Status is UNKNOWN — not a 'no xref' result.",
71
+ }, startTime);
72
+ }
73
+ const maxMatches = args.max_matches ?? 50;
74
+ const { groups, truncated } = selectMatches(strings, args.query, maxMatches);
75
+ if (groups.length === 0) {
76
+ return formatResponse("verify_string_usage", {
77
+ file: args.file, query: args.query, file_type: fileType, is_code_file: isCodeFile, engine: "radare2", basis: BASIS,
78
+ match_count: 0, matches: [],
79
+ note: "The query was not found among this file's strings (radare2 izj/izzj). It is not embedded as a contiguous string — it could still be built at runtime or stored encoded/obfuscated.",
80
+ }, startTime);
81
+ }
82
+ // Non-code file: nothing can reference the string in code.
83
+ if (!isCodeFile) {
84
+ const ctx = { isCodeFile: false, fileType, schemaKnown: false, analysisComplete: false, obscured: false, initializerFunctionAddrs: new Set() };
85
+ const matches = groups.map((g) => classifyMatch(g, [], [], ctx));
86
+ return formatResponse("verify_string_usage", { file: args.file, query: args.query, file_type: fileType, is_code_file: false, engine: "radare2", basis: BASIS, match_count: groups.length, matches_truncated: truncated, matches }, startTime);
87
+ }
88
+ // Detect packing (reused from check_behavior_prerequisites) — a gate for the invariant.
89
+ let obscured = false;
90
+ try {
91
+ const d = await connector.execute(["diec", "-j", filePath], { timeout: 60000 });
92
+ obscured = looksObscured(d.stdout || "");
93
+ }
94
+ catch {
95
+ /* best effort */
96
+ }
97
+ // Select the groups we can afford to xref (bounded), keeping every classified
98
+ // group fully covered so a non-queried vaddr is never read as a negative.
99
+ const queried = new Set();
100
+ const groupsToClassify = [];
101
+ for (const g of groups) {
102
+ const vs = g.vaddrs.map((v) => v.vaddr);
103
+ if (queried.size + vs.length > VADDR_CAP && groupsToClassify.length > 0)
104
+ break;
105
+ vs.forEach((v) => queried.add(v));
106
+ groupsToClassify.push(g);
107
+ }
108
+ const matchesTruncated = truncated || groupsToClassify.length < groups.length;
109
+ // Pass 2 — one analyzed session: version, sections, functions, per-vaddr xrefs.
110
+ const deep = args.depth === "deep";
111
+ const analysisCmd = deep ? "aaa" : "aa; aar";
112
+ const parts = ["?V", analysisCmd, `?e ${R2_MARKERS.sections}`, "iSj", `?e ${R2_MARKERS.functions}`, "aflj"];
113
+ for (const v of queried) {
114
+ const h = "0x" + v.toString(16);
115
+ parts.push(`?e ${R2_MARKERS.xref} ${h}`, `axtj @ ${h}`);
116
+ }
117
+ const soft = deep ? 60 : 20;
118
+ let split;
119
+ try {
120
+ const r = await connector.execute([...["r2"], ...R2_FLAGS, "-e", `anal.timeout=${soft}`, "-c", parts.join("; "), filePath], { timeout: deep ? 120000 : 45000 });
121
+ split = splitMarkedR2Output(r.stdout || "");
122
+ }
123
+ catch {
124
+ /* timeout / kill → unknown below */
125
+ }
126
+ if (!split) {
127
+ const ctx = { isCodeFile: true, fileType, schemaKnown: false, analysisComplete: false, obscured, initializerFunctionAddrs: new Set() };
128
+ const matches = groupsToClassify.map((g) => classifyMatch(g, [], [], ctx));
129
+ return formatResponse("verify_string_usage", { file: args.file, query: args.query, file_type: fileType, is_code_file: true, engine: "radare2", packer_detected: obscured, analysis_complete: false, timed_out: true, basis: BASIS, match_count: groupsToClassify.length, matches_truncated: matchesTruncated, matches }, startTime);
130
+ }
131
+ const sections = parseR2Sections(split.sectionsJson);
132
+ const functions = parseR2Functions(split.functionsJson);
133
+ const ctx = {
134
+ isCodeFile: true,
135
+ fileType,
136
+ schemaKnown: !!split.version,
137
+ analysisComplete: !split.truncated && functions.length > 0,
138
+ obscured,
139
+ initializerFunctionAddrs: new Set(),
140
+ };
141
+ const matches = groupsToClassify.map((g) => {
142
+ const xrefs = [];
143
+ let rawAnomaly = false;
144
+ for (const v of g.vaddrs) {
145
+ const raw = split.xrefsByVaddr.get("0x" + v.vaddr.toString(16));
146
+ if (raw === undefined)
147
+ continue;
148
+ const parsed = parseR2Xrefs(raw);
149
+ const t = raw.trim();
150
+ if (parsed.length === 0 && t !== "" && t !== "[]")
151
+ rawAnomaly = true;
152
+ xrefs.push(...parsed);
153
+ }
154
+ return classifyMatch(g, xrefs, sections, ctx, rawAnomaly);
155
+ });
156
+ return formatResponse("verify_string_usage", {
157
+ file: args.file, query: args.query, file_type: fileType, is_code_file: true, engine: "radare2",
158
+ r2_version: split.version, packer_detected: obscured, analysis_complete: ctx.analysisComplete,
159
+ basis: BASIS, match_count: groupsToClassify.length, matches_truncated: matchesTruncated, matches,
160
+ }, startTime);
161
+ }
162
+ catch (error) {
163
+ return formatError("verify_string_usage", toREMnuxError(error, deps.config.mode), startTime);
164
+ }
165
+ }
166
+ //# sourceMappingURL=verify-string-usage.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"verify-string-usage.js","sourceRoot":"","sources":["../../src/handlers/verify-string-usage.ts"],"names":[],"mappings":"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"}
@@ -1 +1 @@
1
- {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAOtF,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AAoC9E,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,sBAqVtD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,iBAqCrD"}
1
+ {"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../src/index.ts"],"names":[],"mappings":"AAEA,OAAO,EAAE,SAAS,EAAoB,MAAM,yCAAyC,CAAC;AAOtF,OAAO,EAAmB,KAAK,eAAe,EAAE,MAAM,uBAAuB,CAAC;AA0C9E,MAAM,WAAW,YAAa,SAAQ,eAAe;IACnD,UAAU,EAAE,MAAM,CAAC;IACnB,SAAS,EAAE,MAAM,CAAC;IAClB,OAAO,EAAE,MAAM,CAAC;IAChB,SAAS,CAAC,EAAE,OAAO,CAAC;IACpB,UAAU,CAAC,EAAE,MAAM,CAAC;IACpB,SAAS,CAAC,EAAE,OAAO,GAAG,MAAM,CAAC;IAC7B,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,SAAS,CAAC,EAAE,MAAM,CAAC;IACnB,mBAAmB,CAAC,EAAE,OAAO,CAAC;CAC/B;AAED,wBAAsB,YAAY,CAAC,MAAM,EAAE,YAAY,sBA2YtD;AAED,wBAAsB,WAAW,CAAC,MAAM,EAAE,YAAY,iBAqCrD"}