Skip to content

Commit

Permalink
Merge branch 'master' into feat/warn-for-dynamic-dotnet
Browse files Browse the repository at this point in the history
  • Loading branch information
v1bh475u authored Jan 29, 2025
2 parents 55d0d9b + 83ec75c commit 751a755
Show file tree
Hide file tree
Showing 34 changed files with 1,553 additions and 628 deletions.
10 changes: 8 additions & 2 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -3,15 +3,21 @@
## master (unreleased)

### New Features

- add warning for dynamic .NET samples #1864 @v1bh475u
- add span-of-calls scope to match features against a across a sliding window of API calls within a thread @williballenthin #2532

### Breaking Changes

- remove `is_static_limitation` class function from `capa.rules.Rule` to inline function in `capa.capabilities.common.py`

### New Rules (2)
- add span-of-calls scope to rule format
- capabilities functions return dataclasses instead of tuples

### New Rules (3)

- data-manipulation/encryption/rsa/encrypt-data-using-rsa-via-embedded-library @Ana06
- data-manipulation/encryption/use-bigint-function @Ana06
- nursery/dynamic-add-veh [email protected]
-

### Bug Fixes
Expand Down
30 changes: 23 additions & 7 deletions capa/capabilities/common.py
Original file line number Diff line number Diff line change
Expand Up @@ -16,17 +16,28 @@
import logging
import itertools
import collections
from typing import Any
from typing import Optional
from dataclasses import dataclass

from capa.rules import Rule, Scope, RuleSet
from capa.engine import FeatureSet, MatchResults
from capa.features.address import NO_ADDRESS
from capa.render.result_document import LibraryFunction, StaticFeatureCounts, DynamicFeatureCounts
from capa.features.extractors.base_extractor import FeatureExtractor, StaticFeatureExtractor, DynamicFeatureExtractor

logger = logging.getLogger(__name__)


def find_file_capabilities(ruleset: RuleSet, extractor: FeatureExtractor, function_features: FeatureSet):
@dataclass
class FileCapabilities:
features: FeatureSet
matches: MatchResults
feature_count: int


def find_file_capabilities(
ruleset: RuleSet, extractor: FeatureExtractor, function_features: FeatureSet
) -> FileCapabilities:
file_features: FeatureSet = collections.defaultdict(set)

for feature, va in itertools.chain(extractor.extract_file_features(), extractor.extract_global_features()):
Expand All @@ -43,8 +54,8 @@ def find_file_capabilities(ruleset: RuleSet, extractor: FeatureExtractor, functi

file_features.update(function_features)

_, matches = ruleset.match(Scope.FILE, file_features, NO_ADDRESS)
return matches, len(file_features)
features, matches = ruleset.match(Scope.FILE, file_features, NO_ADDRESS)
return FileCapabilities(features, matches, len(file_features))


def is_static_limitation_rule(r: Rule) -> bool:
Expand Down Expand Up @@ -87,9 +98,14 @@ def has_limitation(rules: list, capabilities: MatchResults, is_standalone: bool)
return False


def find_capabilities(
ruleset: RuleSet, extractor: FeatureExtractor, disable_progress=None, **kwargs
) -> tuple[MatchResults, Any]:
@dataclass
class Capabilities:
matches: MatchResults
feature_counts: StaticFeatureCounts | DynamicFeatureCounts
library_functions: Optional[tuple[LibraryFunction, ...]] = None


def find_capabilities(ruleset: RuleSet, extractor: FeatureExtractor, disable_progress=None, **kwargs) -> Capabilities:
from capa.capabilities.static import find_static_capabilities
from capa.capabilities.dynamic import find_dynamic_capabilities

Expand Down
Loading

0 comments on commit 751a755

Please sign in to comment.