dotnet: emit mixed mode characteristic (#1024)

This commit is contained in:
Mike Hunhoff
2022-05-06 14:32:06 -06:00
committed by GitHub
parent f96c7379e0
commit 0d849142ba
6 changed files with 23 additions and 2 deletions

View File

@@ -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

View File

@@ -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,
)

View File

@@ -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)

View File

@@ -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

View File

@@ -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,

View File

@@ -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),