Merge branch 'master' into fix-286

This commit is contained in:
Willi Ballenthin
2020-09-02 14:46:30 -06:00
5 changed files with 65 additions and 3 deletions

View File

@@ -1,7 +1,7 @@
![capa](.github/logo.png)
[![CI status](https://github.com/fireeye/capa/workflows/CI/badge.svg)](https://github.com/fireeye/capa/actions?query=workflow%3ACI+event%3Apush+branch%3Amaster)
[![Number of rules](https://img.shields.io/badge/rules-343-blue.svg)](https://github.com/fireeye/capa-rules)
[![Number of rules](https://img.shields.io/badge/rules-344-blue.svg)](https://github.com/fireeye/capa-rules)
[![License](https://img.shields.io/badge/license-Apache--2.0-green.svg)](LICENSE.txt)
capa detects capabilities in executable files.

View File

@@ -119,7 +119,7 @@ class CapaExplorerSearchProxyModel(QtCore.QSortFilterProxyModel):
Looks for matches in the text of all rows.
Displays the entire tree row if any of the tree branches,
that is, you can filter by rule name, or also
filter by "characteristic(nzsor)" to filter matches with some feature.
filter by "characteristic(nzxor)" to filter matches with some feature.
"""
def __init__(self, parent=None):

View File

@@ -36,6 +36,34 @@ def render_meta(doc, ostream):
ostream.write("\n")
def find_subrule_matches(doc):
"""
collect the rule names that have been matched as a subrule match.
this way we can avoid displaying entries for things that are too specific.
"""
matches = set([])
def rec(node):
if not node["success"]:
# there's probably a bug here for rules that do `not: match: ...`
# but we don't have any examples of this yet
return
elif node["node"]["type"] == "statement":
for child in node["children"]:
rec(child)
elif node["node"]["type"] == "feature":
if node["node"]["feature"]["type"] == "match":
matches.add(node["node"]["feature"]["match"])
for rule in rutils.capability_rules(doc):
for node in rule["matches"].values():
rec(node)
return matches
def render_capabilities(doc, ostream):
"""
example::
@@ -48,8 +76,16 @@ def render_capabilities(doc, ostream):
| ... | ... |
+-------------------------------------------------------+-------------------------------------------------+
"""
subrule_matches = find_subrule_matches(doc)
rows = []
for rule in rutils.capability_rules(doc):
if rule["meta"]["name"] in subrule_matches:
# rules that are also matched by other rules should not get rendered by default.
# this cuts down on the amount of output while giving approx the same detail.
# see #224
continue
count = len(rule["matches"])
if count == 1:
capability = rutils.bold(rule["meta"]["name"])

2
rules

Submodule rules updated: d546744568...242c82574e

View File

@@ -320,3 +320,29 @@ def test_fix262(pma16_01_extractor, capsys):
std = capsys.readouterr()
assert "HTTP/1.0" in std.out
assert "www.practicalmalwareanalysis.com" not in std.out
@pytest.mark.xfail(sys.version_info >= (3, 0), reason="vivsect only works on py2")
def test_not_render_rules_also_matched(z9324d_extractor, capsys):
# rules that are also matched by other rules should not get rendered by default.
# this cuts down on the amount of output while giving approx the same detail.
# see #224
path = z9324d_extractor.path
# `act as TCP client` matches on
# `connect TCP client` matches on
# `create TCP socket`
#
# so only `act as TCP client` should be displayed
assert capa.main.main([path]) == 0
std = capsys.readouterr()
assert "act as TCP client" in std.out
assert "connect TCP socket" not in std.out
assert "create TCP socket" not in std.out
# this strategy only applies to the default renderer, not any verbose renderer
assert capa.main.main([path, "-v"]) == 0
std = capsys.readouterr()
assert "act as TCP client" in std.out
assert "connect TCP socket" in std.out
assert "create TCP socket" in std.out