diff --git a/capa/capabilities/dynamic.py b/capa/capabilities/dynamic.py index 28baae51a..4b87e2c79 100644 --- a/capa/capabilities/dynamic.py +++ b/capa/capabilities/dynamic.py @@ -11,13 +11,12 @@ import collections from dataclasses import dataclass -from capa.features.address import NO_ADDRESS import capa.perf import capa.features.freeze as frz import capa.render.result_document as rdoc from capa.rules import Scope, RuleSet from capa.engine import FeatureSet, MatchResults -from capa.features.common import Feature +from capa.features.address import _NoAddress from capa.capabilities.common import Capabilities, find_file_capabilities from capa.features.extractors.base_extractor import CallHandle, ThreadHandle, ProcessHandle, DynamicFeatureExtractor @@ -126,9 +125,10 @@ def find_thread_capabilities( if len(sequence_feature_sets) == SEQUENCE_SIZE: overflowing_feature_set = sequence_feature_sets.popleft() - # these are the top-level features that will no longer have any associated addresses. for feature, vas in overflowing_feature_set.items(): - if vas == { NO_ADDRESS, }: + if len(vas) == 1 and isinstance(next(iter(vas)), _NoAddress): + # `vas == { NO_ADDRESS }` without the garbage. + # # ignore the common case of global features getting added/removed/trimmed repeatedly, # like arch/os/format. continue