@remnux/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.
Files changed (220) hide show
  1. package/LICENSE +674 -0
  2. package/README.md +720 -0
  3. package/dist/archive-extractor.d.ts +46 -0
  4. package/dist/archive-extractor.d.ts.map +1 -0
  5. package/dist/archive-extractor.js +268 -0
  6. package/dist/archive-extractor.js.map +1 -0
  7. package/dist/catalog/index.d.ts +40 -0
  8. package/dist/catalog/index.d.ts.map +1 -0
  9. package/dist/catalog/index.js +114 -0
  10. package/dist/catalog/index.js.map +1 -0
  11. package/dist/cli.d.ts +3 -0
  12. package/dist/cli.d.ts.map +1 -0
  13. package/dist/cli.js +154 -0
  14. package/dist/cli.js.map +1 -0
  15. package/dist/config/archive-passwords.txt +3 -0
  16. package/dist/connectors/docker.d.ts +13 -0
  17. package/dist/connectors/docker.d.ts.map +1 -0
  18. package/dist/connectors/docker.js +201 -0
  19. package/dist/connectors/docker.js.map +1 -0
  20. package/dist/connectors/index.d.ts +27 -0
  21. package/dist/connectors/index.d.ts.map +1 -0
  22. package/dist/connectors/index.js +23 -0
  23. package/dist/connectors/index.js.map +1 -0
  24. package/dist/connectors/local.d.ts +10 -0
  25. package/dist/connectors/local.d.ts.map +1 -0
  26. package/dist/connectors/local.js +105 -0
  27. package/dist/connectors/local.js.map +1 -0
  28. package/dist/connectors/ssh.d.ts +21 -0
  29. package/dist/connectors/ssh.d.ts.map +1 -0
  30. package/dist/connectors/ssh.js +237 -0
  31. package/dist/connectors/ssh.js.map +1 -0
  32. package/dist/errors/error-mapper.d.ts +9 -0
  33. package/dist/errors/error-mapper.d.ts.map +1 -0
  34. package/dist/errors/error-mapper.js +24 -0
  35. package/dist/errors/error-mapper.js.map +1 -0
  36. package/dist/errors/remnux-error.d.ts +14 -0
  37. package/dist/errors/remnux-error.d.ts.map +1 -0
  38. package/dist/errors/remnux-error.js +19 -0
  39. package/dist/errors/remnux-error.js.map +1 -0
  40. package/dist/file-type-mappings.d.ts +30 -0
  41. package/dist/file-type-mappings.d.ts.map +1 -0
  42. package/dist/file-type-mappings.js +136 -0
  43. package/dist/file-type-mappings.js.map +1 -0
  44. package/dist/file-upload.d.ts +44 -0
  45. package/dist/file-upload.d.ts.map +1 -0
  46. package/dist/file-upload.js +170 -0
  47. package/dist/file-upload.js.map +1 -0
  48. package/dist/handlers/analyze-file.d.ts +10 -0
  49. package/dist/handlers/analyze-file.d.ts.map +1 -0
  50. package/dist/handlers/analyze-file.js +149 -0
  51. package/dist/handlers/analyze-file.js.map +1 -0
  52. package/dist/handlers/check-tools.d.ts +9 -0
  53. package/dist/handlers/check-tools.d.ts.map +1 -0
  54. package/dist/handlers/check-tools.js +47 -0
  55. package/dist/handlers/check-tools.js.map +1 -0
  56. package/dist/handlers/download-file.d.ts +10 -0
  57. package/dist/handlers/download-file.d.ts.map +1 -0
  58. package/dist/handlers/download-file.js +113 -0
  59. package/dist/handlers/download-file.js.map +1 -0
  60. package/dist/handlers/download-from-url.d.ts +30 -0
  61. package/dist/handlers/download-from-url.d.ts.map +1 -0
  62. package/dist/handlers/download-from-url.js +295 -0
  63. package/dist/handlers/download-from-url.js.map +1 -0
  64. package/dist/handlers/extract-archive.d.ts +10 -0
  65. package/dist/handlers/extract-archive.d.ts.map +1 -0
  66. package/dist/handlers/extract-archive.js +57 -0
  67. package/dist/handlers/extract-archive.js.map +1 -0
  68. package/dist/handlers/extract-iocs.d.ts +10 -0
  69. package/dist/handlers/extract-iocs.d.ts.map +1 -0
  70. package/dist/handlers/extract-iocs.js +21 -0
  71. package/dist/handlers/extract-iocs.js.map +1 -0
  72. package/dist/handlers/get-file-info.d.ts +10 -0
  73. package/dist/handlers/get-file-info.d.ts.map +1 -0
  74. package/dist/handlers/get-file-info.js +89 -0
  75. package/dist/handlers/get-file-info.js.map +1 -0
  76. package/dist/handlers/list-files.d.ts +10 -0
  77. package/dist/handlers/list-files.d.ts.map +1 -0
  78. package/dist/handlers/list-files.js +60 -0
  79. package/dist/handlers/list-files.js.map +1 -0
  80. package/dist/handlers/run-tool.d.ts +10 -0
  81. package/dist/handlers/run-tool.d.ts.map +1 -0
  82. package/dist/handlers/run-tool.js +99 -0
  83. package/dist/handlers/run-tool.js.map +1 -0
  84. package/dist/handlers/suggest-tools.d.ts +10 -0
  85. package/dist/handlers/suggest-tools.d.ts.map +1 -0
  86. package/dist/handlers/suggest-tools.js +202 -0
  87. package/dist/handlers/suggest-tools.js.map +1 -0
  88. package/dist/handlers/types.d.ts +15 -0
  89. package/dist/handlers/types.d.ts.map +1 -0
  90. package/dist/handlers/types.js +2 -0
  91. package/dist/handlers/types.js.map +1 -0
  92. package/dist/handlers/upload-file.d.ts +10 -0
  93. package/dist/handlers/upload-file.d.ts.map +1 -0
  94. package/dist/handlers/upload-file.js +33 -0
  95. package/dist/handlers/upload-file.js.map +1 -0
  96. package/dist/handlers/upload-from-host.d.ts +10 -0
  97. package/dist/handlers/upload-from-host.d.ts.map +1 -0
  98. package/dist/handlers/upload-from-host.js +33 -0
  99. package/dist/handlers/upload-from-host.js.map +1 -0
  100. package/dist/handlers/upload-sample.d.ts +10 -0
  101. package/dist/handlers/upload-sample.d.ts.map +1 -0
  102. package/dist/handlers/upload-sample.js +26 -0
  103. package/dist/handlers/upload-sample.js.map +1 -0
  104. package/dist/index.d.ts +15 -0
  105. package/dist/index.d.ts.map +1 -0
  106. package/dist/index.js +254 -0
  107. package/dist/index.js.map +1 -0
  108. package/dist/ioc/extractor.d.ts +21 -0
  109. package/dist/ioc/extractor.d.ts.map +1 -0
  110. package/dist/ioc/extractor.js +91 -0
  111. package/dist/ioc/extractor.js.map +1 -0
  112. package/dist/ioc/known-values.d.ts +7 -0
  113. package/dist/ioc/known-values.d.ts.map +1 -0
  114. package/dist/ioc/known-values.js +43 -0
  115. package/dist/ioc/known-values.js.map +1 -0
  116. package/dist/ioc/noise.d.ts +6 -0
  117. package/dist/ioc/noise.d.ts.map +1 -0
  118. package/dist/ioc/noise.js +170 -0
  119. package/dist/ioc/noise.js.map +1 -0
  120. package/dist/ioc/patterns.d.ts +10 -0
  121. package/dist/ioc/patterns.d.ts.map +1 -0
  122. package/dist/ioc/patterns.js +65 -0
  123. package/dist/ioc/patterns.js.map +1 -0
  124. package/dist/ioc/scoring.d.ts +6 -0
  125. package/dist/ioc/scoring.d.ts.map +1 -0
  126. package/dist/ioc/scoring.js +69 -0
  127. package/dist/ioc/scoring.js.map +1 -0
  128. package/dist/parsers/capa.d.ts +9 -0
  129. package/dist/parsers/capa.d.ts.map +1 -0
  130. package/dist/parsers/capa.js +55 -0
  131. package/dist/parsers/capa.js.map +1 -0
  132. package/dist/parsers/diec.d.ts +9 -0
  133. package/dist/parsers/diec.d.ts.map +1 -0
  134. package/dist/parsers/diec.js +53 -0
  135. package/dist/parsers/diec.js.map +1 -0
  136. package/dist/parsers/floss.d.ts +14 -0
  137. package/dist/parsers/floss.d.ts.map +1 -0
  138. package/dist/parsers/floss.js +89 -0
  139. package/dist/parsers/floss.js.map +1 -0
  140. package/dist/parsers/index.d.ts +16 -0
  141. package/dist/parsers/index.d.ts.map +1 -0
  142. package/dist/parsers/index.js +46 -0
  143. package/dist/parsers/index.js.map +1 -0
  144. package/dist/parsers/oleid.d.ts +8 -0
  145. package/dist/parsers/oleid.d.ts.map +1 -0
  146. package/dist/parsers/oleid.js +94 -0
  147. package/dist/parsers/oleid.js.map +1 -0
  148. package/dist/parsers/olevba.d.ts +8 -0
  149. package/dist/parsers/olevba.d.ts.map +1 -0
  150. package/dist/parsers/olevba.js +83 -0
  151. package/dist/parsers/olevba.js.map +1 -0
  152. package/dist/parsers/passthrough.d.ts +6 -0
  153. package/dist/parsers/passthrough.d.ts.map +1 -0
  154. package/dist/parsers/passthrough.js +13 -0
  155. package/dist/parsers/passthrough.js.map +1 -0
  156. package/dist/parsers/pdf-parser.d.ts +9 -0
  157. package/dist/parsers/pdf-parser.d.ts.map +1 -0
  158. package/dist/parsers/pdf-parser.js +76 -0
  159. package/dist/parsers/pdf-parser.js.map +1 -0
  160. package/dist/parsers/pdfid.d.ts +9 -0
  161. package/dist/parsers/pdfid.d.ts.map +1 -0
  162. package/dist/parsers/pdfid.js +56 -0
  163. package/dist/parsers/pdfid.js.map +1 -0
  164. package/dist/parsers/peframe.d.ts +8 -0
  165. package/dist/parsers/peframe.d.ts.map +1 -0
  166. package/dist/parsers/peframe.js +76 -0
  167. package/dist/parsers/peframe.js.map +1 -0
  168. package/dist/parsers/readelf.d.ts +8 -0
  169. package/dist/parsers/readelf.d.ts.map +1 -0
  170. package/dist/parsers/readelf.js +50 -0
  171. package/dist/parsers/readelf.js.map +1 -0
  172. package/dist/parsers/types.d.ts +30 -0
  173. package/dist/parsers/types.d.ts.map +1 -0
  174. package/dist/parsers/types.js +5 -0
  175. package/dist/parsers/types.js.map +1 -0
  176. package/dist/parsers/yara.d.ts +8 -0
  177. package/dist/parsers/yara.d.ts.map +1 -0
  178. package/dist/parsers/yara.js +88 -0
  179. package/dist/parsers/yara.js.map +1 -0
  180. package/dist/response.d.ts +44 -0
  181. package/dist/response.d.ts.map +1 -0
  182. package/dist/response.js +48 -0
  183. package/dist/response.js.map +1 -0
  184. package/dist/schemas/tools.d.ts +135 -0
  185. package/dist/schemas/tools.d.ts.map +1 -0
  186. package/dist/schemas/tools.js +53 -0
  187. package/dist/schemas/tools.js.map +1 -0
  188. package/dist/security/blocklist.d.ts +69 -0
  189. package/dist/security/blocklist.d.ts.map +1 -0
  190. package/dist/security/blocklist.js +148 -0
  191. package/dist/security/blocklist.js.map +1 -0
  192. package/dist/state/session.d.ts +35 -0
  193. package/dist/state/session.d.ts.map +1 -0
  194. package/dist/state/session.js +45 -0
  195. package/dist/state/session.js.map +1 -0
  196. package/dist/tools/definitions.d.ts +9 -0
  197. package/dist/tools/definitions.d.ts.map +1 -0
  198. package/dist/tools/definitions.js +708 -0
  199. package/dist/tools/definitions.js.map +1 -0
  200. package/dist/tools/invoker.d.ts +17 -0
  201. package/dist/tools/invoker.d.ts.map +1 -0
  202. package/dist/tools/invoker.js +44 -0
  203. package/dist/tools/invoker.js.map +1 -0
  204. package/dist/tools/registry.d.ts +62 -0
  205. package/dist/tools/registry.d.ts.map +1 -0
  206. package/dist/tools/registry.js +53 -0
  207. package/dist/tools/registry.js.map +1 -0
  208. package/dist/workflows/engine.d.ts +27 -0
  209. package/dist/workflows/engine.d.ts.map +1 -0
  210. package/dist/workflows/engine.js +224 -0
  211. package/dist/workflows/engine.js.map +1 -0
  212. package/dist/workflows/loader.d.ts +33 -0
  213. package/dist/workflows/loader.d.ts.map +1 -0
  214. package/dist/workflows/loader.js +130 -0
  215. package/dist/workflows/loader.js.map +1 -0
  216. package/dist/workflows/types.d.ts +109 -0
  217. package/dist/workflows/types.d.ts.map +1 -0
  218. package/dist/workflows/types.js +5 -0
  219. package/dist/workflows/types.js.map +1 -0
  220. package/package.json +68 -0
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parser for olevba text output.
3
+ *
4
+ * Extracts VBA macro indicators, suspicious keywords, and auto-execute triggers.
5
+ */
6
+ import type { ParsedToolOutput } from "./types.js";
7
+ export declare function parseOlevbaOutput(rawOutput: string): ParsedToolOutput;
8
+ //# sourceMappingURL=olevba.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"olevba.d.ts","sourceRoot":"","sources":["../../src/parsers/olevba.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAgBnD,wBAAgB,iBAAiB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAuErE"}
@@ -0,0 +1,83 @@
1
+ /**
2
+ * Parser for olevba text output.
3
+ *
4
+ * Extracts VBA macro indicators, suspicious keywords, and auto-execute triggers.
5
+ */
6
+ /** Keywords indicating suspicious VBA behavior. */
7
+ const SUSPICIOUS_PATTERNS = [
8
+ { pattern: /AutoOpen|Document_Open|Auto_Open|Workbook_Open/i, category: "auto-execute", severity: "high" },
9
+ { pattern: /Shell|WScript\.Shell|CreateObject/i, category: "execution", severity: "high" },
10
+ { pattern: /PowerShell|cmd\.exe|command/i, category: "execution", severity: "high" },
11
+ { pattern: /URLDownloadToFile|XMLHTTP|WinHttp/i, category: "download", severity: "high" },
12
+ { pattern: /Environ|GetTempPath|AppData/i, category: "environment", severity: "medium" },
13
+ { pattern: /Chr\(|Asc\(|StrReverse/i, category: "obfuscation", severity: "medium" },
14
+ { pattern: /Base64|Decode|Encode/i, category: "encoding", severity: "medium" },
15
+ { pattern: /RegWrite|RegRead|Registry/i, category: "registry", severity: "medium" },
16
+ { pattern: /FileSystemObject|CopyFile|DeleteFile/i, category: "file-ops", severity: "medium" },
17
+ { pattern: /CallByName|GetProcAddress|VirtualAlloc/i, category: "api-call", severity: "critical" },
18
+ ];
19
+ export function parseOlevbaOutput(rawOutput) {
20
+ const result = {
21
+ tool: "olevba",
22
+ parsed: false,
23
+ findings: [],
24
+ metadata: {},
25
+ raw: rawOutput,
26
+ };
27
+ const lines = rawOutput.split("\n");
28
+ let hasMacros = false;
29
+ let macroCount = 0;
30
+ const suspiciousKeywords = [];
31
+ // Detect macro presence from olevba summary table
32
+ for (const line of lines) {
33
+ if (/VBA MACRO/i.test(line)) {
34
+ hasMacros = true;
35
+ macroCount++;
36
+ }
37
+ // olevba summary table: "| Type | Keyword | Description |"
38
+ // Keywords can be multi-word (e.g. "Attribute VB_Name"), so capture until next pipe
39
+ const tableMatch = line.match(/^\|\s*Suspicious\s*\|\s*(.+?)\s*\|/i);
40
+ if (tableMatch) {
41
+ suspiciousKeywords.push(tableMatch[1].trim());
42
+ }
43
+ // Also catch "| AutoExec |" and "| IOC |" rows
44
+ const autoExecMatch = line.match(/^\|\s*AutoExec\s*\|\s*(.+?)\s*\|/i);
45
+ if (autoExecMatch) {
46
+ result.findings.push({
47
+ description: `Auto-execute trigger: ${autoExecMatch[1].trim()}`,
48
+ category: "auto-execute",
49
+ severity: "high",
50
+ evidence: line.trim(),
51
+ });
52
+ }
53
+ const iocMatch = line.match(/^\|\s*IOC\s*\|\s*(.+?)\s*\|/i);
54
+ if (iocMatch) {
55
+ result.findings.push({
56
+ description: `IOC detected: ${iocMatch[1].trim()}`,
57
+ category: "ioc",
58
+ severity: "high",
59
+ evidence: line.trim(),
60
+ });
61
+ }
62
+ }
63
+ // Pattern-based detection across full output
64
+ for (const { pattern, category, severity } of SUSPICIOUS_PATTERNS) {
65
+ const matches = rawOutput.match(new RegExp(pattern.source, "gi"));
66
+ if (matches) {
67
+ result.findings.push({
68
+ description: `Suspicious pattern: ${matches[0]}`,
69
+ category,
70
+ severity,
71
+ evidence: matches.slice(0, 3).join(", "),
72
+ });
73
+ }
74
+ }
75
+ if (hasMacros || result.findings.length > 0) {
76
+ result.parsed = true;
77
+ result.metadata.has_macros = hasMacros;
78
+ result.metadata.macro_count = macroCount;
79
+ result.metadata.suspicious_keywords = suspiciousKeywords;
80
+ }
81
+ return result;
82
+ }
83
+ //# sourceMappingURL=olevba.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"olevba.js","sourceRoot":"","sources":["../../src/parsers/olevba.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,6 @@
1
+ /**
2
+ * Default passthrough parser — returns raw output with no structured parsing.
3
+ */
4
+ import type { ParsedToolOutput } from "./types.js";
5
+ export declare function passthroughParser(toolName: string, rawOutput: string): ParsedToolOutput;
6
+ //# sourceMappingURL=passthrough.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passthrough.d.ts","sourceRoot":"","sources":["../../src/parsers/passthrough.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,wBAAgB,iBAAiB,CAAC,QAAQ,EAAE,MAAM,EAAE,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAQvF"}
@@ -0,0 +1,13 @@
1
+ /**
2
+ * Default passthrough parser — returns raw output with no structured parsing.
3
+ */
4
+ export function passthroughParser(toolName, rawOutput) {
5
+ return {
6
+ tool: toolName,
7
+ parsed: false,
8
+ findings: [],
9
+ metadata: {},
10
+ raw: rawOutput,
11
+ };
12
+ }
13
+ //# sourceMappingURL=passthrough.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"passthrough.js","sourceRoot":"","sources":["../../src/parsers/passthrough.ts"],"names":[],"mappings":"AAAA;;GAEG;AAIH,MAAM,UAAU,iBAAiB,CAAC,QAAgB,EAAE,SAAiB;IACnE,OAAO;QACL,IAAI,EAAE,QAAQ;QACd,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,GAAG,EAAE,SAAS;KACf,CAAC;AACJ,CAAC"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Parser for pdf-parser.py --stats output.
3
+ *
4
+ * Extracts keyword counts with object IDs from the "Search keywords" section,
5
+ * and structural summary lines (e.g., "Indirect object: 49").
6
+ */
7
+ import type { ParsedToolOutput } from "./types.js";
8
+ export declare function parsePdfParserOutput(rawOutput: string): ParsedToolOutput;
9
+ //# sourceMappingURL=pdf-parser.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-parser.d.ts","sourceRoot":"","sources":["../../src/parsers/pdf-parser.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAsBnD,wBAAgB,oBAAoB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CA4DxE"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Parser for pdf-parser.py --stats output.
3
+ *
4
+ * Extracts keyword counts with object IDs from the "Search keywords" section,
5
+ * and structural summary lines (e.g., "Indirect object: 49").
6
+ */
7
+ /** Keywords that indicate potentially malicious content. */
8
+ const SUSPICIOUS_KEYWORDS = new Set([
9
+ "/JS",
10
+ "/JavaScript",
11
+ "/AA",
12
+ "/OpenAction",
13
+ "/AcroForm",
14
+ "/JBIG2Decode",
15
+ "/RichMedia",
16
+ "/Launch",
17
+ "/EmbeddedFile",
18
+ "/XFA",
19
+ "/URI",
20
+ ]);
21
+ export function parsePdfParserOutput(rawOutput) {
22
+ const result = {
23
+ tool: "pdf-parser",
24
+ parsed: false,
25
+ findings: [],
26
+ metadata: {},
27
+ raw: rawOutput,
28
+ };
29
+ const keywords = {};
30
+ const structure = {};
31
+ const lines = rawOutput.split("\n");
32
+ for (const line of lines) {
33
+ // Keyword line: " /URI 13: 10, 17, 18, ..."
34
+ const kwMatch = line.match(/^\s*(\/\w+)\s+(\d+):\s*([\d,\s]+)/);
35
+ if (kwMatch) {
36
+ const keyword = kwMatch[1];
37
+ const count = parseInt(kwMatch[2], 10);
38
+ if (isNaN(count))
39
+ continue;
40
+ const objects = kwMatch[3]
41
+ .split(",")
42
+ .map((s) => parseInt(s.trim(), 10))
43
+ .filter((n) => !isNaN(n));
44
+ keywords[keyword] = { count, objects };
45
+ if (count > 0 && SUSPICIOUS_KEYWORDS.has(keyword)) {
46
+ result.findings.push({
47
+ description: `Suspicious keyword ${keyword} found (count: ${count})`,
48
+ category: "suspicious-keyword",
49
+ severity: keyword === "/JS" || keyword === "/JavaScript" ? "high" : "medium",
50
+ evidence: line.trim(),
51
+ });
52
+ }
53
+ continue;
54
+ }
55
+ // Structure line: "Comment: 5" or "Indirect object: 49"
56
+ const structMatch = line.match(/^\s*([A-Za-z][A-Za-z ]*\w):\s+(\d+)\s*$/);
57
+ if (structMatch) {
58
+ const label = structMatch[1];
59
+ const value = parseInt(structMatch[2], 10);
60
+ if (!isNaN(value)) {
61
+ structure[label] = value;
62
+ }
63
+ }
64
+ }
65
+ if (Object.keys(keywords).length > 0 || Object.keys(structure).length > 0) {
66
+ result.parsed = true;
67
+ }
68
+ if (Object.keys(keywords).length > 0) {
69
+ result.metadata.keywords = keywords;
70
+ }
71
+ if (Object.keys(structure).length > 0) {
72
+ result.metadata.structure = structure;
73
+ }
74
+ return result;
75
+ }
76
+ //# sourceMappingURL=pdf-parser.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdf-parser.js","sourceRoot":"","sources":["../../src/parsers/pdf-parser.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,9 @@
1
+ /**
2
+ * Parser for pdfid.py text output.
3
+ *
4
+ * Extracts keyword counts (e.g., /JS, /JavaScript, /OpenAction, /AA).
5
+ * Expects text output from `pdfid.py <file>`.
6
+ */
7
+ import type { ParsedToolOutput } from "./types.js";
8
+ export declare function parsePdfidOutput(rawOutput: string): ParsedToolOutput;
9
+ //# sourceMappingURL=pdfid.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdfid.d.ts","sourceRoot":"","sources":["../../src/parsers/pdfid.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAiBnD,wBAAgB,gBAAgB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAsCpE"}
@@ -0,0 +1,56 @@
1
+ /**
2
+ * Parser for pdfid.py text output.
3
+ *
4
+ * Extracts keyword counts (e.g., /JS, /JavaScript, /OpenAction, /AA).
5
+ * Expects text output from `pdfid.py <file>`.
6
+ */
7
+ /** Keywords that indicate potentially malicious content. */
8
+ const SUSPICIOUS_KEYWORDS = new Set([
9
+ "/JS",
10
+ "/JavaScript",
11
+ "/AA",
12
+ "/OpenAction",
13
+ "/AcroForm",
14
+ "/JBIG2Decode",
15
+ "/RichMedia",
16
+ "/Launch",
17
+ "/EmbeddedFile",
18
+ "/XFA",
19
+ "/URI",
20
+ ]);
21
+ export function parsePdfidOutput(rawOutput) {
22
+ const result = {
23
+ tool: "pdfid",
24
+ parsed: false,
25
+ findings: [],
26
+ metadata: {},
27
+ raw: rawOutput,
28
+ };
29
+ const keywords = {};
30
+ const lines = rawOutput.split("\n");
31
+ for (const line of lines) {
32
+ // pdfid output format: " /Keyword count"
33
+ const match = line.match(/^\s*(\/\w+)\s+(\d+)/);
34
+ if (match) {
35
+ const keyword = match[1];
36
+ const count = parseInt(match[2], 10);
37
+ if (isNaN(count))
38
+ continue;
39
+ keywords[keyword] = count;
40
+ if (count > 0 && SUSPICIOUS_KEYWORDS.has(keyword)) {
41
+ result.findings.push({
42
+ description: `Suspicious keyword ${keyword} found (count: ${count})`,
43
+ category: "suspicious-keyword",
44
+ severity: keyword === "/JS" || keyword === "/JavaScript" ? "high" : "medium",
45
+ evidence: line.trim(),
46
+ });
47
+ }
48
+ }
49
+ }
50
+ if (Object.keys(keywords).length > 0) {
51
+ result.parsed = true;
52
+ result.metadata.keywords = keywords;
53
+ }
54
+ return result;
55
+ }
56
+ //# sourceMappingURL=pdfid.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"pdfid.js","sourceRoot":"","sources":["../../src/parsers/pdfid.ts"],"names":[],"mappings":"AAAA;;;;;GAKG;AAIH,4DAA4D;AAC5D,MAAM,mBAAmB,GAAG,IAAI,GAAG,CAAC;IAClC,KAAK;IACL,aAAa;IACb,KAAK;IACL,aAAa;IACb,WAAW;IACX,cAAc;IACd,YAAY;IACZ,SAAS;IACT,eAAe;IACf,MAAM;IACN,MAAM;CACP,CAAC,CAAC;AAEH,MAAM,UAAU,gBAAgB,CAAC,SAAiB;IAChD,MAAM,MAAM,GAAqB;QAC/B,IAAI,EAAE,OAAO;QACb,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,GAAG,EAAE,SAAS;KACf,CAAC;IAEF,MAAM,QAAQ,GAA2B,EAAE,CAAC;IAC5C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,oDAAoD;QACpD,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,qBAAqB,CAAC,CAAC;QAChD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,OAAO,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC;YACzB,MAAM,KAAK,GAAG,QAAQ,CAAC,KAAK,CAAC,CAAC,CAAC,EAAE,EAAE,CAAC,CAAC;YACrC,IAAI,KAAK,CAAC,KAAK,CAAC;gBAAE,SAAS;YAC3B,QAAQ,CAAC,OAAO,CAAC,GAAG,KAAK,CAAC;YAE1B,IAAI,KAAK,GAAG,CAAC,IAAI,mBAAmB,CAAC,GAAG,CAAC,OAAO,CAAC,EAAE,CAAC;gBAClD,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;oBACnB,WAAW,EAAE,sBAAsB,OAAO,kBAAkB,KAAK,GAAG;oBACpE,QAAQ,EAAE,oBAAoB;oBAC9B,QAAQ,EAAE,OAAO,KAAK,KAAK,IAAI,OAAO,KAAK,aAAa,CAAC,CAAC,CAAC,MAAM,CAAC,CAAC,CAAC,QAAQ;oBAC5E,QAAQ,EAAE,IAAI,CAAC,IAAI,EAAE;iBACtB,CAAC,CAAC;YACL,CAAC;QACH,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,QAAQ,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACrC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,QAAQ,CAAC;IACtC,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parser for peframe text output.
3
+ *
4
+ * Extracts packer info, suspicious imports/sections, and file metadata.
5
+ */
6
+ import type { ParsedToolOutput } from "./types.js";
7
+ export declare function parsePeframeOutput(rawOutput: string): ParsedToolOutput;
8
+ //# sourceMappingURL=peframe.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peframe.d.ts","sourceRoot":"","sources":["../../src/parsers/peframe.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAWnD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAoEtE"}
@@ -0,0 +1,76 @@
1
+ /**
2
+ * Parser for peframe text output.
3
+ *
4
+ * Extracts packer info, suspicious imports/sections, and file metadata.
5
+ */
6
+ /** Imports commonly associated with malicious behavior. */
7
+ const SUSPICIOUS_IMPORTS = new Set([
8
+ "VirtualAlloc", "VirtualProtect", "WriteProcessMemory", "CreateRemoteThread",
9
+ "NtUnmapViewOfSection", "IsDebuggerPresent", "CheckRemoteDebuggerPresent",
10
+ "GetProcAddress", "LoadLibrary", "URLDownloadToFile", "InternetOpen",
11
+ "WinExec", "ShellExecute", "CreateProcess", "RegSetValueEx",
12
+ "CryptDecrypt", "CryptEncrypt",
13
+ ]);
14
+ export function parsePeframeOutput(rawOutput) {
15
+ const result = {
16
+ tool: "peframe",
17
+ parsed: false,
18
+ findings: [],
19
+ metadata: {},
20
+ raw: rawOutput,
21
+ };
22
+ const lines = rawOutput.split("\n");
23
+ let currentSection = "";
24
+ for (const line of lines) {
25
+ const trimmed = line.trim();
26
+ if (!trimmed)
27
+ continue;
28
+ // Skip peframe section dividers: ASCII "--- Packer ---" and Unicode "━━━━━━━━"
29
+ if (/^[-━─═]{3,}(\s.*[-━─═]*)?$/.test(trimmed))
30
+ continue;
31
+ // Section headers in peframe output
32
+ if (/^(file|hashes|packer|strings|imports|sections|metadata)/i.test(trimmed)) {
33
+ currentSection = trimmed.toLowerCase().replace(/:.*/, "").trim();
34
+ continue;
35
+ }
36
+ // Packer detection — only within the packer section, skip metadata lines
37
+ if (currentSection === "packer") {
38
+ if (trimmed !== "None" && trimmed !== "packer" && !/^features\b/i.test(trimmed)) {
39
+ result.findings.push({
40
+ description: `Packer detected: ${trimmed}`,
41
+ category: "packer",
42
+ severity: "medium",
43
+ evidence: trimmed,
44
+ });
45
+ result.metadata.packer = trimmed;
46
+ }
47
+ }
48
+ // Suspicious imports
49
+ for (const imp of SUSPICIOUS_IMPORTS) {
50
+ if (trimmed.includes(imp)) {
51
+ result.findings.push({
52
+ description: `Suspicious import: ${imp}`,
53
+ category: "suspicious-import",
54
+ severity: "medium",
55
+ evidence: trimmed,
56
+ });
57
+ }
58
+ }
59
+ // Suspicious strings (URLs, IPs, paths)
60
+ if (currentSection === "strings" || currentSection === "suspicious") {
61
+ if (/https?:\/\/|\\\\[0-9]|\.exe|\.dll|\.bat|\.ps1/i.test(trimmed)) {
62
+ result.findings.push({
63
+ description: `Suspicious string: ${trimmed.slice(0, 100)}`,
64
+ category: "suspicious-string",
65
+ severity: "low",
66
+ evidence: trimmed.slice(0, 200),
67
+ });
68
+ }
69
+ }
70
+ }
71
+ if (result.findings.length > 0) {
72
+ result.parsed = true;
73
+ }
74
+ return result;
75
+ }
76
+ //# sourceMappingURL=peframe.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"peframe.js","sourceRoot":"","sources":["../../src/parsers/peframe.ts"],"names":[],"mappings":"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"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parser for readelf -h (header) output.
3
+ *
4
+ * Extracts ELF header fields: type, machine, entry point, etc.
5
+ */
6
+ import type { ParsedToolOutput } from "./types.js";
7
+ export declare function parseReadelfOutput(rawOutput: string): ParsedToolOutput;
8
+ //# sourceMappingURL=readelf.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readelf.d.ts","sourceRoot":"","sources":["../../src/parsers/readelf.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAEnD,wBAAgB,kBAAkB,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAiDtE"}
@@ -0,0 +1,50 @@
1
+ /**
2
+ * Parser for readelf -h (header) output.
3
+ *
4
+ * Extracts ELF header fields: type, machine, entry point, etc.
5
+ */
6
+ export function parseReadelfOutput(rawOutput) {
7
+ const result = {
8
+ tool: "readelf-header",
9
+ parsed: false,
10
+ findings: [],
11
+ metadata: {},
12
+ raw: rawOutput,
13
+ };
14
+ const header = {};
15
+ const lines = rawOutput.split("\n");
16
+ for (const line of lines) {
17
+ // readelf -h format: " Key: Value"
18
+ const match = line.match(/^\s*(.+?):\s+(.+)\s*$/);
19
+ if (match) {
20
+ const key = match[1].trim();
21
+ const value = match[2].trim();
22
+ header[key] = value;
23
+ }
24
+ }
25
+ if (Object.keys(header).length > 0) {
26
+ result.parsed = true;
27
+ result.metadata.header = header;
28
+ // Flag interesting attributes
29
+ if (header["Type"]) {
30
+ result.metadata.elf_type = header["Type"];
31
+ }
32
+ if (header["Machine"]) {
33
+ result.metadata.machine = header["Machine"];
34
+ }
35
+ if (header["Entry point address"]) {
36
+ result.metadata.entry_point = header["Entry point address"];
37
+ }
38
+ // Flag unusual entry point (0x0 may indicate shared lib or corrupt binary)
39
+ if (header["Entry point address"] === "0x0") {
40
+ result.findings.push({
41
+ description: "Entry point is 0x0 (shared library or unusual binary)",
42
+ category: "binary-info",
43
+ severity: "info",
44
+ evidence: "Entry point address: 0x0",
45
+ });
46
+ }
47
+ }
48
+ return result;
49
+ }
50
+ //# sourceMappingURL=readelf.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"readelf.js","sourceRoot":"","sources":["../../src/parsers/readelf.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAIH,MAAM,UAAU,kBAAkB,CAAC,SAAiB;IAClD,MAAM,MAAM,GAAqB;QAC/B,IAAI,EAAE,gBAAgB;QACtB,MAAM,EAAE,KAAK;QACb,QAAQ,EAAE,EAAE;QACZ,QAAQ,EAAE,EAAE;QACZ,GAAG,EAAE,SAAS;KACf,CAAC;IAEF,MAAM,MAAM,GAA2B,EAAE,CAAC;IAC1C,MAAM,KAAK,GAAG,SAAS,CAAC,KAAK,CAAC,IAAI,CAAC,CAAC;IAEpC,KAAK,MAAM,IAAI,IAAI,KAAK,EAAE,CAAC;QACzB,8DAA8D;QAC9D,MAAM,KAAK,GAAG,IAAI,CAAC,KAAK,CAAC,uBAAuB,CAAC,CAAC;QAClD,IAAI,KAAK,EAAE,CAAC;YACV,MAAM,GAAG,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC5B,MAAM,KAAK,GAAG,KAAK,CAAC,CAAC,CAAC,CAAC,IAAI,EAAE,CAAC;YAC9B,MAAM,CAAC,GAAG,CAAC,GAAG,KAAK,CAAC;QACtB,CAAC;IACH,CAAC;IAED,IAAI,MAAM,CAAC,IAAI,CAAC,MAAM,CAAC,CAAC,MAAM,GAAG,CAAC,EAAE,CAAC;QACnC,MAAM,CAAC,MAAM,GAAG,IAAI,CAAC;QACrB,MAAM,CAAC,QAAQ,CAAC,MAAM,GAAG,MAAM,CAAC;QAEhC,8BAA8B;QAC9B,IAAI,MAAM,CAAC,MAAM,CAAC,EAAE,CAAC;YACnB,MAAM,CAAC,QAAQ,CAAC,QAAQ,GAAG,MAAM,CAAC,MAAM,CAAC,CAAC;QAC5C,CAAC;QACD,IAAI,MAAM,CAAC,SAAS,CAAC,EAAE,CAAC;YACtB,MAAM,CAAC,QAAQ,CAAC,OAAO,GAAG,MAAM,CAAC,SAAS,CAAC,CAAC;QAC9C,CAAC;QACD,IAAI,MAAM,CAAC,qBAAqB,CAAC,EAAE,CAAC;YAClC,MAAM,CAAC,QAAQ,CAAC,WAAW,GAAG,MAAM,CAAC,qBAAqB,CAAC,CAAC;QAC9D,CAAC;QAED,2EAA2E;QAC3E,IAAI,MAAM,CAAC,qBAAqB,CAAC,KAAK,KAAK,EAAE,CAAC;YAC5C,MAAM,CAAC,QAAQ,CAAC,IAAI,CAAC;gBACnB,WAAW,EAAE,uDAAuD;gBACpE,QAAQ,EAAE,aAAa;gBACvB,QAAQ,EAAE,MAAM;gBAChB,QAAQ,EAAE,0BAA0B;aACrC,CAAC,CAAC;QACL,CAAC;IACH,CAAC;IAED,OAAO,MAAM,CAAC;AAChB,CAAC"}
@@ -0,0 +1,30 @@
1
+ /**
2
+ * Common types for structured tool output parsing.
3
+ */
4
+ /** A single finding extracted from tool output. */
5
+ export interface Finding {
6
+ /** What was found (e.g., "UPX packer detected", "VBA macro present") */
7
+ description: string;
8
+ /** Severity: info, low, medium, high, critical */
9
+ severity?: "info" | "low" | "medium" | "high" | "critical";
10
+ /** Optional category (e.g., "packer", "capability", "indicator") */
11
+ category?: string;
12
+ /** Raw evidence from tool output */
13
+ evidence?: string;
14
+ }
15
+ /** Structured metadata extracted from tool output. */
16
+ export interface ParsedToolOutput {
17
+ /** Tool that produced this output */
18
+ tool: string;
19
+ /** Whether parsing succeeded (false = fell back to passthrough) */
20
+ parsed: boolean;
21
+ /** Structured findings, if any */
22
+ findings: Finding[];
23
+ /** Key-value metadata extracted from output */
24
+ metadata: Record<string, unknown>;
25
+ /** Raw output preserved for reference */
26
+ raw: string;
27
+ }
28
+ /** A parser function: takes raw output, returns structured data. */
29
+ export type ToolOutputParser = (rawOutput: string) => ParsedToolOutput;
30
+ //# sourceMappingURL=types.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.d.ts","sourceRoot":"","sources":["../../src/parsers/types.ts"],"names":[],"mappings":"AAAA;;GAEG;AAEH,mDAAmD;AACnD,MAAM,WAAW,OAAO;IACtB,wEAAwE;IACxE,WAAW,EAAE,MAAM,CAAC;IACpB,kDAAkD;IAClD,QAAQ,CAAC,EAAE,MAAM,GAAG,KAAK,GAAG,QAAQ,GAAG,MAAM,GAAG,UAAU,CAAC;IAC3D,oEAAoE;IACpE,QAAQ,CAAC,EAAE,MAAM,CAAC;IAClB,oCAAoC;IACpC,QAAQ,CAAC,EAAE,MAAM,CAAC;CACnB;AAED,sDAAsD;AACtD,MAAM,WAAW,gBAAgB;IAC/B,qCAAqC;IACrC,IAAI,EAAE,MAAM,CAAC;IACb,mEAAmE;IACnE,MAAM,EAAE,OAAO,CAAC;IAChB,kCAAkC;IAClC,QAAQ,EAAE,OAAO,EAAE,CAAC;IACpB,+CAA+C;IAC/C,QAAQ,EAAE,MAAM,CAAC,MAAM,EAAE,OAAO,CAAC,CAAC;IAClC,yCAAyC;IACzC,GAAG,EAAE,MAAM,CAAC;CACb;AAED,oEAAoE;AACpE,MAAM,MAAM,gBAAgB,GAAG,CAAC,SAAS,EAAE,MAAM,KAAK,gBAAgB,CAAC"}
@@ -0,0 +1,5 @@
1
+ /**
2
+ * Common types for structured tool output parsing.
3
+ */
4
+ export {};
5
+ //# sourceMappingURL=types.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"types.js","sourceRoot":"","sources":["../../src/parsers/types.ts"],"names":[],"mappings":"AAAA;;GAEG"}
@@ -0,0 +1,8 @@
1
+ /**
2
+ * Parser for yara-rules output.
3
+ *
4
+ * Deduplicates packer-family rule variants (e.g., 24 PECompact rules → 1 finding with count).
5
+ */
6
+ import type { ParsedToolOutput } from "./types.js";
7
+ export declare function parseYaraOutput(rawOutput: string): ParsedToolOutput;
8
+ //# sourceMappingURL=yara.d.ts.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yara.d.ts","sourceRoot":"","sources":["../../src/parsers/yara.ts"],"names":[],"mappings":"AAAA;;;;GAIG;AAEH,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,YAAY,CAAC;AAwBnD,wBAAgB,eAAe,CAAC,SAAS,EAAE,MAAM,GAAG,gBAAgB,CAkEnE"}
@@ -0,0 +1,88 @@
1
+ /**
2
+ * Parser for yara-rules output.
3
+ *
4
+ * Deduplicates packer-family rule variants (e.g., 24 PECompact rules → 1 finding with count).
5
+ */
6
+ /** Patterns that indicate packer-family rule variants. */
7
+ const PACKER_FAMILY_PATTERNS = [
8
+ /^(PECompact)[\s_]?v?\d/i,
9
+ /^(UPX)[\s_]?v?\d/i,
10
+ /^(ASPack)[\s_]?v?\d/i,
11
+ /^(Themida)[\s_]?v?\d/i,
12
+ /^(MPRESS)[\s_]?v?\d/i,
13
+ /^(Armadillo)[\s_]?v?\d/i,
14
+ /^(Petite)[\s_]?v?\d/i,
15
+ /^(FSG)[\s_]?v?\d/i,
16
+ /^(MEW)[\s_]?v?\d/i,
17
+ /^(nspack)[\s_]?v?\d/i,
18
+ ];
19
+ function getPackerFamily(ruleName) {
20
+ for (const pattern of PACKER_FAMILY_PATTERNS) {
21
+ const match = ruleName.match(pattern);
22
+ if (match)
23
+ return match[1];
24
+ }
25
+ return null;
26
+ }
27
+ export function parseYaraOutput(rawOutput) {
28
+ const result = {
29
+ tool: "yara-rules",
30
+ parsed: false,
31
+ findings: [],
32
+ metadata: {},
33
+ raw: rawOutput,
34
+ };
35
+ const lines = rawOutput.split("\n").filter((l) => l.trim());
36
+ if (lines.length === 0)
37
+ return result;
38
+ // YARA output format: "RuleName filePath" per line
39
+ const ruleNames = [];
40
+ for (const line of lines) {
41
+ const match = line.match(/^(\S+)\s+/);
42
+ if (match)
43
+ ruleNames.push(match[1]);
44
+ }
45
+ if (ruleNames.length === 0)
46
+ return result;
47
+ // Group by packer family for deduplication
48
+ const packerGroups = new Map();
49
+ const nonPackerRules = [];
50
+ for (const name of ruleNames) {
51
+ const family = getPackerFamily(name);
52
+ if (family) {
53
+ const existing = packerGroups.get(family) ?? [];
54
+ existing.push(name);
55
+ packerGroups.set(family, existing);
56
+ }
57
+ else {
58
+ nonPackerRules.push(name);
59
+ }
60
+ }
61
+ // Emit deduplicated packer findings
62
+ for (const [family, variants] of packerGroups) {
63
+ result.findings.push({
64
+ description: variants.length > 1
65
+ ? `Packer: ${family} (${variants.length} rule variants matched)`
66
+ : `Packer: ${family}`,
67
+ category: "packer",
68
+ severity: "medium",
69
+ evidence: variants.length <= 3 ? variants.join(", ") : `${variants.slice(0, 3).join(", ")} +${variants.length - 3} more`,
70
+ });
71
+ }
72
+ // Emit individual non-packer rules
73
+ for (const name of nonPackerRules) {
74
+ result.findings.push({
75
+ description: `YARA match: ${name}`,
76
+ category: "yara-match",
77
+ severity: "low",
78
+ evidence: name,
79
+ });
80
+ }
81
+ result.metadata.total_rules_matched = ruleNames.length;
82
+ result.metadata.deduplicated_findings = result.findings.length;
83
+ if (result.findings.length > 0) {
84
+ result.parsed = true;
85
+ }
86
+ return result;
87
+ }
88
+ //# sourceMappingURL=yara.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"file":"yara.js","sourceRoot":"","sources":["../../src/parsers/yara.ts"],"names":[],"mappings":"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"}