← Voltar ao blog

Dentro de um registro MFT: cabeçalho e atributos

· 5 min de leitura

Cada entrada da Master File Table tem 1.024 bytes dispostos da mesma forma: um cabeçalho fixo, uma pequena estrutura de reparo, depois um fluxo de atributos tipados. Este post é um olhar próximo nessa disposição — o tipo de detalhe de que você precisa quando está lendo os bytes brutos de $MFT em um editor hexadecimal ou escrevendo seu próprio parser.

A assinatura FILE

Os quatro primeiros bytes de cada registro são a string ASCII FILE (46 49 4C 45). Os parsers usam isso como âncora ao escanear um volume bruto em busca de registros órfãos: toda fronteira de 1.024 bytes que começa com FILE é um registro MFT, mesmo se o cabeçalho da própria tabela for ilegível.

Um registro cujo conteúdo o chkdsk não conseguiu reparar carrega no lugar a assinatura BAAD (42 41 41 44). O NTFS mantém esses registros no lugar em vez de apagá-los — eles preservam o número de sequência do slot — mas o resto dos bytes não deve ser confiável.

O cabeçalho do registro

Os 56 bytes após a assinatura descrevem que tipo de registro é esse e como lê-lo com segurança:

  • Offset do update sequence array (2 bytes) e tamanho do array em palavras de 16 bits (2 bytes). Juntos descrevem os dados de fixup; veja abaixo.
  • Número de sequência do $LogFile (8 bytes). Aponta de volta para o log de transações para recuperação após falha.
  • Número de sequência (2 bytes). Incrementado toda vez que o slot do registro é reutilizado.
  • Contador de hard links (2 bytes). Um por atributo $FILE_NAME.
  • Offset para o primeiro atributo (2 bytes).
  • Flags (2 bytes). O bit 0 é IN_USE; o bit 1 marca um diretório.
  • Tamanho usado (4 bytes) e tamanho alocado (4 bytes) do registro. O alocado é sempre 1.024 em volumes padrão.
  • Referência ao registro base (8 bytes). Diferente de zero em registros de extensão — slots extras usados quando os atributos de um arquivo transbordam um único registro.
  • Próximo ID de atributo (2 bytes). Usado para atribuir IDs únicos a novos atributos.
  • Número do registro (4 bytes, NTFS 3.1+). Autorreferência, útil para verificação de sanidade da análise.

O número de sequência é o que torna a análise de arquivos excluídos confiável. O número do registro sozinho é reutilizado; a referência de arquivo de 64 bits (número do registro mais número de sequência) não é. Uma referência que discorda da sequência atual naquele número de registro é um ponteiro para um inquilino anterior — geralmente um arquivo excluído.

O fixup array

O NTFS detecta gravações interrompidas com um pequeno truque chamado update sequence array (USA), ou fixup array. Cada registro de 1.024 bytes é também dividido em dois setores de 512 bytes. O NTFS:

  1. Escolhe um update sequence number (USN — não relacionado ao USN do $UsnJrnl apesar do acrônimo compartilhado) de 16 bits.
  2. Substitui os dois últimos bytes de cada setor de 512 bytes por esse USN antes de gravar.
  3. Armazena os dois últimos bytes originais de cada setor no fixup array, em ordem, logo após o próprio USN.

Na leitura, o NTFS verifica que os dois últimos bytes de cada setor coincidem com o USN. Se sim, os setores foram escritos juntos; os bytes originais são puxados do fixup array e colocados de volta no lugar. Se a cauda de algum setor não bater, a gravação foi interrompida e o registro é suspeito.

Isso significa que um parser que lê $MFT byte por byte sem aplicar os fixups vai obter lixo nos offsets 510 e 1022 de cada registro. Todo parser MFT sério aplica o fixup como primeiro passo após localizar um registro.

O fluxo de atributos

Depois do cabeçalho (e do fixup array) vêm os atributos do arquivo. Cada atributo começa com seu próprio cabeçalho curto — código de tipo, comprimento, flag residente ou não residente, nome opcional — seguido pelos dados do atributo. Os atributos são alinhados em 8 bytes, escritos um após o outro e terminados por uma sentinela 0xFFFFFFFF.

Um registro mínimo carrega três:

  • $STANDARD_INFORMATION (0x10) — carimbos de tempo e flags DOS.
  • $FILE_NAME (0x30) — nome, referência ao diretório pai e um segundo conjunto de carimbos de tempo.
  • $DATA (0x80) — o conteúdo do arquivo, residente inline para arquivos pequenos ou uma lista de cluster runs caso contrário.

Os registros podem carregar muito mais, incluindo $ATTRIBUTE_LIST quando os atributos do arquivo crescem além de um único slot de 1.024 bytes. A lista completa está na referência da Master File Table.

Por que isso importa para a forense

A combinação de um layout estável de 1.024 bytes e da assinatura FILE é o que torna o carving de arquivos NTFS excluídos possível. Mesmo que a própria $MFT tenha sumido, uma varredura do volume bruto em busca de cabeçalhos FILE recupera a maioria dos registros — incluindo os nomes, os carimbos de tempo e (para arquivos pequenos) os dados das entradas excluídas. O mecanismo de fixup significa que esses registros carvados podem ser confiados desde que o USA verifique.

Recursos externos