Como posso visualizar o conteúdo binário de um arquivo nativamente no Windows 7? (É possível.)


35

Eu tenho um arquivo, um pouco maior que 500 MB, que está causando alguns problemas.

Acredito que o problema esteja no fim da linha (EOL) da convenção usada. Gostaria de examinar o arquivo em sua forma bruta não interpretada (1) para confirmar a convenção EOL do arquivo.

Como posso visualizar o "binário" de um arquivo usando algo incorporado ao Windows 7? Eu preferiria evitar ter que baixar qualquer coisa adicional.

(1) Meu colega e eu abrimos o arquivo nos editores de texto e eles mostram as linhas como seria de esperar. Mas os dois editores de texto abrirão arquivos com diferentes convenções de EOL e os interpretarão automaticamente. (TextEdit e Emacs 24.2. Para o Emacs, criei um segundo arquivo com apenas os primeiros bytes de 4K usando head -c4096uma caixa Linux e abri-o na caixa do meu Windows.

Tentei usar o modo hexl no Emacs, mas quando fui para o modo hexl e retornei ao modo de texto, o conteúdo do buffer mudou, adicionando um ^ M visível ao final de cada linha, por isso não estou confiando nisso no momento.

Acredito que o problema possa estar no final dos caracteres de linha usados. Os editores que eu e meu colega de trabalho tentamos (1) reconheceram automagicamente a convenção de fim de linha e nos mostraram as linhas. E com base em outras evidências, acredito que a convenção da EOL é apenas para retorno de carro. (2) somente retorno.

Para saber o que realmente está no arquivo, eu gostaria de examinar o conteúdo binário do arquivo, ou pelo menos alguns milhares de bytes do arquivo, preferencialmente em Hex, embora eu possa trabalhar com decimal ou octal. Apenas os zeros seriam bem difíceis de se olhar.

ATUALIZAR

Exceto o que sugere DEBUG, todas as respostas abaixo funcionam em certa medida ou em outra. Votei cada um deles como útil. Minha pergunta foi mal formada. Ao testar cada solução sugerida, achei que realmente queria exibir lado a lado o conteúdo hexadecimal e de texto, e que queria que fosse algo em que, quando eu tivesse o cursor sobre alguma coisa, um valor de byte ou o caractere de texto, a coisa correspondente na outro lado seria destacado.

Na verdade, eu resolvi meu problema quando o modo hexl do Emacs começou a funcionar "corretamente". Acabei não usando nenhuma dessas respostas, apenas as testando (realmente deveria investigar o comportamento estranho do Emacs e registrar um relatório de erro).


É provável que exista algum tipo de ferramenta no Cygwin, mas isso exigiria a instalação do Cygwin. Ou, se você tem, por exemplo, Java instalado em sua caixa, seria uma tarefa bastante simples escrever um programa hex dump em Java.
Daniel R Hicks

Respostas:


11

Você precisa de um "editor hexadecimal". Eu uso o "Hex Editor Neo" há anos e é muito bom. Está disponível nas versões gratuita e paga . (E tenho certeza de que existem outras ferramentas semelhantes disponíveis.)


4
Eu havia perguntado como, sem nada além do Windows 7, porque não gosto de adicionar programas adicionais porque 1) Muitos instalam de uma maneira que os direitos que tenho não permitem. 2) Alguns parecem desonestos. Dito isso, o Hex Editor Neo parece ser uma boa recomendação. +1
Shannon Severance

1
zblist.com é um programa autônomo que não precisa ser instalado ou precisa de quaisquer direitos especiais e tem uma Alt-H ou modo hex
sgmoore

Atendeu a todos os meus requisitos, incluindo declarado, incorreto e não declarado. O Hex Editor Neo também foi rápido e foi adicionado à minha bolsa de ferramentas.
Shannon Severance

1. Outros editores não são nativos. 2. Os gerenciadores de arquivos são bons para esse fim e existem muitos portáteis. 3. O comando Type pode exibir o conteúdo nativamente e possui filtros úteis (como página por página).
Overmind

37

Se você possui o powershell versão 5.0 ou posterior, pode usar a powershellfunção internaFormat-Hex

PS:21 C:\Temp >Format-Hex application.exe

            0  1  2  3  4  5  6  7  8  9  A  B  C  D  E  F

00000000   42 4D 5E 00 00 00 00 00 00 00 36 00 00 00 28 00  BM^.......6...(. 
00000010   00 00 0A 00 00 00 01 00 00 00 01 00 20 00 00 00  ............ ... 
00000020   00 00 00 00 00 00 C4 0E 00 00 C4 0E 00 00 00 00  ......Ä...Ä..... 
00000030   00 00 00 00 00 00 B7 59 71 FF B7 59 71 FF B7 59  ......•Yq.•Yq.•Y 
00000040   71 FF B7 59 71 FF B7 59 71 FF B7 59 71 FF B7 59  q.•Yq.•Yq.•Yq.•Y 
00000050   71 FF B7 59 71 FF B7 59 71 FF B7 59 71 FF        q.•Yq.•Yq.•Yq.

4
Estou francamente surpreso que esta não seja a resposta principal. Essa é a maneira correta de fazer isso usando uma ferramenta interna do Windows. Se você deseja gravar a saída em um arquivo, pode usar> Format-Hex application.exe> ​​out.txt
techdude

Parece bom, mas Format-Hexnão está disponível no meu PowerShell; Acabei de receber um erro "não reconhecido"
Kidburla

De acordo com JamieSee, aparentemente não foi adicionado até o PowerShell 5.0.
techdude

26

Integrado, rápido e sujo: inicie powershell, execute:

gc -encoding byte -TotalCount 100 "your_file_path" |% {write-host ("{0:x}" -f $_) -noNewline " "}; write-host   

TotalCount é a contagem de bytes que você deseja ler do arquivo.

Google 'powershell hexdump' para obter versões muito mais polidas / viáveis.

Se você possui as Ferramentas do Windows Resource Kit (não exatamente integradas, mas fechadas), também pode usar um utilitário de linha cmd chamado list.exe. É um pequeno editor com o modo hexadecimal. Projetado especificamente para trabalhar com arquivos grandes:

A ferramenta List File File (List) é uma ferramenta de linha de comando que exibe e pesquisa um ou mais arquivos de texto. Ao contrário de outras ferramentas de exibição de texto, a Lista não lê o arquivo inteiro na memória quando você o abre. Ele permite que um usuário edite um arquivo de texto em um formato hexadecimal.

A lista é útil para exibir arquivos de texto ou log remotamente e para uso em servidores nos quais os administradores estão preocupados com a degradação do desempenho do sistema.


1
Até agora, essa solução é a mais próxima que eu estava pedindo.
Shannon Severance

1
Bom, simples, já instalado. Alterei o formato para host de gravação ("{0: X2}" para forçar 0x0A a aparecer como "0A" e não "A", os 2 por 2 dígitos em maiúsculas porque é assim que eu gosto
Adam Straughan

1
List.exe foi perfeito - o list.exe /?comando help não fornece muitas informações, mas uma vez dentro do editor, basta clicar ?para ver os comandos. Habre o editor Hex, e F1alterna a forma como o Hex é exibido
Coruscate5

7

Isso também funciona em tudo após o XP:

certutil -encodehex MyProgram.exe MyProgram.txt

O XP requer o Pacote de Ferramentas Administrativas do Windows Server 2003 a partir daqui:

https://www.microsoft.com/en-us/download/details.aspx?id=16770


mais solução portátil e de trás compatível nas janelas, poderia ser usado até mesmo a partir de scripts janelas lote, espantado porque é que esta ainda não está no topo de todas as respostas
Andry

6

Copie o arquivo para um nome com uma .COMextensão, onde o nome base não tenha mais que oito caracteres. Corre

DEBUG your_filename

Ele dará um -prompt ' '. Tipo

DEnter

repetidamente para d isplay o arquivo 128 bytes de cada vez. Tipo

D endereço Enter

para exibir 128 bytes começando no endereço , que deve ser digitado em hexadecimal, em que o início do arquivo é o endereço 100. Digite

D endereço 1 endereço 2 Enter

para exibir do endereço 1 para o endereço 2 . Tipo

D endereço Lnum Enter

para exibir num bytes (comprimento) começando no endereçonum também é inserido em hexadecimal. Use Qpara sair.

Por exemplo,

C:\Users\scott\Documents> debug thispost.com
-d
0BE4:0100  43 6F 70 79 20 74 68 65-20 66 69 6C 65 20 74 6F   Copy the file to
0BE4:0110  20 61 20 6E 61 6D 65 20-77 69 74 68 20 61 20 2E    a name with a .
0BE4:0120  43 4F 4D 20 65 78 74 65-6E 73 69 6F 6E 2C 20 77   COM extension, w
0BE4:0130  68 65 72 65 20 74 68 65-20 62 61 73 65 20 6E 61   here the base na
0BE4:0140  6D 65 20 69 73 20 6E 6F-20 6C 6F 6E 67 65 72 20   me is no longer
0BE4:0150  74 68 61 6E 20 65 69 67-68 74 20 63 68 61 72 61   than eight chara
0BE4:0160  63 74 65 72 73 2E 0D 0A-52 75 6E 20 44 45 42 55   cters...Run DEBU
0BE4:0170  47 20 2A 79 6F 75 72 5F-66 69 6C 65 6E 61 6D 65   G *your_filename
-d
0BE4:0180  2A 0D 0A 49 74 20 77 69-6C 6C 20 67 69 76 65 20   *..It will give
0BE4:0190  61 20 27 2D 27 20 70 72-6F 6D 70 74 2E 0D 0A 54   a '-' prompt...T
0BE4:01A0  79 70 65 20 44 20 45 6E-74 65 72 20 72 65 70 65   ype D Enter repe
0BE4:01B0  61 74 65 64 6C 79 20 74-6F 20 2A 2A 64 2A 2A 69   atedly to **d**i
0BE4:01C0  73 70 6C 61 79 20 74 68-65 20 66 69 6C 65 20 31   splay the file 1
0BE4:01D0  32 38 20 62 79 74 65 73-20 61 74 20 61 20 74 69   28 bytes at a ti
0BE4:01E0  6D 65 2E 0D 0A 54 79 70-65 20 44 20 5F 61 64 64   me...Type D _add
0BE4:01F0  72 65 73 73 5F 20 74 6F-20 64 69 73 70 6C 61 79   ress_ to display
-d 200 L16
0BE4:0200  20 31 32 38 20 62 79 74-65 73 20 73 74 61 72 74    128 bytes start
0BE4:0210  69 6E 67 20 61 74                                 ing at
-

3
Infelizmente, isso não funcionará se o arquivo for maior que cerca de 64 KB, o máximo para um .COM. (Ele deve caber no segmento que começa no deslocamento 100h.) #
Ken

1
C:\>attrib debug.exe /s. Resultados: File not found - debug.exe. Não foi possível encontrar o funcionário, a depuração não é mais uma declaração suportada , mas pelo que vi na Web, parece que o suporte a depuração foi descartado há algum tempo. Encontrei DebugDiag da Microsoft. (Download extra.) Depuração? Talvez ele suporte a visualização de arquivos em HEX? Entregue como um arquivo .MSI. Precisa de uma senha de administrador para instalar. Eu não sou um.
Shannon Severance

@ Ken já tinha usado head -c4096 bigFileName > smallFileNameno linux para obter os primeiros 4 KB dos arquivos. Linhas são pequenos o suficiente para que quatro KB tem abundância de linhas para os meus propósitos
Shannon Severance

Então, por que não usar hexdump -Cenquanto estiver no Linux?
Ken

3
A depuração @ Shannon faz parte do DOS e, como tal, se você estiver usando x64, ele não estará lá.
kinokijuf



2

Não é o ideal, mas se você realmente não deseja baixar nada, tente usar fc / b (isto é, comparação de arquivos no modo binário) para comparar esse arquivo com outro arquivo completamente diferente, e ele mostrará o código hexadecimal valores de cada byte diferente. Você pode obter alguns valores que são iguais nos dois arquivos e, portanto, podem ser ignorados na saída, mas é possível saber se isso acontece verificando os valores ausentes na coluna de deslocamento.


Não é o ideal, mas consegui criar um arquivo de 0x00 bytes e depois comparar com isso. Sendo um arquivo de texto que eu estava olhando, e que eu estava interessado em 0a e 0d, principalmente um arquivo de nulos conforme a comparação funcionava. Mas não fornece a visualização de caracteres e a visualização hexadecimal, lado a lado, para descobrir onde eu queria parecer mais. (Como depuração faz em resposta de Scott e como modo de hexl do Emacs faz eu não tinha pedido lado a lado vista, mas é muito crucial para como eu realmente usar dumps hexadecimais..)
Shannon Severance

2

Você pode usar a função PowerShell abaixo, juntamente com Get-Content, para ver um hexdump do conteúdo do arquivo, ou seja Get-Content -Encoding Byte 'MyFile.bin' | Format-HexDump,. Demora cerca de 23 segundos para despejar um arquivo de 222 KB e, se desejado, a saída pode ser redirecionada para um arquivo de texto para facilitar a análise do despejo.

$encodingAutoCompleter = {
    param($commandName, $parameterName, $wordToComplete, $commandAst, $fakeBoundParameters)
    $availableEncodings = ([System.Text.Encoding]::GetEncodings() | Select Name, CodePage, DisplayName) + @( [PSCustomObject] @{ CodePage = '20127'; Name = 'ascii'; DisplayName = 'US-ASCII' }, [PSCustomObject] @{ CodePage = '1200'; Name = 'unicode'; DisplayName = 'Unicode' } )
    $availableEncodings | ?{ $_.Name.StartsWith($wordToComplete) } | %{ New-Object System.Management.Automation.CompletionResult -ArgumentList $_.Name, $_.Name, 'ParameterValue', "$($_.DisplayName). Code Page $($_.CodePage)." }
}

function Format-BufferText([byte[]] $buffer, [System.Text.Encoding] $displayEncoding, [switch] $useControlPictures)
{
    $bufferChars = $displayEncoding.GetChars($buffer);
    $bufferText = (($bufferChars | %{ if ([char]::IsControl($_) -eq $true) { if ($useControlPictures -eq $false) { '.' } else { [char] ($_.ToInt16([cultureinfo]::InvariantCulture) + 0x2400) } } else { "$_" } }) -join "")

    $bufferText
}

<#
    .Synopsis
    Displays binary data as a hexadecimal dump.

    .Description
     Displays binary data as a hexadecimal dump. Options are available to suppress displaying text and to display control characters 
     as Unicode Control Pictures instead of dots.

    .Parameter Bytes
    The bytes to be displayed.

    .Parameter Encoding
    The name of the text encoding to use. The default is ascii.

    .Parameter NoTextDisplay
    If specified the text display sidebar will be suppressed; otherwise, the display text sidebar will be present.

    .Parameter UseControlPictures
    If specified control characters will be displayed as Unicode Control pictures; otherwise, dots are used to represent control 
    characters.

    .Example
    Format-HexDump -Encoding unicode $bytes

    .Example
    Get-Content -Encoding Byte 'MyFile.bin' | Format-HexDump -Encoding unicode

    .Example
    0..255 | Format-HexDump -NoTextDisplay
#>
function Format-HexDump
{
    [CmdletBinding()]
    param
    (
        [Parameter(ValueFromPipeline = $true, ValueFromPipelineByPropertyName = $true)]
        [byte[]] $Bytes,
        [ValidateScript({ if (([System.Text.Encoding]::GetEncodings().Name + @('unicode', 'ascii')) -icontains $_) { return $true } else { Throw "Encoding must be one of the following: $([System.Text.Encoding]::GetEncodings().Name -join ', '), unicode, or ascii." } })]
        [Parameter(ValueFromPipeline = $false)]
        [string] $Encoding = "ASCII",
        [Parameter()]
        [switch] $NoTextDisplay,
        [Parameter()]
        [switch] $UseControlPictures
    )

    BEGIN
    {
        $displayEncoding = [System.Text.Encoding]::GetEncoding($Encoding)

        $counter = 0
        $hexRow = ""
        [byte[]] $buffer = @()
    }

    PROCESS
    {
        foreach ($byte in $Bytes)
        {
            $buffer += $byte
            $hexValue = $byte.ToString("X2")

            if ($counter % 16 -eq 0)
            {
                $buffer = @($byte)
                $hexRow = "$($counter.ToString("X8")): $($hexValue) "
            }
            elseif ($counter % 16 -eq 15)
            {
                if ($NoTextDisplay -eq $true)
                {
                    $hexRow += "$($hexValue)"
                    $hexRow
                }
                else
                {
                    $bufferText = Format-BufferText $buffer $displayEncoding $UseControlPictures
                    $hexRow += "$($hexValue)   $($bufferText)"
                    $hexRow
                }
            }
            else
            {
                $hexRow += "$($hexValue) "
            }

            $counter++
        }
    }

    END
    {
        $counter--

        if ($counter % 16 -ne 15)
        {
            $hexRow += " " * (((16 - $counter % 16) * 3) - 1)

            if ($NoTextDisplay -eq $false)
            {
                $bufferText = Format-BufferText $buffer $displayEncoding $UseControlPictures
                $hexRow += "$($bufferText)"
            }

            $hexRow
        }
    }
}

Register-ArgumentCompleter -CommandName Format-HexDump -ParameterName Encoding -ScriptBlock $encodingAutoCompleter

A saída é assim:

00000000: 00 01 02 03 04 05 06 07 08 09 0A 0B 0C 0D 0E 0F   ................
00000010: 10 11 12 13 14 15 16 17 18 19 1A 1B 1C 1D 1E 1F   ................
00000020: 20 21 22 23 24 25 26 27 28 29 2A 2B 2C 2D 2E 2F    !"#$%&'()*+,-./
00000030: 30 31 32 33 34 35 36 37 38 39 3A 3B 3C 3D 3E 3F   0123456789:;<=>?
00000040: 40 41 42 43 44 45 46 47 48 49 4A 4B 4C 4D 4E 4F   @ABCDEFGHIJKLMNO
00000050: 50 51 52 53 54 55 56 57 58 59 5A 5B 5C 5D 5E 5F   PQRSTUVWXYZ[\]^_
00000060: 60 61 62 63 64 65 66 67 68 69 6A 6B 6C 6D 6E 6F   `abcdefghijklmno
00000070: 70 71 72 73 74 75 76 77 78 79 7A 7B 7C 7D 7E 7F   pqrstuvwxyz{|}~.
00000080: 80 81 82 83 84 85 86 87 88 89 8A 8B 8C 8D 8E 8F   ????????????????
00000090: 90 91 92 93 94 95 96 97 98 99 9A 9B 9C 9D 9E 9F   ????????????????
000000A0: A0 A1 A2 A3 A4 A5 A6 A7 A8 A9 AA AB AC AD AE AF   ????????????????
000000B0: B0 B1 B2 B3 B4 B5 B6 B7 B8 B9 BA BB BC BD BE BF   ????????????????
000000C0: C0 C1 C2 C3 C4 C5 C6 C7 C8 C9 CA CB CC CD CE CF   ????????????????
000000D0: D0 D1 D2 D3 D4 D5 D6 D7 D8 D9 DA DB DC DD DE DF   ????????????????
000000E0: E0 E1 E2 E3 E4 E5 E6 E7 E8 E9 EA EB EC ED EE EF   ????????????????
000000F0: F0 F1 F2 F3 F4 F5 F6 F7 F8 F9 FA FB FC FD FE FF   ????????????????

Ou apenas use Format-Hex filename
techdude

O @techdude Format-Hex não está disponível em todas as versões do PowerShell. Não existe no PowerShell 4 e versões anteriores. Eu escrevi esse código antes que o Format-Hex existisse.
JamieSee

Como reverter isso de volta para o arquivo binário?
Zimba


0

Eu sei que você está usando o Emacs, mas os usuários do Vim podem usar o xxdutilitário:

xxd -s <start_offset> -l <length_offest> <file>

ie

Usage:
       xxd.exe [options] [infile [outfile]]
    or
       xxd.exe -r [-s [-]offset] [-c cols] [-ps] [infile [outfile]]
Options:
    -a          toggle autoskip: A single '*' replaces nul-lines. Default off.
    -b          binary digit dump (incompatible with -ps,-i,-r). Default hex.
    -c cols     format <cols> octets per line. Default 16 (-i: 12, -ps: 30).
    -E          show characters in EBCDIC. Default ASCII.
    -g          number of octets per group in normal output. Default 2.
    -h          print this summary.
    -i          output in C include file style.
    -l len      stop after <len> octets.
    -ps         output in postscript plain hexdump style.
    -r          reverse operation: convert (or patch) hexdump into binary.
    -r -s off   revert with <off> added to file positions found in hexdump.
    -s [+][-]seek  start at <seek> bytes abs. (or +: rel.) infile offset.
    -u          use upper case hex letters.
    -v          show version: "xxd V1.10 27oct98 by Juergen Weigert (Win32)".
Ao utilizar nosso site, você reconhece que leu e compreendeu nossa Política de Cookies e nossa Política de Privacidade.
Licensed under cc by-sa 3.0 with attribution required.