Merge pull request #818 from volatilityfoundation/issue_713_fix_vad_end_off_by_one_pr

refs #713 add a vad.get_size() method and fix several off-by-one issues with calculating vad size
This commit is contained in:
ikelos
2022-09-21 21:19:06 +01:00
committed by GitHub
7 changed files with 26 additions and 19 deletions
+5 -1
View File
@@ -4,9 +4,13 @@ API Changes
When an addition to the existing API is made, the minor version is bumped.
When an API feature or function is removed or changed, the major version is bumped.
2.4.0
=====
Add a `get_size()` method to Windows VAD structures and fix several off-by-one issues when calculating VAD sizes.
2.3.1
=====
Update in the windows `_EPROCESS.owning_process` method for support Windows Vista and later versions.
Update in the windows `_EPROCESS.owning_process` method to support Windows Vista and later versions.
2.3.0
=====
+2 -2
View File
@@ -39,8 +39,8 @@ BANG = "!"
# We use the SemVer 2.0.0 versioning scheme
VERSION_MAJOR = 2 # Number of releases of the library with a breaking change
VERSION_MINOR = 3 # Number of changes that only add to the interface
VERSION_PATCH = 1 # Number of changes that do not change the interface
VERSION_MINOR = 4 # Number of changes that only add to the interface
VERSION_PATCH = 0 # Number of changes that do not change the interface
VERSION_SUFFIX = ""
# TODO: At version 2.0.0, remove the symbol_shift feature
@@ -17,7 +17,7 @@ vollog = logging.getLogger(__name__)
class Malfind(interfaces.plugins.PluginInterface):
"""Lists process memory ranges that potentially contain injected code."""
_required_framework_version = (2, 0, 0)
_required_framework_version = (2, 4, 0)
@classmethod
def get_requirements(cls):
@@ -56,7 +56,7 @@ class Malfind(interfaces.plugins.PluginInterface):
all_zero_page = b"\x00" * CHUNK_SIZE
offset = 0
vad_length = vad.get_end() - vad.get_start()
vad_length = vad.get_size()
while offset < vad_length:
next_addr = vad.get_start() + offset
@@ -41,7 +41,7 @@ vollog = logging.getLogger(__name__)
class Skeleton_Key_Check(interfaces.plugins.PluginInterface):
""" Looks for signs of Skeleton Key malware """
_required_framework_version = (2, 0, 0)
_required_framework_version = (2, 4, 0)
@classmethod
def get_requirements(cls):
@@ -262,7 +262,7 @@ class Skeleton_Key_Check(interfaces.plugins.PluginInterface):
if isinstance(filename, str) and filename.lower().endswith("cryptdll.dll"):
base = vad.get_start()
return base, vad.get_end() - base
return base, vad.get_size()
return None, None
@@ -33,7 +33,7 @@ winnt_protections = {
class VadInfo(interfaces.plugins.PluginInterface):
"""Lists process memory ranges."""
_required_framework_version = (2, 0, 0)
_required_framework_version = (2, 4, 0)
_version = (2, 0, 0)
MAXSIZE_DEFAULT = 1024 * 1024 * 1024 # 1 Gb
@@ -132,7 +132,7 @@ class VadInfo(interfaces.plugins.PluginInterface):
vollog.debug("Unable to find the starting/ending VPN member")
return None
if 0 < maxsize < (vad_end - vad_start):
if 0 < maxsize < vad.get_size():
vollog.debug(f"Skip VAD dump {vad_start:#x}-{vad_end:#x} due to maxsize limit")
return None
@@ -151,8 +151,9 @@ class VadInfo(interfaces.plugins.PluginInterface):
file_handle = open_method(file_name)
chunk_size = 1024 * 1024 * 10
offset = vad_start
while offset < vad_end:
to_read = min(chunk_size, vad_end - offset)
vad_size = vad.get_size()
while offset < vad_start + vad_size:
to_read = min(chunk_size, vad_start + vad_size - offset)
data = proc_layer.read(offset, to_read, pad = True)
if not data:
break
@@ -17,7 +17,7 @@ vollog = logging.getLogger(__name__)
class VadYaraScan(interfaces.plugins.PluginInterface):
"""Scans all the Virtual Address Descriptor memory maps using yara."""
_required_framework_version = (2, 0, 0)
_required_framework_version = (2, 4, 0)
_version = (1, 0, 0)
@classmethod
@@ -82,9 +82,7 @@ class VadYaraScan(interfaces.plugins.PluginInterface):
"""
vad_root = task.get_vad_root()
for vad in vad_root.traverse():
end = vad.get_end()
start = vad.get_start()
yield (start, end - start)
yield (vad.get_start(), vad.get_size())
def run(self):
return renderers.TreeGrid([('Offset', format_hints.Hex), ('PID', int), ('Rule', str), ('Component', str),
@@ -197,8 +197,8 @@ class MMVAD_SHORT(objects.StructType):
raise AttributeError("Unable to find the parent member")
def get_start(self):
"""Get the VAD's starting virtual address."""
def get_start(self) -> int:
"""Get the VAD's starting virtual address. This is the first accessible byte in the range."""
if self.has_member("StartingVpn"):
@@ -216,8 +216,8 @@ class MMVAD_SHORT(objects.StructType):
raise AttributeError("Unable to find the starting VPN member")
def get_end(self):
"""Get the VAD's ending virtual address."""
def get_end(self) -> int:
"""Get the VAD's ending virtual address. This is the last accessible byte in the range."""
if self.has_member("EndingVpn"):
@@ -234,6 +234,10 @@ class MMVAD_SHORT(objects.StructType):
raise AttributeError("Unable to find the ending VPN member")
def get_size(self) -> int:
"""Get the size of the VAD region. The OS ensures page granularity."""
return (self.get_end() - self.get_start()) + 1
def get_commit_charge(self):
"""Get the VAD's commit charge (number of committed pages)"""