diff --git a/src/core/operations/YARARules.mjs b/src/core/operations/YARARules.mjs index 58b3576..c453d6b 100644 --- a/src/core/operations/YARARules.mjs +++ b/src/core/operations/YARARules.mjs @@ -49,6 +49,12 @@ class YARARules extends Operation { type: "boolean", hint: "Show the metadata of each rule", value: false + }, + { + name: "Show counts", + type: "boolean", + hint: "Show the number of matches per rule", + value: true } ]; } @@ -61,7 +67,7 @@ class YARARules extends Operation { run(input, args) { if (ENVIRONMENT_IS_WORKER()) self.sendStatusMessage("Instantiating YARA."); - const [rules, showStrings, showLengths, showMeta] = args; + const [rules, showStrings, showLengths, showMeta, showCounts] = args; return new Promise((resolve, reject) => { Yara().then(yara => { if (ENVIRONMENT_IS_WORKER()) self.sendStatusMessage("Converting data for YARA."); @@ -97,10 +103,11 @@ class YARARules extends Operation { } meta = meta.slice(0, -2) + "]"; } + const countString = showCounts ? `${matches.size()} time${matches.size() > 1 ? "s" : ""}` : ""; if (matches.size() === 0 || !(showStrings || showLengths)) { - matchString += `Input matches rule "${rule.ruleName}"${meta}.\n`; + matchString += `Input matches rule "${rule.ruleName}"${meta}${countString.length > 0 ? ` ${countString}`: ""}.\n`; } else { - matchString += `Rule "${rule.ruleName}"${meta} matches:\n`; + matchString += `Rule "${rule.ruleName}"${meta} matches (${countString}):\n`; for (let j = 0; j < matches.size(); j++) { const match = matches.get(j); if (showStrings || showLengths) { diff --git a/tests/operations/index.mjs b/tests/operations/index.mjs index da9d41b..48bd08a 100644 --- a/tests/operations/index.mjs +++ b/tests/operations/index.mjs @@ -82,6 +82,7 @@ import "./tests/TranslateDateTimeFormat"; import "./tests/Magic"; import "./tests/ParseTLV"; import "./tests/Media"; +import "./tests/YARA.mjs"; // Cannot test operations that use the File type yet //import "./tests/SplitColourChannels"; diff --git a/tests/operations/tests/YARA.mjs b/tests/operations/tests/YARA.mjs new file mode 100644 index 0000000..e3c28ef --- /dev/null +++ b/tests/operations/tests/YARA.mjs @@ -0,0 +1,24 @@ +/** + * YARA Rules tests. + * + * @author Matt C [matt@artemisbot.uk] + * + * @copyright Crown Copyright 2019 + * @license Apache-2.0 + */ +import TestRegister from "../TestRegister"; + +TestRegister.addTests([ + { + name: "YARA Match: simple foobar", + input: "foobar foobar bar foo foobar", + expectedOutput: "Rule \"foo\" matches (4 times):\nPos 0, length 3, identifier $re1, data: \"foo\"\nPos 7, length 3, identifier $re1, data: \"foo\"\nPos 18, length 3, identifier $re1, data: \"foo\"\nPos 22, length 3, identifier $re1, data: \"foo\"\nRule \"bar\" matches (4 times):\nPos 3, length 3, identifier $re1, data: \"bar\"\nPos 10, length 3, identifier $re1, data: \"bar\"\nPos 14, length 3, identifier $re1, data: \"bar\"\nPos 25, length 3, identifier $re1, data: \"bar\"\n", + recipeConfig: [ + { + "op": "YARA Rules", + "args": ["rule foo {strings: $re1 = /foo/ condition: $re1} rule bar {strings: $re1 = /bar/ condition: $re1}", true, true, true, true], + } + ], + }, +]); +