Skip to content

Commit 4c0a0b9

Browse files
committed
Update linux.proc --dump changes based on comments from ikelos
1 parent eb06117 commit 4c0a0b9

File tree

1 file changed

+37
-27
lines changed
  • volatility3/framework/plugins/linux

1 file changed

+37
-27
lines changed

volatility3/framework/plugins/linux/proc.py

Lines changed: 37 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,7 @@
55
found in Linux's /proc file system."""
66

77
import logging
8-
from typing import Callable, List, Generator, Iterable, Type, Optional
8+
from typing import Callable, Generator, Type, Optional
99

1010
from volatility3.framework import renderers, interfaces, exceptions
1111
from volatility3.framework.configuration import requirements
@@ -16,6 +16,7 @@
1616

1717
vollog = logging.getLogger(__name__)
1818

19+
1920
class Maps(plugins.PluginInterface):
2021
"""Lists all memory maps for all processes."""
2122

@@ -48,9 +49,9 @@ def get_requirements(cls):
4849
),
4950
requirements.ListRequirement(
5051
name="address",
51-
description="Process virtual memory address to include "
52-
"(all other address ranges are excluded). This must be "
53-
"a base address, not an address within the desired range.",
52+
description="Process virtual memory addresses to include "
53+
"(all other VMA sections are excluded). This can be any "
54+
"virtual address within the VMA section.",
5455
element_type=int,
5556
optional=True,
5657
),
@@ -69,21 +70,25 @@ def list_vmas(
6970
task: interfaces.objects.ObjectInterface,
7071
filter_func: Callable[
7172
[interfaces.objects.ObjectInterface], bool
72-
] = lambda _: False,
73+
] = lambda _: True,
7374
) -> Generator[interfaces.objects.ObjectInterface, None, None]:
7475
"""Lists the Virtual Memory Areas of a specific process.
7576
7677
Args:
7778
task: task object from which to list the vma
78-
filter_func: Function to take a vma and return True if it should be filtered out
79+
filter_func: Function to take a vma and return False if it should be filtered out
7980
8081
Returns:
81-
A list of vmas based on the task and filtered based on the filter function
82+
Yields vmas based on the task and filtered based on the filter function
8283
"""
8384
if task.mm:
8485
for vma in task.mm.get_mmap_iter():
85-
if not filter_func(vma):
86+
if filter_func(vma):
8687
yield vma
88+
else:
89+
vollog.debug(
90+
f"Excluded vma at offset {vma.vol.offset:#x} for pid {task.pid} due to filter_func"
91+
)
8792

8893
@classmethod
8994
def vma_dump(
@@ -106,23 +111,15 @@ def vma_dump(
106111
Returns:
107112
An open FileInterface object containing the complete data for the task or None in the case of failure
108113
"""
114+
pid = task.pid
109115
try:
110116
vm_start = vma.vm_start
111117
vm_end = vma.vm_end
112118
except AttributeError:
113-
vollog.debug("Unable to find the vm_start and vm_end")
114-
return None
115-
116-
vm_size = vm_end - vm_start
117-
if 0 < maxsize < vm_size:
118-
vollog.debug(
119-
f"Skip virtual memory dump {vm_start:#x}-{vm_end:#x} due to maxsize limit"
120-
)
119+
vollog.debug(f"Unable to find the vm_start and vm_end for pid {pid}")
121120
return None
122121

123-
pid = "Unknown"
124122
try:
125-
pid = task.tgid
126123
proc_layer_name = task.add_process_layer()
127124
except exceptions.InvalidAddressException as excp:
128125
vollog.debug(
@@ -132,6 +129,13 @@ def vma_dump(
132129
)
133130
return None
134131

132+
vm_size = vm_end - vm_start
133+
if 0 < maxsize < vm_size:
134+
vollog.warning(
135+
f"Skip virtual memory dump for pid {pid} between {vm_start:#x}-{vm_end:#x} as {vm_size} is larger than maxsize limit of {maxsize}"
136+
)
137+
return None
138+
135139
proc_layer = context.layers[proc_layer_name]
136140
file_name = f"pid.{pid}.vma.{vm_start:#x}-{vm_end:#x}.dmp"
137141
try:
@@ -141,8 +145,6 @@ def vma_dump(
141145
while offset < vm_start + vm_size:
142146
to_read = min(chunk_size, vm_start + vm_size - offset)
143147
data = proc_layer.read(offset, to_read, pad=True)
144-
if not data:
145-
break
146148
file_handle.write(data)
147149
offset += to_read
148150

@@ -154,24 +156,32 @@ def vma_dump(
154156

155157
def _generator(self, tasks):
156158
# build filter for addresses if required
157-
address_list = self.config.get("address", [])
158-
if address_list == []:
159+
address_list = self.config.get("address", None)
160+
if not address_list:
159161
# do not filter as no address_list was supplied
160-
filter_func = lambda _: False
162+
vma_filter_func = lambda _: True
161163
else:
162164
# filter for any vm_start that matches the supplied address config
163-
def filter_function(x: interfaces.objects.ObjectInterface) -> bool:
164-
return x.vm_start not in address_list
165+
def vma_filter_function(x: interfaces.objects.ObjectInterface) -> bool:
166+
addrs_in_vma = [
167+
addr for addr in address_list if x.vm_start <= addr <= x.vm_end
168+
]
169+
170+
# if any of the user supplied addresses would fall within this vma return true
171+
if addrs_in_vma:
172+
return True
173+
else:
174+
return False
165175

166-
filter_func = filter_function
176+
vma_filter_func = vma_filter_function
167177

168178
for task in tasks:
169179
if not task.mm:
170180
continue
171181

172182
name = utility.array_to_string(task.comm)
173183

174-
for vma in self.list_vmas(task, filter_func=filter_func):
184+
for vma in self.list_vmas(task, filter_func=vma_filter_func):
175185
flags = vma.get_protection()
176186
page_offset = vma.get_page_offset()
177187
major = 0

0 commit comments

Comments
 (0)