dnfile: fix types

This commit is contained in:
Willi Ballenthin
2022-04-08 18:33:12 -06:00
parent ed1009096d
commit 808b7fb4dc
11 changed files with 25 additions and 79 deletions

View File

@@ -12,8 +12,6 @@ import capa.features.extractors.pefile
from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_WINDOWS, FORMAT_FREEZE, Arch, Format, String, Feature from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_WINDOWS, FORMAT_FREEZE, Arch, Format, String, Feature
from capa.features.freeze import is_freeze from capa.features.freeze import is_freeze
from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress from capa.features.address import NO_ADDRESS, Address, FileOffsetAddress
from capa.features.common import OS, FORMAT_PE, FORMAT_ELF, OS_WINDOWS, FORMAT_FREEZE, Arch, Format, String
from capa.features.freeze import is_freeze
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)

View File

@@ -14,22 +14,23 @@ if TYPE_CHECKING:
import dnfile import dnfile
from capa.features.common import Feature, Format from capa.features.common import Feature, Format
from capa.features.file import Import from capa.features.file import Import
from capa.features.address import Address
import capa.features.extractors import capa.features.extractors
def extract_file_import_names(pe: dnfile.dnPE) -> Iterator[Tuple[Import, int]]: def extract_file_import_names(pe: dnfile.dnPE) -> Iterator[Tuple[Import, Address]]:
yield from capa.features.extractors.dotnetfile.extract_file_import_names(pe) yield from capa.features.extractors.dotnetfile.extract_file_import_names(pe)
def extract_file_format(pe: dnfile.dnPE) -> Iterator[Tuple[Format, int]]: def extract_file_format(pe: dnfile.dnPE) -> Iterator[Tuple[Format, Address]]:
yield from capa.features.extractors.dotnetfile.extract_file_format(pe=pe) yield from capa.features.extractors.dotnetfile.extract_file_format(pe=pe)
def extract_features(pe: dnfile.dnPE) -> Iterator[Tuple[Feature, int]]: def extract_features(pe: dnfile.dnPE) -> Iterator[Tuple[Feature, Address]]:
for file_handler in FILE_HANDLERS: for file_handler in FILE_HANDLERS:
for (feature, token) in file_handler(pe): for (feature, address) in file_handler(pe):
yield feature, token yield feature, address
FILE_HANDLERS = ( FILE_HANDLERS = (

View File

@@ -152,12 +152,12 @@ def get_dotnet_unmanaged_imports(pe: dnfile.dnPE) -> Iterator[Tuple[int, str]]:
yield token, imp yield token, imp
def get_dotnet_managed_method_bodies(pe: dnfile.dnPE) -> Iterator[CilMethodBody]: def get_dotnet_managed_method_bodies(pe: dnfile.dnPE) -> Iterator[Tuple[int, CilMethodBody]]:
"""get managed methods from MethodDef table""" """get managed methods from MethodDef table"""
if not hasattr(pe.net.mdtables, "MethodDef"): if not hasattr(pe.net.mdtables, "MethodDef"):
return return
for row in pe.net.mdtables.MethodDef: for (rid, row) in enumerate(pe.net.mdtables.MethodDef):
if not row.ImplFlags.miIL or any((row.Flags.mdAbstract, row.Flags.mdPinvokeImpl)): if not row.ImplFlags.miIL or any((row.Flags.mdAbstract, row.Flags.mdPinvokeImpl)):
# skip methods that do not have a method body # skip methods that do not have a method body
continue continue
@@ -166,4 +166,5 @@ def get_dotnet_managed_method_bodies(pe: dnfile.dnPE) -> Iterator[CilMethodBody]
if body is None: if body is None:
continue continue
yield body token: int = calculate_dotnet_token_value(dnfile.enums.MetadataTables.MethodDef.value, rid + 1)
yield token, body

View File

@@ -11,15 +11,15 @@ from capa.features.extractors.base_extractor import FeatureExtractor
logger = logging.getLogger(__name__) logger = logging.getLogger(__name__)
def extract_file_format(**kwargs): def extract_file_format(**kwargs) -> Iterator[Tuple[Feature, Address]]:
yield Format(FORMAT_DOTNET), NO_ADDRESS yield Format(FORMAT_DOTNET), NO_ADDRESS
def extract_file_os(**kwargs): def extract_file_os(**kwargs) -> Iterator[Tuple[Feature, Address]]:
yield OS(OS_ANY), NO_ADDRESS yield OS(OS_ANY), NO_ADDRESS
def extract_file_arch(pe, **kwargs): def extract_file_arch(pe, **kwargs) -> Iterator[Tuple[Feature, Address]]:
# to distinguish in more detail, see https://stackoverflow.com/a/23614024/10548020 # to distinguish in more detail, see https://stackoverflow.com/a/23614024/10548020
# .NET 4.5 added option: any CPU, 32-bit preferred # .NET 4.5 added option: any CPU, 32-bit preferred
if pe.net.Flags.CLR_32BITREQUIRED and pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE: if pe.net.Flags.CLR_32BITREQUIRED and pe.PE_TYPE == pefile.OPTIONAL_HEADER_MAGIC_PE:

View File

@@ -12,8 +12,6 @@ import idautils
import capa.features.extractors.helpers import capa.features.extractors.helpers
import capa.features.extractors.ida.helpers import capa.features.extractors.ida.helpers
from capa.features.insn import API, Number, Offset, Mnemonic, OperandNumber, OperandOffset
from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Characteristic
from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic, OperandNumber, OperandOffset from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic, OperandNumber, OperandOffset
from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Characteristic from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Characteristic

View File

@@ -3,7 +3,7 @@ import struct
from typing import Tuple, Iterator from typing import Tuple, Iterator
from capa.features.common import Feature, Characteristic from capa.features.common import Feature, Characteristic
from capa.features.address import Address, AbsoluteVirtualAddress from capa.features.address import Address
from capa.features.basicblock import BasicBlock from capa.features.basicblock import BasicBlock
from capa.features.extractors.helpers import MIN_STACKSTRING_LEN from capa.features.extractors.helpers import MIN_STACKSTRING_LEN
from capa.features.extractors.base_extractor import BBHandle, FunctionHandle from capa.features.extractors.base_extractor import BBHandle, FunctionHandle

View File

@@ -10,8 +10,6 @@ from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic
from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Feature, Characteristic from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Feature, Characteristic
from capa.features.address import Address, AbsoluteVirtualAddress from capa.features.address import Address, AbsoluteVirtualAddress
from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle
from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic, OperandNumber, OperandOffset
from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Characteristic
# security cookie checks may perform non-zeroing XORs, these are expected within a certain # security cookie checks may perform non-zeroing XORs, these are expected within a certain
# byte range within the first and returning basic blocks, this helps to reduce FP features # byte range within the first and returning basic blocks, this helps to reduce FP features

View File

@@ -19,26 +19,10 @@ import envi.archs.amd64.disasm
import capa.features.extractors.helpers import capa.features.extractors.helpers
import capa.features.extractors.viv.helpers import capa.features.extractors.viv.helpers
<<<<<<< HEAD
from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic, OperandNumber, OperandOffset from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic, OperandNumber, OperandOffset
from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Feature, Characteristic from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Feature, Characteristic
from capa.features.address import Address, AbsoluteVirtualAddress from capa.features.address import Address, AbsoluteVirtualAddress
from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle
||||||| de312d8
from capa.features.insn import API, Number, Offset, Mnemonic, OperandNumber, OperandOffset
from capa.features.common import (
BITNESS_X32,
BITNESS_X64,
MAX_BYTES_FEATURE_SIZE,
THUNK_CHAIN_DEPTH_DELTA,
Bytes,
String,
Characteristic,
)
=======
from capa.features.insn import API, MAX_STRUCTURE_SIZE, Number, Offset, Mnemonic, OperandNumber, OperandOffset
from capa.features.common import MAX_BYTES_FEATURE_SIZE, THUNK_CHAIN_DEPTH_DELTA, Bytes, String, Characteristic
>>>>>>> 580a2d7e4519ea5d353650d66468020968f0f27d
from capa.features.extractors.viv.indirect_calls import NotFoundError, resolve_indirect_call from capa.features.extractors.viv.indirect_calls import NotFoundError, resolve_indirect_call
# security cookie checks may perform non-zeroing XORs, these are expected within a certain # security cookie checks may perform non-zeroing XORs, these are expected within a certain
@@ -46,23 +30,7 @@ from capa.features.extractors.viv.indirect_calls import NotFoundError, resolve_i
SECURITY_COOKIE_BYTES_DELTA = 0x40 SECURITY_COOKIE_BYTES_DELTA = 0x40
<<<<<<< HEAD
def interface_extract_instruction_XXX(
f: FunctionHandle, bb: BBHandle, insn: InsnHandle
) -> Iterator[Tuple[Feature, Address]]:
||||||| de312d8
def get_bitness(vw):
bitness = vw.getMeta("Architecture")
if bitness == "i386":
return BITNESS_X32
elif bitness == "amd64":
return BITNESS_X64
def interface_extract_instruction_XXX(f, bb, insn): def interface_extract_instruction_XXX(f, bb, insn):
=======
def interface_extract_instruction_XXX(f, bb, insn):
>>>>>>> 580a2d7e4519ea5d353650d66468020968f0f27d
""" """
parse features from the given instruction. parse features from the given instruction.

View File

@@ -65,24 +65,6 @@ from capa.features.common import (
FORMAT_FREEZE, FORMAT_FREEZE,
) )
from capa.features.address import NO_ADDRESS from capa.features.address import NO_ADDRESS
from capa.helpers import (
get_format,
get_file_taste,
get_auto_format,
log_unsupported_os_error,
log_unsupported_arch_error,
log_unsupported_format_error,
)
from capa.exceptions import UnsupportedOSError, UnsupportedArchError, UnsupportedFormatError, UnsupportedRuntimeError
from capa.features.common import (
FORMAT_PE,
FORMAT_ELF,
FORMAT_AUTO,
FORMAT_SC32,
FORMAT_SC64,
FORMAT_DOTNET,
FORMAT_FREEZE,
)
from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle, FeatureExtractor from capa.features.extractors.base_extractor import BBHandle, InsnHandle, FunctionHandle, FeatureExtractor
RULES_PATH_DEFAULT_STRING = "(embedded rules)" RULES_PATH_DEFAULT_STRING = "(embedded rules)"

View File

@@ -325,21 +325,21 @@ def sample(request):
def get_function(extractor, fva): def get_function(extractor, fva):
for f in extractor.get_functions(): for f in extractor.get_functions():
if int(f) == fva: if str(f) == fva:
return f return f
raise ValueError("function not found") raise ValueError("function not found")
def get_basic_block(extractor, f, va): def get_basic_block(extractor, f, va):
for bb in extractor.get_basic_blocks(f): for bb in extractor.get_basic_blocks(f):
if int(bb) == va: if str(bb) == va:
return bb return bb
raise ValueError("basic block not found") raise ValueError("basic block not found")
def get_instruction(extractor, f, bb, va): def get_instruction(extractor, f, bb, va):
for insn in extractor.get_instructions(f, bb): for insn in extractor.get_instructions(f, bb):
if int(insn) == va: if str(insn) == va:
return insn return insn
raise ValueError("instruction not found") raise ValueError("instruction not found")
@@ -824,10 +824,10 @@ def mixed_mode_64_dotnetfile_extractor():
@pytest.fixture @pytest.fixture
def hello_world_dnfile_extractor(): def hello_world_dotnetfile_extractor():
return get_dnfile_extractor(get_data_path_by_name("hello-world")) return get_dnfile_extractor(get_data_path_by_name("hello-world"))
@pytest.fixture @pytest.fixture
def _1c444_dnfile_extractor(): def _1c444_dotnetfile_extractor():
return get_dnfile_extractor(get_data_path_by_name("1c444...")) return get_dnfile_extractor(get_data_path_by_name("1c444..."))

View File

@@ -24,12 +24,12 @@ def test_dnfile_features(sample, scope, feature, expected):
@parametrize( @parametrize(
"extractor,function,expected", "extractor,function,expected",
[ [
("b9f5b_dnfile_extractor", "is_dotnet_file", True), ("b9f5b_dotnetfile_extractor", "is_dotnet_file", True),
("b9f5b_dnfile_extractor", "is_mixed_mode", False), ("b9f5b_dotnetfile_extractor", "is_mixed_mode", False),
("mixed_mode_64_dnfile_extractor", "is_mixed_mode", True), ("mixed_mode_64_dotnetfile_extractor", "is_mixed_mode", True),
("b9f5b_dnfile_extractor", "get_entry_point", 0x6000007), ("b9f5b_dotnetfile_extractor", "get_entry_point", 0x6000007),
("b9f5b_dnfile_extractor", "get_runtime_version", (2, 5)), ("b9f5b_dotnetfile_extractor", "get_runtime_version", (2, 5)),
("b9f5b_dnfile_extractor", "get_meta_version_string", "v2.0.50727"), ("b9f5b_dotnetfile_extractor", "get_meta_version_string", "v2.0.50727"),
], ],
) )
def test_dnfile_extractor(request, extractor, function, expected): def test_dnfile_extractor(request, extractor, function, expected):