mirror of
https://github.com/mandiant/capa.git
synced 2025-12-15 09:00:45 -08:00
add tests
This commit is contained in:
@@ -19,7 +19,7 @@ EXPECTED = textwrap.dedent(
|
|||||||
- user@domain.com
|
- user@domain.com
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- foo1234
|
- foo1234
|
||||||
- bar5678
|
- bar5678
|
||||||
@@ -45,7 +45,7 @@ def test_rule_reformat_top_level_elements():
|
|||||||
- user@domain.com
|
- user@domain.com
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- foo1234
|
- foo1234
|
||||||
- bar5678
|
- bar5678
|
||||||
@@ -65,7 +65,7 @@ def test_rule_reformat_indentation():
|
|||||||
- user@domain.com
|
- user@domain.com
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- foo1234
|
- foo1234
|
||||||
- bar5678
|
- bar5678
|
||||||
@@ -91,7 +91,7 @@ def test_rule_reformat_order():
|
|||||||
- bar5678
|
- bar5678
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
name: test rule
|
name: test rule
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
@@ -117,7 +117,7 @@ def test_rule_reformat_meta_update():
|
|||||||
- bar5678
|
- bar5678
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
name: AAAA
|
name: AAAA
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
@@ -143,7 +143,7 @@ def test_rule_reformat_string_description():
|
|||||||
- user@domain.com
|
- user@domain.com
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- string: foo
|
- string: foo
|
||||||
|
|||||||
@@ -38,7 +38,7 @@ def test_main_single_rule(z9324d_extractor, tmpdir):
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
authors:
|
authors:
|
||||||
- test
|
- test
|
||||||
features:
|
features:
|
||||||
@@ -103,7 +103,7 @@ def test_ruleset():
|
|||||||
name: file rule
|
name: file rule
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- characteristic: embedded pe
|
- characteristic: embedded pe
|
||||||
"""
|
"""
|
||||||
@@ -117,7 +117,7 @@ def test_ruleset():
|
|||||||
name: function rule
|
name: function rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- characteristic: tight loop
|
- characteristic: tight loop
|
||||||
"""
|
"""
|
||||||
@@ -131,7 +131,7 @@ def test_ruleset():
|
|||||||
name: basic block rule
|
name: basic block rule
|
||||||
scopes:
|
scopes:
|
||||||
static: basic block
|
static: basic block
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- characteristic: nzxor
|
- characteristic: nzxor
|
||||||
"""
|
"""
|
||||||
@@ -170,7 +170,7 @@ def test_ruleset():
|
|||||||
assert len(rules.file_rules) == 2
|
assert len(rules.file_rules) == 2
|
||||||
assert len(rules.function_rules) == 2
|
assert len(rules.function_rules) == 2
|
||||||
assert len(rules.basic_block_rules) == 1
|
assert len(rules.basic_block_rules) == 1
|
||||||
assert len(rules.process_rules) == 1
|
assert len(rules.process_rules) == 4
|
||||||
assert len(rules.thread_rules) == 1
|
assert len(rules.thread_rules) == 1
|
||||||
|
|
||||||
|
|
||||||
@@ -186,7 +186,7 @@ def test_match_across_scopes_file_function(z9324d_extractor):
|
|||||||
name: install service
|
name: install service
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- 9324d1a8ae37a36ae560c37448c9705a:0x4073F0
|
- 9324d1a8ae37a36ae560c37448c9705a:0x4073F0
|
||||||
features:
|
features:
|
||||||
@@ -206,7 +206,7 @@ def test_match_across_scopes_file_function(z9324d_extractor):
|
|||||||
name: .text section
|
name: .text section
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- 9324d1a8ae37a36ae560c37448c9705a
|
- 9324d1a8ae37a36ae560c37448c9705a
|
||||||
features:
|
features:
|
||||||
@@ -225,7 +225,7 @@ def test_match_across_scopes_file_function(z9324d_extractor):
|
|||||||
name: .text section and install service
|
name: .text section and install service
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- 9324d1a8ae37a36ae560c37448c9705a
|
- 9324d1a8ae37a36ae560c37448c9705a
|
||||||
features:
|
features:
|
||||||
@@ -255,7 +255,7 @@ def test_match_across_scopes(z9324d_extractor):
|
|||||||
name: tight loop
|
name: tight loop
|
||||||
scopes:
|
scopes:
|
||||||
static: basic block
|
static: basic block
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- 9324d1a8ae37a36ae560c37448c9705a:0x403685
|
- 9324d1a8ae37a36ae560c37448c9705a:0x403685
|
||||||
features:
|
features:
|
||||||
@@ -273,7 +273,7 @@ def test_match_across_scopes(z9324d_extractor):
|
|||||||
name: kill thread loop
|
name: kill thread loop
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- 9324d1a8ae37a36ae560c37448c9705a:0x403660
|
- 9324d1a8ae37a36ae560c37448c9705a:0x403660
|
||||||
features:
|
features:
|
||||||
@@ -293,7 +293,7 @@ def test_match_across_scopes(z9324d_extractor):
|
|||||||
name: kill thread program
|
name: kill thread program
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- 9324d1a8ae37a36ae560c37448c9705a
|
- 9324d1a8ae37a36ae560c37448c9705a
|
||||||
features:
|
features:
|
||||||
@@ -322,7 +322,7 @@ def test_subscope_bb_rules(z9324d_extractor):
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- basic block:
|
- basic block:
|
||||||
@@ -348,7 +348,7 @@ def test_byte_matching(z9324d_extractor):
|
|||||||
name: byte match test
|
name: byte match test
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- bytes: ED 24 9E F4 52 A9 07 47 55 8E E1 AB 30 8E 23 61
|
- bytes: ED 24 9E F4 52 A9 07 47 55 8E E1 AB 30 8E 23 61
|
||||||
@@ -373,7 +373,7 @@ def test_count_bb(z9324d_extractor):
|
|||||||
namespace: test
|
namespace: test
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- count(basic blocks): 1 or more
|
- count(basic blocks): 1 or more
|
||||||
@@ -399,7 +399,7 @@ def test_instruction_scope(z9324d_extractor):
|
|||||||
namespace: test
|
namespace: test
|
||||||
scopes:
|
scopes:
|
||||||
static: instruction
|
static: instruction
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- mnemonic: push
|
- mnemonic: push
|
||||||
@@ -429,7 +429,7 @@ def test_instruction_subscope(z9324d_extractor):
|
|||||||
namespace: test
|
namespace: test
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- arch: i386
|
- arch: i386
|
||||||
|
|||||||
@@ -25,7 +25,7 @@ def test_optimizer_order():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- substring: "foo"
|
- substring: "foo"
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ def test_render_meta_attack():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
authors:
|
authors:
|
||||||
- foo
|
- foo
|
||||||
att&ck:
|
att&ck:
|
||||||
@@ -90,7 +90,7 @@ def test_render_meta_mbc():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
authors:
|
authors:
|
||||||
- foo
|
- foo
|
||||||
mbc:
|
mbc:
|
||||||
|
|||||||
@@ -22,7 +22,7 @@ R1 = capa.rules.Rule.from_yaml(
|
|||||||
- user@domain.com
|
- user@domain.com
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- foo1234
|
- foo1234
|
||||||
- bar5678
|
- bar5678
|
||||||
@@ -44,7 +44,7 @@ R2 = capa.rules.Rule.from_yaml(
|
|||||||
- user@domain.com
|
- user@domain.com
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- foo1234
|
- foo1234
|
||||||
- bar5678
|
- bar5678
|
||||||
|
|||||||
@@ -56,7 +56,7 @@ def test_rule_yaml():
|
|||||||
- user@domain.com
|
- user@domain.com
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
examples:
|
examples:
|
||||||
- foo1234
|
- foo1234
|
||||||
- bar5678
|
- bar5678
|
||||||
@@ -248,7 +248,7 @@ def test_invalid_rule_feature():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- characteristic: nzxor
|
- characteristic: nzxor
|
||||||
"""
|
"""
|
||||||
@@ -264,7 +264,7 @@ def test_invalid_rule_feature():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: thread
|
||||||
features:
|
features:
|
||||||
- characteristic: embedded pe
|
- characteristic: embedded pe
|
||||||
"""
|
"""
|
||||||
@@ -280,28 +280,90 @@ def test_invalid_rule_feature():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: basic block
|
static: basic block
|
||||||
dynamic: dev
|
dynamic: thread
|
||||||
features:
|
features:
|
||||||
- characteristic: embedded pe
|
- characteristic: embedded pe
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
)
|
||||||
|
|
||||||
with pytest.raises(capa.rules.InvalidRule):
|
|
||||||
|
def test_multi_scope_rules_features():
|
||||||
|
_ = capa.rules.Rule.from_yaml(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
rule:
|
||||||
|
meta:
|
||||||
|
name: test rule
|
||||||
|
scopes:
|
||||||
|
static: function
|
||||||
|
dynamic: process
|
||||||
|
features:
|
||||||
|
- or:
|
||||||
|
- api: write
|
||||||
|
- and:
|
||||||
|
- os: linux
|
||||||
|
- mnemonic: syscall
|
||||||
|
- number: 1 = write
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
_ = capa.rules.Rule.from_yaml(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
rule:
|
||||||
|
meta:
|
||||||
|
name: test rule
|
||||||
|
features:
|
||||||
|
- or:
|
||||||
|
- api: read
|
||||||
|
- and:
|
||||||
|
- os: linux
|
||||||
|
- mnemonic: syscall
|
||||||
|
- number: 0 = read
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
|
|
||||||
|
def test_rules_flavor_filtering():
|
||||||
|
rules = [
|
||||||
capa.rules.Rule.from_yaml(
|
capa.rules.Rule.from_yaml(
|
||||||
textwrap.dedent(
|
textwrap.dedent(
|
||||||
"""
|
"""
|
||||||
rule:
|
rule:
|
||||||
meta:
|
meta:
|
||||||
name: test rule
|
name: static rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: process
|
|
||||||
features:
|
features:
|
||||||
- mnemonic: xor
|
- api: CreateFileA
|
||||||
"""
|
"""
|
||||||
)
|
)
|
||||||
)
|
),
|
||||||
|
capa.rules.Rule.from_yaml(
|
||||||
|
textwrap.dedent(
|
||||||
|
"""
|
||||||
|
rule:
|
||||||
|
meta:
|
||||||
|
name: dynamic rule
|
||||||
|
scopes:
|
||||||
|
dynamic: thread
|
||||||
|
features:
|
||||||
|
- api: CreateFileA
|
||||||
|
"""
|
||||||
|
)
|
||||||
|
),
|
||||||
|
]
|
||||||
|
|
||||||
|
static_rules = capa.rules.RuleSet(rules, rules_filter_func=lambda rule: rule.scopes.static)
|
||||||
|
dynamic_rules = capa.rules.RuleSet(rules, rules_filter_func=lambda rule: rule.scopes.dynamic)
|
||||||
|
|
||||||
|
# only static rule
|
||||||
|
assert len(static_rules) == 1
|
||||||
|
# only dynamic rule
|
||||||
|
assert len(dynamic_rules) == 1
|
||||||
|
|
||||||
|
|
||||||
def test_lib_rules():
|
def test_lib_rules():
|
||||||
@@ -348,7 +410,7 @@ def test_subscope_rules():
|
|||||||
name: test function subscope
|
name: test function subscope
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- characteristic: embedded pe
|
- characteristic: embedded pe
|
||||||
@@ -407,7 +469,7 @@ def test_subscope_rules():
|
|||||||
|
|
||||||
# the process rule scope has three rules:
|
# the process rule scope has three rules:
|
||||||
# - the rule on which `test process subscope` depends,
|
# - the rule on which `test process subscope` depends,
|
||||||
assert len(rules.process_rules) == 2
|
assert len(rules.process_rules) == 3
|
||||||
|
|
||||||
# the thread rule scope has one rule:
|
# the thread rule scope has one rule:
|
||||||
# - the rule on which `test thread subscope` depends
|
# - the rule on which `test thread subscope` depends
|
||||||
@@ -1025,7 +1087,7 @@ def test_function_name_features():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- function-name: strcpy
|
- function-name: strcpy
|
||||||
@@ -1049,7 +1111,7 @@ def test_os_features():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- os: windows
|
- os: windows
|
||||||
@@ -1069,7 +1131,7 @@ def test_format_features():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- format: pe
|
- format: pe
|
||||||
@@ -1089,7 +1151,7 @@ def test_arch_features():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: file
|
static: file
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- arch: amd64
|
- arch: amd64
|
||||||
|
|||||||
@@ -22,9 +22,8 @@ def test_rule_scope_instruction():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: instruction
|
static: instruction
|
||||||
dynamic: dev
|
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- mnemonic: mov
|
- mnemonic: mov
|
||||||
- arch: i386
|
- arch: i386
|
||||||
- os: windows
|
- os: windows
|
||||||
@@ -41,7 +40,6 @@ def test_rule_scope_instruction():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: instruction
|
static: instruction
|
||||||
dynamic: dev
|
|
||||||
features:
|
features:
|
||||||
- characteristic: embedded pe
|
- characteristic: embedded pe
|
||||||
"""
|
"""
|
||||||
@@ -60,7 +58,7 @@ def test_rule_subscope_instruction():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- instruction:
|
- instruction:
|
||||||
@@ -91,7 +89,7 @@ def test_scope_instruction_implied_and():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- instruction:
|
- instruction:
|
||||||
@@ -112,7 +110,7 @@ def test_scope_instruction_description():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- instruction:
|
- instruction:
|
||||||
@@ -132,7 +130,7 @@ def test_scope_instruction_description():
|
|||||||
name: test rule
|
name: test rule
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- instruction:
|
- instruction:
|
||||||
|
|||||||
@@ -109,7 +109,7 @@ def test_detect_duplicate_features(tmpdir):
|
|||||||
name: Test Rule 0
|
name: Test Rule 0
|
||||||
scopes:
|
scopes:
|
||||||
static: function
|
static: function
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- number: 1
|
- number: 1
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ def test_null_feature_extractor():
|
|||||||
name: xor loop
|
name: xor loop
|
||||||
scopes:
|
scopes:
|
||||||
static: basic block
|
static: basic block
|
||||||
dynamic: dev
|
dynamic: process
|
||||||
features:
|
features:
|
||||||
- and:
|
- and:
|
||||||
- characteristic: tight loop
|
- characteristic: tight loop
|
||||||
|
|||||||
Reference in New Issue
Block a user