mirror of
https://github.com/mandiant/capa.git
synced 2026-06-12 19:11:32 -07:00
fix: implement extract_function_loop in dnfile extractor
The stub always raised NotImplementedError and was not registered in FUNCTION_HANDLERS, so loop detection was silently skipped for all .NET samples. Detects backward branches (target offset < instruction offset) as loops, matching the approach used by other extractors.
This commit is contained in:
committed by
Willi Ballenthin
parent
f9df8f0a5c
commit
69a1ba862c
@@ -50,6 +50,7 @@
|
||||
- fix: correct wrong dict key in VMRay _compute_monitor_threads assertion (used thread_id instead of process_id) @williballenthin
|
||||
fix: replace assert with isinstance guard in get_callee for invalid MethodSpec tokens @williballenthin
|
||||
- fix: replace assert with isinstance guard in get_callee for invalid MethodSpec tokens @williballenthin
|
||||
- fix: implement extract_function_loop in dnfile extractor to detect backward branches as loops @williballenthin (SURF-55)
|
||||
- fix: remove dead find_process function and helpers.py from cape extractor @williballenthin (SURF-54)
|
||||
- fix: remove dead interface_extract_* stub functions from viv basicblock, function, and insn extractors @williballenthin (SURF-53)
|
||||
- fix: remove unused import of capa.features.extractors.strings from binexport2 intel insn.py @williballenthin (SURF-52)
|
||||
|
||||
@@ -18,6 +18,8 @@ from __future__ import annotations
|
||||
import logging
|
||||
from typing import Iterator
|
||||
|
||||
from dncil.cil.opcode import FlowControl
|
||||
|
||||
from capa.features.common import Feature, Characteristic
|
||||
from capa.features.address import Address
|
||||
from capa.features.extractors.base_extractor import FunctionHandle
|
||||
@@ -45,7 +47,24 @@ def extract_recursive_call(fh: FunctionHandle) -> Iterator[tuple[Characteristic,
|
||||
|
||||
def extract_function_loop(fh: FunctionHandle) -> Iterator[tuple[Characteristic, Address]]:
|
||||
"""extract loop indicators from a function"""
|
||||
raise NotImplementedError()
|
||||
for insn in fh.inner.instructions:
|
||||
if insn.opcode.flow_control not in (
|
||||
FlowControl.Branch,
|
||||
FlowControl.Cond_Branch,
|
||||
):
|
||||
continue
|
||||
|
||||
if isinstance(insn.operand, list):
|
||||
targets = insn.operand
|
||||
elif isinstance(insn.operand, int):
|
||||
targets = [insn.operand]
|
||||
else:
|
||||
continue
|
||||
|
||||
for target in targets:
|
||||
if target < insn.offset:
|
||||
yield Characteristic("loop"), fh.address
|
||||
return
|
||||
|
||||
|
||||
def extract_features(fh: FunctionHandle) -> Iterator[tuple[Feature, Address]]:
|
||||
@@ -54,4 +73,9 @@ def extract_features(fh: FunctionHandle) -> Iterator[tuple[Feature, Address]]:
|
||||
yield feature, addr
|
||||
|
||||
|
||||
FUNCTION_HANDLERS = (extract_function_calls_to, extract_function_calls_from, extract_recursive_call)
|
||||
FUNCTION_HANDLERS = (
|
||||
extract_function_calls_to,
|
||||
extract_function_calls_from,
|
||||
extract_recursive_call,
|
||||
extract_function_loop,
|
||||
)
|
||||
|
||||
+42
-10
@@ -1185,19 +1185,46 @@ FEATURE_PRESENCE_TESTS_DOTNET = sorted(
|
||||
("_1c444", "token=0x6000018", capa.features.common.Characteristic("calls to"), False),
|
||||
("_1c444", "token=0x600001D", capa.features.common.Characteristic("calls from"), True),
|
||||
("_1c444", "token=0x600000F", capa.features.common.Characteristic("calls from"), False),
|
||||
("_1c444", "token=0x600001D", capa.features.common.Characteristic("loop"), True),
|
||||
("_1c444", "token=0x6000001", capa.features.common.Characteristic("loop"), False),
|
||||
("_1c444", "function=0x1F68", capa.features.insn.Number(0x0), True),
|
||||
("_1c444", "function=0x1F68", capa.features.insn.Number(0x1), False),
|
||||
("_692f", "token=0x6000004", capa.features.insn.API("System.Linq.Enumerable::First"), True), # generic method
|
||||
(
|
||||
"_692f",
|
||||
"token=0x6000004",
|
||||
capa.features.insn.API("System.Linq.Enumerable::First"),
|
||||
True,
|
||||
), # generic method
|
||||
(
|
||||
"_692f",
|
||||
"token=0x6000004",
|
||||
capa.features.insn.Property("System.Linq.Enumerable::First"),
|
||||
False,
|
||||
), # generic method
|
||||
("_692f", "token=0x6000004", capa.features.common.Namespace("System.Linq"), True), # generic method
|
||||
("_692f", "token=0x6000004", capa.features.common.Class("System.Linq.Enumerable"), True), # generic method
|
||||
("_1c444", "token=0x6000020", capa.features.common.Namespace("Reqss"), True), # ldftn
|
||||
("_1c444", "token=0x6000020", capa.features.common.Class("Reqss.Reqss"), True), # ldftn
|
||||
(
|
||||
"_692f",
|
||||
"token=0x6000004",
|
||||
capa.features.common.Namespace("System.Linq"),
|
||||
True,
|
||||
), # generic method
|
||||
(
|
||||
"_692f",
|
||||
"token=0x6000004",
|
||||
capa.features.common.Class("System.Linq.Enumerable"),
|
||||
True,
|
||||
), # generic method
|
||||
(
|
||||
"_1c444",
|
||||
"token=0x6000020",
|
||||
capa.features.common.Namespace("Reqss"),
|
||||
True,
|
||||
), # ldftn
|
||||
(
|
||||
"_1c444",
|
||||
"token=0x6000020",
|
||||
capa.features.common.Class("Reqss.Reqss"),
|
||||
True,
|
||||
), # ldftn
|
||||
(
|
||||
"_1c444",
|
||||
"function=0x1F59, bb=0x1F59, insn=0x1F5B",
|
||||
@@ -1236,7 +1263,8 @@ FEATURE_PRESENCE_TESTS_DOTNET = sorted(
|
||||
"_1c444",
|
||||
"token=0x6000081",
|
||||
capa.features.insn.Property(
|
||||
"System.Diagnostics.ProcessStartInfo::UseShellExecute", access=FeatureAccess.WRITE
|
||||
"System.Diagnostics.ProcessStartInfo::UseShellExecute",
|
||||
access=FeatureAccess.WRITE,
|
||||
), # MemberRef property access
|
||||
True,
|
||||
),
|
||||
@@ -1244,7 +1272,8 @@ FEATURE_PRESENCE_TESTS_DOTNET = sorted(
|
||||
"_1c444",
|
||||
"token=0x6000081",
|
||||
capa.features.insn.Property(
|
||||
"System.Diagnostics.ProcessStartInfo::WorkingDirectory", access=FeatureAccess.WRITE
|
||||
"System.Diagnostics.ProcessStartInfo::WorkingDirectory",
|
||||
access=FeatureAccess.WRITE,
|
||||
), # MemberRef property access
|
||||
True,
|
||||
),
|
||||
@@ -1252,7 +1281,8 @@ FEATURE_PRESENCE_TESTS_DOTNET = sorted(
|
||||
"_1c444",
|
||||
"token=0x6000081",
|
||||
capa.features.insn.Property(
|
||||
"System.Diagnostics.ProcessStartInfo::FileName", access=FeatureAccess.WRITE
|
||||
"System.Diagnostics.ProcessStartInfo::FileName",
|
||||
access=FeatureAccess.WRITE,
|
||||
), # MemberRef property access
|
||||
True,
|
||||
),
|
||||
@@ -1316,7 +1346,8 @@ FEATURE_PRESENCE_TESTS_DOTNET = sorted(
|
||||
"_692f",
|
||||
"token=0x6000006",
|
||||
capa.features.insn.Property(
|
||||
"System.Management.Automation.PowerShell::Streams", access=FeatureAccess.READ
|
||||
"System.Management.Automation.PowerShell::Streams",
|
||||
access=FeatureAccess.READ,
|
||||
), # MemberRef property access
|
||||
False,
|
||||
),
|
||||
@@ -1365,7 +1396,8 @@ FEATURE_PRESENCE_TESTS_DOTNET = sorted(
|
||||
"_039a6",
|
||||
"token=0x6000023",
|
||||
capa.features.insn.Property(
|
||||
"System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Task", access=FeatureAccess.READ
|
||||
"System.Runtime.CompilerServices.AsyncTaskMethodBuilder::Task",
|
||||
access=FeatureAccess.READ,
|
||||
), # MemberRef method
|
||||
False,
|
||||
),
|
||||
|
||||
Reference in New Issue
Block a user