Skip to content

Formato de los valores BAM: FILETIME, rutas e internos

Un valor de registro BAM byte a byte: el REG_BINARY de 24 bytes, el FILETIME, rutas de dispositivo o nombres de paquete, Version y SequenceNumber.

Publicado el 7 min de lectura

TL;DR. Cada valor BAM sigue el esquema nombre = ejecutable, datos = REG_BINARY. Los primeros 8 bytes de los datos son un FILETIME little-endian (intervalos de 100 ns desde el 1601-01-01 UTC); en las compilaciones estudiadas los datos miden 24 bytes y los 16 restantes no hacen falta para leer la hora. Los nombres de valor son rutas de dispositivo NT (\Device\HarddiskVolume3\…) o nombres de familia de paquete. Version y SequenceNumber son valores de control, no programas. La hora de última escritura de la propia clave SID es una marca de tiempo extra que viene gratis.

Si solo lees BAM a través de una herramienta, este artículo te cuenta qué hace esa herramienta y dónde puede equivocarse. Para el contexto: la guía completa de BAM/DAM y dónde está la clave BAM.

Anatomía de una clave SID

Una clave bam\State\UserSettings\<SID> típica tiene este aspecto (datos de ejemplo ficticios del sitio):

Nombre del valorTipoDatos (hex)
VersionREG_DWORD01 00 00 00
SequenceNumberREG_DWORD76 00 00 00
\Device\HarddiskVolume3\Users\alice\Downloads\Invoice_2026-0914.pdf.exeREG_BINARY80 0d 7c 1d 29 44 dd 01 + 16 bytes
MSTeams_8wekyb3d8bbweREG_BINARY24 bytes

Tres tipos de valor, tres reglas:

  1. DWORD de control — Version y SequenceNumber. Ignóralos al enumerar programas. Su semántica no está documentada públicamente; cualquier interpretación (por ejemplo, que SequenceNumber crece con cada actualización) es una hipótesis que debes probar en tu propio sistema de referencia.
  2. Entradas de ejecutables — REG_BINARY, el nombre es una ruta y los datos tienen al menos 8 bytes.
  3. Todo lo demás — un valor que no es REG_BINARY o que mide menos de 8 bytes no es un registro BAM. Un analizador robusto lo ignora en lugar de fallar. El nuestro hace exactamente eso, y notifica los valores ilegibles como avisos en lugar de descartarlos en silencio.

Decodificar el FILETIME

Un FILETIME es un contador de 64 bits de intervalos de 100 nanosegundos desde el 1 de enero de 1601 UTC (Microsoft Learn). Se guarda en little-endian, así que lee los bytes de derecha a izquierda:

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

Dos cosas que conviene tener presentes:

  • Es UTC. El registro no guarda la zona horaria del equipo en el valor. La colmena SYSTEM sí registra la zona configurada (Control\TimeZoneInformation\TimeZoneKeyName), que nuestra herramienta muestra en la cabecera para razonar sobre la hora local. El botón «Local» de la herramienta convierte a la zona horaria de tu navegador, no a la del equipo investigado.
  • Precisión. El FILETIME tiene una resolución de 100 ns. Date en JavaScript solo llega a milisegundos, así que las herramientas web que convierten con Date redondean. El BAM/DAM Parser conserva los siete decimales en la vista UTC y exporta el FILETIME en bruto como cadena decimal (un entero de 64 bits no cabe sin pérdida en un número JSON).

Qué evento marca la hora

El análisis de bam.sys de Maxim Suhanov muestra que la marca de tiempo se actualiza tanto al crearse el proceso como al terminar (BAM internals). Por tanto, el valor es el más reciente de esos eventos que BAM llegó a guardar. Para programas que estuvieron mucho tiempo abiertos, en los informes es preferible hablar de «última actividad registrada», y recurrir a Prefetch o a los registros de creación de procesos si necesitas la hora de inicio.

Los 16 bytes restantes

En las compilaciones de Windows 10 que examinó Suhanov, los valores BAM miden 24 bytes: el FILETIME y 16 bytes más. Su análisis relaciona uno de los DWORD finales con el estado de moderación (si el usuario dejó que Windows gestionara la actividad en segundo plano o cambió la opción para esa aplicación) y señala que las entradas con un estado distinto del predeterminado no se ven afectadas por la limpieza por antigüedad (fuente). Más allá de eso, la estructura no está documentada públicamente.

Consecuencias prácticas:

  • No supongas un tamaño fijo de 24 bytes; lee los 8 primeros y conserva el resto.
  • Guarda los bytes en bruto en tu exportación. Nuestra herramienta muestra los datos completos en el panel de detalle («Datos sin procesar») y en la columna CSV DataHex, para que puedas volver sobre los bytes finales si aparece investigación nueva.

Nombres de valor: rutas de dispositivo y paquetes

Rutas de dispositivo NT

La mayoría de los nombres tienen la forma \Device\HarddiskVolume3\Windows\System32\cmd.exe. Es la ruta de dispositivo NT del kernel: el objeto de volumen y luego la ruta en ese volumen. No hay letra de unidad porque las letras son una asignación del modo usuario (Microsoft Learn: definir un nombre de dispositivo MS-DOS).

Para asociar HarddiskVolumeN a una letra sin conexión:

  • Casi siempre, el volumen del sistema es el que contiene las entradas \Windows\System32\…; todo lo que tenga ese número de volumen está en C:.
  • Para los demás números, cruza con artefactos que registren ambas formas — por ejemplo los archivos Prefetch, que guardan las rutas de dispositivo y los números de serie de los volúmenes (formato libscca). También ayuda la salida de una recopilación en vivo que haya anotado a la vez la ruta de dispositivo y la letra. (La clave MountedDevices de la misma colmena asocia letras con identificadores de volumen, no con números HarddiskVolumeN, así que solo ayuda en parte.)
  • Los números de volumen los asigna el sistema en ejecución y no son un identificador estable entre equipos, ni siquiera necesariamente tras cambios de configuración en el mismo equipo.

Nombres de familia de paquete

Las aplicaciones empaquetadas (Store, MSIX) aparecen por su nombre de familia de paquete: Microsoft.WindowsCalculator_8wekyb3d8bbwe. La parte tras el guion bajo es el hash del identificador del editor y la parte anterior es el nombre del paquete (Microsoft Learn: identidad de paquete). No hay ruta ni nombre de ejecutable. Nuestro analizador muestra el nombre del paquete como programa, marca la fila como aplicación y no le aplica las heurísticas de ruta.

Otras formas

A veces aparece un nombre que no es ni una cosa ni otra — por ejemplo, una ruta sin el prefijo \Device\. No lo descartes: la herramienta lo clasifica como «otro» y decodifica igualmente la marca de tiempo.

La hora de última escritura de la clave SID

Toda clave de registro tiene un FILETIME de última escritura en su nodo de clave (especificación msuhanov/regf). En una clave SID de BAM, esa hora cambia cada vez que cambia cualquier valor que contenga. Te aporta:

  • Una comprobación de coherencia: la hora de la clave debe ser igual o posterior a la del valor más reciente de ese usuario. Una hora de clave muy posterior a todos los valores sugiere que después se borró o reescribió una entrada — ver antiforense en BAM.
  • Un límite inferior de la última actualización de la colmena para ese usuario.

Nuestra herramienta la muestra como «Última escritura de la clave SID» en el panel de detalle y la exporta como SidKeyLastWriteUtc.

Los campos de la colmena que importan

Algunos campos del bloque base cambian la confianza que merecen los valores (libregf):

OffsetCampoPor qué importa para BAM
0Firma regfConfirma que es una colmena
4 / 8Números de secuencia primario / secundarioSi difieren = colmena dirty: puede haber escrituras BAM recientes en los registros
12FILETIME de última escrituraCuándo se escribió por última vez el archivo principal
48Nombre de archivo incrustadoDistingue SYSTEM de SOFTWARE, SAM… cuando los archivos se han renombrado

Cómo lo traduce el analizador

Columna de salidaOrigen
LastExecutionUtcPrimeros 8 bytes de los datos, en ISO-8601 con 100 ns
FileTimeEl mismo valor, en decimal bruto
ProgramNombre del archivo, o nombre del paquete sin el hash del editor
Path, VolumeNombre del valor; HarddiskVolumeN cuando existe
SID, UserNombre de la clave; cuenta según la ProfileList o etiqueta de SID conocido
Service, ControlSet, ActiveControlSet, LegacyLayoutDónde se encontró la clave en la colmena
SidKeyLastWriteUtcMarca de tiempo del nodo de clave
DataHexDatos completos del valor

Suelta una colmena en el BAM/DAM Parser y abre el panel de detalle de cualquier fila para ver todos estos campos juntos. Para el mismo ejercicio con otros artefactos del registro, Registry Parser cubre el resto de la colmena.

Fuentes

Artículos relacionados