From ce7fb39aa841a48e36c3570e745fdb70c2bd9c60 Mon Sep 17 00:00:00 2001 From: William Ballenthin Date: Fri, 3 Jul 2020 10:33:14 -0600 Subject: [PATCH] render: show feature counts closes #96 --- capa/render/verbose.py | 2 ++ capa/render/vverbose.py | 23 +++++++++++++++++++++++ 2 files changed, 25 insertions(+) diff --git a/capa/render/verbose.py b/capa/render/verbose.py index c2576155..7c9d8fa6 100644 --- a/capa/render/verbose.py +++ b/capa/render/verbose.py @@ -33,6 +33,8 @@ def render_verbose(doc): rows.append(("format", doc["meta"]["analysis"]["format"])) rows.append(("extractor", doc["meta"]["analysis"]["extractor"])) rows.append(("base address", hex(doc["meta"]["analysis"]["base_address"]))) + rows.append(("function count", len(doc["meta"]["counts"]["functions"]))) + rows.append(("total feature count", doc["meta"]["counts"]["file"] + sum(doc["meta"]["counts"]["functions"].values()))) ostream.writeln(tabulate.tabulate(rows, tablefmt="plain")) ostream.write("\n") diff --git a/capa/render/vverbose.py b/capa/render/vverbose.py index 342a9dd4..46e7c6c7 100644 --- a/capa/render/vverbose.py +++ b/capa/render/vverbose.py @@ -1,3 +1,5 @@ +import collections + import tabulate import capa.rules @@ -151,9 +153,30 @@ def render_vverbose(doc): rows.append(("format", doc["meta"]["analysis"]["format"])) rows.append(("extractor", doc["meta"]["analysis"]["extractor"])) rows.append(("base address", hex(doc["meta"]["analysis"]["base_address"]))) + rows.append(("function count", len(doc["meta"]["counts"]["functions"]))) + rows.append( + ("total feature count", doc["meta"]["counts"]["file"] + sum(doc["meta"]["counts"]["functions"].values()))) ostream.writeln(tabulate.tabulate(rows, tablefmt="plain")) ostream.write("\n") + matches_by_function = collections.defaultdict(set) + for rule in rutils.capability_rules(doc): + for va in rule["matches"].keys(): + matches_by_function[va].add(rule["meta"]["name"]) + + ostream.writeln("## functions") + for va, feature_count in sorted(doc["meta"]["counts"]["functions"].items()): + va = int(va) + ostream.write("function at 0x%x with %d features: " % (va, feature_count)) + if not matches_by_function.get(va, {}): + ostream.writeln("no matches") + else: + ostream.writeln("") + for rule_name in matches_by_function[va]: + ostream.writeln(" - " + rule_name) + + ostream.write("\n") + ostream.writeln("## rules") for rule in rutils.capability_rules(doc): count = len(rule["matches"]) if count == 1: