mirror of https://github.com/pwndbg/pwndbg.git
Add command to display information about kernel tasks (#3099)
* oops, merge conflicts fixed v3 * Fix lint errors * ktask commit * add uid/gid * Fix lint errorsrevert-3087-ng-scaffold
parent
c64d44b2c8
commit
0a4f9f8832
@ -0,0 +1,23 @@
|
|||||||
|
<!-- THIS PART OF THIS FILE IS AUTOGENERATED. DO NOT MODIFY IT. See scripts/generate-docs.sh -->
|
||||||
|
# ktask
|
||||||
|
|
||||||
|
```text
|
||||||
|
usage: ktask [-h] [task_name]
|
||||||
|
|
||||||
|
```
|
||||||
|
|
||||||
|
Displays information about kernel tasks.
|
||||||
|
### Positional arguments
|
||||||
|
|
||||||
|
|Positional Argument|Help|
|
||||||
|
| :--- | :--- |
|
||||||
|
|task_name|A task name to search for|
|
||||||
|
|
||||||
|
### Optional arguments
|
||||||
|
|
||||||
|
|Short|Long|Help|
|
||||||
|
| :--- | :--- | :--- |
|
||||||
|
|-h|--help|show this help message and exit|
|
||||||
|
|
||||||
|
<!-- END OF AUTOGENERATED PART. Do not modify this line or the line below, they mark the end of the auto-generated part of the file. If you want to extend the documentation in a way which cannot easily be done by adding to the command help description, write below the following line. -->
|
||||||
|
<!-- ------------\>8---- ----\>8---- ----\>8------------ -->
|
||||||
@ -0,0 +1,87 @@
|
|||||||
|
"""
|
||||||
|
Displays information about kernel tasks. This command iterates through the kernel's task list
|
||||||
|
and prints details about each task, including its address, PID, user space status, CPU, UID, GID, and name.
|
||||||
|
"""
|
||||||
|
|
||||||
|
from __future__ import annotations
|
||||||
|
|
||||||
|
import argparse
|
||||||
|
|
||||||
|
import pwndbg.color.message as message
|
||||||
|
import pwndbg.commands
|
||||||
|
from pwndbg.aglib.kernel.macros import container_of
|
||||||
|
|
||||||
|
parser = argparse.ArgumentParser(description="Displays information about kernel tasks.")
|
||||||
|
|
||||||
|
parser.add_argument("task_name", nargs="?", type=str, help="A task name to search for")
|
||||||
|
|
||||||
|
|
||||||
|
@pwndbg.commands.Command(parser, category=pwndbg.commands.CommandCategory.KERNEL)
|
||||||
|
@pwndbg.commands.OnlyWhenQemuKernel
|
||||||
|
@pwndbg.commands.OnlyWhenPagingEnabled
|
||||||
|
@pwndbg.commands.OnlyWithKernelDebugSyms
|
||||||
|
def ktask(task_name=None) -> None:
|
||||||
|
print(f"{'Address':>18} {'PID':>6} {'User':>4} {'CPU':>4} {'UID':>4} {'GID':>4} {'Name'}")
|
||||||
|
|
||||||
|
# Look up the init_task symbol, which is the first task in the kernel's task list.
|
||||||
|
init_task = pwndbg.aglib.symbol.lookup_symbol_addr("init_task")
|
||||||
|
if init_task is None:
|
||||||
|
print(
|
||||||
|
"The init_task symbol was not found. This may indicate that the symbol is not available in the current build."
|
||||||
|
)
|
||||||
|
return
|
||||||
|
|
||||||
|
curr_task = init_task
|
||||||
|
|
||||||
|
try:
|
||||||
|
# The task list is implemented a circular doubly linked list, so we traverse starting from init_task.
|
||||||
|
while True:
|
||||||
|
task_struct = pwndbg.aglib.memory.get_typed_pointer_value(
|
||||||
|
"struct task_struct", curr_task
|
||||||
|
)
|
||||||
|
thread_head = task_struct["signal"]["thread_head"]
|
||||||
|
|
||||||
|
curr_thread = thread_head["next"]
|
||||||
|
|
||||||
|
# Iterate through all threads in the task_struct's thread list.
|
||||||
|
while True:
|
||||||
|
if int(thread_head.address) == int(curr_thread):
|
||||||
|
break
|
||||||
|
|
||||||
|
thread = container_of(int(curr_thread), "struct task_struct", "thread_node")
|
||||||
|
|
||||||
|
task_struct2 = pwndbg.aglib.memory.get_typed_pointer_value(
|
||||||
|
"struct task_struct", thread
|
||||||
|
)
|
||||||
|
|
||||||
|
comm = task_struct2["comm"].string()
|
||||||
|
|
||||||
|
# Print task information if no specific task name is provided or if the current task matches the provided name.
|
||||||
|
if not task_name or task_name in comm:
|
||||||
|
curr_task_hex = hex(curr_task)
|
||||||
|
pid = int(task_struct2["pid"])
|
||||||
|
user = "✓" if int(task_struct2["mm"]) != 0 else "✗"
|
||||||
|
cpu = int(task_struct2["thread_info"]["cpu"])
|
||||||
|
|
||||||
|
# Get UID and GID from the credentials structure
|
||||||
|
uid = int(task_struct2["real_cred"]["uid"]["val"])
|
||||||
|
gid = int(task_struct2["real_cred"]["gid"]["val"])
|
||||||
|
|
||||||
|
print(
|
||||||
|
f"{curr_task_hex:>18} {pid:>6} {user:>4} {cpu:>4} {uid:>6} {gid:>6} {comm:<7}"
|
||||||
|
)
|
||||||
|
|
||||||
|
curr_thread = curr_thread["next"]
|
||||||
|
|
||||||
|
next_task = container_of(
|
||||||
|
int(task_struct["tasks"]["next"]), "struct task_struct", "tasks"
|
||||||
|
)
|
||||||
|
|
||||||
|
if int(next_task) == init_task:
|
||||||
|
break
|
||||||
|
|
||||||
|
curr_task = int(next_task)
|
||||||
|
|
||||||
|
except pwndbg.dbg_mod.Error as e:
|
||||||
|
print(message.error(f"ERROR: {e}"))
|
||||||
|
return
|
||||||
Loading…
Reference in new issue