How to Analyze BAM and DAM Registry Keys, Step by Step
A practical workflow to parse BAM/DAM from a SYSTEM hive: collect, parse in the browser, scope by user and control set, triage flags, corroborate and export.
TL;DR. Collect SYSTEM + its two .LOG files + SOFTWARE. Replay the logs if the hive is dirty. Drop everything on the BAM/DAM Parser. Keep "Active control set only" on, pick a user, sort by time. Use the flags to decide what to open first, check the detail panel, corroborate with Prefetch/Amcache/event logs, export the filtered rows. About twenty minutes for a single host.
This is the workflow we use for a single Windows 10/11 host. It assumes you know what BAM is — if not, read the BAM/DAM forensics guide first. The examples use the tool's built-in "Try a sample" data: synthetic hives describing a fictional intrusion on a host called FIN-WKS-07. No real data is involved.
Step 1 — Collect the hives
You need, from C:\Windows\System32\config\:
| File | Why |
|---|---|
SYSTEM | BAM and DAM live here |
SYSTEM.LOG1, SYSTEM.LOG2 | Pending writes — often the most recent executions |
SOFTWARE | ProfileList turns SIDs into account names |
The files are locked on a running system. Use KAPE (RegistryHivesSystem target, or !SANS_Triage), Velociraptor, FTK Imager, or copy them from a mounted disk image. reg save HKLM\SYSTEM also works and produces an already-consolidated hive. Commands and pitfalls are in where the BAM key is and how to collect it.
If you want older activity than the last week, also pull SYSTEM from each Volume Shadow Copy.
Step 2 — Check for a dirty hive and replay the logs
When Windows had unflushed changes at copy time, the two sequence numbers in the hive header differ: the hive is dirty. The BAM/DAM Parser shows a banner in that case ("Dirty hive: recent BAM writes may still be in SYSTEM.LOG1/LOG2 and are not replayed").
The parser does not replay logs itself. Run Eric Zimmerman's rla.exe (or open the hive in Registry Explorer and save the cleaned copy) — both are on the EZ tools page — and parse the result. Parsing the dirty file anyway is fine for a first look; just don't conclude that an entry is absent from it.
Step 3 — Load the hives
Open the tool and either:
- drop the files onto the page,
- use Choose files or Choose a folder, or
- drop a whole KAPE or Velociraptor ZIP.
The parser runs as WebAssembly in a Web Worker inside your browser; nothing is uploaded. It picks the SYSTEM and SOFTWARE hives out of a collection, and lists every file it skipped with the reason (a transaction log, a different hive, an all-zero file from a locked copy, and so on).
Then read the header:
- Host — from
ControlSet00X\Control\ComputerName(FIN-WKS-07in the sample). - Time zone — the configured
TimeZoneKeyName(Romance Standard Timein the sample, i.e. Paris). - Active control set — from
Select\Current. - Entries / Accounts / Flagged — counts for the current view.
Step 4 — Scope the view
Control set. Keep Active control set only on. The sample's ControlSet002 holds an older snapshot of alice's entries from before the incident; turning the filter off shows both, which is useful for comparison but noisy for a timeline. More on this in the location article.
Account. The account list shows each SID with its name from ProfileList, busiest first. Well-known SIDs get labels (SYSTEM for S-1-5-18, DWM-1, UMFD-0…). How to reason about those accounts is covered in BAM user attribution.
Source. "BAM + DAM" by default; restrict to one if needed (DAM explained).
Sort. Click Last execution to read a user's activity in order. The time column is UTC with 100 ns precision; the Local toggle converts to your browser's time zone and shows the offset, which is not necessarily the suspect host's zone.
Search. The filter box matches path, user, SID or date string — 2026-09-14 narrows the sample to the day of the incident, \Users\Public\ to one folder.
Step 5 — Triage flagged rows
The tool flags four patterns. They are simple, explainable heuristics that tell you where to look first — not verdicts:
| Flag | Rule | Sample hit |
|---|---|---|
| User-writable folder | Path under a user profile's AppData, Downloads, Desktop…, Users\Public, ProgramData, Windows\Temp, $Recycle.Bin, PerfLogs | \Users\Public\rclone.exe |
| Double extension | Document/archive extension followed by an executable one | Invoice_2026-0914.pdf.exe |
| System binary out of place | Name of a core Windows binary outside its expected folder | \Windows\Temp\svchost.exe |
| Dual-use / attack tool | Name matches a list of remote-admin, exfiltration and credential tools | PsExec64.exe, Advanced_IP_Scanner.exe |
Tick Flagged only for a quick shortlist, then clear it: legitimate-looking entries (cmd.exe, mstsc.exe, 7z.exe) are often the context that makes the flagged ones make sense.
Click any row to open the detail panel:
- Registry key — full path including control set and layout.
- Raw value data — the full
REG_BINARYin hex (format explained). - FILETIME — the raw 64-bit value.
- SID key last written — when that user's key last changed; a useful tampering check (anti-forensics).
- Source hive — which file the row came from, important when you load several SYSTEM hives.
Step 6 — Corroborate
BAM gives you who, what path and when (last). It doesn't give hash, run count, command line or parent. For each row that matters:
- Prefetch — run count and up to eight run times, loaded files (Prefetch Parser).
- Amcache — SHA-1 and metadata of the file (Amcache Parser).
- Event logs — 4688 process creation (if auditing is enabled), Sysmon event 1, 4624/4648 logons, 7045 service installs (EVTX Parser).
- ShimCache — path presence on disk (ShimCache Parser).
The comparison matrix summarises which artifact answers which question.
Step 7 — Export
CSV and JSON export the rows currently shown, so apply your filters first (or clear them for a full export). Files are named after the host (FIN-WKS-07_bamdam.csv).
- CSV columns:
LastExecutionUtc,Program,Path,User,SID,Service,ControlSet,ActiveControlSet,LegacyLayout,Volume,Flags,SidKeyLastWriteUtc,FileTime,DataHex,SourceFile. Cells that start with=,+,-or@are prefixed so a malicious path can't run as a spreadsheet formula. - JSON adds per-source metadata: hive name, dirty flag, parser version, host, time zone, control sets and warnings.
Feed either into your timeline tool of choice (for example Plaso or a spreadsheet super-timeline) alongside the corroborating artifacts.
Common mistakes
- Parsing
SYSTEMwithout its logs and reporting an absence. - Mixing
ControlSet002rows into the current timeline. - Reporting the Local-time column as the suspect's local time.
- Treating a flag as a finding, or the absence of a flag as clean.
- Forgetting that BAM misses removable-media, network-share and many command-line executions.
For a complete worked case, read the fictional lateral-movement investigation with BAM.