⬢ DragonFlyBSD Kernel Audit
DF-3017 / forensics2.py
← back to finding ↓ download raw
#!/usr/bin/env python3
"""Forensic dump v2: relaxed cdev matcher over stack heap candidates."""
import sys
sys.path.insert(0, ".")
from rsp import rsp

FRAME = 0xfffff80118573528
PTS_OPS = 0xffffffff810e5ea0
DEAD_OPS = 0xffffffff81187fe0

def rd(addr, n):
    return bytes.fromhex(rsp(b"m%x,%x" % (addr, n)).decode())

def rq(a):
    try:
        return int.from_bytes(rd(a, 8), "little")
    except Exception:
        return None

stack = rd(FRAME - 0x400, 0x800)
cands = set()
for off in range(0, len(stack), 8):
    v = int.from_bytes(stack[off:off+8], "little")
    if 0xfffff80000000000 <= v < 0xfffff81000000000:
        cands.add(v & ~7)
print("[*] %d base candidates" % len(cands))

hits = []
for p in sorted(cands):
    for d in range(-0x140, 0x148, 8):
        q = p + d
        ops = rq(q + 168)
        if ops in (PTS_OPS, DEAD_OPS, 0x40000000, 0x0000000040000000):
            fl = rq(q + 236)
            nm = rd(q + 88, 8)
            hits.append((q, ops, fl, nm))
            print("[!] CDEV? %x si_ops=%016x flags@236=%s name=%r"
                  % (q, ops, ("%x" % fl) if fl is not None else "?", nm))
if not hits:
    print("[-] no cdev found near frames; dumping stack words for manual review:")
    for off in range(0, 0x300, 8):
        v = int.from_bytes(stack[off:off+8], "little")
        print("  %016x: %016x" % (FRAME - 0x400 + off, v))