Análise de linha do tempo · Aula 1 de 5
Formatos de carimbo de data/hora: FILETIME, Unix, Apple e DOS
12 min de leitura
Um carimbo de data/hora é apenas um número até que você conheça quatro características dele: sua época (o instante a partir do qual ele conta), sua unidade, seu tamanho e ordem dos bytes e se ele registra UTC ou hora local. Errar uma delas transforma um valor correto em uma resposta errada, às vezes com décadas de diferença e às vezes com apenas algumas horas, o que é mais difícil de perceber. Os módulos anteriores decodificaram carimbos de data/hora individuais conforme eles surgiam. Esta aula reúne os formatos em uma única referência, mostra como reconhecer um formato a partir de um valor bruto e decodifica um mesmo instante em vários formatos. A aula 3.5 aborda erros de fuso horário e de relógio; aqui, informamos apenas se cada formato armazena UTC ou hora local.
Tabela de referência
| Formato | Época | Unidade e tamanho | Ordem dos bytes | Fuso | Onde é encontrado |
|---|---|---|---|---|---|
| FILETIME | 1601-01-01 | 100 ns, inteiro de 64 bits sem sinal | Little-endian | UTC | NTFS, Registro, EVTX, Prefetch, LNK |
| Tempo Chrome/WebKit | 1601-01-01 | microssegundos, inteiro de 64 bits | Inteiro SQLite | UTC | Navegadores baseados em Chromium (Módulo 4) |
| Tempo Unix | 1970-01-01 | segundos, 32 ou 64 bits | Little-endian no ext4 e no Windows; frequentemente texto | UTC | ext4, DWORDs do Registro, cabeçalhos PE, logs |
| Milissegundos / microssegundos Unix | 1970-01-01 | ms ou µs, 64 bits | Varia | UTC | JavaScript, armazenamento de navegadores, PRTime do Firefox |
| APFS | 1970-01-01 | nanossegundos, inteiro de 64 bits sem sinal | Little-endian | UTC | Inodes APFS |
| Mac Absolute Time | 2001-01-01 | segundos, frequentemente um double de 64 bits | Big-endian em plists binários | UTC | plists, bancos de dados SQLite da Apple |
| HFS+ | 1904-01-01 | segundos, inteiro de 32 bits sem sinal | Big-endian | UTC (veja abaixo) | Catálogo HFS+, imagens de disco antigas |
| Data OLE Automation | 1899-12-30 | dias, double de 64 bits | Little-endian | Definido pelo programa que grava | Bancos de dados ESE, como SRUM, Office |
| Data/hora DOS | 1980-01-01 | 2 s, duas palavras de 16 bits | Little-endian | Local (UTC em itens do shell) | FAT, exFAT, ZIP, itens do shell |
| SYSTEMTIME | nenhuma (campos) | 8 × WORD de 16 bits, 16 bytes | Little-endian | Definido pelo programa que grava | Perfis NetworkList, arquivos .job legados |
| ISO 8601 / RFC 3339 | nenhuma (texto) | texto, qualquer precisão | n/a | Informado na string, se presente | Logs, XML, JSON, XML de eventos |
Formatos do Windows
FILETIME é uma contagem de 64 bits de intervalos de 100 nanossegundos desde 1601-01-01T00:00:00Z. A estrutura tem duas metades de 32 bits (dwLowDateTime, depois dwHighDateTime), portanto, no disco, os oito bytes estão em little-endian e precisam ser invertidos antes da leitura. Para decodificar, divida por 10.000.000 para obter os segundos desde 1601 e depois subtraia 11.644.473.600, o número de segundos de 1601 a 1970, para obter o tempo Unix. Alguns artefatos armazenam FILETIME como texto: o MRU do Office [T01DCB128E569DA00] (aula 2.4) já está na ordem de leitura e não deve ser invertido.
SYSTEMTIME é uma estrutura de 16 bytes com oito WORDs little-endian: wYear, wMonth, wDayOfWeek (0 = domingo), wDay, wHour, wMinute, wSecond, wMilliseconds. Ela não tem época, então os campos são lidos diretamente. Ser UTC ou hora local depende do programa que a gravou. Os valores DateCreated e DateLastConnected dos perfis de rede em SOFTWARE\Microsoft\Windows NT\CurrentVersion\NetworkList\Profiles são SYSTEMTIME em hora local. O campo de dia da semana é uma verificação de consistência sem custo adicional: ele deve corresponder à data.
Data OLE Automation (o tipo COM DATE) é um número de ponto flutuante de 64 bits de dias desde 1899-12-30T00:00:00. A parte inteira é o dia e a fração é a hora do dia, portanto 0,5 é meio-dia. Os bancos de dados ESE armazenam colunas de data/hora dessa forma. O TimeStamp do SRUM (aula 2.8) é um exemplo, em UTC, mas outros programas gravam hora local. Para decodificar: datetime(1899,12,30) + timedelta(days=v) em Python.
Data/hora DOS compacta uma data e uma hora em duas palavras de 16 bits:
| Palavra | Bits 15–9 / 15–11 | Bits 8–5 / 10–5 | Bits 4–0 |
|---|---|---|---|
| Data | ano − 1980 (7 bits) | mês (4 bits) | dia (5 bits) |
| Hora | hora (5 bits) | minuto (6 bits) | segundos ÷ 2 (5 bits) |
Assim, data = (ano − 1980) << 9 | mês << 5 | dia, e hora = hora << 11 | minuto << 5 | segundo ÷ 2. O campo de ano abrange de 1980 a 2107, e a hora tem resolução de 2 segundos. Em uma entrada de diretório FAT, a hora de gravação está no offset 0x16 e a data de gravação em 0x18, portanto a palavra de hora vem primeiro. A hora de criação em 0x0E tem um byte complementar em 0x0D que acrescenta unidades de 10 milissegundos, e a data do último acesso em 0x12 não tem hora. FAT e os cabeçalhos ZIP básicos armazenam hora local (campos extras do ZIP podem acrescentar tempos Unix em UTC). O exFAT usa a mesma disposição em um campo de 32 bits, mas acrescenta incrementos de 10 ms e um campo de deslocamento UTC. Os itens do shell do Windows (aula 2.5) usam a mesma disposição, mas armazenam UTC. A disposição, por si só, nunca informa o fuso.
Formatos baseados em Unix
Tempo Unix conta segundos desde 1970-01-01T00:00:00Z, ignorando segundos intercalares. Um valor de 32 bits com sinal termina em 2.147.483.647, que corresponde a 2038-01-19T03:14:07Z. Ele aparece em valores do Registro como InstallDate e horários de concessão DHCP (aula 2.2), no TimeDateStamp do cabeçalho PE (embora muitos binários modernos, incluindo a maioria dos binários do Windows desde o Windows 10, armazenem ali um hash de compilação reproduzível em vez de uma hora) e em inúmeros logs. As variantes alteram apenas a unidade: milissegundos em Date.now() do JavaScript e em grande parte do armazenamento de navegadores e aplicativos, microssegundos no PRTime do Firefox (por exemplo, visit_date em places.sqlite) e nanossegundos no APFS.
O ext4 mantém segundos de 32 bits e os estende com os campos _extra: 2 bits de época mais 30 bits de nanossegundos (aula 1.6). O APFS armazena nanossegundos de 64 bits sem sinal desde 1970 UTC (aula 1.7).
O tempo Chrome/WebKit conta microssegundos desde 1601-01-01 UTC, a época do FILETIME com uma unidade menos granular. O Módulo 4 aborda os bancos de dados de navegadores que o utilizam.
Formatos da Apple
Mac Absolute Time, também chamado de tempo Cocoa ou Core Data, conta segundos desde 2001-01-01T00:00:00Z. Tempo Unix = Mac Absolute + 978.307.200. Geralmente é um double com uma parte fracionária. As listas de propriedades binárias armazenam datas dessa forma, como doubles de 64 bits big-endian, enquanto os plists XML as mostram como texto ISO 8601, como <date>2026-03-14T09:21:07Z</date>. Alguns bancos de dados mais recentes da Apple, como o banco de dados do Messages, chat.db, armazenam nanossegundos desde 2001 em vez disso.
O HFS+ armazena segundos de 32 bits sem sinal big-endian desde 1904-01-01; o intervalo termina em 2040-02-06T06:28:15. Tempo Unix = HFS+ − 2.082.844.800. As datas do catálogo HFS+ são UTC, com uma exceção documentada: a data de criação do cabeçalho do volume é hora local. O HFS clássico (Mac OS Standard) armazenava todas as datas em hora local.
Formatos de texto: ISO 8601 e RFC 3339
A ISO 8601 representa datas e horas como texto, por exemplo 2026-03-14T09:21:07Z ou 2026-03-14T06:21:07-03:00. A RFC 3339 é um perfil mais restrito dela para protocolos de internet: uma data e hora completas com Z ou deslocamento numérico obrigatório. A exibição XML do Visualizador de Eventos mostra os FILETIMEs do EVTX dessa forma, como SystemTime="2026-03-14T09:21:07.2500000Z". Uma string sem Z e sem deslocamento não informa um fuso; a ISO 8601 a trata como hora local, portanto não a identifique como UTC a menos que esteja documentado que o programa que a gravou usa UTC. O exame CFX espera respostas em ISO 8601 com Z.
Exemplo resolvido: um instante, cinco codificações
Considere 2026-03-14T09:21:07Z, em um sistema configurado para UTC−3.
Segundos Unix. De 1970-01-01 a 2026-03-14 há 20.526 dias. 20.526 × 86.400 = 1.773.446.400. Some 9 h 21 min 7 s = 33.667 s: 1.773.480.067.
FILETIME. (1.773.480.067 + 11.644.473.600) × 10.000.000 = 13.417.953.667 × 10.000.000 = 134.179.536.670.000.000 = 0x01DCB393E3578380. Armazenado em little-endian: 80 83 57 E3 93 B3 DC 01.
Mac Absolute Time. 1.773.480.067 − 978.307.200 = 795.172.867 (como double, 795172867,0).
Microssegundos WebKit. 13.417.953.667 s desde 1601 × 1.000.000 = 13.417.953.667.000.000.
DOS (local). A hora local é 09:21:07 − 3 h = 2026-03-14 06:21:07.
- Data: (2026 − 1980) << 9 | 3 << 5 | 14 = 46 × 512 + 96 + 14 = 23.662 = 0x5C6E, bytes
6E 5C. - Hora: 6 << 11 | 21 << 5 | 7 ÷ 2 = 12.288 + 672 + 3 = 12.963 = 0x32A3, bytes
A3 32. - Em uma entrada FAT em 0x16, os quatro bytes são
A3 32 6E 5C. A decodificação resulta em 3 × 2 = 06 segundos: 2026-03-14 06:21:06 local, ou 09:21:06Z. O segundo ímpar foi perdido: a fórmula o trunca, enquanto alguns programas, incluindo o Windows ao copiar um arquivo para FAT, arredondam para cima até o próximo segundo par (08) em vez disso (aula 3.5).
Para comparação, a mesma hora local como SYSTEMTIME é EA 07 03 00 06 00 0E 00 06 00 15 00 07 00 00 00 (2026, março, sábado = 6, dia 14, 06:21:07.000).
Que formato é este?
A ordem de grandeza é a pista mais rápida. Valores para 2026:
| Valor bruto em torno de | Dígitos | Formato provável |
|---|---|---|
1,34 × 10^17; bytes terminam em DC 01 ou DD 01 | 18 | FILETIME |
| 1,34 × 10^16 | 17 | Microssegundos WebKit |
| 1,77 × 10^18 | 19 | Nanossegundos Unix ou APFS |
| 1,77 × 10^15 | 16 | Microssegundos Unix (PRTime) |
| 1,77 × 10^12 | 13 | Milissegundos Unix |
| 1,77–1,80 × 10^9 | 10 | Segundos Unix |
| 7,9–8,2 × 10^8, frequentemente com uma fração | 9 | Mac Absolute Time |
| 7,9 × 10^17 | 18 | Nanossegundos Mac Absolute |
| 3,85–3,88 × 10^9 | 10 | Segundos HFS+ |
| 46.023–46.388 com uma fração | 5 + fração | Data OLE Automation |
A ordem de grandeza restringe as opções, mas não comprova o formato. O valor Mac Absolute 795.172.867 lido como segundos Unix resulta em 1995-03-14T09:21:07Z, uma data que parece perfeitamente válida. Sempre confirme com uma segunda fonte: a documentação do campo ou seu analisador, um artefato relacionado que registre o mesmo evento ou a plausibilidade em relação à data de instalação do sistema e ao horário da aquisição.
Exercício. Identifique e decodifique cada valor: (a) bytes 80 B6 F9 4D 6B E7 DC 01; (b) 1.779.180.097; (c) 800.872.897,0 em um plist; (d) 13.423.653.697.000.000 em uma coluna SQLite; (e) bytes FAT32 em 0x16 32 2D B3 5C, sistema em UTC−3.
Solução. (a) FILETIME 0x01DCE76B4DF9B680 = 134.236.536.970.000.000; ÷ 10^7 − 11.644.473.600 = 1.779.180.097 = 2026-05-19T08:41:37Z. (b) Segundos Unix, o mesmo instante. (c) Mac Absolute: + 978.307.200 = 1.779.180.097, novamente o mesmo instante; lido como Unix, resultaria incorretamente em 1995-05-19. (d) WebKit: ÷ 10^6 = 13.423.653.697 s desde 1601, menos 11.644.473.600 = 1.779.180.097. (e) Hora 0x2D32: hora 5, minuto 41, 18 × 2 = 36 s; data 0x5CB3: 1980 + 46 = 2026, mês 5, dia 19. A hora local 2026-05-19 05:41:36 é 08:41:36Z, novamente com resolução de dois segundos. Cinco fontes concordando dentro de dois segundos são exatamente a corroboração na qual a aula 3.4 se baseia.
Precisão e exatidão
Precisão é o menor incremento que um formato pode representar: 100 ns para FILETIME, 1 ns para APFS, 2 s para horários de gravação DOS, pouco menos de um microssegundo para uma data OLE em 2026. Exatidão é o quanto o valor armazenado se aproxima do instante real e depende do relógio do sistema e do programa que o gravou. Muitos FILETIMEs terminam em sete zeros porque o programa que os gravou tinha apenas segundos inteiros. Informe a precisão que a fonte realmente tem e, quando uma tarefa pedir segundos, trunque em vez de arredondar. Um FILETIME de 100 ns não é mais confiável do que uma hora DOS de 2 segundos se o relógio estava errado.
Ferramentas de decodificação
As ferramentas são auxiliares, não autoridades. O DCode decodifica a maioria dos formatos acima a partir de uma única caixa de entrada. O CyberChef oferece operações como "Converter Filetime do Windows em carimbo de data/hora UNIX" e "Converter de carimbo de data/hora UNIX". Em Python, datetime(1601,1,1,tzinfo=timezone.utc) + timedelta(microseconds=ft//10) decodifica um FILETIME, e datetime.fromtimestamp(u, timezone.utc) decodifica segundos Unix. Sem timezone.utc, fromtimestamp converte silenciosamente para o fuso local da máquina de análise. Verifique qualquer ferramenta usando um valor que você calculou manualmente.
Foco no exame: Espere valores brutos, frequentemente como bytes hexadecimais little-endian, que você deverá identificar e converter para ISO 8601 UTC com Z. Conheça as constantes 11.644.473.600 e 978.307.200, a disposição dos bits DOS e sua resolução de 2 segundos, e quais formatos armazenam hora local (DOS, HFS clássico) ou dependem do programa que os grava (SYSTEMTIME, OLE). As alternativas incorretas frequentemente apresentam o número certo decodificado com a época errada.
Pontos principais
- Todo carimbo de data/hora precisa de quatro informações: época, unidade, tamanho e ordem dos bytes, e UTC ou hora local.
- FILETIME e WebKit contam a partir de 1601 (100 ns e µs); Unix, APFS e ext4 contam a partir de 1970; Mac Absolute conta a partir de 2001; HFS+ a partir de 1904; datas OLE a partir de 1899-12-30; DOS a partir de 1980.
- Data/hora DOS é local, com resolução de 2 segundos, anos de 1980–2107; SYSTEMTIME e datas OLE são UTC ou locais, dependendo do programa que os grava.
- A ordem de grandeza e a quantidade de dígitos sugerem o formato, mas uma segunda fonte deve confirmá-lo.
- Precisão é o que o formato pode representar; exatidão depende do relógio e do programa que grava o valor.