Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Volshell: Add Dedicated Method to retrieve EPROCESS/Task object given the PID #1381

Open
wants to merge 3 commits into
base: develop
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions doc/source/volshell.rst
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,13 @@ python environment, we can do the following:
(layer_name) >>> proc
<EPROCESS symbol_table_name1!_EPROCESS: layer_name @ 0xe08ff2459040 #1968>

Alternatively, given a PID of a process we can grab and assign the data using the `gp()` (`get_process`) function as so:

::
(layer_name) >>> proc = gp(736)
(layer_name) >>> proc
<EPROCESS symbol_table_name1!_EPROCESS: layer_name @ 0xb90b880bc080 #2624>

When printing a volatility structure, various information is output, in this case the `type_name`, the `layer` and
`offset` that it's been constructed on, and the size of the structure.

Expand Down
11 changes: 10 additions & 1 deletion volatility3/cli/volshell/linux.py
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@
name="kernel", description="Linux kernel module"
),
requirements.PluginRequirement(
name="pslist", plugin=pslist.PsList, version=(2, 0, 0)
name="pslist", plugin=pslist.PsList, version=(3, 0, 0)
),
requirements.IntRequirement(
name="pid", description="Process ID", optional=True
Expand All @@ -40,6 +40,14 @@
return None
print(f"No task with task ID {pid} found")

def get_task(self, pid):

Check notice

Code scanning / CodeQL

Explicit returns mixed with implicit (fall through) returns Note

Mixing implicit and explicit returns may indicate an error as implicit returns always return None.
Copy link
Member

Choose a reason for hiding this comment

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

Please make sure this ends in an explicit return None if the pid isn't found or there's no tasks.

Copy link
Member

Choose a reason for hiding this comment

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

It also looks like there's two bits of whitespace that are causing black to complain

"""Get Task based on a process ID. Does not retrieve the layer, to change layer use the .pid attribute"""
tasks = self.list_tasks()
for task in tasks:
if task.pid == pid:
return task
print(f"No task with task ID {pid} found")

def list_tasks(self):
"""Returns a list of task objects from the primary layer"""
# We always use the main kernel memory and associated symbols
Expand All @@ -50,6 +58,7 @@
result += [
(["ct", "change_task", "cp"], self.change_task),
(["lt", "list_tasks", "ps"], self.list_tasks),
(["gp", "get_task"], self.get_task),
Copy link
Member

Choose a reason for hiding this comment

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

How do we feel about the naming? Should it be gt in linux, or will the difference be confusing? Should we call it get_process instead to keep with windows? We can allow alternatives (see list_tasks as both lt and ps in the line above). Perhaps we should have it as gt and then with gp as a secondary?

Copy link
Author

Choose a reason for hiding this comment

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

gt is reserved for generate_tree afaik

Copy link
Member

Choose a reason for hiding this comment

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

Ah, you're right... shame... 5:S Would it be worth aliasing it to get_process as well, or do we just live with the inconsistency?

(["symbols"], self.context.symbol_space[self.current_symbol_table]),
]
if self.config.get("pid", None) is not None:
Expand Down
10 changes: 10 additions & 0 deletions volatility3/cli/volshell/windows.py
Original file line number Diff line number Diff line change
Expand Up @@ -43,12 +43,22 @@ def list_processes(self):
self.context, self.current_layer, self.current_symbol_table
)
)

def get_process(self, pid):
"""Returns the EPROCESS object that matches the pid"""
processes = self.list_processes()
for process in processes:
if process.UniqueProcessId == pid:
return process
print(f"No process with process ID {pid} found")
return None

def construct_locals(self) -> List[Tuple[List[str], Any]]:
result = super().construct_locals()
result += [
(["cp", "change_process"], self.change_process),
(["lp", "list_processes", "ps"], self.list_processes),
(["gp", "get_process"], self.get_process),
(["symbols"], self.context.symbol_space[self.current_symbol_table]),
]
if self.config.get("pid", None) is not None:
Expand Down
Loading