Na semana passada o Emmanuel Brandão me pediu ajuda com um problema que ele estava tendo num cliente:

(um sistema) está criando uns arquivos com extensão .log, mas são arquivos binários… vc sabe como eu abro isso?
são arquivos com 300Mb, tentei abrir no Notepad e não rolou, travou
então tentei no Code e daí deu a mensagem que são arquivos binários

Como eram arquivos de log, eles não deveriam ser binários. Havia algo de errado…

O problema é que ele não estava conseguindo abrir no Bloco de Notas nem no Visual Studio Code. E, como era uma máquina no cliente, ele não podia instalar nenhum outro editor lá.

#comofaz?

Afinal, são arquivos binários ou não?

Essa era a primeira coisa que não fazia muito sentido. Arquivos de log binários?

Por isso, o primeiro passo era descobrir se o arquivo era mesmo binário. Se fosse, precisaríamos descobrir qual o formato para saber qual programa precisaríamos usar para então abrir aqueles logs.

O grande “truque” aqui é tirar proveito dos magic bytes: Identificadores comumente utilizados nos cabeçalhos de arquivos e que são usados para identificar seu formato. Eles servem como uma “assinatura” do formato do arquivo. Assim, bastaria ver os primeiros bytes da maioria dos arquivos binários para descobrirmos seu formato, sem depender de nome ou extensão (que podem estar errados).

Quer ver como funciona? Dá uma olhada em alguns exemplos de formatos de arquivos que têm magic bytes. Vou imprimir os primeiros 16 bytes de alguns tipos comuns de arquivos binários:

Arquivos EXE (magic number 0x4D 0x5A, “MZ”)

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00  MZ.............

Arquivos ZIP (magic number 0x50 0x4B, “PK”)

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

50 4B 03 04 14 00 02 00 08 00 09 91 5B 40 86 7F  PK.........‘[@†

Arquivos PNG (magic number 0x89 0x50 0x4E 0x47, “.PNG”)

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

89 50 4E 47 0D 0A 1A 0A 00 00 00 0D 49 48 44 52  ‰PNG........IHDR

Arquivos RAR (magic number 0x52 0x61 0x72 0x21, “Rar!”)

00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

52 61 72 21 1A 07 00 CF 90 73 00 00 0D 00 00 00  Rar!...ϐs......

Viu só? Apenas “batendo o olho” nos primeiros bytes de um arquivo binário é provável que você consiga descobrir o seu formato. Aliás, tem uma lista bem extensa de magic numbers de diversos formatos de arquivo na Wikipedia.

PowerShell ao resgate!

Agora que sabemos como identificar o formato de um arquivo a partir dos seus bytes iniciais, como fazer para ler esses bytes?

“Elementar, meu caro Watson”. Com PowerShell! 😃

O truque aqui é combinar dois cmdletsGet-Content e Format-Hex. É possível orientar o Get-Content para pegar apenas os primeiros bytes de um arquivo e então usar o Format-Hex para torná-los legíveis. Veja um exemplo:

Get-Content C:\Windows\System32\cmd.exe -TotalCount 16 -Encoding Byte | Format-Hex

Usei os argumentos -TotalCount (para limitar a quantidade de bytes) e -Encoding (para ler como bytes e não como texto). O resultado desse comando é um array de bytes, que formatei usando o Format-Hex. O resultado?

PS C:\> Get-Content C:\Windows\System32\cmd.exe -TotalCount 16 -Encoding Byte | Format-Hex


           Path:

           00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F

00000000   4D 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00  MZ.............

Curtiu a dica? Não esqueça de deixar seu comentário!

Um abraço,
Igor

(Cross-post de http://www.tshooter.com.br/2017/03/10/como-obter-os-primeiros-bytes-de-um-arquivo-com-powershell)

Igor Abade

Igor Abade V. Leite ([email protected]) é Microsoft MVP (Most Valuable Professional) de Visual Studio ALM desde 2006. Palestrante em diversos eventos da comunidade de desenvolvimento de software (TechEd Brasil, The Developers’ Conference, DevOps Summit Brasil, Agile Brazil, Visual Studio Summit, QCON e outros), é também autor de artigos em revistas e sites como o MSDN Brasil. Desde março de 2011 é um dos sócios da Lambda3, uma consultoria especializada em ALM, desenvolvimento de software e treinamentos. Siga-o no Twitter @igorabade.