22# which is available at https://www.volatilityfoundation.org/license/vsl-v1.0
33#
44
5+ import io
56import logging
67from typing import Iterable , List , Tuple
78
8- from volatility3 .framework import interfaces , renderers
9+ from volatility3 .framework import exceptions , interfaces , renderers
910from volatility3 .framework .configuration import requirements
1011from volatility3 .framework .renderers import format_hints
1112from volatility3 .plugins import yarascan
@@ -18,7 +19,7 @@ class VadYaraScan(interfaces.plugins.PluginInterface):
1819 """Scans all the Virtual Address Descriptor memory maps using yara."""
1920
2021 _required_framework_version = (2 , 4 , 0 )
21- _version = (1 , 0 , 1 )
22+ _version = (1 , 1 , 0 )
2223
2324 @classmethod
2425 def get_requirements (cls ) -> List [interfaces .configuration .RequirementInterface ]:
@@ -32,11 +33,8 @@ def get_requirements(cls) -> List[interfaces.configuration.RequirementInterface]
3233 requirements .PluginRequirement (
3334 name = "pslist" , plugin = pslist .PsList , version = (2 , 0 , 0 )
3435 ),
35- requirements .VersionRequirement (
36- name = "yarascanner" , component = yarascan .YaraScanner , version = (2 , 0 , 0 )
37- ),
3836 requirements .PluginRequirement (
39- name = "yarascan" , plugin = yarascan .YaraScan , version = (1 , 2 , 0 )
37+ name = "yarascan" , plugin = yarascan .YaraScan , version = (1 , 3 , 0 )
4038 ),
4139 requirements .ListRequirement (
4240 name = "pid" ,
@@ -59,6 +57,8 @@ def _generator(self):
5957
6058 filter_func = pslist .PsList .create_pid_filter (self .config .get ("pid" , None ))
6159
60+ sanity_check = 0x1000 * 0x1000 * 0x1000
61+
6262 for task in pslist .PsList .list_processes (
6363 context = self .context ,
6464 layer_name = kernel .layer_name ,
@@ -67,18 +67,34 @@ def _generator(self):
6767 ):
6868 layer_name = task .add_process_layer ()
6969 layer = self .context .layers [layer_name ]
70- for offset , rule_name , name , value in layer .scan (
71- context = self .context ,
72- scanner = yarascan .YaraScanner (rules = rules ),
73- sections = self .get_vad_maps (task ),
74- ):
75- yield 0 , (
76- format_hints .Hex (offset ),
77- task .UniqueProcessId ,
78- rule_name ,
79- name ,
80- value ,
81- )
70+ for start , end in self .get_vad_maps (task ):
71+ size = end - start
72+ if size > sanity_check :
73+ vollog .warn (
74+ f"VAD at 0x{ start :x} over sanity-check size, not scanning"
75+ )
76+ continue
77+
78+ for match in rules .match (data = layer .read (start , end - start , True )):
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+ )
8298
8399 @staticmethod
84100 def get_vad_maps (
0 commit comments