Skip to content

Formato de archivo SEGB de Biome: referencia v1 y v2

Referencia byte a byte de SEGB v1 y v2 de Biome: cabeceras, trailer, estados de registro, CRC32, alineación, horas en el nombre y campos protobuf por flujo.

Publicado el 11 min de lectura

Resumen. Un flujo (stream) de Biome es una carpeta de archivos SEGB. v1 tiene una cabecera de 56 bytes con SEGB en los bytes 52–55 y el desplazamiento de fin de datos en los bytes 0–3; cada registro tiene una cabecera de 32 bytes (longitud, estado, dos marcas de tiempo, CRC32, desconocido) y se rellena hasta un múltiplo de 8 bytes. v2 empieza por SEGB, un número de entradas y una hora de creación, e indexa sus registros mediante un trailer de entradas de 16 bytes (desplazamiento final, estado, hora) situado al final del archivo; cada registro es un CRC32, un int32 desconocido y el payload, alineado a 4 bytes. Los estados son 1 escrito, 3 eliminado, 4 vacío. Los payloads son protocol buffers sin esquema publicado. Apple no documenta nada de esto.

Esta referencia sigue a ccl-segb de CCL Forensics (licencia MIT), que atribuye a Cellebrite la investigación sobre la estructura v2, y es lo que implementa KnowledgeC Parser. Para saber dónde están estos archivos y por qué importan, empiece por la guía de análisis forense de knowledgeC.db y por knowledgeC frente a Biome.

Dónde están los archivos SEGB

~/Library/Biome/streams/restricted/<Stream>/local/<file>
~/Library/Biome/streams/public/<Stream>/local/<file>
~/Library/Biome/streams/restricted/<Stream>/remote/<device UUID>/<file>
~/Library/Biome/streams/restricted/<Stream>/local/tombstone/<file>
/private/var/db/biome/streams/...

El nombre del flujo (App.InFocus, App.WebUsage, ...) no se guarda en el archivo: lo da la carpeta. Conserve la estructura de carpetas al recolectar, o perderá el nombre del flujo, la distinción entre local y remote y el UUID del dispositivo. Los archivos de tombstone/ están caducados (tombstone de Biome).

Todos los enteros que siguen son little-endian. Las horas están en tiempo absoluto de Mac, guardadas como doubles de 64 bits: segundos desde el 2001-01-01 00:00:00 UTC. Sume 978307200 para obtener tiempo Unix.

SEGB v1

Cabecera de archivo (56 bytes)

DesplazamientoTamañoTipoCampo
0x004uint32Desplazamiento de fin de datos (absoluto, desde el inicio del archivo)
0x0448No documentado
0x344ASCIIFirma SEGB (bytes 52–55)

Los registros empiezan en el byte 56 (0x38) y llegan hasta el desplazamiento de fin de datos. Si ese desplazamiento apunta más allá del final del archivo, la copia está truncada.

Cabecera de registro (32 bytes)

Desplazamiento en el registroTamañoTipoCampo
0x004int32Longitud del payload
0x044int32Estado
0x088doubletimestamp1 (tiempo absoluto de Mac)
0x108doubletimestamp2 (tiempo absoluto de Mac)
0x184uint32CRC32 del payload
0x1C4int32Desconocido
0x20longitudbytesPayload

Después del payload, el siguiente registro empieza en el siguiente múltiplo de 8 contado desde el inicio del archivo. Los nombres timestamp1 y timestamp2 son descriptivos: las fuentes públicas no les asignan un significado fijo en todos los flujos, así que conviene informar de ambos valores en bruto en lugar de etiquetar uno como "inicio" y otro como "fin".

SEGB v2

Cabecera de archivo (32 bytes)

DesplazamientoTamañoTipoCampo
0x004ASCIIFirma SEGB
0x044int32Número de entradas (entradas del trailer)
0x088doubleHora de creación (tiempo absoluto de Mac)
0x1016No documentado

Trailer (16 bytes por entrada, al final del archivo)

El trailer ocupa los últimos count × 16 bytes del archivo.

Desplazamiento en la entradaTamañoTipoCampo
0x004int32Desplazamiento final del registro, relativo al byte 32
0x044int32Estado
0x088doubleHora (tiempo absoluto de Mac)

Registros

Los registros empiezan en el byte 32. Cada uno se compone de:

Desplazamiento en el registroTamañoTipoCampo
0x004uint32CRC32 del payload
0x044int32Desconocido
0x08variablebytesPayload, hasta el desplazamiento final

Un registro v2 no tiene campo de longitud. Para leerlo, ordene las entradas del trailer por desplazamiento final, empiece en el byte 32 y lea hasta 32 + end offset. El siguiente registro empieza en el siguiente límite de 4 bytes. Como el estado y la hora están en el trailer, la cabecera de un registro v2 solo contiene el CRC y la palabra desconocida.

Desplazamientos finales compartidos

Dos entradas del trailer pueden tener el mismo desplazamiento final. El caso habitual es un registro escrito (estado 1) y eliminado más tarde (estado 3): ambas entradas apuntan a los mismos bytes, cada una con su propia hora. Un parser debe informar de las dos, sin tratar la segunda como un registro nuevo. KnowledgeC Parser muestra la entrada eliminada con el mismo payload y la marca como eliminada. También ignora las entradas del trailer con estado 0, que no hacen referencia a ningún dato.

Estados de registro y CRC

EstadoSignificadoQué hacer
1EscritoRegistro normal
3EliminadoEl payload puede seguir presente: decodifíquelo e infórmelo como eliminado
4Vacío / sin usarNo hay registro aprovechable

El CRC es el CRC-32 estándar tal como lo calcula zlib (zlib.crc32), solo sobre el payload. Una discrepancia indica un registro escrito a medias o dañado, o una copia tomada mientras se escribía el archivo. Conserve esos registros pero márquelos; no los descarte sin avisar.

Un ejemplo v2 comentado

El archivo siguiente se construyó para este artículo con la estructura descrita: un registro App.InFocus que indica que Terminal pasó a primer plano. Es sintético, y aquí los bytes no documentados de la cabecera valen cero.

00000000  53 45 47 42 01 00 00 00 00 00 00 a6 c0 2b c8 41   SEGB.........+.A
00000010  00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00   ................
00000020  67 88 af ff 00 00 00 00 18 01 21 00 00 00 80 ff   g.........!.....
00000030  2b c8 41 32 12 63 6f 6d 2e 61 70 70 6c 65 2e 54   +.A2.com.apple.T
00000040  65 72 6d 69 6e 61 6c 00 27 00 00 00 01 00 00 00   erminal.'.......
00000050  66 66 66 80 ff 2b c8 41                           fff..+.A
BytesValorSignificado
0x00–0x03SEGBFirma v2
0x04–0x0701 00 00 001 entrada en el trailer
0x08–0x0Fdouble 811041100.0Creado el 2026-09-14 01:11:40 UTC
0x10–0x1FcerosNo documentado
0x20–0x230xffaf8867CRC32 del payload
0x24–0x270Desconocido
0x28–0x4631 bytesPayload protobuf (abajo)
0x4700Relleno hasta un límite de 4 bytes
0x48–0x4B27 00 00 00Desplazamiento final 39: 32 + 39 = 0x47, el final del payload
0x4C–0x4F01 00 00 00Estado 1, escrito
0x50–0x57double 811073280.82026-09-14 10:08:00.8 UTC

El payload se decodifica así:

BytesEtiquetaCampoValor
18 01campo 3, varintestado1 = en primer plano
21 + 8 bytescampo 4, 64 bitshora811073280.0 = 10:08:00 UTC
32 12 + 18 bytescampo 6, delimitado por longitudbundle IDcom.apple.Terminal

Un archivo real de este tipo llevaría como nombre su hora de creación en microsegundos, aquí 811041100000000.

Horas en el nombre de archivo

Los nombres de los archivos SEGB son enteros. mac_apt los interpreta como tiempo Cocoa en microsegundos, lo que da una hora de creación aproximada del archivo:

date -u -r $(( 811041100000000 / 1000000 + 978307200 ))
# Mon Sep 14 01:11:40 UTC 2026

Trátela como un indicio a nivel de archivo. Las horas de los eventos proceden de los registros y, en algunos flujos, del payload.

Payloads protobuf

Los tipos de wire en resumen

Un mensaje protobuf es una secuencia de campos. Cada uno empieza por una clave varint: field number << 3 | wire type (guía de codificación).

Tipo de wireCodificaciónContenido habitual
0VarintEnteros, booleanos, enums
18 bytesdouble, fixed64
2Longitud varint + bytesCadenas, bytes, mensajes anidados
54 bytesfloat, fixed32

Los tipos de wire 3 y 4 (grupos) están obsoletos y no se esperan aquí.

Por qué la decodificación sin esquema es ambigua

Apple no publica archivos .proto para Biome. Sin esquema:

  • un campo delimitado por longitud puede ser una cadena, bytes en bruto o un mensaje anidado, y cadenas cortas como los bundle IDs a veces se interpretan como mensajes válidos;
  • un campo de 8 bytes puede ser un double o un entero;
  • un varint puede ser un valor con signo, sin signo, codificado en zigzag o booleano.

KnowledgeC Parser prueba primero texto UTF-8 imprimible, después un mensaje anidado que consuma todos los bytes y, por último, bytes en bruto. Muestra los valores de 8 bytes como doubles, con una fecha cuando el valor es un tiempo absoluto de Mac plausible. Algunos payloads incluyen property lists binarias, que se muestran como tales. Los números de campo se conservan siempre, para que pueda contrastar cualquier interpretación con otra herramienta.

Números de campo por flujo

Estos números proceden de la ingeniería inversa de la comunidad, en el plugin BIOME de mac_apt y en iLEAPP. No son documentación de Apple; valídelos con datos de prueba de la misma compilación del sistema operativo antes de apoyarse en ellos.

FlujoCampoSignificadoFuente
App.InFocus3Estado: 1 en primer plano, 0 fuera de primer planomac_apt
App.InFocus4Hora (double)iLEAPP
App.InFocus6Bundle IDmac_apt
App.InFocus9, 10Cadenas de versiónmac_apt
App.WebUsage2HoraiLEAPP
App.WebUsage4 / 5 / 6URL / dominio / bundle IDmac_apt
Safari.*1Dominiomac_apt
ScreenTime.AppUsage1 / 3Estado / bundle IDmac_apt
Notification.Usage4 / 8 / 9App / título / subtítulomac_apt
Device.Wireless.WiFi1 / 2SSID / estadomac_apt
Device.Wireless.Bluetooth1 / 2 / 3 / 4Dirección / nombre / ID de producto / estadomac_apt
SystemSettings.SearchTerms1Término de búsquedamac_apt

Los registros de App.InFocus son eventos, no intervalos: a un registro "en primer plano" le sigue más tarde un registro "fuera de primer plano" de la misma app. KnowledgeC Parser los empareja en intervalos (mismo usuario, mismo dispositivo, mismo bundle ID, en un plazo de 24 horas) y deja los registros sin pareja como eventos sueltos.

Lo que se desconoce

  • Los 48 bytes no documentados de la cabecera v1, los 16 de la cabecera v2 y el int32 "desconocido" de cada registro.
  • Un significado fijo de timestamp1 y timestamp2 de v1 en todos los flujos.
  • Los campos que no figuran en la tabla anterior, y todos los campos de los flujos sin decodificador público. App.MenuItem, documentado por Unit 42 en macOS Tahoe 26, no tiene un mapa de campos público: KnowledgeC Parser lo decodifica sin esquema y muestra los números de campo en bruto.
  • La versión de macOS en la que v2 sustituyó a v1.

Cuando un informe dependa de alguno de estos puntos, indíquelo y muestre el valor en bruto.

Herramientas que leen SEGB

HerramientaQué hace
ccl-segbLector de referencia para archivos v1 y v2 individuales, registros en bruto
Plugin BIOME de mac_aptLee los flujos desde una imagen o una carpeta y decodifica los flujos anteriores
iLEAPPFlujos de Biome de iOS
KnowledgeC Parserv1 y v2 en el navegador, con estados, comprobación de CRC, origen remote y tombstone, y una cronología combinada con knowledgeC.db

Preguntas frecuentes

¿Documenta Apple el formato SEGB?

No. Las estructuras de SEGB v1 y v2 proceden de la ingeniería inversa de la comunidad, implementada en ccl-segb (CCL Forensics), que atribuye parte de la investigación a Cellebrite. El significado de los campos del payload procede de mac_apt y de iLEAPP. Todo lo que esas fuentes no cubren debe tratarse como desconocido.

¿Cómo se distingue SEGB v1 de v2?

Busque la firma SEGB. En v1 está en los bytes 52 a 55, al final de una cabecera de 56 bytes. En v2 son los cuatro primeros bytes del archivo, al principio de una cabecera de 32 bytes.

¿Un registro SEGB eliminado sigue conteniendo datos?

A menudo, sí. El estado 3 marca un registro como eliminado, pero el payload puede seguir en el archivo. En v2, una entrada eliminada puede compartir su desplazamiento final con una escrita, de modo que ambas apuntan a los mismos bytes. Informe de esos registros como eliminados, no como actividad vigente.

¿Qué versión de macOS pasó de SEGB v1 a v2?

Ese límite no está documentado públicamente para macOS. En iOS, se indica v1 para iOS 14 a 16 y v2 a partir de iOS 17. Los parsers detectan la versión a partir de la cabecera, así que no es necesario conocerla de antemano.

Artículos relacionados

Artículos relacionados

Paso a paso: cargue knowledgeC.db con su -wal y los flujos SEGB de Biome en un parser gratuito en el navegador, fije un rango, revise sesiones y exporte.
Qué registra knowledgeC.db en macOS, dónde está, cómo funcionan ZOBJECT y sus flujos, cómo convertir sus marcas de tiempo y qué no demuestran los datos.
¿knowledgeC.db o Biome? En qué se diferencian los dos almacenes de actividad de macOS, qué flujo de Biome equivale a cada flujo de knowledgeC y qué esperar hoy.