mirror of
https://github.com/mandiant/capa.git
synced 2026-02-04 19:12:01 -08:00
@@ -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,
|
||||
|
||||
12
capa/main.py
12
capa/main.py
@@ -21,7 +21,7 @@ import itertools
|
||||
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
|
||||
@@ -29,6 +29,7 @@ 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
|
||||
@@ -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__,
|
||||
@@ -1032,6 +1041,7 @@ def collect_metadata(
|
||||
sha256=sha256,
|
||||
path=str(Path(sample_path).resolve()),
|
||||
),
|
||||
flavor=flavor,
|
||||
analysis=get_sample_analysis(
|
||||
format_,
|
||||
arch,
|
||||
|
||||
@@ -25,7 +25,7 @@ $ protoc.exe --python_out=. --mypy_out=. <path_to_proto> (e.g. capa/render/proto
|
||||
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
|
||||
|
||||
@@ -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,
|
||||
@@ -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),
|
||||
@@ -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,
|
||||
|
||||
@@ -198,6 +198,7 @@ message Metadata {
|
||||
repeated string argv = 3;
|
||||
Sample sample = 4;
|
||||
Analysis analysis = 5;
|
||||
string flavor = 6;
|
||||
}
|
||||
|
||||
message MnemonicFeature {
|
||||
|
||||
File diff suppressed because one or more lines are too long
@@ -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
|
||||
@@ -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,
|
||||
*,
|
||||
@@ -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
|
||||
|
||||
|
||||
@@ -125,6 +125,7 @@ class Metadata(Model):
|
||||
version: str
|
||||
argv: Optional[Tuple[str, ...]]
|
||||
sample: Sample
|
||||
flavor: Literal["static", "dynamic"]
|
||||
analysis: Analysis
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user