BAM-Werteformat: FILETIME, Pfade und Interna
Ein BAM-Registry-Wert Byte für Byte: der 24-Byte-REG_BINARY, der FILETIME, Gerätepfade oder Paketnamen, Version, SequenceNumber und Schlüsselzeitstempel.
TL;DR. Jeder BAM-Wert folgt dem Muster Name = ausführbare Datei, Daten = REG_BINARY. Die ersten 8 Datenbytes sind ein FILETIME in Little-Endian (100-ns-Intervalle seit dem 1601-01-01 UTC); auf den untersuchten Builds sind die Daten 24 Bytes lang, und die restlichen 16 Bytes braucht man zum Lesen der Zeit nicht. Wertnamen sind entweder NT-Gerätepfade (\Device\HarddiskVolume3\…) oder Paketfamiliennamen. Version und SequenceNumber sind Verwaltungswerte, keine Programme. Der Zeitpunkt des letzten Schreibzugriffs auf den SID-Schlüssel ist ein zusätzlicher Zeitstempel gratis dazu.
Wer BAM nur über ein Tool liest, erfährt hier, was dieses Tool tut und wo es danebenliegen kann. Zum Einstieg: der komplette BAM/DAM-Leitfaden und wo der BAM-Schlüssel liegt.
Aufbau eines SID-Schlüssels
Ein typischer Schlüssel bam\State\UserSettings\<SID> sieht so aus (fiktive Beispieldaten dieser Website):
| Wertname | Typ | Daten (hex) |
|---|---|---|
Version | REG_DWORD | 01 00 00 00 |
SequenceNumber | REG_DWORD | 76 00 00 00 |
\Device\HarddiskVolume3\Users\alice\Downloads\Invoice_2026-0914.pdf.exe | REG_BINARY | 80 0d 7c 1d 29 44 dd 01 + 16 Bytes |
MSTeams_8wekyb3d8bbwe | REG_BINARY | 24 Bytes |
Drei Arten von Werten, drei Regeln:
- Verwaltungs-DWORDs –
VersionundSequenceNumber. Beim Auflisten der Programme überspringen. Ihre Bedeutung ist nicht öffentlich dokumentiert; jede Deutung (etwa dassSequenceNumbermit jeder Aktualisierung wächst) ist eine Hypothese, die Sie auf Ihrem eigenen Referenzsystem testen sollten. - Einträge ausführbarer Dateien –
REG_BINARY, der Name ist ein Pfad, die Daten sind mindestens 8 Bytes lang. - Alles andere – ein Wert, der kein
REG_BINARYoder kürzer als 8 Bytes ist, ist kein BAM-Eintrag. Ein robuster Parser ignoriert ihn, statt abzustürzen. Unserer macht genau das und meldet unlesbare Werte als Warnungen, statt sie stillschweigend zu verwerfen.
Den FILETIME dekodieren
Ein FILETIME ist ein 64-Bit-Zähler von 100-Nanosekunden-Intervallen seit dem 1. Januar 1601 UTC (Microsoft Learn). Er wird in Little-Endian gespeichert, also die Bytes von rechts nach links lesen:
bytes 80 0d 7c 1d 29 44 dd 01
as u64 0x01DD44291D7C0D80 = 134338507270000000
seconds 13433850727 (÷ 10,000,000)
minus 11644473600 (1601 → 1970 offset)
unix 1789377127 → 2026-09-14 09:12:07 UTC
Zwei Dinge sollte man im Kopf behalten:
- Es ist UTC. Die Registry speichert die Zeitzone des Hosts nicht im Wert. Der SYSTEM-Hive enthält aber die konfigurierte Zone (
Control\TimeZoneInformation\TimeZoneKeyName), die unser Tool in der Kopfzeile anzeigt, damit Sie über die Ortszeit nachdenken können. Der Schalter „Lokal“ im Tool rechnet in die Zeitzone Ihres Browsers um, nicht in die des untersuchten Systems. - Genauigkeit. FILETIME hat eine Auflösung von 100 ns. JavaScript-
Datekennt nur Millisekunden, daher runden Browser-Tools, die überDateumrechnen. Der BAM/DAM Parser behält in der UTC-Ansicht alle sieben Nachkommastellen und exportiert den rohen FILETIME als Dezimalzeichenkette (eine 64-Bit-Ganzzahl passt nicht verlustfrei in eine JSON-Zahl).
Welches Ereignis die Zeit markiert
Maxim Suhanovs Analyse von bam.sys zeigt, dass der Zeitstempel sowohl beim Erzeugen als auch beim Beenden des Prozesses aktualisiert wird (BAM internals). Der Wert ist also das jüngste dieser Ereignisse, das BAM gespeichert hat. Bei lange laufenden Programmen spricht man im Bericht besser von „zuletzt erfasster Aktivität“ und greift für den Startzeitpunkt auf Prefetch oder Protokolle der Prozesserstellung zurück.
Die restlichen 16 Bytes
Auf den von Suhanov untersuchten Windows-10-Builds sind BAM-Werte 24 Bytes lang: der FILETIME, dann 16 weitere Bytes. Seine Analyse verknüpft eines der abschließenden DWORDs mit dem Moderationsstatus (ob der Benutzer die Hintergrundaktivität Windows überlassen oder die Einstellung für diese App geändert hat) und stellt fest, dass Einträge mit einem vom Standard abweichenden Status nicht der altersbasierten Bereinigung unterliegen (Quelle). Darüber hinaus ist der Aufbau nicht öffentlich dokumentiert.
Praktische Folgen:
- Gehen Sie nicht von fest 24 Bytes aus; lesen Sie die ersten 8 Bytes und behalten Sie den Rest.
- Bewahren Sie die Rohbytes im Export auf. Unser Tool zeigt die vollständigen Daten im Detailbereich („Rohdaten des Werts“) und in der CSV-Spalte
DataHex, damit Sie die abschließenden Bytes neu betrachten können, falls neue Forschung erscheint.
Wertnamen: Gerätepfade und Pakete
NT-Gerätepfade
Die meisten Namen sehen aus wie \Device\HarddiskVolume3\Windows\System32\cmd.exe. Das ist der NT-Gerätepfad des Kernels: das Volume-Objekt, dann der Pfad auf diesem Volume. Es gibt keinen Laufwerksbuchstaben, weil Laufwerksbuchstaben eine Zuordnung im Benutzermodus sind (Microsoft Learn: Definieren eines MS-DOS-Gerätenamens).
So ordnen Sie HarddiskVolumeN offline einem Buchstaben zu:
- Meist ist das Systemvolume dasjenige mit den Einträgen
\Windows\System32\…; alles mit dieser Volume-Nummer liegt aufC:. - Für andere Nummern gleichen Sie mit Artefakten ab, die beide Formen festhalten – etwa Prefetch-Dateien, die Volume-Gerätepfade und Seriennummern speichern (libscca-Format). Auch die Ausgabe einer Live-Response, die sowohl Gerätepfad als auch Laufwerksbuchstaben erfasst hat, hilft. (Der Schlüssel
MountedDevicesim selben Hive ordnet Buchstaben Volume-Kennungen zu, nichtHarddiskVolumeN-Nummern, und hilft daher nur teilweise.) - Volume-Nummern vergibt das laufende System; sie sind keine stabile Kennung über Hosts hinweg und nicht einmal zwingend nach Konfigurationsänderungen auf demselben Host.
Paketfamiliennamen
Paketierte Apps (Store, MSIX) erscheinen mit ihrem Paketfamiliennamen: Microsoft.WindowsCalculator_8wekyb3d8bbwe. Der Teil nach dem Unterstrich ist der Hash der Herausgeber-ID, der Teil davor der Paketname (Microsoft Learn: Paketidentität). Es gibt weder Pfad noch Dateinamen. Unser Parser zeigt den Paketnamen als Programm, kennzeichnet die Zeile als App und wendet die pfadbasierten Heuristiken nicht an.
Andere Formen
Gelegentlich begegnet man einem Namen, der weder das eine noch das andere ist – etwa einem Pfad ohne das Präfix \Device\. Nicht verwerfen: Das Tool stuft ihn als „andere“ ein und dekodiert den Zeitstempel trotzdem.
Der letzte Schreibzugriff auf den SID-Schlüssel
Jeder Registry-Schlüssel hat im Schlüsselknoten einen FILETIME für den letzten Schreibzugriff (Spezifikation msuhanov/regf). Bei einem BAM-SID-Schlüssel ändert sich diese Zeit, sobald sich irgendein Wert darunter ändert. Das bringt:
- Eine Plausibilitätsprüfung: Die Schlüsselzeit sollte gleich oder später als die jüngste Wertzeit dieses Benutzers sein. Liegt die Schlüsselzeit weit nach allen Werten, wurde danach möglicherweise ein Eintrag gelöscht oder überschrieben – siehe BAM-Anti-Forensik.
- Eine Untergrenze dafür, wann der Hive für diesen Benutzer zuletzt aktualisiert wurde.
Unser Tool zeigt sie als „Letzter Schreibzugriff des SID-Schlüssels“ im Detailbereich und exportiert sie als SidKeyLastWriteUtc.
Relevante Felder auf Hive-Ebene
Einige Felder des Basisblocks beeinflussen, wie sehr man den Werten trauen kann (libregf):
| Offset | Feld | Warum es für BAM zählt |
|---|---|---|
| 0 | Signatur regf | Bestätigt, dass es überhaupt ein Hive ist |
| 4 / 8 | Primäre / sekundäre Sequenznummer | Unterschiedlich = Dirty Hive: jüngste BAM-Schreibvorgänge können in den Protokollen liegen |
| 12 | FILETIME des letzten Schreibens | Wann die Hauptdatei zuletzt geschrieben wurde |
| 48 | Eingebetteter Dateiname | Unterscheidet SYSTEM von SOFTWARE, SAM … bei umbenannten Dateien |
Wie der Parser das abbildet
| Ausgabespalte | Quelle |
|---|---|
LastExecutionUtc | Erste 8 Bytes der Wertdaten, als ISO-8601 mit 100 ns |
FileTime | Derselbe Wert, roh dezimal |
Program | Dateiname oder Paketname ohne Herausgeber-Hash |
Path, Volume | Wertname; HarddiskVolumeN, falls vorhanden |
SID, User | Schlüsselname; Konto aus der ProfileList oder Bezeichnung einer bekannten SID |
Service, ControlSet, ActiveControlSet, LegacyLayout | Wo im Hive der Schlüssel gefunden wurde |
SidKeyLastWriteUtc | Zeitstempel des Schlüsselknotens |
DataHex | Vollständige Wertdaten |
Ziehen Sie einen Hive auf den BAM/DAM Parser und öffnen Sie den Detailbereich einer beliebigen Zeile, um all diese Felder nebeneinander zu sehen. Für dieselbe Übung mit anderen Registry-Artefakten deckt Registry Parser den übrigen Hive ab.
Quellen
- Maxim Suhanov, BAM internals.
- Microsoft Learn, FILETIME.
- Maxim Suhanov, Windows registry file format specification; Joachim Metz, libregf-Dokumentation.