Skip to content

Commit 104f430

Browse files
committed
Plugins: Update vmayarascan and vadyarascan
1 parent ac482e3 commit 104f430

File tree

2 files changed

+69
-60
lines changed

2 files changed

+69
-60
lines changed

volatility3/framework/plugins/linux/vmayarascan.py

Lines changed: 38 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,7 @@
22
# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
33
#
44

5+
import logging
56
from typing import Iterable, List, Tuple
67

78
from volatility3.framework import interfaces, renderers
@@ -10,12 +11,14 @@
1011
from volatility3.plugins import yarascan
1112
from volatility3.plugins.linux import pslist
1213

14+
vollog = logging.getLogger(__name__)
15+
1316

1417
class VmaYaraScan(interfaces.plugins.PluginInterface):
1518
"""Scans all virtual memory areas for tasks using yara."""
1619

1720
_required_framework_version = (2, 4, 0)
18-
_version = (1, 0, 0)
21+
_version = (1, 0, 2)
1922

2023
@classmethod
2124
def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]:
@@ -33,6 +36,9 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]
3336
requirements.PluginRequirement(
3437
name="yarascan", plugin=yarascan.YaraScan, version=(2, 0, 0)
3538
),
39+
requirements.VersionRequirement(
40+
name="yarascanner", component=yarascan.YaraScanner, version=(2, 0, 0)
41+
),
3642
requirements.ModuleRequirement(
3743
name="kernel",
3844
description="Linux kernel",
@@ -50,6 +56,8 @@ def _generator(self):
5056
# use yarascan to parse the yara options provided and create the rules
5157
rules = yarascan.YaraScan.process_yara_options(dict(self.config))
5258

59+
sanity_check = 1024 * 1024 * 1024 # 1 GB
60+
5361
# filter based on the pid option if provided
5462
filter_func = pslist.PsList.create_pid_filter(self.config.get("pid", None))
5563
for task in pslist.PsList.list_tasks(
@@ -66,29 +74,36 @@ def _generator(self):
6674
# get the proc_layer object from the context
6775
proc_layer = self.context.layers[proc_layer_name]
6876

69-
for start, end in self.get_vma_maps(task):
70-
for match in rules.match(
71-
data=proc_layer.read(start, end - start, True)
77+
max_vma_size = 0
78+
vma_maps_to_scan = []
79+
for start, size in self.get_vma_maps(task):
80+
if size > sanity_check:
81+
vollog.debug(
82+
f"VMA at 0x{start:x} over sanity-check size, not scanning"
83+
)
84+
continue
85+
max_vma_size = max(max_vma_size, size)
86+
vma_maps_to_scan.append((start, size))
87+
88+
if not vma_maps_to_scan:
89+
vollog.warning(f"No VMAs were found for task {task.tgid}, not scanning")
90+
continue
91+
92+
scanner = yarascan.YaraScanner(rules=rules)
93+
scanner.chunk_size = max_vma_size
94+
95+
# scan the VMA data (in one contiguous block) with the yarascanner
96+
for start, size in vma_maps_to_scan:
97+
for offset, rule_name, name, value in scanner(
98+
proc_layer.read(start, size, pad=True), start
7299
):
73-
if yarascan.YaraScan.yara_returns_instances():
74-
for match_string in match.strings:
75-
for instance in match_string.instances:
76-
yield 0, (
77-
format_hints.Hex(instance.offset + start),
78-
task.UniqueProcessId,
79-
match.rule,
80-
match_string.identifier,
81-
instance.matched_data,
82-
)
83-
else:
84-
for offset, name, value in match.strings:
85-
yield 0, (
86-
format_hints.Hex(offset + start),
87-
task.tgid,
88-
match.rule,
89-
name,
90-
value,
91-
)
100+
yield 0, (
101+
format_hints.Hex(offset),
102+
task.tgid,
103+
rule_name,
104+
name,
105+
value,
106+
)
92107

93108
@staticmethod
94109
def get_vma_maps(

volatility3/framework/plugins/windows/vadyarascan.py

Lines changed: 31 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -32,6 +32,9 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]
3232
requirements.PluginRequirement(
3333
name="pslist", plugin=pslist.PsList, version=(2, 0, 0)
3434
),
35+
requirements.VersionRequirement(
36+
name="yarascanner", component=yarascan.YaraScanner, version=(2, 0, 0)
37+
),
3538
requirements.PluginRequirement(
3639
name="yarascan", plugin=yarascan.YaraScan, version=(2, 0, 0)
3740
),
@@ -66,49 +69,40 @@ def _generator(self):
6669
):
6770
layer_name = task.add_process_layer()
6871
layer = self.context.layers[layer_name]
72+
73+
max_vad_size = 0
74+
vad_maps_to_scan = []
75+
6976
for start, size in self.get_vad_maps(task):
7077
if size > sanity_check:
7178
vollog.debug(
7279
f"VAD at 0x{start:x} over sanity-check size, not scanning"
7380
)
7481
continue
75-
76-
data = layer.read(start, size, True)
77-
if not yarascan.YaraScan._yara_x:
78-
for match in rules.match(data=data):
79-
if yarascan.YaraScan.yara_returns_instances():
80-
for match_string in match.strings:
81-
for instance in match_string.instances:
82-
yield 0, (
83-
format_hints.Hex(instance.offset + start),
84-
task.UniqueProcessId,
85-
match.rule,
86-
match_string.identifier,
87-
instance.matched_data,
88-
)
89-
else:
90-
for offset, name, value in match.strings:
91-
yield 0, (
92-
format_hints.Hex(offset + start),
93-
task.UniqueProcessId,
94-
match.rule,
95-
name,
96-
value,
97-
)
98-
else:
99-
for match in rules.scan(data).matching_rules:
100-
for match_string in match.patterns:
101-
for instance in match_string.matches:
102-
yield 0, (
103-
format_hints.Hex(instance.offset + start),
104-
task.UniqueProcessId,
105-
f"{match.namespace}.{match.identifier}",
106-
match_string.identifier,
107-
data[
108-
instance.offset : instance.offset
109-
+ instance.length
110-
],
111-
)
82+
max_vad_size = max(max_vad_size, size)
83+
vad_maps_to_scan.append((start, size))
84+
85+
if not vad_maps_to_scan:
86+
vollog.warning(
87+
f"No VADs were found for task {task.UniqueProcessID}, not scanning"
88+
)
89+
continue
90+
91+
scanner = yarascan.YaraScanner(rules=rules)
92+
scanner.chunk_size = max_vad_size
93+
94+
# scan the VAD data (in one contiguous block) with the yarascanner
95+
for start, size in vad_maps_to_scan:
96+
for offset, rule_name, name, value in scanner(
97+
layer.read(start, size, pad=True), start
98+
):
99+
yield 0, (
100+
format_hints.Hex(offset),
101+
task.UniqueProcessId,
102+
rule_name,
103+
name,
104+
value,
105+
)
112106

113107
@staticmethod
114108
def get_vad_maps(

0 commit comments

Comments
 (0)