Skip to content

Commit

Permalink
result document: wire analysis flavor through metadata
Browse files Browse the repository at this point in the history
ref #1711
  • Loading branch information
williballenthin authored Aug 11, 2023
1 parent f48e4a8 commit c91dc71
Show file tree
Hide file tree
Showing 7 changed files with 3,710 additions and 127 deletions.
1 change: 1 addition & 0 deletions capa/ida/helpers.py
Original file line number Diff line number Diff line change
Expand Up @@ -153,6 +153,7 @@ def collect_metadata(rules: List[Path]):
sha256=sha256,
path=idaapi.get_input_file_path(),
),
flavor="static",
analysis=rdoc.StaticAnalysis(
format=idaapi.get_file_type_name(),
arch=arch,
Expand Down
12 changes: 11 additions & 1 deletion capa/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,14 +21,15 @@
import contextlib
import collections
from enum import Enum
from typing import Any, Dict, List, Tuple, Callable, Optional
from typing import Any, Dict, List, Tuple, Literal, Callable, Optional
from pathlib import Path

import halo
import tqdm
import colorama
import tqdm.contrib.logging
from pefile import PEFormatError
from typing_extensions import assert_never
from elftools.common.exceptions import ELFError

import capa.perf
Expand Down Expand Up @@ -1022,6 +1023,14 @@ def collect_metadata(
arch = get_arch(sample_path)
os_ = get_os(sample_path) if os_ == OS_AUTO else os_

flavor: Literal["static", "dynamic"]
if isinstance(extractor, StaticFeatureExtractor):
flavor = "static"
elif isinstance(extractor, DynamicFeatureExtractor):
flavor = "dynamic"
else:
assert_never(extractor)

return rdoc.Metadata(
timestamp=datetime.datetime.now(),
version=capa.version.__version__,
Expand All @@ -1032,6 +1041,7 @@ def collect_metadata(
sha256=sha256,
path=str(Path(sample_path).resolve()),
),
flavor=flavor,
analysis=get_sample_analysis(
format_,
arch,
Expand Down
9 changes: 8 additions & 1 deletion capa/render/proto/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,7 +25,7 @@
Alternatively, --pyi_out=. can be used to generate a Python Interface file that supports development
"""
import datetime
from typing import Any, Dict, Union
from typing import Any, Dict, Union, Literal

import google.protobuf.json_format

Expand Down Expand Up @@ -128,6 +128,7 @@ def metadata_to_pb2(meta: rd.Metadata) -> capa_pb2.Metadata:
version=meta.version,
argv=meta.argv,
sample=google.protobuf.json_format.ParseDict(meta.sample.model_dump(), capa_pb2.Sample()),
flavor=meta.flavor,
analysis=capa_pb2.Analysis(
format=meta.analysis.format,
arch=meta.analysis.arch,
Expand Down Expand Up @@ -480,6 +481,11 @@ def scope_from_pb2(scope: capa_pb2.Scope.ValueType) -> capa.rules.Scope:
assert_never(scope)


def flavor_from_pb2(flavor: str) -> Literal["static", "dynamic"]:
assert flavor in ("static", "dynamic")
return flavor # type: ignore


def metadata_from_pb2(meta: capa_pb2.Metadata) -> rd.Metadata:
return rd.Metadata(
timestamp=datetime.datetime.fromisoformat(meta.timestamp),
Expand All @@ -491,6 +497,7 @@ def metadata_from_pb2(meta: capa_pb2.Metadata) -> rd.Metadata:
sha256=meta.sample.sha256,
path=meta.sample.path,
),
flavor=flavor_from_pb2(meta.flavor),
analysis=rd.StaticAnalysis(
format=meta.analysis.format,
arch=meta.analysis.arch,
Expand Down
1 change: 1 addition & 0 deletions capa/render/proto/capa.proto
Original file line number Diff line number Diff line change
Expand Up @@ -198,6 +198,7 @@ message Metadata {
repeated string argv = 3;
Sample sample = 4;
Analysis analysis = 5;
string flavor = 6;
}

message MnemonicFeature {
Expand Down
3,808 changes: 3,684 additions & 124 deletions capa/render/proto/capa_pb2.py

Large diffs are not rendered by default.

5 changes: 4 additions & 1 deletion capa/render/proto/capa_pb2.pyi
Original file line number Diff line number Diff line change
Expand Up @@ -776,6 +776,7 @@ class Metadata(google.protobuf.message.Message):
ARGV_FIELD_NUMBER: builtins.int
SAMPLE_FIELD_NUMBER: builtins.int
ANALYSIS_FIELD_NUMBER: builtins.int
FLAVOR_FIELD_NUMBER: builtins.int
timestamp: builtins.str
"""iso8601 format, like: 2019-01-01T00:00:00Z"""
version: builtins.str
Expand All @@ -785,6 +786,7 @@ class Metadata(google.protobuf.message.Message):
def sample(self) -> global___Sample: ...
@property
def analysis(self) -> global___Analysis: ...
flavor: builtins.str
def __init__(
self,
*,
Expand All @@ -793,9 +795,10 @@ class Metadata(google.protobuf.message.Message):
argv: collections.abc.Iterable[builtins.str] | None = ...,
sample: global___Sample | None = ...,
analysis: global___Analysis | None = ...,
flavor: builtins.str = ...,
) -> None: ...
def HasField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "sample", b"sample"]) -> builtins.bool: ...
def ClearField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "argv", b"argv", "sample", b"sample", "timestamp", b"timestamp", "version", b"version"]) -> None: ...
def ClearField(self, field_name: typing_extensions.Literal["analysis", b"analysis", "argv", b"argv", "flavor", b"flavor", "sample", b"sample", "timestamp", b"timestamp", "version", b"version"]) -> None: ...

global___Metadata = Metadata

Expand Down
1 change: 1 addition & 0 deletions capa/render/result_document.py
Original file line number Diff line number Diff line change
Expand Up @@ -125,6 +125,7 @@ class Metadata(Model):
version: str
argv: Optional[Tuple[str, ...]]
sample: Sample
flavor: Literal["static", "dynamic"]
analysis: Analysis


Expand Down

0 comments on commit c91dc71

Please sign in to comment.