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

Fix MultipleProcessesReturned caused by parent PID reuse #939

Merged
merged 3 commits into from
Jul 26, 2024
Merged
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
51 changes: 24 additions & 27 deletions drakrun/drakrun/lib/postprocessing/build_process_tree.py
Original file line number Diff line number Diff line change
Expand Up @@ -96,24 +96,10 @@ def __init__(self, processes: List[Process]):
super().__init__(message)


class MissingParentProcessError(Exception):
def __init__(self, process: Process):
message = f"Cannot find parent process of {process}"
super().__init__(message)


def parse_running_process_entry(pstree: ProcessTree, entry: Dict[str, Any]) -> None:
# We assume here that running processes are enumerated in order of creation
# (created by appending new entries to the end of EPROCESS linked list)
parent = pstree.get_single_process(entry["PPID"], 0, float(entry["TimeStamp"]))
if parent is None:
# Running processes might have parents that we don't have any information about. Mock them.
parent = Process(
pid=entry["PPID"],
procname="Mocked parent",
ts_from=0.0, # We don't know when the process was created.
# But we know it is not longer alive.
ts_to=float(entry["TimeStamp"]),
)
pstree.add_process(parent)
p = Process(
pid=entry["PID"],
procname=entry["RunningProcess"],
Expand All @@ -122,7 +108,8 @@ def parse_running_process_entry(pstree: ProcessTree, entry: Dict[str, Any]) -> N
ts_to=None,
parent=parent,
)
parent.children.append(p)
if parent is not None:
parent.children.append(p)
pstree.add_process(p)


Expand All @@ -145,11 +132,13 @@ def parse_nt_create_user_process_entry(
if int(entry["Status"], 16) != 0:
# Ignore unsuccessful entries.
return
process_pid = entry["NewPid"]
process_ppid = entry["PID"]
parent = pstree.get_single_process(
entry["PID"], float(entry["TimeStamp"]), float(entry["TimeStamp"])
process_ppid, float(entry["TimeStamp"]), float(entry["TimeStamp"])
)
p = Process(
pid=entry["NewPid"],
pid=process_pid,
procname=entry["ImagePathName"],
ts_from=float(entry["TimeStamp"]),
# At this point, we don't know yet when the process will be terminated.
Expand All @@ -158,9 +147,12 @@ def parse_nt_create_user_process_entry(
args=split_commandline(entry["CommandLine"]) if entry["CommandLine"] else [],
)
if parent is None:
# Parent must be alive at the process creation time.
raise MissingParentProcessError(p)
parent.children.append(p)
# Parent must be alive at the process creation time, but who knows what happened
logger.warning(
f"Parent process not found at the process creation time (PID: {process_pid}, PPID: {process_ppid})"
)
else:
parent.children.append(p)
pstree.add_process(p)


Expand All @@ -171,21 +163,26 @@ def parse_nt_create_process_ex_entry(
if int(entry["Status"], 16) != 0:
# Ignore unsuccessful entries.
return
process_pid = entry["NewPid"]
process_ppid = entry["PID"]
parent = pstree.get_single_process(
entry["PID"], float(entry["TimeStamp"]), float(entry["TimeStamp"])
process_ppid, float(entry["TimeStamp"]), float(entry["TimeStamp"])
)
p = Process(
pid=entry["NewPid"],
pid=process_pid,
procname="Unnamed",
ts_from=float(entry["TimeStamp"]),
# At this point, we don't know yet when the process will be terminated.
ts_to=None,
parent=parent,
)
if parent is None:
# Parent must be alive at the process creation time.
raise MissingParentProcessError(p)
parent.children.append(p)
# Parent must be alive at the process creation time, but who knows what happened
logger.warning(
f"Parent process not found at the process creation time (PID: {process_pid}, PPID: {process_ppid})"
)
else:
parent.children.append(p)
pstree.add_process(p)


Expand Down
Loading