Skip to content
44 changes: 44 additions & 0 deletions test/plugins/windows/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -83,6 +83,50 @@ def test_windows_specific_psscan(self, volatility, python):
assert out.find(b"svchost.exe") != -1
assert out.count(b"\n") > 10

def test_windows_specific_psscan_physical(self, volatility, python):
image = WindowsSamples.WINDOWSXP_GENERIC.value.path
rc, out, _err = test_volatility.runvol_plugin(
"windows.psscan.PsScan",
image,
volatility,
python,
pluginargs=("--physical",),
)
assert rc == 0
out = out.lower()
assert out.find(b"system") != -1
assert out.find(b"csrss.exe") != -1
assert out.find(b"svchost.exe") != -1
assert out.count(b"\n") > 10

def test_windows_10_specific_psscan(self, volatility, python):
image = WindowsSamples.WINDOWS10_GENERIC.value.path
rc, out, _err = test_volatility.runvol_plugin(
"windows.psscan.PsScan", image, volatility, python
)
assert rc == 0
out = out.lower()
assert out.find(b"system") != -1
assert out.find(b"csrss.exe") != -1
assert out.find(b"svchost.exe") != -1
assert out.count(b"\n") > 10

def test_windows_10_specific_psscan_physical(self, volatility, python):
image = WindowsSamples.WINDOWS10_GENERIC.value.path
rc, out, _err = test_volatility.runvol_plugin(
"windows.psscan.PsScan",
image,
volatility,
python,
pluginargs=("--physical",),
)
assert rc == 0
out = out.lower()
assert out.find(b"system") != -1
assert out.find(b"csrss.exe") != -1
assert out.find(b"svchost.exe") != -1
assert out.count(b"\n") > 10


class TestWindowsDlllist:
def test_windows_generic_dlllist(self, volatility, python, image):
Expand Down
45 changes: 24 additions & 21 deletions volatility3/framework/plugins/windows/psscan.py
Original file line number Diff line number Diff line change
Expand Up @@ -23,7 +23,7 @@ class PsScan(interfaces.plugins.PluginInterface, timeliner.TimeLinerInterface):
"""Scans for processes present in a particular windows memory image."""

_required_framework_version = (2, 3, 1)
_version = (2, 0, 0)
_version = (2, 0, 1)

@classmethod
def get_requirements(cls):
Expand Down Expand Up @@ -269,39 +269,42 @@ def _generator(self):
filter_func=pslist.PsList.create_pid_filter(self.config.get("pid", None)),
):
file_output = "Disabled"
if self.config["dump"]:
# windows 10 objects (maybe others in the future) are already in virtual memory
if proc.vol.layer_name == kernel.layer_name:
vproc = proc

if isinstance(self.context.layers[proc.vol.layer_name], layers.intel.Intel):
vproc = proc
if self.config["physical"]:
_, _, offset, _, _ = list(
memory.mapping(offset=proc.vol.offset, length=0)
)[0]
else:
try:
vproc = self.virtual_process_from_physical(
self.context,
self.config["kernel"],
proc,
)
except exceptions.PagedInvalidAddressException:
vproc = None
offset = proc.vol.offset
else:
vproc = self.virtual_process_from_physical(
self.context, self.config["kernel"], proc
)
if self.config["physical"]:
offset = proc.vol.offset
else:
offset = vproc.vol.offset if vproc is not None else None

if self.config["dump"]:
Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Ideally we'd guard for if vproc is None:. If we hand it in, it will debug log but otherwise return None, so it's not catastrophic, but feels like an easy thing we can check (and catchall exception handlers aren't ideal, so that may go away at some point in the future)...

file_output = "Error outputting file"
if vproc:
if vproc is not None:
file_handle = pslist.PsList.process_dump(
self.context,
kernel.symbol_table_name,
pe_table_name,
vproc,
self.open,
)

if file_handle:
file_output = file_handle.preferred_filename

if not self.config["physical"]:
offset = proc.vol.offset
# format offset for display
if offset is None:
display_offset = renderers.UnreadableValue()
else:
(_, _, offset, _, _) = list(
memory.mapping(offset=proc.vol.offset, length=0)
)[0]
display_offset = format_hints.Hex(offset)

try:
yield (
Expand All @@ -314,7 +317,7 @@ def _generator(self):
max_length=proc.ImageFileName.vol.count,
errors="replace",
),
format_hints.Hex(offset),
display_offset,
proc.ActiveThreads,
proc.get_handle_count(),
proc.get_session_id(),
Expand Down
Loading