Course outline

Digital Forensics / Advanced: models, validation, correlation, and reporting / Lesson 14

Reason about memory and process records safely

Use created process snapshots to examine identity, parent relationships, and incomplete views without reading memory.

About 4 min readContent reviewed
On this page

Lesson goals

  • Explain why a PID or process name is not a stable identity across time.
  • Retain missing relationships and acquisition limitations without labeling them malicious.

Distinguish a process record from a memory acquisition

A process inventory is a view of selected runtime metadata, while a memory image and its interpretation involve different material and assumptions. Live systems change during observation, and incomplete views can arise for many reasons. The Linux proc documentation is one platform reference; it is not a universal process schema. This lesson creates dictionaries only and reads no procfs, memory, dump, device, account, or live process. It provides no acquisition procedure and extracts no secrets. Every result concerns declared classroom records rather than an actual hostโ€™s state.

Scope a process identity beyond its PID

A PID can be reused after a process exits, so equal numeric ids in different snapshots do not automatically identify one continuous process. Include the source context and a documented start-time or generation field when supported. The first program shows two invented records sharing a PID but differing in start marker. It demonstrates why a richer join key matters without claiming that these markers correspond to an actual operating-system time format. Process names can also be changed, duplicated, or misleading, so a name alone cannot establish executable integrity, operator identity, or intent.

python Compare scoped synthetic process identities
first = {"source":"host-lab", "pid":42, "start":"generation-a", "name":"worker"}
second = {"source":"host-lab", "pid":42, "start":"generation-b", "name":"worker"}
identity = lambda p: (p["source"], p["pid"], p["start"])
assert first["pid"] == second["pid"]
assert first["name"] == second["name"]
assert identity(first) != identity(second)
print("same PID and name; distinct modeled process identities")
Expected output
same PID and name; distinct modeled process identities

The complete program compares two local dictionaries with invented generation markers. It reads no host metadata and confirms no real PID reuse. The example establishes only that the selected identity key distinguishes the supplied records.

Keep missing parents as unresolved relationships

A parent id absent from a snapshot can reflect an incomplete view, exit, reparenting, parser support, or other platform behavior. It is not automatic proof of hidden malware. The second program separates a resolved parent from a missing reference and preserves both records in the accounting. This is a relationship check over synthetic data, not a process-tree detector. A real parent interpretation must consider source timing and platform semantics, including whether the reported relationship is creation-time or current state. Avoid inventing a parent node merely to make the graph visually complete.

python Account for a missing synthetic parent reference
processes = [{"pid":1,"parent":None}, {"pid":42,"parent":1}, {"pid":77,"parent":99}]
known = {p["pid"] for p in processes}
resolved = [p["pid"] for p in processes if p["parent"] in known]
unresolved = [p["pid"] for p in processes if p["parent"] is not None and p["parent"] not in known]
assert resolved == [42]
assert unresolved == [77]
assert len(resolved) + len(unresolved) + 1 == len(processes)
print("resolved and missing parent references retained")
Expected output
resolved and missing parent references retained

The complete program organizes three invented records and counts one root separately. It performs no memory inspection, process enumeration, or malware detection. Missing reference 99 remains unexplained within the supplied fixture.

Compare views without assuming one is complete

Different tools or APIs may expose different runtime structures and require different symbols or version support. Disagreement can reveal a parser limitation, timing difference, or a real condition, so preserve it before choosing an explanation. A list of strings found in a memory-like fixture does not show which process used them or whether they were active at the relevant time. Content can be stale, duplicated, compressed, or unrelated. Do not interpret a suggestive path or domain as proof of execution or communication without supported object and time relationships.

Keep volatile-source limits in the report

Report the exact supplied record, extraction or mapping rule, identity key, timing context, and unresolved relationships. Explain that a synthetic snapshot is not a validated memory acquisition. Real volatile-material handling requires separate approved procedures, tools, authority, and privacy safeguards that are not performed here. The local examples teach identity and graph reasoning, not host triage or operational response. A careful finding can identify a missing relationship or conflicting view without converting it into an unsupported malware, persistence, or human-attribution claim.

Common errors and fixes

Equal PIDs across snapshots identify one process

Why it happens
Identifier reuse and source scope are ignored.
How to fix it
Use supported start/generation and source context.
Prevent it next time
Review identity keys before joining runtime records.

A missing parent proves malware

Why it happens
Incomplete relationships are assigned a malicious cause.
How to fix it
Retain alternatives and seek authorized corroboration.
Prevent it next time
Label unresolved references rather than inventing nodes.

A found string proves execution

Why it happens
Content presence is confused with object use and time.
How to fix it
Require supported process, source, and temporal relationships.
Prevent it next time
Keep string matches as leads with explicit limits.

Check your understanding

1. Two records share PID 42 and worker but have different start markers. What can be concluded?

Show worked solution

The chosen source/PID/start identity model distinguishes them. Their equal names and PIDs alone do not establish continuity. State that the markers are fictional and that no real process state was inspected, then preserve any uncertainty about how a real source defines start identity.

2. Why should unresolved parent 99 not be silently added as a known process?

Show worked solution

The fixture contains no record establishing that nodeโ€™s properties or even its presence at the snapshot time. Add an explicit missing-reference marker if needed for display, clearly distinguished from an observed process. Do not fabricate a name, start time, or malicious role.

Key takeaways

  • Runtime identifiers need source and temporal scope.
  • Missing relationships are questions, not automatic malicious findings.
  • Synthetic snapshots perform no memory acquisition or host inspection.

Official references