APFS: Algoritmo de Recuperação de Dados do Sistema de Ficheiros e Estrutura do Sistema de Ficheiros

ApFS fornece a capacidade de restaurar estados específicos do sistema de arquivos, incluindo versões antigas ou excluídas de arquivos. O superbloco de contêineres contém um link para a estrutura do ponto de controle. O ponto de verificação refere-se ao superbloco anterior do recipiente, que contém informações sobre o estado anterior do sistema de arquivo. É possível, portanto, restaurar vários estados antigos, analisando a cadeia de superbloqueio do recipiente.

APFS: Algoritmo de Recuperação de Dados do Sistema de Ficheiros e Estrutura do Sistema de Ficheiros

Vá para 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

Contêineres e Volume

A estrutura do sistema de arquivos APFS tem a forma de uma árvore b, onde o diretório de dados raiz são as folhas desta árvore. Todas as filiais armazenam apenas links para o próximo nó até alcançarem as folhas. O sistema de arquivo usa recipientes como locais de armazenamento. Estes recipientes podem conter vários volumes. É também o principal objeto para o armazenamento de dados. Para um volume, o tamanho do recipiente deve ser superior a 512 MB, para dois volumes, mais de 1024 MB, etc.

A figura seguinte mostra a estrutura do sistema de ficheiros “ApFS”.

ApFS

Cada elemento desta estrutura (excepto o ficheiro de atribuição) começa com um cabeçalho de bloco de 32 bytes contendo informações gerais sobre o bloco. O seguinte é o corpo do sistema de arquivo. É composto pelos seguintes elementos:

  • 0x01: Superbloco de contêiner
  • 0x02: (Nó)
  • 0x05: Gerenciador de espaço (gerenciador de espaço)
  • 0x07: Localização do arquivo (arquivo de informações de alocação)
  • 0x0C: Checkpoint (Checkpoint)
  • 0x0D: Superbloco de Volume (Superbloco de Volume)

Os contentores são normalmente exactamente os mesmos que as entradas numa tabela de partição GUID (GPT). Têm o seu próprio esquema de atribuição de discos e protecção em caso de falha. Cada contentor contém um ou mais volumes, cada um com o seu próprio espaço de nomes, conjunto de ficheiros e directórios.

O “ApFS” sistema de ficheiros não é directamente compatível com o programa “RAID”, mas pode ser usado com volumes RAID da Apple para suportar striping (RAID 0), mirroring (RAID 1), e splicing (JBOD).

Com um índice de 64 bits o “ApFS” volumes suporta até 9 quintilhões (1018) de ficheiros.

O novo sistema de ficheiros da Apple utiliza nanossegundos para definir os carimbos temporais. No HFS+, os carimbos temporais foram definidos para o segundo mais próximo. Isto reduzirá o número de falhas durante as transferências de dados e outras operações de arquivo.

“ApFS” tem encriptação incorporada e utiliza AES-XTS ou AES-CBC, dependendo do dispositivo. O utilizador pode utilizar múltiplas chaves de encriptação para manter a segurança dos dados mesmo no caso de “Ataque Cibernético Físico” do meio.

Esta não é uma lista completa das inovações possuídas por “ApFS”.

Seções formatadas em “ApFS”, não são reconhecidas pelo OS X 10.11 Yosemite ou sistemas operativos anteriores.

Cabeçalho de Bloco

Cada estrutura de sistema de ficheiros em “ApFS” começa com um cabeçalho de bloco. E o cabeçalho em si começa com uma soma de controlo. Outras informações no cabeçalho incluem a versão copy-on-write do bloco, o ID do bloco, e o seu 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)

Da tabela podemos ver que 1uint = 1 bit, 8 bits = 1 byte, desse uint64 = 8, uint32 = 4 e uint16 = 2 bytes.

Superbloqueio de contentor

Container Superblock (Container Superblock) – é o ponto de entrada para o sistema de ficheiros. Devido à estrutura do sistema de arquivo com contentores e volumes flexíveis, a distribuição deve ser feita ao nível do contentor. O super bloco de contentores contém informações sobre o tamanho do bloco, o seu número e indicações no gestor do espaço para esta tarefa. Além disso, o superbloco armazena identificações de blocos para todos os volumes. Para atribuir identificações de blocos a blocos de deslocamento, é armazenado um ponteiro para o mapa de blocos da árvore B. Esta árvore contém entradas para cada volume com a sua identificação e offset. O superbloco de contentores é o nível mais alto no sistema de ficheiros. O superbloco de contentores é o nível mais alto no sistema de ficheiros.

Possui o seguinte tipo:

Parcialidade (HEX) Tipo Id Descrição
0 tApFS_COH Cabeçalho Cabeçalho do objeto Container
20 uint32 MagicNumber (NXSB) O valor a ser verificado para ler o Superblock do contêiner.
24 uint32 BlockSize Tamanho do bloco de contêiner (em bytes)
28 uint64 BlocksCount Número de blocos de contêiner
30 uint64 Recursos Bitmap das principais funções do contêiner
38 uint64 ReadOnlyFeatures Bitmap de funções de base do contêiner (somente leitura)
40 uint64 IncompatibleFeatures Bitmap das principais funções incompatíveis do contêiner
48 tApFS_Uuid Uuid UUID do contêiner
58 tApFS_Ident NextIdent Próximo identificador para novo objeto lógico ou virtual
60 tApFS_Transaction NextTransaction Número da próxima transação
68 uint32 DescriptorBlocks Número de blocos usados pelo descritor
6C uint32 DataBlocks Número de blocos usados pelos dados
70 tApFS_Address DescriptorBase Endereço básico de um descritor ou identificador de um objeto físico com uma árvore de endereço
78 int32 Banco de dados Endereço do banco de dados ou identificador de um objeto físico com árvore de endereços
80 uint32 DescriptorNext Índice do próximo descritor
84 uint32 DataNext Próximo índice de dados
88 uint32 DescriptorIndex O índice do primeiro elemento válido no segmento do descritor.
8C uint32 DescriptorLength O número de blocos no segmento descritor usado pelo superbloco
90 uint32 DataIndex O índice do primeiro elemento válido no segmento de dados
94 uint32 DataLength Número de blocos no segmento de dados usado pelo superbloco
98 tApFS_Ident SpaceManagerIdent Gerenciador de espaço para ID de entidade
A0 tApFS_Ident ObjectsMapIdent O identificador de objeto físico do mapa de objeto do contêiner
A8 tApFS_Ident ReaperIdent Identificador de entidade
B0 uint32 ReservedForTesting
B4 uint32 MaximumVolumes O número máximo possível de volumes em um contêiner
B8 tApFS_Ident VolumesIdents [100] Volume da matriz do identificador de objeto virtual
3D8 uint64 Contadores [32] Matriz de contadores que armazenam informações sobre o contêiner
4D8 tApFS_BlockRange BlockedOutOfRange Intervalo físico de blocos que não podem ser usados
4E8 tApFS_Ident MappingTreeIdent O identificador de um objeto físico na árvore que é usado para rastrear objetos que são movidos do armazenamento bloqueado.
4F0 uint64 OtherFlags Mapa de outras funções de contêiner
4F8 tApFS_Address JumpstartEFI Identificação de um objeto físico com dados do controlador EFI
500 tApFS_Uuid FusionUuid UUID para contêineres Fusion ou zero para contêineres não Fusion
510 tApFS_BlockRange KeyLocker Localização da marca da chave do contêiner
520 uint64 EphemeralInfo [4] Matriz de campos usados para manipular dados lógicos
540 tApFS_Ident ReservedForTesting
548 tApFS_Ident FusionMidleTreeIdent Apenas para dispositivos vinculados
550 tApFS_Ident FusionWriteBackIdent Apenas para dispositivos vinculados
558 tApFS_BlockRange FusionWriteBackBlocks Blocos usados para a área de cache

Com definição de tipo:

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

u

struct tApFS_BlockRange
{
& nbsp; & nbsp; & nbsp; & nbsp; tApFS_Address & nb sp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Primeiro; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; // Primeiro bloco
& nbsp; & nbsp; & nbsp; & nbsp; uint64 & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Contagem & nbsp; & nbsp; & nbsp; & nbsp; // Número de blocos
}
struct tApFS_COH
{
    uint64              CheckSum;       // Bloquear checksum
    tApFS_Ident         Ident;          // Identificador
    tApFS_Transaction   Transaction;    // Número da transação de alteração do objeto
    uint16              Type;           // Tipo de objeto
    uint16              Flags;          // Sinalizador de objeto
& nbsp; & nbsp; & nbsp; & nbsp; uint32 & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; & nbsp; Subtipo & nbsp; & nbsp; // Subtipo de objeto
};

com uma lista de tipos de objetos:

enum & nbsp; 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;
};

Exemplo da estrutura de um sistema de ficheiros ApFS:

Exemplo da estrutura de um sistema de ficheiros ApFS

Volume Superbloqueio (Superbloqueio de Volume)

Superbloqueio de Volume (Volume Superblock)- existe para cada volume no sistema de arquivo. Contém o nome do volume, ID e carimbo da hora. Como um Container Superblock, contém um ponteiro para um mapa de blocos que atribui um ID de bloco aos seus offsets. Além disso, o superbloco de volume armazena um ponteiro no directório raiz, que é armazenado como um nó.

Parcialidad (HEX) Tipo Id Descripción
0 tApFS_COH Header Cabeçalho do objecto do contentorr (Container Object Header)
20 uint32 MagicNumber (APSB) Um valor que pode ser usado para verificar se estamos a ler uma instância. Superbloco de volume
24 uint32 IndexInSuperBlock O índice do ID do objecto deste volume na matriz de volume do contentor.
28 uint64 Features Mapa de bits de las principales funciones utilizadas por volumen
>30 uint64 ReadOnlyFeatures Bitmap das funções básicas (apenas de leitura) utilizadas por volume
38 uint64 IncompatibleFeatures Bitmap de funções de volume incompatíveis /td>
40 uint64 LastUnmountTime A hora em que o volume foi desmontado pela última vez (em nanossegundos a partir da meia-noite de 01/01/1970)
48 uint64 ReservedBlocksCount Número de blocos reservados para atribuição de volume.
50 uint64 QuotaBlocksCount O número máximo de blocos que este volume pode atribuir.
58 uint64 AllocatedCount O número de blocos actualmente atribuídos ao sistema de ficheiros neste volume.
60 uint8 MetaCryptoState[20] Informação sobre a chave utilizada para encriptar os metadados deste volume (ejemplar wrapped_meta_crypto_state_t)
74 uint32 RootTreeType Tipo de raiz de árvore de pasta (geralmente): Tipo ( eApFS_ObjectFlag_Virtual << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo eApFS_ObjectType_0E_FileSystemTree )
78 uint32 ExtentRefTreeType Tipo de árvore de Spanning (geralmente): Tipo ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo OBJECT_TYPE_BLOCKREF )
7C uint32 SnapshotMetaTreeType Tipo de árvore de metadados do instantâneo (tipicamente): Tipo ( eApFS_ObjectFlag_Physical << 16) \ eApFS_ObjectType_02_BTreeRoot , subtipo OBJECT_TYPE_BLOCKREF )
80 tApFS_Ident ObjectsMapIdent IIdentificador físico do objecto no mapa volumétrico de objectos
88 tApFS_Ident RootTreeIdent Root Folder Árvore Identificador de Objecto Virtual
90 tApFS_Ident ExtentRefTreeIdent Identificador físico do objecto da árvore de ligação.
98 tApFS_Ident SnapshotMetaTreeIdent Identificador de Objecto Virtual de Árvore de Metadados do instantâneo
)">A0 tApFS_Transaction RevertToXid O número da transacção do instantâneo ao qual o volume deve ser devolvido.
>A8 tApFS_Ident RevertToSuperBlock Identificador del objeto VS físico al que se revertirá el volumen
B0 uint64 NextObjectIdent O próximo identificador a ser atribuído ao objecto do sistema de ficheiros de volume.
B8 uint64 NumberOfFiles Número de ficheiros regulares em volume
C0 uint64 NumberOfDirectories Número de pastas em volume
C8 uint64 NumberOfSymbolicLinks Número de ligações simbólicas em volume
D0 uint64 NumberOfOtherObjects Número de outros objectos no volume (não da chave x0B8_NumberOfFiles , x0C0_NumberOfDirectories и x0C8_NumberOfSymbolicLinks )
D8 uint64 NumberOfSnapshots Número de instantâneos neste volume
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 da última mudança deste volume (em nanossegundos desde a meia-noite de 01/01/1970)
108 uint64 Flags
110 tApFS_0D_FSM FormattedBy Informação sobre o software que criou este volume
140 tApFS_0D_FSM ModifiedBy[8] Informação sobre o software que alterou este volume
2C0 uint8 VolumeName[256] Nome do volume zero da linha UTF-8
3C0 uint32 NextDocumentIdent Próximo identificador de documento a asignar (almacenado en el campo ampliado) APFS_0E_TYPE_DOCUMENT_ID del documento)
3C4 uint16 Role Bitmap do papel do volume
3C6 uint16 Reserved
3C8 tApFS_Transaction RootToXid Número de transacção instantânea para não-root ou zero para root
3D0 tApFS_Ident EncryptStateIdent O estado actual de encriptação ou desencriptação, ou zero se não houver encriptação

Ilustração detalhada de «APFS»:

Ilustração detalhada de APFS

Checkpoint (Ponto de controlo)

Ponto de controlo - este é o estado temporário do recipiente. Cada ponto de controlo é rubricado no Superbloco do contentor, e o estado actual é normalmente o último. O ponto de controlo contém metadados tanto para o recipiente como para o volume. Os pontos e instantâneos de recuperação são semelhantes entre si. A principal diferença entre um ponto de controlo e um instantâneo é a capacidade do utilizador de restaurar o sistema de ficheiros a partir de instantâneos guardados utilizando o API do sistema de ficheiros.

Checkpoint Superblock Descriptor (Descritor do Superbloco do Ponto de Controlo)

Este bloco contém informação sobre as estruturas de metadados em "ApFS" e é o bloco Descritor anterior. A informação mais importante neste bloco é a localização da estrutura do bitmap (BMS), o ficheiro de distribuição anterior em HFS+.

Descritor de super-bloco do ponto de verificação:

Descritor de super-bloco do ponto de verificação

Estruturas de bitmap (Bitmap ou mapa de volume)

Registos de blocos usados e não utilizados. Existe apenas um mapa de volume que cobre todo o contentor e é comum a todos os volumes do sistema de ficheiros. "ApFS" utiliza um conjunto de blocos para armazenar o mapa de volume (Estruturas Bitmap).

Em "ApFS" o mapa é comum a todos os volumes no contentor. Cada volume contém citações para o bloco no contentor, mas os blocos em si não se encontram nas áreas cartografadas. A ligação ao mapa do volume está no Superblock Checkpoint Descriptor (CSBD), que contém informação sobre o nível superior da estrutura, o Bitmap Descriptor (BMD). A figura abaixo mostra a estrutura básica deste mapa. Está dividido em níveis, com BMD no topo e estabelecendo limites. Por baixo estão "Blocos de Bitmap" (BMB), que mantêm um registo dos blocos no contentor. Um byte na pista BMB oito blocos, cada um dos quais fornece um estado de atribuição. Cada bit é o estado de um bloco independente.

Bitmap Blocks

Tabelas (Tabelas)

Tabelas são utilizadas no catálogo e nas extensões das árvores B, na lista de volumes e no mapa de ID de objectos.

Tabelas utilizadas em "ApFS", são pequenas "bases de dados" de um bloco com uma finalidade ligeiramente diferente nas estruturas do sistema de ficheiros. O campo tipo tabela consiste em 2 bytes localizados no bloco com partição 0x20 imediatamente a seguir ao cabeçalho do nó. Há oito tabelas de 0 a 7. Os 2 bytes seguintes fornecem a tabela de nível 0 e superior. A tabela do segundo nível conterá registos relacionados com a tabela base do primeiro nível. E as tabelas de nível zero referem-se a blocos que frequentemente contêm metadados de ficheiros.

Tipos de mesa variam em estrutura, mas o cabeçalho da tabela para todos os tipos é de 24 bytes.

A figura mostra uma estrutura de cabeçalho da tabela de amostras:

A figura mostra uma estrutura de cabeçalho de tabela de amostras

Descrição dos valores de campo na estrutura de cabeçalho:

Parcialidade (HEX) Campo Tipo de dados Descrição
20 tableType uint16 Los valores posibles son 0-7. Esta eé a tabela 1
22 tableLevel uint16 Indica o nível da árvore B.
24 tableRecords uint16 Número de registos na tabela
26 Unknown 1 uint16
28 Unknown 2 uint16
2A tableIndexSize uint16 tamanho das áreas de índice da tabela.
2C tableKeyAreaSize uint16 tamanho da área da tabela chave.
2E tableFreeSpaceSize uint16 tamanho da área livre. A área de dados da tabela termina com um enviesamento
0x38+tableIndexSize+tableKeyAreaSize+tableFreeSpaceSize. 0x38 + 0x80 + 0x170 + 0xd58 .
30 Unknown 3 uint16
32 Unknown 4 uint16
34 Unknown 5 uint16
36 Unknown 6 uint16

Aqui está um esquema geral das diferentes tabelas:

Aqui está um esquema geral das diferentes tabelas.

Nem todos os elementos da imagem são utilizados em todas as tabelas. A figura mostra um bloco completo com o cabeçalho do bloco do nó superior. O resto do bloco é uma tabela.

O índice de registo segue-se imediatamente após o cabeçalho da tabela. Existem 2 tipos deles. Um com dois valores: Parcialidade na chave, e Parcialidade na secção de dados para cada um dos Uint16. O segundo utiliza 4 valores Uint16 com Parcialidade e comprimento para as chaves e partições de dados. O índice de registos da tabela contém informações sobre a chave e os registos de dados na tabela. Outra diferença entre os tipos de tabelas é a utilização de rodapés.

Tabelas 1, 3, 5 e 7 utilizam rodapés de 0x28 bytes no final do bloco. Nestas tabelas, todos os offsets de dados referem-se ao offset 0xFD8 e o rodapé contém vários valores específicos do tipo de tabela. Outros tipos de tabelas não têm um rodapé, e todas as referências ao conteúdo da secção de dados referem-se ao fim do bloco.

In B-trees com múltiplos níveis, - тTables 1, 3, 5 e 7 estão ao mais alto nível, uma vez que têm rodapés. O rodapé, utilizado para armazenar informação sobre toda a árvore B. Um dos valores no rodapé é o número total de entradas nesta estrutura de árvore.

A definição da tabela começa em offset 0x20 no bloco. Mostra o tipo da tabela, o número de filas, o tamanho da secção da chave e o espaçamento entre a chave e a secção de dados. Após as propriedades da tabela, o offset 0x38 descreve as definições de linha e coluna. O quadro contém o título, definições de registos, secções-chave e dados. Alguns tipos de mesas também têm um rodapé. O cabeçalho começa em offset 0x20 e tem um comprimento de 0x18 bytes. O cabeçalho deste tipo de tabela começa com um valor de 16 bits que representa o tipo da tabela. Seguem-se dois bytes, representando o nível na árvore B em que a tabela é utilizada. Os dois bytes seguintes representam o número de filas na tabela. O comprimento do registo de definição de scan é 0x2A, seguido de Uint16, que regista o comprimento da chave da secção. A seguir vem a lacuna entre a chave e a secção de dados. O rodapé da mesa é sempre 0x28 bytes e ocupa sempre o fim do bloco. E os índices da tabela ou são de 4 ou 8 bytes cada. Nos índices de 8 bytes, os dois primeiros "Uint16" são a parcialidade e o comprimento do registo chave. Os dois seguintes "Uint16" são registos de parcialidade e comprimento de dados na tabela. As tabelas com índices de 4 bytes têm dois valores Uint16 que contêm o enviesamento de chaves e registos de dados. O comprimento dos dados em duas entradas é o valor por defeito. Nas tabelas de rodapé de partialidade, os registos de dados são relativos ao início do rodapé (0x28 bytes). E para outros tipos de tabelas, esta parcialidade refere-se ao fim do bloco.

A maior parte dos significados relacionados com o cabeçalho e rodapé de uma tabela são claros, pelo menos de um tipo de leitura de tabela. Parcialidade 0x18 no rodapé (parcialidade 0xFF num bloco de 4 KB) é o número de registos na tabela e em todas as tabelas de base (se for uma tabela com um nível superior a 0, em offset 0x22). O offset 0x20 no rodapé é o número da entrada seguinte na tabela.

Tabela 0

Uma tabela de tipo 0 está localizada na estrutura do directório da árvore B entre os nós da folha e o nó de raiz. Os valores desconhecidos de 3 a 6 são apresentados como desvio e comprimento da chave. Compensações de dados e duração do próximo registo disponível. Se não houver entradas de índice livres, os offsets são definidos para "0xFFFFFF" e o comprimento "0x00".

As entradas da tabela são quatro "Uint16" valores. Os primeiros 2 - estes são os valores de enviesamento e comprimento na secção chave, e os 2 seguintes são os valores de enviesamento e conteúdo na secção de dados.

Um exemplo de tabela tipo 0 seria um identificador de nó de catálogo, uma chave de nome na secção de chave, e um identificador de objecto na secção de dados. Esta tabela não tem um rodapé.

Tabela 1

A primeira tabela tem um rodapé e o índice da tabela contém quatro valores de 16 bits, onde os 2 primeiros valores são o viés de registo da secção chave e o comprimento do registo. Os 2 valores seguintes fornecem a entrada de enviesamento da secção de dados e o seu comprimento. Esta tabela é frequentemente encontrada tanto na estrutura do directório da árvore B como na árvore de cobertura do nó de nível superior. Um exemplo são os valores: "Parent ID" e nome chave (o nome de um ficheiro ou pasta na estrutura do directório e o número de bloco inicial na árvore B de extensão), o identificador do objecto quando usado como nó raiz na estrutura do directório ou o número de bloco quando usado na árvore de extensão.

Exemplos desta tabela são mostrados abaixo:

Tabela 2

A segunda tabela. Inicialmente, esta tabela é idêntica à anterior, mas não tem rodapé. Este tipo de tabela é muito comum em nós de folhas na estrutura do directório da árvore B onde a secção chave é representada com "Parent ID" e o nome chave.

Tabela 3

A terceira tabela é idêntica à anterior. O índice da tabela é o mesmo que a primeira tabela. Os valores típicos dependem da estrutura em que são utilizados. Na estrutura de directório de árvore B e de árvore de extensão, esta tabela é frequentemente utilizada como um nó de nível superior em pequenos volumes, onde o nó de raiz é a raiz e os nós de folha. Neste caso, a entrada chave poderia ser "Parent ID". A chave do nome e a entrada de dados pode ser um ficheiro de metadados com grande variação de tamanho.

A chave do nome e a entrada de dados pode ser um ficheiro de metadados com grande variação de tamanho.

Outras entradas da tabela são identificadores de objectos "ID do objecto" e o seu tipo no registo chave, com extensão de informação do ficheiro e registos de dados. A terceira tabela tem uma página зie.

Exemplo de tabela:

Table example

Tabela 4

Tabela 4 é ligeiramente diferente das anteriores. Não há nenhum rodapé na tabela e o índice da tabela tem apenas 2 valores: Parcialidade da entrada na secção chave e 1 valor para a secção de dados. O comprimento do conteúdo é fixado em 16 bytes na secção chave e 8 bytes na secção de dados. Os offsets na secção de dados referem-se ao fim do bloco.

Tabela 5

Tabela 5 é semelhante à tabela 4. A única diferença é que este tipo tem um rodapé e todos os offsets de dados começam com "offset-0x28" (início do rodapé). As entradas na secção chave são 16 bytes e 8 bytes na secção de dados. Este tipo de tabela é mais comumente visto em nós de nível superior na estrutura do directório de árvores B e em grandes contentores com árvores escalonadas.

Tabela 6

Tabela 6 também se parece com a tabela 4. O índice da tabela é apenas parcial ao conteúdo da chave e da secção de dados, mas não ao seu comprimento. O comprimento é pré-definido. Cada entrada tem um comprimento de 16 bytes. Não existe um rodapé para este tipo de mesa. Esta tabela encontra-se frequentemente nos nós de folhas da estrutura do directório B-tree. O conteúdo típico da secção chave da tabela inclui o identificador do objecto e o ID do volume do Ponto de Controlo do Superbloco "Volume Checkpoint Superbloco ID", enquanto a secção de dados regista normalmente o tamanho e o número do bloco.

Tabela 7

Tabela 7 é semelhante à tabela 6. A única diferença é o rodapé, que contém informação semelhante à descrita para o Quadro 1. Este tipo de tabela é visto numa vasta gama de estruturas e encontra-se frequentemente nos níveis mais elevados de uma estrutura de várias camadas ou em estruturas de camada única, tais como a descrição do volume.

Exemplo

Exemplo

Síntese da tabela

Esta tabela mostra as principais propriedades de vários tipos de tabelas:

Tipo Rodapé Parcialidade da secção chave Comprimento da secção chave Parcialidade da secção de dados Comprimento da secção de dados Comprimento da chave Comprimento dos dados
0 NO uint16 uint16 uint16 uint16 Varies Possible
1 SI uint16 uint16 uint16 uint16 Varies Possible
2 NO uint16 uint16 uint16 uint16 Varies Possible
3 SI uint16 uint16 uint16 uint16 Varies Possible
4 NO uint16 uint16 >16 bytes 16 bytes
5 SI uint16 uint16 16 bytes >8 bytes
6 NO uint16 uint16 16 bytes 16 bytes
7 SI uint16 uint16 16 bytes 16 bytes

Um dos blocos mais importantes na estrutura de directório da árvore B é o nó raiz, que é o nível mais alto na estrutura de pastas. Este nó utiliza chaves de pesquisa de comprimento variável. Uma das características melhoradas de "ApFS" é uma pesquisa rápida de directório. Um valor que está intimamente relacionado com esta característica é o número de todos os registos na estrutura em árvore localizados no rodapé da tabela.

O nó raiz da estrutura de árvore B tem 2 opções de selecção de tabela, uma vez que ambos têm rodapés. Quadro 3: como um nó raiz, visto apenas em pequenos recipientes com uma pequena quantidade de ficheiros, onde o nó raiz é também um nó índice e nós foliares.

No mapa de características para o nó raiz, apenas a quinta tabela é utilizada, excepto para estruturas muito pequenas onde se pode encontrar a sétima.

A interpretação das tabelas mostra que as tabelas 0 e 2 têm o mesmo significado. O mesmo é observado entre os quadros 1 e 3. Estes quadros parecem ter objectivos diferentes dependendo da estrutura em que se encontram.

Instantaneous (Snapshots)

Snapshots são instantâneos de um sistema de arquivo só de leitura de um volume. O sistema operativo pode utilizar estes instantâneos para backups mais eficientes. Graças à "Máquina do Tempo" funcionará mais rapidamente. E graças a Time Machine suporte de instantâneo, já não precisa de manter múltiplas cópias completas de um ficheiro em disco, pode simplesmente manter um registo das alterações específicas. Por exemplo, se editar um ficheiro modificado usando HFS+, mantém duas cópias do ficheiro, a primeira regista as novas alterações e a segunda no caso de querer voltar à vista anterior. Em "APFS" apenas o ficheiro original é retido e as diferenças entre o ficheiro original e as versões actualizadas são registadas, ocupando menos espaço em disco. Tal como com os melhoramentos a Fusion Drive, a informação ocupa menos espaço em disco.

Al embora "ApFS" seja significativamente inferior nas suas capacidades ao ZFS de 128 bits, que é compatível com Linux, FreeBSD e outros sistemas operativos livres, este é um passo na direcção certa da Apple.

Como mencionado acima, a Apple tem vindo a tentar mudar o ZFS para OS X há muito tempo. Mais tarde, o OpenZFS foi implementado para OS X (O3X) e MacZFX.

Nós

Nós são recipientes flexíveis utilizados para armazenar vários tipos de registos. Podem fazer parte da árvore B ou podem existir por si próprios. Os nós podem conter entradas de tamanho fixo ou flexível. O nó começa com uma lista de apontadores para introduzir chaves e entradas. Portanto, para cada registo, o nó contém o cabeçalho de entrada no início do nó, a chave de entrada no meio do nó, e o registo de entrada no fim do nó.

Nodes (nodos)
Posição tamanho Tipo ID
0 4 uint32 alinhamento
4 4 uint32 ENTRY_COUNT
10 2 uint16 HEAD_SIZE
16 8 entry meta_entry
24 ... entry entries (repeat entry_count times)

Estrutura de cabeçalho do nó (Node header):

Parcialidade Campo Tipo de dados Comentário
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

Gestor de espaço (Space Manager)

«Space Manager» (Gestor de espaço) é utilizado para gerir blocos atribuídos num recipiente "ApFS". Armazena o número de blocos livres e um ponteiro para os ficheiros de informação de localização.

Posição tamanho Tipo ID
0 4 uint32 tamanho do bloco
16 8 uint64 totalblocks
40 8 uint64 freeblocks
144 8 uint64 prev_allocationinfofile_block
352 8 uint64 allocationinfofile_block

Allocation info file (Ficheiro de informação de distribuição)

O ficheiro de distribuição funciona como um cabeçalho em falta. É aqui que são armazenados o comprimento dos ficheiros, a versão e a sua parcialidade.

Posição tamanho 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

Ficheiro e pasta de árvore B

Registos de todos os ficheiros e pastas sobre o volume. Têm a mesma função que os ficheiros de directório em "HFS+".

Extensões (extensões de árvore B)

Uma árvore B dividida de todas as extensões no volume. As extensões são links para o conteúdo de um ficheiro com informação sobre onde começa o conteúdo dos dados e a sua extensão em blocos. Um ficheiro com algum conteúdo terá pelo menos uma extensão. Um ficheiro fragmentado terá várias extensões. A árvore de extensão é uma estrutura separada.

Em cada entrada de ficheiro, são definidas extensões para cada um destes ficheiros na árvore B. Esta estrutura de extensão separada faz parte da funcionalidade snapshot.

64-bit inodes (descritores de índice) - descritores de índice

inódios de 64 bits aumentam significativamente o espaço de nomes sobre identificadores de 32 bits em "HFS+". Sistema de ficheiros de 64 bits em "ApFS" suporta mais de 9 quintilhões de ficheiros por volume. Como Bill Gates disse, isto deve ser suficiente para todos.

"ApFS" proporciona a capacidade de restaurar certos estados do sistema de ficheiros, incluindo versões antigas ou apagadas de ficheiros. O superbloco de contentores contém uma ligação à estrutura do ponto de controlo. O ponto de controlo refere-se ao anterior superbloco do contentor, que contém informação no estado anterior do sistema de arquivo. Por conseguinte, é possível restaurar vários estados antigos através da análise da cadeia de super-bloqueio do contentor.

Vá para 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 🍏

Raidel Becerra

Autor: , Escritor técnico

Raidel Arbelay Becerra é um escritor técnico para a Hetman Software e a voz e rosto do Hetman Software: Canal YouTube de recuperação de dados. Escreve artigos aprofundados, tutoriais e resenhas sobre como funciona o software da empresa com todos os tipos de dispositivos de armazenamento.

Mykhailo Miroshnichenko

Editor: , Escritor técnico

Mykhailo Miroshnychenko é um dos principais programadores da Hetman Software. Com base em quinze anos de experiência em desenvolvimento de software, partilha os seus conhecimentos com os leitores do nosso blogue. Para além da programação, Mikhail é um especialista em recuperação de dados, sistemas de ficheiros, dispositivos de armazenamento e matrizes RAID.

Recomendado para você

Bem-vindo ao assistente com tecnologia de IA da Hetman Software.
Iniciar bate-papo