mirror of
https://github.com/mandiant/capa.git
synced 2025-12-12 15:49:46 -08:00
dotnet: emit mixed mode characteristic (#1024)
This commit is contained in:
@@ -12,6 +12,7 @@
|
||||
- add file string extraction for dotnet files #1012 @mike-hunhoff
|
||||
- add file function-name extraction for dotnet files #1015 @mike-hunhoff
|
||||
- add unmanaged call characteristic for dotnet files #1023 @mike-hunhoff
|
||||
- add mixed mode characteristic feature extraction for dotnet files #1024 @mike-hunhoff
|
||||
|
||||
### Breaking Changes
|
||||
|
||||
|
||||
@@ -12,7 +12,7 @@ from typing import TYPE_CHECKING, Tuple, Iterator
|
||||
|
||||
if TYPE_CHECKING:
|
||||
import dnfile
|
||||
from capa.features.common import Feature, Format, String
|
||||
from capa.features.common import Feature, Format, String, Characteristic
|
||||
from capa.features.file import Import, FunctionName
|
||||
|
||||
import capa.features.extractors
|
||||
@@ -34,6 +34,10 @@ def extract_file_strings(pe: dnfile.dnPE) -> Iterator[Tuple[String, int]]:
|
||||
yield from capa.features.extractors.dotnetfile.extract_file_strings(pe=pe)
|
||||
|
||||
|
||||
def extract_mixed_mode_characteristic_features(pe: dnfile.dnPE) -> Iterator[Tuple[Characteristic, int]]:
|
||||
yield from capa.features.extractors.dotnetfile.extract_mixed_mode_characteristic_features(pe=pe)
|
||||
|
||||
|
||||
def extract_features(pe: dnfile.dnPE) -> Iterator[Tuple[Feature, int]]:
|
||||
for file_handler in FILE_HANDLERS:
|
||||
for (feature, token) in file_handler(pe):
|
||||
@@ -45,4 +49,5 @@ FILE_HANDLERS = (
|
||||
extract_file_function_names,
|
||||
extract_file_strings,
|
||||
extract_file_format,
|
||||
extract_mixed_mode_characteristic_features,
|
||||
)
|
||||
|
||||
@@ -206,3 +206,7 @@ def get_dotnet_managed_method_names(pe: dnfile.dnPE) -> Iterator[Tuple[int, str]
|
||||
token = calculate_dotnet_token_value(index.table.number, index.row_index)
|
||||
|
||||
yield token, name
|
||||
|
||||
|
||||
def is_dotnet_mixed_mode(pe: dnfile.dnPE) -> bool:
|
||||
return not bool(pe.net.Flags.CLR_ILONLY)
|
||||
|
||||
@@ -17,9 +17,11 @@ from capa.features.common import (
|
||||
Format,
|
||||
String,
|
||||
Feature,
|
||||
Characteristic,
|
||||
)
|
||||
from capa.features.extractors.base_extractor import FeatureExtractor
|
||||
from capa.features.extractors.dnfile.helpers import (
|
||||
is_dotnet_mixed_mode,
|
||||
get_dotnet_managed_imports,
|
||||
calculate_dotnet_token_value,
|
||||
get_dotnet_unmanaged_imports,
|
||||
@@ -69,6 +71,11 @@ def extract_file_strings(pe: dnfile.dnPE, **kwargs) -> Iterator[Tuple[String, in
|
||||
yield from capa.features.extractors.common.extract_file_strings(pe.__data__)
|
||||
|
||||
|
||||
def extract_mixed_mode_characteristic_features(pe: dnfile.dnPE, **kwargs) -> Iterator[Tuple[Characteristic, int]]:
|
||||
if is_dotnet_mixed_mode(pe):
|
||||
yield Characteristic("mixed mode"), 0x0
|
||||
|
||||
|
||||
def extract_file_features(pe: dnfile.dnPE) -> Iterator[Tuple[Feature, int]]:
|
||||
for file_handler in FILE_HANDLERS:
|
||||
for feature, va in file_handler(pe=pe): # type: ignore
|
||||
@@ -80,6 +87,7 @@ FILE_HANDLERS = (
|
||||
extract_file_function_names,
|
||||
extract_file_strings,
|
||||
extract_file_format,
|
||||
extract_mixed_mode_characteristic_features,
|
||||
)
|
||||
|
||||
|
||||
@@ -120,7 +128,7 @@ class DotnetFileFeatureExtractor(FeatureExtractor):
|
||||
return bool(self.pe.net)
|
||||
|
||||
def is_mixed_mode(self) -> bool:
|
||||
return not bool(self.pe.net.Flags.CLR_ILONLY)
|
||||
return is_dotnet_mixed_mode(self.pe)
|
||||
|
||||
def get_runtime_version(self) -> Tuple[int, int]:
|
||||
return self.pe.net.struct.MajorRuntimeVersion, self.pe.net.struct.MinorRuntimeVersion
|
||||
|
||||
@@ -101,6 +101,7 @@ SUPPORTED_FEATURES: Dict[str, Set] = {
|
||||
capa.features.common.Characteristic("embedded pe"),
|
||||
capa.features.common.String,
|
||||
capa.features.common.Format,
|
||||
capa.features.common.Characteristic("mixed mode"),
|
||||
},
|
||||
FUNCTION_SCOPE: {
|
||||
capa.features.common.MatchedRule,
|
||||
|
||||
@@ -669,6 +669,8 @@ FEATURE_PRESENCE_TESTS_DOTNET = sorted(
|
||||
("b9f5b", "file", Arch(ARCH_AMD64), False),
|
||||
("mixed-mode-64", "file", Arch(ARCH_AMD64), True),
|
||||
("mixed-mode-64", "file", Arch(ARCH_I386), False),
|
||||
("mixed-mode-64", "file", capa.features.common.Characteristic("mixed mode"), True),
|
||||
("hello-world", "file", capa.features.common.Characteristic("mixed mode"), False),
|
||||
("b9f5b", "file", OS(OS_ANY), True),
|
||||
("b9f5b", "file", Format(FORMAT_DOTNET), True),
|
||||
("hello-world", "file", capa.features.file.FunctionName("HelloWorld::Main"), True),
|
||||
|
||||
Reference in New Issue
Block a user