APFS: Algoritmo de recuperación de datos del sistema de archivos y su estructura

ApFS ofrece la capacidad de restaurar estados específicos del sistema de archivos, incluidas versiones antiguas o eliminadas de archivos. El superbloque de contenedores contiene un enlace a la estructura del punto de control. El punto de control se refiere al superbloque anterior del contenedor, que contiene información en el estado anterior del sistema de archivos. Por lo tanto, es posible restaurar varios estados antiguos analizando la cadena del superbloque de contenedores.

APFS: Algoritmo de recuperación de datos del sistema de archivos y su estructura

Ir a ver
🍏 TOP programas para recuperar datos de discos APFS o cómo recuperar el disco Apple MacOs en Windows

🍏 TOP programas para recuperar datos de discos APFS o cómo recuperar el disco Apple MacOs en Windows

Contenedores y Volumen

La estructura del sistema de archivos APFS tiene la forma de un árbol b, donde el directorio de datos raíz son las hojas de este árbol. Todas las ramas almacenan solo enlaces al siguiente nodo hasta que llegan a las hojas. El sistema de archivos utiliza contenedores como ubicaciones de almacenamiento. Estos contenedores pueden contener varios volúmenes. También es el objeto principal para almacenar datos. Para un volumen, el tamaño del contenedor debe ser superior a 512 MB, para dos volúmenes, más de 1024 MB, etc.

La siguiente figura muestra la estructura del sistema de archivos “ApFS”.

ApFS

Cada elemento de esta estructura (excepto el archivo de asignación) comienza con un encabezado de bloque de 32 bytes que contiene información general sobre el bloque. El siguiente es el cuerpo del sistema de archivos. Consta de los siguientes elementos:

  • 0x01: Superbloque del contenedor (Container Superblock)
  • 0x02: Nodo (Node)
  • 0x05: Administrador de Espacio (Space manager)
  • 0x07: Ubicación de Archivo (Allocation Info File)
  • 0x0C: Punto de Control (Checkpoint)
  • 0x0D: Superbloque de volumen (Volume Superblock)

Los contenedores suelen ser exactamente iguales a las entradas de una tabla de particiones GUID (GPT). Tienen su propio esquema de asignación de disco y protección contra fallas. Cada contenedor contiene uno o más volúmenes, cada uno con su propio espacio de nombres, conjunto de archivos y directorios.

El sistema de archivos «ApFS» no es compatible directamente con el programa «RAID», pero se puede utilizar con volúmenes RAID de Apple para admitir la creación de bandas (RAID 0), duplicación (RAID 1) y empalme (JBOD).

Con un índice de 64 bits los volúmenes «ApFS» admite hasta 9 quintillones (1018) de archivos.

El nuevo sistema de archivos de Apple usa nanosegundos para establecer marcas de tiempo. En HFS +, las marcas de tiempo se han establecido en el segundo más cercano. Esto reducirá la cantidad de fallas durante las transferencias de datos y otras operaciones de archivos.

«ApFS» tiene un cifrado incorporado y utiliza AES-XTS o AES-CBC, según el dispositivo. El usuario puede utilizar varias claves de cifrado para mantener la seguridad de los datos incluso en caso de «Ataque cibernético físico» de los medios.

Esta no es una lista completa de las innovaciones que posee «ApFS».

Las secciones formateadas en «ApFS», no son reconocidas por OS X 10.11 Yosemite o sistemas operativos anteriores.

Block Header (Encabezado de bloque)

Cada estructura del sistema de archivos en «ApFS» comienza con un encabezado de bloque. Y el encabezado en sí comienza con una suma de comprobación. Otra información en el encabezado incluye la versión de copia en escritura del bloque, el ID del bloque y su tipo.

Parcialidad Tamaño Tipo ID
0 8 uint64 Suma de control (checksum)
8 8 uint64 Identificador (block_id)
16 8 uint64 Versión (version)
24 2 uint16 Tipo de bloque (block_type)
26 2 uint16 Banderas (flags)
28 4 uint32 Relleno (padding)

De la tabla podemos ver que 1uint = 1 bit, 8 bits = 1 byte, de eso uint64 = 8, uint32 = 4 y uint16 = 2 bytes.

Container Superblock

Superbloque del contenedor (Container Superblock) – es el punto de entrada al sistema de archivos. Debido a la estructura del sistema de archivos con contenedores y volúmenes de disquete, la distribución debe manejarse a nivel de contenedor. El superbloque contenedor contiene información sobre el tamaño del bloque, su número y punteros en el administrador de espacio para esta tarea. Además, el superbloque almacena ID de bloque para todos los volúmenes. Para asignar identificadores de bloque a bloques de desplazamiento, se almacena un puntero al mapa de bloques del árbol B. Este árbol contiene entradas para cada volumen con su ID y compensación. El superbloque de contenedores es el nivel más alto en el sistema de archivos.

Tiene el siguiente tipo:

Parcialidad (HEX) Tipo Id Descripción
0 tApFS_COH Header Encabezado del objeto contenedor (Container Object Header)
20 uint32 MagicNumber (NXSB) El valor a verificar para leer el Superbloque del contenedor.
24 uint32 BlockSize Tamaño del bloque de contenedor (en bytes)
28 uint64 BlocksCount Número de bloques de contenedores
30 uint64 Features Mapa de bits de las principales funciones del contenedor
38 uint64 ReadOnlyFeatures Mapa de bits de las funciones básicas del contenedor (solo de lectura)
40 uint64 IncompatibleFeatures Mapa de bits de las principales funciones incompatibles del contenedor
48 tApFS_Uuid Uuid UUID del contenedor
58 tApFS_Ident NextIdent Siguiente identificador para nuevo objeto lógico o virtual
60 tApFS_Transaction NextTransaction Siguiente número de transacción
68 uint32 DescriptorBlocks Número de bloques utilizados por el descriptor
6C uint32 DataBlocks Número de bloques usados ​​por datos
70 tApFS_Address DescriptorBase Dirección base de un descriptor o identificador de un objeto físico con un árbol de direcciones
78 int32 DataBase Dirección de base de datos o identificador de un objeto físico con un árbol de direcciones
80 uint32 DescriptorNext Siguiente índice de descriptor
84 uint32 DataNext Siguiente índice de datos
88 uint32 DescriptorIndex El índice del primer elemento válido en el segmento descriptor.
8C uint32 DescriptorLength El número de bloques en el segmento descriptor utilizado por el superbloque
90 uint32 DataIndex El índice del primer elemento válido en el segmento de datos
94 uint32 DataLength Número de bloques en el segmento de datos utilizados por el superbloque
98 tApFS_Ident SpaceManagerIdent Administrador de espacio de ID de entidad
A0 tApFS_Ident ObjectsMapIdent El identificador de objeto físico del mapa de objetos del contenedor
A8 tApFS_Ident ReaperIdent Identificador de entidad
B0 uint32 ReservedForTesting
B4 uint32 MaximumVolumes El número máximo posible de volúmenes en un contenedor
B8 tApFS_Ident VolumesIdents[100] Volumen de matriz de identificadores de objetos virtuales
3D8 uint64 Counters[32] Matriz de contadores que almacenan información sobre el contenedor
4D8 tApFS_BlockRange BlockedOutOfRange Rango físico de bloques que no se pueden usar
4E8 tApFS_Ident MappingTreeIdent El identificador de un objeto físico en el árbol que se usa para rastrear los objetos que se mueven desde el almacenamiento bloqueado.
4F0 uint64 OtherFlags Mapa de otras funciones de contenedor
4F8 tApFS_Address JumpstartEFI Identificación de un objeto físico con datos del controlador EFI
500 tApFS_Uuid FusionUuid UUID de contenedor de Fusion, o cero para contenedores que no son de Fusion
510 tApFS_BlockRange KeyLocker Ubicación de la marca clave del contenedor
520 uint64 EphemeralInfo[4] Matriz de campos utilizados para manipular datos lógicos
540 tApFS_Ident ReservedForTesting
548 tApFS_Ident FusionMidleTreeIdent Solo para dispositivos vinculados
550 tApFS_Ident FusionWriteBackIdent Solo para dispositivos vinculados
558 tApFS_BlockRange FusionWriteBackBlocks Bloques utilizados para el área de caché

Con definición de tipo:

uint8  tApFS_Uuid;
uint64 tApFS_Ident;
uint64 tApFS_Transaction;
int64  tApFS_Address;
uint64 tApFS_BTreeKey;

и

struct tApFS_BlockRange
{
    tApFS_Address       First;          // Primer bloque
    uint64              Count;          // Cantidad de bloques
}
struct tApFS_COH
{
    uint64              CheckSum;       // Suma de control del bloque
    tApFS_Ident         Ident;          // Identificador
    tApFS_Transaction   Transaction;    // Object change transaction number
    uint16              Type;           // Tipo de objeto
    uint16              Flags;          // Bandera de objeto
    uint32              SubType;        // Subtipo de objeto
};

con una lista de tipos de objetos:

enum eApFS_ObjectType
{
    eApFS_ObjectType_01_SuperBlock            = 0x0001, //Superbloque del contenedor
    eApFS_ObjectType_02_BTreeRoot             = 0x0002, // Árbol-B: nodal elemento
    eApFS_ObjectType_03_BTreeNode             = 0x0003, // Árbol-B: lista
    eApFS_ObjectType_05_SpaceManager          = 0x0005, // Administrador de espacio
    eApFS_ObjectType_06_SpaceManagerCAB       = 0x0006, // Administrador de espacio: dirección de segmentos
    eApFS_ObjectType_07_SpaceManagerCIB       = 0x0007, // Administrador de espacio: información de segmentos
    eApFS_ObjectType_08_SpaceManagerBitmap    = 0x0008, // Mapa de espacio libre utilizado por el Administrador de espacio
    eApFS_ObjectType_09_SpaceManagerFreeQueue = 0x0009, // Espacio libre utilizado por el administrador de espacio_ (llaves - _tApFS_09_SpaceManagerFreeQueue_Key_, significado - _tApFS_09_SpaceManagerFreeQueue_Value_)
    eApFS_ObjectType_0A_ExtentListTree        = 0x000A, // Árbol lista extensiones (llaves – Parcialidad del principio экстента_tApFS_Address_, significado – ubicación física de datos _tApFS_BlockRange_)
    eApFS_ObjectType_0B_ObjectsMap            = 0x000B, // Tipo – Mapa de objetos; subType – Árbol registros mapas de objetos (llaves - _tApFS_0B_ObjectsMap_Key_, significado - _tApFS_0B_ObjectsMap_Value_)
    eApFS_ObjectType_0C_CheckPointMap         = 0x000C, // Mapa de puntos de control (puntos de control)
    eApFS_ObjectType_0D_FileSystem            = 0x000D, // Sistema de archivos volumen
    eApFS_ObjectType_0E_FileSystemTree        = 0x000E, // Árbol sistema de archivos (llaves comienzan с _tApFS_BTreeKey_, describe Tipo и valor de la llave)
    eApFS_ObjectType_0F_BlockReferenceTree    = 0x000F, // Árbol enlace a bloques (llaves - _tApFS_BTreeKey_, valor - _tApFS_0F_BlockReferenceTree_Value_)
    eApFS_ObjectType_10_SnapshotMetaTree      = 0x0010, // Árbol instantáneas (llaves - _tApFS_BTreeKey_, valor - _tApFS_10_SnapshotMetaTree_Value_)
    eApFS_ObjectType_11_Reaper                = 0x0011, // Reaper
    eApFS_ObjectType_12_ReaperList            = 0x0012, // Reaper List
    eApFS_ObjectType_13_ObjectsMapSnapshot    = 0x0013, // Árbol instantáneas mapas objetos (llaves - _tApFS_Transaction_, valor - _tApFS_13_ObjectsMapSnapshot_Value_)
    eApFS_ObjectType_14_JumpStartEFI          = 0x0014, // EFI Cargador
    eApFS_ObjectType_15_FusionMiddleTree      = 0x0015, // Árbol dispositivos conectados para el seguimiento de bloques de discos duros, SSD en caché (llave - _tApFS_Address_, valor - _tApFS_15_FusionMiddleTree_Value_)
    eApFS_ObjectType_16_FusionWriteBack       = 0x0016, // Estado de caché respuesta de dispositivos conectados
    eApFS_ObjectType_17_FusionWriteBackList   = 0x0017, // Lista de caché respuesta de dispositivos conectados
    eApFS_ObjectType_18_EncryptionState       = 0x0018, // Cifrado
    eApFS_ObjectType_19_GeneralBitmap         = 0x0019, // General Bitmap
    eApFS_ObjectType_1A_GeneralBitmapTree     = 0x001A, // Árbol General Bitmap (keys - uint64, keys - uint64)
    eApFS_ObjectType_1B_GeneralBitmapBlock    = 0x001B, // Bloque General Bitmap
    eApFS_ObjectType_00_Invalid               = 0x0000, // No es válido como tipo o no está como subtipo
    eApFS_ObjectType_FF_Test                  = 0x00FF  // Reservado para pruebas (nunca se guarda en dispositivo)
    eApFS_ObjectType_FF_Test                  = 0x00FF  // Reservado para pruebas (nunca se guarda en dispositivo)
};

enum eApFS_ObjectFlag
{
    eApFS_ObjectFlag_Virtual         = 0x0000, // Objeto virtual
    eApFS_ObjectFlag_Ephemeral       = 0x8000, // Objeto lógico
    eApFS_ObjectFlag_Physical        = 0x4000, // Objeto físico
    eApFS_ObjectFlag_NoHeader        = 0x2000, // Objeto sin título _tApFS_ContainerObjectHeader_ (por ejemplo, mapa (bitmap) administrador de espacio)
    eApFS_ObjectFlag_Encrypted       = 0x1000, // Objeto cifrado
    eApFS_ObjectFlag_NonPersistent   = 0x0800, // Objeto con estas banderas nunca se guardaran en dispositivo
    eApFS_ObjectFlag_StorageTypeMask = 0xC000, // Битовая (bitmask) máscara para permiso a banderas de objetos de categoría
    eApFS_ObjectFlag_ValidMask       = 0xF800  // Bandera real de máscara de bits
};

struct tApFS_0B_ObjectsMap_Key
{
    tApFS_Ident       ObjectIdent; // Identificador de Objeto
    tApFS_Transaction Transaction; // Número de transacción
};

struct tApFS_0B_ObjectsMap_Value
{
    uint32       Flags;    // Bandera
    uint32       Size;     // tamaño objeto en bites (tamaño corto de bloque del contenedor)
    tApFS_Address Address; // Dirección del objeto
};

struct tApFS_09_SpaceManagerFreeQueue_Key
{
    tApFS_Transaction sfqk_xid;
    tApFS_Address     sfqk_paddr;
};

struct tApFS_09_SpaceManagerFreeQueue_Value
{
    uint64            sfq_count;
    tApFS_Ident       sfq_tree_oid;
    tApFS_Transaction sfq_oldest_xid;
    uint16            sfq_tree_node_limit;
    uint16            sfq_pad16;
    uint32            sfq_pad32;
    uint64            sfq_reserved;
};

struct tApFS_10_SnapshotMetaTree_Value
{
    tApFS_Ident ExtentRefIdent;    // Identificador de objeto físico árbol-B, en el que se guarda la información sobre la extención
    tApFS_Ident SuperBlockIdent;   // Identificador del superbloque
    uint64      CreatedTime;       // Hora de instantánea (en nanosegundos desde medianoche  de 01/01/1970)
    uint64      LastModifiedTime;  // Hora de instantánea (en nanosegundos desde medianoche  de 01/01/1970)
    uint64      iNum;
    uint32      ExtentRefTreeType; // Tipo árbol-B, en el que se guarda la información sobre la extención
    uint16      NameLength;        // Largo de nombre de la instantánea incluye símbolos al final de la fila)
    uint8       Name;            // Nombre instantánea (termina en 0)
};

struct tApFS_13_ObjectsMapSnapshot_Value
{
    uint32      Flags;    // Banderas de instantaneas
    uint32      Padding;  // Reservado (para correcciones)
    tApFS_Ident Reserved; // Reservado
};

struct tApFS_15_FusionMiddleTree_Value
{
    tApFS_Address fmv_lba;
    uint32        fmv_length;
    uint32        fmv_flags;
};

Ejemplo de la estructura de un sistema de archivos ApFS:

Пример структуры файловой системы ApFS

Volume Superblock (Superbloque de Volumen)

Superbloque de volumen (Volume Superblock) - existe para cada volumen del sistema de archivos. Contiene el nombre del volumen, el ID y la marca de tiempo. Como superbloque de contenedores (Container Superblock), contiene un puntero a un mapa de bloques que asigna un ID de bloque a sus compensaciones. Además, el superbloque de volumen almacena un puntero al directorio raíz, que se almacena como un nodo.

Parcialidad (HEX) Tipo Id Descripción
0 tApFS_COH Header Encabezado del objeto contenedor (Container Object Header)
20 uint32 MagicNumber (APSB) Un valor que se puede utilizar para comprobar que estamos leyendo una instancia. Volume Superblock
24 uint32 IndexInSuperBlock El índice del ID de objeto de este volumen en la matriz de volúmenes del contenedor.
28 uint64 Features Mapa de bits de las principales funciones utilizadas por volumen
30 uint64 ReadOnlyFeatures Mapa de bits de funciones básicas (solo lectura) utilizadas por volumen
38 uint64 IncompatibleFeatures Mapa de bits de funciones de volumen incompatibles
40 uint64 LastUnmountTime La hora en que se desmontó el volumen por última vez (en nanosegundos desde la medianoche del 01/01/1970)
48 uint64 ReservedBlocksCount Número de bloques reservados para asignación de volumen
50 uint64 QuotaBlocksCount El número máximo de bloques que puede asignar este volumen
58 uint64 AllocatedCount El número de bloques asignados actualmente al sistema de archivos de este volumen.
60 uint8 MetaCryptoState[20] nformación sobre la clave utilizada para cifrar los metadatos de este volumen (ejemplar wrapped_meta_crypto_state_t)
74 uint32 RootTreeType Tipo de raíz del árbol de carpeta (generalmente: Tipo ( eApFS_ObjectFlag_Virtual << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo eApFS_ObjectType_0E_FileSystemTree )
78 uint32 ExtentRefTreeType Tipo de árbol de mapeo de extensión (generalmente: Tipo ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo OBJECT_TYPE_BLOCKREF )
7C uint32 SnapshotMetaTreeType Tipo de árbol de metadatos de instantáneas (generalmente: Tipo ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo OBJECT_TYPE_BLOCKREF )
80 tApFS_Ident ObjectsMapIdent Identificador de objeto físico en el mapa de objeto volumétrico
88 tApFS_Ident RootTreeIdent Identificador de objeto virtual del árbol de carpetas raíz
90 tApFS_Ident ExtentRefTreeIdent Identificador de objeto físico del árbol de vínculos de extensión
98 tApFS_Ident SnapshotMetaTreeIdent Identificador de objeto virtual de árbol de metadatos de instantánea
A0 tApFS_Transaction RevertToXid El número de transacción de la instantánea a la que se devolverá el volumen.
A8 tApFS_Ident RevertToSuperBlock Identificador del objeto VS físico al que se revertirá el volumen
B0 uint64 NextObjectIdent El siguiente identificador que se asignará al objeto del sistema de archivos en volumen.
B8 uint64 NumberOfFiles Cantidad de archivos regulares en volumen
C0 uint64 NumberOfDirectories Cantidad de carpetas en volumen
C8 uint64 NumberOfSymbolicLinks Cantidad de enlaces simbólicos en volumen
D0 uint64 NumberOfOtherObjects Cantidad de otros objetos en el volumen (no de la llave x0B8_NumberOfFiles , x0C0_NumberOfDirectories и x0C8_NumberOfSymbolicLinks )
D8 uint64 NumberOfSnapshots Cantidad de instantáneas en este volumen
E0 uint64 TotalBlocksAllocated Cantidad total de bloques asignados por este volumen
E8 uint64 TotalBlocksFreed Cantidad total de bloques liberados por este volumen
F0 tApFS_Uuid Uuid
100 uint64 LastModifiedTime Hora del último cambio de este volumen (en nanosegundos desde la medianoche del 01/01/1970)
108 uint64 Flags
110 tApFS_0D_FSM FormattedBy Información sobre el software que creó este volumen
140 tApFS_0D_FSM ModifiedBy[8] Información sobre el software que cambió este volumen
2C0 uint8 VolumeName[256] Nombre del volumen cero de la fila UTF-8
3C0 uint32 NextDocumentIdent Siguiente identificador de documento que se asignará (almacenado en el campo extendido APFS_0E_TYPE_DOCUMENT_ID del documento)
3C4 uint16 Role Mapa de bits de rol de volumen
3C6 uint16 Reserved
3C8 tApFS_Transaction RootToXid Número de transacción de instantánea para no root o cero para root
3D0 tApFS_Ident EncryptStateIdent El estado actual de cifrado o descifrado, o cero si no hay cifrado

Ilustración detallada de «APFS»:

Подробная иллюстрация APFS

Checkpoint (Punto de Control)

Punto de control - este es el estado temporal del contenedor. Cada punto de control se inicializa en el Superbloque del contenedor, y el estado actual suele ser el último. El punto de control contiene metadatos tanto para el contenedor como para el volumen. Los puntos de recuperación y las instantáneas son similares entre sí. La principal diferencia entre un punto de control y una instantánea es la capacidad del usuario para restaurar el sistema de archivos a partir de instantáneas guardadas mediante la API del sistema de archivos.

Checkpoint Superblock Descriptor (Descriptor de punto de control de superbloque)

Este bloque contiene información sobre las estructuras de metadatos en «ApFS» y es el bloque Descriptor precedente. La información más importante de este bloque es la ubicación de la estructura de mapa de bits (BMS), el archivo de distribución anterior en HFS+.

Descriptor del superbloque del punto de control:

Дескриптор суперблока контрольной точки

Bitmap Structures (Mapa de bits o mapa de volumen)

Registros de bloques usados ​​y no usados. Solo hay un mapa de volumen que cubre todo el contenedor y es común a todos los volúmenes del sistema de archivos. «ApFS» utiliza un conjunto de bloques para almacenar el mapa de volumen (Bitmap Structures).

En «ApFS» el mapa es común a todos los volúmenes del contenedor. Cada volumen contiene cotizaciones para el bloque en el contenedor, pero los bloques en sí no están en las áreas asignadas. El enlace al mapa de volumen se encuentra en el Descriptor de punto de control de superbloque (CSBD), que contiene información sobre el nivel superior de la estructura, el descriptor de mapa de bits (BMD). La siguiente figura muestra la estructura básica de este mapa. Se divide en niveles, con BMD en la parte superior y estableciendo límites. Debajo se encuentran «Bitmap Blocks» (BMB), que realizan un seguimiento de los bloques en el contenedor. Un byte en el BMB realiza un seguimiento de ocho bloques, cada bit de los cuales proporciona un estado de asignación. Cada bit es el estado de un bloque independiente.

Bitmap Blocks

Tablas (Tables)

Las tablas se utilizan en el catálogo y las extensiones del árbol B, la lista de volúmenes y el mapa de ID de objeto.

Las tablas utilizadas en «ApFS», son pequeñas «bases de datos» de un bloque con un propósito ligeramente diferente en las estructuras del sistema de archivos. El campo de tipo de tabla consta de 2 bytes ubicados en el bloque con parcialidad 0x20 inmediatamente después del encabezado del nodo. Hay ocho tablas del 0 al 7. Los siguientes 2 bytes proporcionan el nivel de tabla 0 y superior. La tabla del segundo nivel contendrá registros relacionados con la tabla base del primer nivel. Y las tablas de nivel cero se refieren a bloques que a menudo contienen metadatos de archivos.

Los tipos de tablas varían en estructura, pero el encabezado de la tabla para todos los tipos es de 24 bytes.

La figura muestra una estructura de encabezado de tabla de muestra:

La figura muestra una estructura de encabezado de tabla de muestra

Descripción de valores de campo en la estructura del encabezado:

Parcialidad (HEX) Campo Tipo de datos Descripción
20 tableType uint16 Los valores posibles son 0-7. Esta es la tabla 1
22 tableLevel uint16 Indica el nivel del árbol B.
24 tableRecords uint16 Número de registros en la tabla
26 Unknown 1 uint16
28 Unknown 2 uint16
2A tableIndexSize uint16 tamaño de áreas de índice de tabla.
2C tableKeyAreaSize uint16 tamaño de área clave de la mesa.
2E tableFreeSpaceSize uint16 tamaño de área libre. El área de datos de la mesa termina con parcialidad
0x38+tableIndexSize+tableKeyAreaSize+tableFreeSpaceSize. 0x38 + 0x80 + 0x170 + 0xd58 .
30 Unknown 3 uint16
32 Unknown 4 uint16
34 Unknown 5 uint16
36 Unknown 6 uint16

Aquí hay un diseño general de las distintas tablas:

Aquí hay un diseño general de las distintas tablas.

No todos los elementos de la imagen se utilizan en todas las tablas. La figura muestra un bloque completo con el encabezado del bloque de nodo superior. El resto del bloque es una tabla.

El índice del registro sigue inmediatamente después del encabezado de la tabla. Hay 2 tipos de ellos. Uno con dos valores: Parcialidad en la llave, y Parcialidad en la sección de datos para cada uno de Uint16. El segundo usa 4 valores Uint16 con Parcialidad y longitud para las particiones de la llave y de datos. El índice de registros de la tabla contiene información sobre los registros de la llave y de datos en la tabla. Otra diferencia entre tipos de tablas es el uso de pies de página.

Las tablas 1, 3, 5 y 7 usan Pie de página tamaño 0x28 bytes al final del bloque. En estas tablas, todos los offsets de datos se refieren al offset 0xFD8 y el pie de página contiene varios valores específicos del tipo de tabla. Otros tipos de tablas no tienen pie de página, y todas las referencias al contenido de la sección de datos se refieren al final del bloque.

En los árboles B con múltiples niveles, - тLas tablas 1, 3, 5 y 7 están al más alto nivel, ya que tienen pie de página. El pie de página, utilizado para almacenar información sobre el árbol B completo. Uno de los valores en el pie de página es el número total de entradas en la estructura de este árbol.

La definición de la tabla comienza en el desplazamiento 0x20 en el bloque. Muestra el Tipo de la tabla, el número de filas, el tamaño de la sección clave y el espacio entre la clave y la sección de datos. Después de las propiedades de la tabla, la parcialidad 0x38 describe las definiciones de filas y columnas. La tabla contiene el título, las definiciones de registros, las secciones clave y los datos. Algunos tipos de tablas también tienen un pie de página. El encabezado comienza en el desplazamiento 0x20 y tiene una longitud de 0x18 bytes. El encabezado de este tipo de tabla comienza con un valor de 16 bits que representa el tipo de la tabla. Luego siguen dos bytes, que representan el nivel en el árbol B en el que se usa la tabla. Los siguientes dos bytes representan el número de filas de la tabla. La longitud del registro de definición de escaneo es 0x2A, seguida de Uint16, que registra la longitud de la clave de sección. Luego viene la brecha entre la clave y la sección de datos. El pie de página de la tabla es siempre 0x28 bytes y siempre ocupa el final del bloque. Y los índices de la tabla son de 4 u 8 bytes cada uno. En índices de 8 bytes, los dos primeros "Uint16" son la parcialidad y longitud del registro de claves. Los siguientes dos "Uint16" son registros de parcialidad y longitud de datos en la tabla. Las tablas con índices de 4 bytes tienen dos valores Uint16 que contienen registros de parcialidad de la llave y de datos. La longitud de datos en dos entradas está predeterminada. En las tablas de pie de página de parcialidad, los registros de datos son relativos al inicio del pie de página (0x28 bytes). Y para otros tipos de tablas, esta parcialidad se refiere al final del bloque.

La mayoría de los significados relacionados con el encabezado y pie de página de una tabla son claros, al menos a partir de un tipo de lectura de la tabla. La parcialidad es 0x18 en el pie de página (parcialidad 0xFF en un bloque de 4 KB) es el número de registros en la tabla y en todas las tablas base (si es una tabla con un nivel superior a 0, en el offset 0x22). La parcialidad 0x20 en el pie de página es el número de la siguiente entrada en la tabla.

Tabla 0

Una tabla de tipo 0 se encuentra en la estructura de directorios del árbol B entre los nodos hoja y el nodo raíz. Los valores desconocidos del 3 al 6 se presentan como desplazamiento y longitud de la llave. Compensaciones de datos y longitud del siguiente registro disponible. Si no hay entradas de índice libres, las compensaciones se establecen en «0xFFFF» y la longitud «0x00».

Los registros de la tabla son cuatro valores «Uint16». Los primeros 2 - estos son los valores de parcialidad y longitud en la sección clave, y los siguientes son la parcialidad y el valor de contenido en la sección de datos.

Un ejemplo de tabla tipo 0 sería un identificador de nodo de catálogo, una clave de nombre en la sección de claves y un identificador de objeto en la sección de datos. Esta tabla no tiene pie de página.

Tabla 1

La primera tabla tiene un pie de página y el índice de la tabla contiene cuatro valores de 16 bits, donde los primeros 2 valores son la parcialidad del registro de la sección de clave y la longitud del registro. Los siguientes 2 valores proporcionan la entrada de parcialidad en la sección de datos y su longitud. Esta tabla se encuentra a menudo tanto en la estructura de directorios del árbol B como en el árbol de extensión del nodo de nivel superior. Un ejemplo son los valores: «Parent ID» y nombre de la llave (el nombre de un archivo o carpeta en la estructura del directorio y el número de bloque inicial en el árbol B de extensión), el identificador de objeto cuando se usa como nodo raíz en la estructura de directorio o el número de bloque cuando se usa en el árbol de extensión.

A continuación se muestran ejemplos de esta tabla:

A continuación se ofrecen ejemplos de esta tabla.

Tabla 2

La segunda tabla. Inicialmente, esta tabla es idéntica a la anterior, pero no tiene pie de página. Este tipo de tabla es muy común en los nodos hoja en la estructura de directorios del árbol B donde se representa la sección clave con «Parent ID» y el nombre de la llave.

Tabla 3

La tercera tabla es idéntica a la anterior. El índice de la tabla es el mismo que el de la primera tabla. Los valores típicos dependen de la estructura en la que se utilizan. En la estructura de directorio del árbol B y el árbol de extensión, esta tabla se usa a menudo como un nodo de nivel superior en volúmenes pequeños, donde el nodo raíz son los nodos raíz y hoja. En tal caso de uso, la entrada clave podría ser «Parent ID». La clave de nombre y la entrada de datos pueden ser un archivo de datos de metado con gran variación de tamaño.

Otras entradas de la tabla son identificadores de objeto «Object ID» y su tipo en el registro de claves, con extensión de información de archivo y registros de datos. La tercera mesa tiene un зie de página.

Ejemplo de tabla:

Пример таблицы

Tabla 4

La tabla 4 es ligeramente diferente a los anteriores. No hay pie de página en la tabla y el índice de la tabla tiene solo 2 valores: Parcialidad de la entrada en la sección clave y 1 valor para la sección de datos. La longitud del contenido se fija en 16 bytes en la sección clave y 8 bytes en la sección de datos. Las compensaciones en la sección de datos se refieren al final del bloque.

Tabla 5

La tabla 5 es parecida a la 4. La única diferencia es que este tipo tiene un pie de página y todas las compensaciones de datos comienzan con «offset-0x28» (inicio de pie de página). Las entradas en la sección clave son 16 bytes y 8 bytes en la sección de datos. Este tipo de tabla se ve más comúnmente en los nodos de nivel superior en la estructura de directorios del árbol B y en contenedores grandes con árboles en niveles.

Tabla 6

La tabla 6 también se parece a la 4. El índice de la tabla solo tiene parcialidad a los contenidos en la sección de claves y de datos, pero no a su longitud. La longitud está predefinida. Cada entrada tiene 16 bytes. No hay pie de página para este tipo de tabla. Esta tabla se encuentra a menudo en los nodos hoja de la estructura de directorios del árbol B. Уl contenido típico de la sección de la llave de la incluye el identificador de objeto y el ID de volumen del Superblock Checkpoint «Volume Checkpoint Superblock ID», mientras que la sección de datos suele registrar su tamaño y número de bloque.

Tabla 7

La tabla 7 se parece a la sexta. La única diferencia es el pie de página, que contiene información similar a la descrita para la Tabla 1. Este tipo de tabla se ve en una amplia gama de estructuras y a menudo se encuentra en los niveles más altos de una estructura de múltiples capas o en estructuras de una sola capa como la descripción del volumen.

Ejemplo

Ejemplo

Resumen de tablas

Esta tabla muestra las propiedades principales de varios tipos de tablas:

Tipo Pie de página Parcialidad de sección clave Longitud de sección clave Parcialidad de sección de datos Longitud de sección de datos Longitud de la llave Longitud de datos
0 NO uint16 uint16 uint16 uint16 Varies Possible
1 uint16 uint16 uint16 uint16 Varies Possible
2 NO uint16 uint16 uint16 uint16 Varies Possible
3 uint16 uint16 uint16 uint16 Varies Possible
4 NO uint16 uint16 16 bytes 8 bytes
5 uint16 uint16 16 bytes 8 bytes
6 NO uint16 uint16 16 bytes 16 bytes
7 uint16 uint16 16 bytes 16 bytes

Uno de los bloques más importantes en la estructura de directorios del árbol B es el nodo raíz, que es el nivel más alto en la estructura de carpetas. Este nodo utiliza claves de búsqueda de longitud variable. Una de las características mejoradas de «ApFS» es una búsqueda rápida en directorios. Un valor que está estrechamente relacionado con esta característica es el número de todos los registros en la estructura de árbol ubicada en el pie de la tabla.

El nodo raíz de la estructura del árbol B tiene 2 opciones de selección de tabla ya que ambas tienen pies de página. La tabla 3: como un nodo raíz, visto solo en contenedores pequeños con una pequeña cantidad de archivos, donde el nodo raíz también es un índice y nodos hoja.

En el mapa de características para el nodo raíz, solo se usa la quinta tabla, excepto para estructuras muy pequeñas donde puede encontrar la séptima.

La interpretación de las tablas muestra que las tablas 0 y 2 tienen el mismo significado. Lo mismo se observa entre las tablas 1 y 3. Estas tablas parecen tener diferentes propósitos según la estructura en la que se encuentren.

Instantáneas (Snapshots)

Las instantáneas son instantáneas del sistema de archivos de solo lectura de un volumen. El sistema operativo puede utilizar estas instantáneas para realizar copias de seguridad más eficientes. Gracias a la «Time Machine» correrá más rápido. Y gracias al soporte de imágenes instantáneas «Time Machine», ya no es necesario guardar varias copias completas de un archivo en el disco, simplemente puede realizar un seguimiento de cambios específicos. Por ejemplo, si edita un archivo modificado usando HFS+, conserva dos copias del archivo, la primera registra los nuevos cambios y la segunda en caso de que quiera volver a la vista anterior. En «APFS» sólo se conserva el archivo original y se registran las diferencias entre el archivo original y las versiones actualizadas, ocupando menos espacio en disco. Al igual que con las mejoras en «Fusion Drive», la información ocupa menos espacio en disco.

Aunque «ApFS» es significativamente inferior en sus capacidades a ZFS de 128 bits, que es compatible con Linux, FreeBSD y otros sistemas operativos gratuitos, este es un paso en la dirección correcta de Apple.

Como se mencionó anteriormente, Apple ha intentado cambiar ZFS a OS X durante mucho tiempo. Más tarde, OpenZFS se implementó para OS X (O3X) y MacZFX.

Nodes (nodos)

Los nodos son contenedores flexibles que se utilizan para almacenar varios tipos de registros. Pueden ser parte del árbol B o pueden existir por sí mismos. Los nodos pueden contener entradas de tamaño fijo o flexible. El nodo comienza con una lista de punteros a claves de entrada y entradas de entrada. Por lo tanto, para cada registro, el nodo contiene el encabezado de entrada al principio del nodo, la clave de entrada en el medio del nodo y la grabación de entrada al final del nodo.

Nodes (nodos)
Posición tamaño Tipo ID
0 4 uint32 alignment
4 4 uint32 ENTRY_COUNT
10 2 uint16 HEAD_SIZE
16 8 entry meta_entry
24 ... entry entries (repeat entry_count times)

Estructura de encabezado de nodo (Node header):

Parcialidad Campo Tipo de datos Comentario
0 Checksum Uint64 Fletchers Checksum Algorithm
8 ID Uint64 Object-ID or Block#
10 Checkpoint Uint64
18 Unknown Uint16 Possible level in B-Tree
1A Unknown Uint16 All observations shows value 0x4000
1C Unknown Uint16 Flag?
1E Unknown Uint16 Often seen value 0x0b, 0x0e and 0x0f

Administrador de Espacio (Space Manager)

«Space Manager» (Administrador de Espacio) se utiliza para gestionar bloques asignados en un contenedor «ApFS». Almacena el número de bloques libres y un puntero a archivos de información de ubicación.

Posición tamaño Tipo ID
0 4 uint32 tamaño de bloque
16 8 uint64 totalblocks
40 8 uint64 freeblocks
144 8 uint64 prev_allocationinfofile_block
352 8 uint64 allocationinfofile_block

Allocation info file (Archivo de información de distribución)

El archivo de distribución actúa como un encabezado faltante. Aquí es donde se almacena la Longitud de los archivos, la versión y su parcialidad.

Posición tamaño Tipo ID
4 4 uint32 alloc_file_length
8 4 uint32 alloc_file_version
24 4 uint32 TOTAL_BLOCKS
28 4 uint32 free_blocks
32 4 uint32 allocationfile_block

Archivo y carpeta de árbol B

Registros de todos los archivos y carpetas del volumen. Tienen la misma función que los archivos de directorio en «HFS+».

Extents (Extensiones de árbol B)

Un árbol B dividido de todas las extensiones del volumen. Las extensiones son enlaces al contenido de un archivo con información sobre dónde comienzan los contenidos de datos y su longitud en bloques. Un archivo con algún contenido tendrá al menos una extensión. Un archivo fragmentado tendrá varias extensiones. El árbol de extensiones es una estructura separada.

En cada entrada de archivo, se definen extensiones para cada uno de estos archivos en el árbol B. Esta estructura de extensión separada es parte de la funcionalidad de instantánea.

64-bit inodes (index descriptors) - descriptores de índices

Los inodos de 64 bits aumentan significativamente el espacio de nombres sobre los identificadores de 32 bits en «HFS+». Sistema de archivos de 64 bits en «ApFS» admite más de 9 quintillones de archivos por volumen. Como dijo Bill Gates, esto debería ser suficiente para todos.

«ApFS» ofrece la capacidad de restaurar ciertos estados del sistema de archivos, incluidas versiones antiguas o eliminadas de archivos. El superbloque de contenedores contiene un enlace a la estructura del punto de control. El punto de control se refiere al superbloque anterior del contenedor, que contiene información en el estado anterior del sistema de archivos. Por tanto, es posible restaurar varios estados antiguos analizando la cadena del superbloque de contenedores.

Ir a ver
🍏 Recuperación de datos después de actualizar, reinstalar MacOS o formatear un disco 🍏

🍏 Recuperación de datos después de actualizar, reinstalar MacOS o formatear un disco 🍏

Angel Villares

Autor: Angel Villares, Escritor técnico

Ángel Villares es autor y uno de los ingenieros informáticos de Hetman Software. Cuenta con casi 10 años de experiencia en el campo de la informática: administración y configuración de servidores, instalación de sistemas operativos y de diferentes programas informáticos, configuración de redes, seguridad de la información, implantación y asesoramiento en el uso de software especializado. Es un experto en el campo de la recuperación de datos, sistemas de archivos, dispositivos de almacenamiento y matrices RAID. Leer más

Recomendado para ti