From 8b5f58bf31c188f1f0cbfaa6be6b3ba58b4c7c90 Mon Sep 17 00:00:00 2001 From: Moritz Raabe Date: Thu, 2 Jul 2020 23:44:39 +0200 Subject: [PATCH] ensure string feature values are strings, tests --- capa/rules.py | 2 ++ tests/test_rules.py | 73 +++++++++++++++++++++++++++++++++++++++++++++ 2 files changed, 75 insertions(+) diff --git a/capa/rules.py b/capa/rules.py index a616172e..2c645ba4 100644 --- a/capa/rules.py +++ b/capa/rules.py @@ -347,6 +347,8 @@ def build_statements(d, scope): return Range(feature, min=min, max=max) else: raise InvalidRule("unexpected range: %s" % (count)) + elif key == "string" and not isinstance(d[key], six.string_types): + raise InvalidRule("ambiguous string value %s, must be defined as explicit string" % d[key]) elif key == "string" and d[key].startswith("/") and (d[key].endswith("/") or d[key].endswith("/i")): try: return Regex(d[key]) diff --git a/tests/test_rules.py b/tests/test_rules.py index a593c094..e2319148 100644 --- a/tests/test_rules.py +++ b/tests/test_rules.py @@ -463,6 +463,79 @@ def test_count_offset_symbol(): assert r.evaluate({Offset(0x100, "symbol name"): {1, 2, 3}}) == True +def test_invalid_string_values_int(): + with pytest.raises(capa.rules.InvalidRule): + r = capa.rules.Rule.from_yaml( + textwrap.dedent( + """ + rule: + meta: + name: test rule + features: + - string: 123 + """ + ) + ) + + with pytest.raises(capa.rules.InvalidRule): + r = capa.rules.Rule.from_yaml( + textwrap.dedent( + """ + rule: + meta: + name: test rule + features: + - string: 0x123 + """ + ) + ) + + +def test_explicit_string_values_int(): + rule = textwrap.dedent( + """ + rule: + meta: + name: test rule + features: + - or: + - string: "123" + - string: "0x123" + """ + ) + r = capa.rules.Rule.from_yaml(rule) + children = list(r.statement.get_children()) + assert (String("123") in children) == True + assert (String("0x123") in children) == True + + +def test_regex_values_always_string(): + rules = [ + capa.rules.Rule.from_yaml( + textwrap.dedent( + """ + rule: + meta: + name: test rule + features: + - or: + - string: /123/ + - string: /0x123/ + """ + ) + ), + ] + features, matches = capa.engine.match( + capa.engine.topologically_order_rules(rules), {capa.features.String("123"): {1}}, 0x0, + ) + assert capa.features.MatchedRule("test rule") in features + + features, matches = capa.engine.match( + capa.engine.topologically_order_rules(rules), {capa.features.String("0x123"): {1}}, 0x0, + ) + assert capa.features.MatchedRule("test rule") in features + + def test_invalid_offset(): with pytest.raises(capa.rules.InvalidRule): r = capa.rules.Rule.from_yaml(