Skip to content

Formato de archivo FSEvents: páginas 1SLD, 2SLD y 3SLD

Estructura en disco de los logs .fseventsd de macOS: archivos gzip, cabeceras de página DLS, campos por versión y cómo tratar datos truncados o dañados.

Publicado el 5 min de lectura

En resumen. Cada log de .fseventsd es un archivo gzip. Una vez descomprimido, es una secuencia de páginas; cada página empieza con una cabecera de 12 bytes (1SLD, 2SLD o 3SLD, cuatro bytes desconocidos y un tamaño de página en little-endian) seguida de registros: una ruta terminada en NUL y 12, 20 o 24 bytes de campos fijos. Esta estructura coincide con lo que implementan FSEventsParser (Nicole Ibrahim, Apache-2.0) y mac_apt (ydkhatri, MIT); Apple no la documenta.

La carpeta

.fseventsd/
  0000000012a44181      gzip log file; name = an event ID in hex
  0000000012a4439d
  fseventsd-uuid        text: the stream UUID
  no_log                optional, empty: logging disabled

Los nombres de los logs tienen 16 dígitos hexadecimales. FSEventsParser interpreta el nombre como el último event ID del archivo; el FSEvents Parser de este sitio contrasta el nombre con los IDs que contiene y marca los archivos cuyo nombre queda fuera de su propio rango (archivos renombrados o fuera de lugar).

Capa gzip

Cada log es un flujo gzip convencional (RFC 1952). Algunos archivos contienen más de un miembro gzip, y las copias de un log que aún se estaba escribiendo terminan antes de tiempo. Un lector robusto:

  • descomprime un miembro tras otro;
  • conserva todos los bytes que haya podido descomprimir cuando el flujo está cortado o dañado, en lugar de rechazar el archivo;
  • comprueba el CRC-32 y el tamaño del trailer, e informa de cualquier discrepancia sin descartar datos;
  • acepta datos ya descomprimidos por otra herramienta (empiezan directamente con un magic de página).

Cabecera de página

OffsetTamañoCampo
04Magic, almacenado como los bytes ASCII 1SLD, 2SLD o 3SLD
44Desconocido
84Tamaño de página, u32 little-endian, contado desde el inicio de la cabecera

Las páginas se suceden hasta el final de los datos descomprimidos. Algunos artículos las llaman "DLS1/DLS2" porque eso es lo que se lee al interpretar el magic como entero little-endian; los bytes en disco son 1SLD. Consulta página DLS.

Registros

Tras la cabecera, los registros se empaquetan uno detrás de otro hasta alcanzar el tamaño de página:

Campo1SLD2SLD3SLD
Ruta, UTF-8, terminada en NULsísísí
Event ID, u64 LE+0+0+0
Flags, u32 LE+8+8+8
Node ID, u64 LE+12+12
Extra, 4 bytes+20
Parte fija tras la ruta12 bytes20 bytes24 bytes
  • 2SLD apareció con macOS 10.13 High Sierra y 3SLD con macOS 14 Sonoma (según las notas de implementación de FSEventsParser). Un volumen que ha pasado por varias actualizaciones puede contener varias versiones.
  • La ruta es relativa a la raíz del volumen, tal como era en el momento del registro: Users/dana/Library/LaunchAgents/com.example.updater.plist, no /System/Volumes/Data/Users/…. Pueden aparecer rutas vacías.
  • FSEventsParser decodifica el campo adicional de 3SLD como un ID de usuario de 32 bits con signo (fs_uid), mientras que mac_apt lo deja sin nombre. Apple no lo ha documentado; trata cualquier interpretación como una hipótesis y compruébala con datos conocidos.
  • Los flags se explican en la referencia de flags.

Análisis defensivo

Las adquisiciones reales contienen logs truncados, recuperados mediante carving o dañados. Estas son las reglas que sigue el parser de este sitio:

  1. Una página cuyo tamaño declarado sobrepasa los datos disponibles se analiza hasta el final de los datos, y se informa de ello.
  2. Un registro cuya ruta no tiene NUL, o cuyos campos fijos no caben, se descarta y se informa; los registros anteriores se conservan.
  3. Los bytes a cero tras el último registro o página son slack, no un error.
  4. Los bytes que no son un magic de página se omiten hasta el siguiente 1SLD/2SLD/3SLD, y se informa del número de bytes omitidos.
  5. Los registros con combinaciones de flags imposibles (File y Folder a la vez, Symlink y Hard link a la vez) se contabilizan como indicio de daño, igual que hace FSEventsParser con los datos recuperados mediante carving.
  6. Las rutas que no son UTF-8 válido se muestran con caracteres de sustitución y se contabilizan.

Marcas de tiempo

El formato no incluye ninguna. Cómo fechar los registros a partir de las fechas de modificación de los archivos de log se explica en datación de registros FSEvents.

Preguntas frecuentes

¿Qué diferencia hay entre 1SLD, 2SLD y 3SLD?

El tamaño del registro. Los registros 1SLD contienen una ruta, un event ID de 8 bytes y flags de 4 bytes; 2SLD añade un node ID de 8 bytes (macOS 10.13 y posteriores); 3SLD añade 4 bytes más (macOS 14 y posteriores).

¿Los logs de FSEvents están en little-endian?

Sí. El tamaño de página, el event ID, los flags, el node ID y el campo adicional se almacenan en little-endian. Algunas herramientas leen los flags en big-endian y usan constantes con los bytes invertidos, lo que da los mismos nombres.

Artículos relacionados