diff --git a/capa/features/extractors/viv/insn.py b/capa/features/extractors/viv/insn.py index 1516b13e..5e83c3b2 100644 --- a/capa/features/extractors/viv/insn.py +++ b/capa/features/extractors/viv/insn.py @@ -7,7 +7,6 @@ from capa.features import MAX_BYTES_FEATURE_SIZE, Bytes, String, Characteristic from capa.features.insn import Number, Offset, Mnemonic from capa.features.extractors.viv.indirect_calls import NotFoundError, resolve_indirect_call - # security cookie checks may perform non-zeroing XORs, these are expected within a certain # byte range within the first and returning basic blocks, this helps to reduce FP features SECURITY_COOKIE_BYTES_DELTA = 0x40 diff --git a/capa/ida/explorer/model.py b/capa/ida/explorer/model.py index 3325e283..888cb71c 100644 --- a/capa/ida/explorer/model.py +++ b/capa/ida/explorer/model.py @@ -7,19 +7,10 @@ from PyQt5 import Qt, QtGui, QtCore import capa.ida.helpers import capa.render.utils as rutils -from capa.ida.explorer.item import ( - CapaExplorerDataItem, - CapaExplorerRuleItem, - CapaExplorerBlockItem, - CapaExplorerDefaultItem, - CapaExplorerFeatureItem, - CapaExplorerByteViewItem, - CapaExplorerFunctionItem, - CapaExplorerSubscopeItem, - CapaExplorerRuleMatchItem, - CapaExplorerStringViewItem, - CapaExplorerInstructionViewItem, -) +from capa.ida.explorer.item import (CapaExplorerDataItem, CapaExplorerRuleItem, CapaExplorerBlockItem, + CapaExplorerDefaultItem, CapaExplorerFeatureItem, CapaExplorerByteViewItem, + CapaExplorerFunctionItem, CapaExplorerSubscopeItem, CapaExplorerRuleMatchItem, + CapaExplorerStringViewItem, CapaExplorerInstructionViewItem) # default highlight color used in IDA window DEFAULT_HIGHLIGHT = 0xD096FF diff --git a/capa/main.py b/capa/main.py index 503f5f09..2672e061 100644 --- a/capa/main.py +++ b/capa/main.py @@ -334,12 +334,12 @@ def get_rules(rule_path): return rules -def collect_metadata(argv, path, format, extractor): +def collect_metadata(argv, sample_path, rules_path, format, extractor): md5 = hashlib.md5() sha1 = hashlib.sha1() sha256 = hashlib.sha256() - with open(path, "rb") as f: + with open(sample_path, "rb") as f: buf = f.read() md5.update(buf) @@ -354,11 +354,12 @@ def collect_metadata(argv, path, format, extractor): "md5": md5.hexdigest(), "sha1": sha1.hexdigest(), "sha256": sha256.hexdigest(), - "path": os.path.normpath(path), + "path": os.path.normpath(sample_path), }, "analysis": { "format": format, "extractor": extractor.__class__.__name__, + "rules": rules_path, "base_address": extractor.get_base_address(), }, } @@ -437,17 +438,18 @@ def main(argv=None): if hasattr(sys, "frozen") and hasattr(sys, "_MEIPASS"): logger.debug("detected running under PyInstaller") - args.rules = os.path.join(sys._MEIPASS, "rules") - logger.debug("default rule path (PyInstaller method): %s", args.rules) + rules_path = os.path.join(sys._MEIPASS, "rules") + logger.debug("default rule path (PyInstaller method): %s", rules_path) else: logger.debug("detected running from source") - args.rules = os.path.join(os.path.dirname(__file__), "..", "rules") - logger.debug("default rule path (source method): %s", args.rules) + rules_path = os.path.join(os.path.dirname(__file__), "..", "rules") + logger.debug("default rule path (source method): %s", rules_path) else: - logger.info("using rules path: %s", args.rules) + rules_path = args.rules + logger.info("using rules path: %s", rules_path) try: - rules = get_rules(args.rules) + rules = get_rules(rules_path) rules = capa.rules.RuleSet(rules) logger.info("successfully loaded %s rules", len(rules)) if args.tag: @@ -492,7 +494,7 @@ def main(argv=None): logger.error("-" * 80) return -1 - meta = collect_metadata(argv, args.sample, format, extractor) + meta = collect_metadata(argv, args.sample, args.rules, format, extractor) capabilities, counts = find_capabilities(rules, extractor) meta["analysis"].update(counts) @@ -552,7 +554,7 @@ def ida_main(): rules = get_rules(rules_path) rules = capa.rules.RuleSet(rules) - meta = capa.ida.helpers.collect_metadata() + meta = collect_metadata([], '', rules_path, format, 'IdaExtractor') capabilities, counts = find_capabilities(rules, capa.features.extractors.ida.IdaFeatureExtractor()) meta["analysis"].update(counts) diff --git a/capa/render/verbose.py b/capa/render/verbose.py index 4b096206..99a78f23 100644 --- a/capa/render/verbose.py +++ b/capa/render/verbose.py @@ -33,6 +33,7 @@ def render_meta(ostream, doc): format auto extractor VivisectFeatureExtractor base address 0x10000000 + rules (embedded rules) function count 42 total feature count 1918 """ @@ -46,6 +47,7 @@ def render_meta(ostream, doc): ("format", doc["meta"]["analysis"]["format"]), ("extractor", doc["meta"]["analysis"]["extractor"]), ("base address", hex(doc["meta"]["analysis"]["base_address"])), + ("rules", doc["meta"]["analysis"]["rules"]), ("function count", len(doc["meta"]["analysis"]["feature_counts"]["functions"])), ( "total feature count", diff --git a/scripts/show-capabilities-by-function.py b/scripts/show-capabilities-by-function.py index 80b09b7b..a5d7615c 100644 --- a/scripts/show-capabilities-by-function.py +++ b/scripts/show-capabilities-by-function.py @@ -214,7 +214,7 @@ def main(argv=None): logger.error("-" * 80) return -1 - meta = capa.main.collect_metadata(argv, args.sample, format, extractor) + meta = capa.main.collect_metadata(argv, args.sample, args.rules, format, extractor) capabilities, counts = capa.main.find_capabilities(rules, extractor) meta["analysis"].update(counts)