Skip to content

Commit 7f24c4d

Browse files
authored
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
2 parents 42d0a6c + 82a46a3 commit 7f24c4d

File tree

7 files changed

+26
-19
lines changed

7 files changed

+26
-19
lines changed

API_CHANGES.md

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,9 +4,13 @@ API Changes
44
When an addition to the existing API is made, the minor version is bumped.
55
When an API feature or function is removed or changed, the major version is bumped.
66

7+
2.4.0
8+
=====
9+
Add a `get_size()` method to Windows VAD structures and fix several off-by-one issues when calculating VAD sizes.
10+
711
2.3.1
812
=====
9-
Update in the windows `_EPROCESS.owning_process` method for support Windows Vista and later versions.
13+
Update in the windows `_EPROCESS.owning_process` method to support Windows Vista and later versions.
1014

1115
2.3.0
1216
=====

volatility3/framework/constants/__init__.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -39,8 +39,8 @@
3939

4040
# We use the SemVer 2.0.0 versioning scheme
4141
VERSION_MAJOR = 2 # Number of releases of the library with a breaking change
42-
VERSION_MINOR = 3 # Number of changes that only add to the interface
43-
VERSION_PATCH = 1 # Number of changes that do not change the interface
42+
VERSION_MINOR = 4 # Number of changes that only add to the interface
43+
VERSION_PATCH = 0 # Number of changes that do not change the interface
4444
VERSION_SUFFIX = ""
4545

4646
# TODO: At version 2.0.0, remove the symbol_shift feature

volatility3/framework/plugins/windows/malfind.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
class Malfind(interfaces.plugins.PluginInterface):
1818
"""Lists process memory ranges that potentially contain injected code."""
1919

20-
_required_framework_version = (2, 0, 0)
20+
_required_framework_version = (2, 4, 0)
2121

2222
@classmethod
2323
def get_requirements(cls):
@@ -56,7 +56,7 @@ def is_vad_empty(cls, proc_layer, vad):
5656
all_zero_page = b"\x00" * CHUNK_SIZE
5757

5858
offset = 0
59-
vad_length = vad.get_end() - vad.get_start()
59+
vad_length = vad.get_size()
6060

6161
while offset < vad_length:
6262
next_addr = vad.get_start() + offset

volatility3/framework/plugins/windows/skeleton_key_check.py

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -41,7 +41,7 @@
4141
class Skeleton_Key_Check(interfaces.plugins.PluginInterface):
4242
""" Looks for signs of Skeleton Key malware """
4343

44-
_required_framework_version = (2, 0, 0)
44+
_required_framework_version = (2, 4, 0)
4545

4646
@classmethod
4747
def get_requirements(cls):
@@ -262,7 +262,7 @@ def _find_cryptdll(self, lsass_proc: interfaces.context.ContextInterface) -> \
262262

263263
if isinstance(filename, str) and filename.lower().endswith("cryptdll.dll"):
264264
base = vad.get_start()
265-
return base, vad.get_end() - base
265+
return base, vad.get_size()
266266

267267
return None, None
268268

volatility3/framework/plugins/windows/vadinfo.py

Lines changed: 5 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,7 @@
3333
class VadInfo(interfaces.plugins.PluginInterface):
3434
"""Lists process memory ranges."""
3535

36-
_required_framework_version = (2, 0, 0)
36+
_required_framework_version = (2, 4, 0)
3737
_version = (2, 0, 0)
3838
MAXSIZE_DEFAULT = 1024 * 1024 * 1024 # 1 Gb
3939

@@ -132,7 +132,7 @@ def vad_dump(cls,
132132
vollog.debug("Unable to find the starting/ending VPN member")
133133
return None
134134

135-
if 0 < maxsize < (vad_end - vad_start):
135+
if 0 < maxsize < vad.get_size():
136136
vollog.debug(f"Skip VAD dump {vad_start:#x}-{vad_end:#x} due to maxsize limit")
137137
return None
138138

@@ -151,8 +151,9 @@ def vad_dump(cls,
151151
file_handle = open_method(file_name)
152152
chunk_size = 1024 * 1024 * 10
153153
offset = vad_start
154-
while offset < vad_end:
155-
to_read = min(chunk_size, vad_end - offset)
154+
vad_size = vad.get_size()
155+
while offset < vad_start + vad_size:
156+
to_read = min(chunk_size, vad_start + vad_size - offset)
156157
data = proc_layer.read(offset, to_read, pad = True)
157158
if not data:
158159
break

volatility3/framework/plugins/windows/vadyarascan.py

Lines changed: 2 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
class VadYaraScan(interfaces.plugins.PluginInterface):
1818
"""Scans all the Virtual Address Descriptor memory maps using yara."""
1919

20-
_required_framework_version = (2, 0, 0)
20+
_required_framework_version = (2, 4, 0)
2121
_version = (1, 0, 0)
2222

2323
@classmethod
@@ -82,9 +82,7 @@ def get_vad_maps(task: interfaces.objects.ObjectInterface) -> Iterable[Tuple[int
8282
"""
8383
vad_root = task.get_vad_root()
8484
for vad in vad_root.traverse():
85-
end = vad.get_end()
86-
start = vad.get_start()
87-
yield (start, end - start)
85+
yield (vad.get_start(), vad.get_size())
8886

8987
def run(self):
9088
return renderers.TreeGrid([('Offset', format_hints.Hex), ('PID', int), ('Rule', str), ('Component', str),

volatility3/framework/symbols/windows/extensions/__init__.py

Lines changed: 8 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -197,8 +197,8 @@ def get_parent(self):
197197

198198
raise AttributeError("Unable to find the parent member")
199199

200-
def get_start(self):
201-
"""Get the VAD's starting virtual address."""
200+
def get_start(self) -> int:
201+
"""Get the VAD's starting virtual address. This is the first accessible byte in the range."""
202202

203203
if self.has_member("StartingVpn"):
204204

@@ -216,8 +216,8 @@ def get_start(self):
216216

217217
raise AttributeError("Unable to find the starting VPN member")
218218

219-
def get_end(self):
220-
"""Get the VAD's ending virtual address."""
219+
def get_end(self) -> int:
220+
"""Get the VAD's ending virtual address. This is the last accessible byte in the range."""
221221

222222
if self.has_member("EndingVpn"):
223223

@@ -234,6 +234,10 @@ def get_end(self):
234234

235235
raise AttributeError("Unable to find the ending VPN member")
236236

237+
def get_size(self) -> int:
238+
"""Get the size of the VAD region. The OS ensures page granularity."""
239+
return (self.get_end() - self.get_start()) + 1
240+
237241
def get_commit_charge(self):
238242
"""Get the VAD's commit charge (number of committed pages)"""
239243

0 commit comments

Comments
 (0)