Resultados 1 a 2 de 2
  1. #1
    Newbie
    Data de Ingresso
    May 2011
    Localização
    São Paulo
    Posts
    62

    Programação C# II - Criando um HexDump

    Salve manolos , novamente aqui trazendo mais um tuto, hoje sobre como criar um HexDump em C#.
    Para quem nunca ouviu falar nisso, HexDump é uma espécie de operação em que podemos listar o conteúdo de um arquivo ou ainda de uma área da memória, byte a byte em hexadecimal e ASCII. Muitas vezes é útil para ver o que existe no arquivo e conseguirmos algumas informações interessantes.
    Para quem nunca viu ou talvez viu e não sabia o que era:



    No nosso caso criaremos um HexDump para arquivos.

    Vamos utilizar o Visual Studio (2005 ou superior). Criem um projeto do tipo Console Application, o nome do projeto fica da escolha de vcs.
    Após a criação do projeto, criem uma classe com o nome de HexDump, e vamos começar a implementá-la.

    Código PHP:
    private const int MAXBYTES 16;
    private 
    StreamWriter writer;
    private 
    string hexbyte;
    private 
    int gravados 0;
    private 
    int[] bytes = new int[MAXBYTES]; 
    Começamos declarando as variáveis/constantes da classe. A constante MAXBYTES irá controlar o número de bytes escritos em cada linha, já que estamos falando de hexadecimal, esse valor será 16. A variável writer (StreamWriter) não é nada mais do que o objeto que utilizaremos para escrever no nosso arquivo que irá gerar o hexdump. As variáveis hexbyte e gravados também irão nos auxiliar no controle e escrita dos bytes no arquivo, mais a frente o entendimento delas será mais fácil. Por último a array int[] bytes, irá guardar cada byte dos 16 bytes de cada linha.

    Código PHP:
    public Hexdump(string caminho)
    {
        
    writer = new StreamWriter(caminho);

    Esse será o construtor da nossa classe. Ao instanciá-la devemos passar o caminho de onde será salvo nosso arquivo com o resultado do hexdump.

    Código PHP:
    public void GetByte(int b)
    {
        
    bytes[gravados] = b;
        
    gravados++;
        if (
    gravados == MAXBYTES)
        {
            
    Gravar();
        }

    O método GetByte será o método que irá receber cada byte lido do arquivo. Como vcs podem ver cada byte que é passado ao método é armazenado na array, até o momento que seja gravado 16 bytes dentro da array (MAXBYTES = 16) ou seja, 1 linha inteira. Vamos ver agora o que é o método Gravar().

    Código PHP:
    public void Gravar()
    {
        if (
    gravados <= 0)
        {
            return;
        }

        for (
    int i 0MAXBYTESi++)
        {
            if (
    >= gravados)
            {
                
    writer.Write("   ");
            }
            else
            {
                
    hexbyte HexString(bytes[i]);
                
    writer.Write(hexbyte);
                
    writer.Write(" ");
            }
        }

        
    writer.Write("  ");

        for (
    int i 0MAXBYTESi++)
        {
            if (
    >= gravados)
            {
                
    writer.Write(" ");
            }
            else
            {
                
    char ch Ascii(bytes[i]);
                
    writer.Write(ch);
            }
        }

        
    writer.WriteLine("");

        
    gravados 0;

    Vamos dividir em 2 partes para entender esse método:

    Código PHP:
        if (gravados <= 0)
        {
            return;
        }

        for (
    int i 0MAXBYTESi++)
        {
            if (
    >= gravados)
            {
                
    writer.Write("   ");
            }
            else
            {
                
    hexbyte HexString(bytes[i]);
                
    writer.Write(hexbyte);
                
    writer.Write(" ");
            }
        }

        
    writer.Write("  "); 
    O método começa fazendo uma validação para verificar se a variável gravados é menor ou igual a zero. Caso verdadeiro, o método não deve fazer nada, pois não há bytes para gravar no arquivo. Em seguida, o loop varre os 16 bytes da array, convertendo cada byte em hexadecimal e escrevendo-o no arquivo, seguido de um espaço para separarmos cada byte. Após o loop terminar de varrer os 16 bytes, ele escreve um espaço no arquivo para iniciarmos a escrita ASCII de cada um desses bytes:

    Código PHP:
    for (int i 0MAXBYTESi++)
        {
            if (
    >= gravados)
            {
                
    writer.Write(" ");
            }
            else
            {
                
    char ch Ascii(bytes[i]);
                
    writer.Write(ch);
            }
        }

        
    writer.WriteLine("");

        
    gravados 0
    Esse loop é bem parecido com o anterior, varre os 16 bytes da array, porém escreve-os no arquivo no formato ASCII, e termina pulando uma linha no arquivo (writer.WriteLine("")), para que os próximos 16 bytes já sejam escritos na linha correta, e assim por diante.
    A variável "gravados" também é setada de volta para 0, afinal já gravamos todos os 16 bytes dessa linha.

    Dentro do método Gravar(), utilizamos 2 funções que ainda não as criamos: HexString e Ascii. Então vamos criá-las...

    Código PHP:
    public static string HexString(int b)
    {
        return 
    b.ToString("X").PadRight(2'0');

    O método HexString é bem simples, recebe o byte dentro de uma variável inteiro e a converte para hexadecimal. Para quem nunca viu isso, ao passar "X" para o método ToString, além de converter a variável para uma string, ele converte o valor para hexadecimal. Simples né? :P também chamamos o método PadRight para ter certeza que cada byte será representado por 2 caracteres. O zero deve ser exibido dessa forma '00'.

    Código PHP:
    public static char Ascii(int b)
    {
        if (
    >= 32 && <= 126)
        {
            return (
    char)b;
        }
        return 
    '_';

    O método Ascii serve para nos certificarmos que esse byte está dentro dos caracteres que conhecemos, ou seja, letras, números e etc. Caso ele não faça parte, será substituído por um _ (underline). Normalmente em um HexDump ao invés de underline, é utilizado um ponto (.), portanto fica da forma que vcs preferirem.

    Código PHP:
    public void Fechar()
    {
        
    writer.Close();

    Por último, o método responsável por fechar a nossa Stream.

    Nossa classe já está pronta agora falta implementar a parte que irá utilizar a nossa classe. Faremos isso direto dentro do método Main.

    Código PHP:
    Hexdump dump = new Hexdump(@"c:\dump.txt");
    FileStream fs File.OpenRead(@"c:\WINDOWS\system32\notepad.exe");
    while (
    fs.Position fs.Length)
    {
        
    int b fs.ReadByte();
        
    dump.GetByte(b);
    }
    dump.Fechar(); 
    A primeira linha declara e instância a nossa classe, passando como parâmetro o local onde será salvo o nosso arquivo. Em seguida utilizamos a classe FileStream, para abrir como leitura um executável qualquer. O loop while irá ler o arquivo até o seu fim, desse modo a variável b receberá cada byte do arquivo e passará para o método GetByte da nossa classe que fará todo o trabalho. Finalizamos chamando o método que fechará a nossa stream, e consequentemente fechando e salvando o nosso arquivo.

    Segue abaixo o código das classes HexDump.cs e Program.cs respectivamente:

    HexDump.cs
    Código PHP:
    using System;
    using System.IO;

    namespace 
    ConsoleApplication2
    {
        public class 
    Hexdump
        
    {
            private const 
    int MAXBYTES 16;
            private 
    StreamWriter writer;
            private 
    string hexbyte;
            private 
    int gravados 0;
            private 
    int[] bytes = new int[MAXBYTES];

            public 
    Hexdump(string caminho)
            {
                
    writer = new StreamWriter(caminho);
            }

            public 
    void GetByte(int b)
            {
                
    bytes[gravados] = b;
                
    gravados++;
                if (
    gravados == MAXBYTES)
                {
                    
    Gravar();
                }
            }

            public static 
    string HexString(int b)
            {
                return 
    b.ToString("X").PadRight(2'0');
            }

            public static 
    char Ascii(int b)
            {
                if (
    >= 32 && <= 126)
                {
                    return (
    char)b;
                }
                return 
    '_';
            }

            public 
    void Gravar()
            {
                if (
    gravados <= 0)
                {
                    return;
                }

                for (
    int i 0MAXBYTESi++)
                {
                    if (
    >= gravados)
                    {
                        
    writer.Write("   ");
                    }
                    else
                    {
                        
    hexbyte HexString(bytes[i]);
                        
    writer.Write(hexbyte);
                        
    writer.Write(" ");
                    }
                }

                
    writer.Write("  ");

                for (
    int i 0MAXBYTESi++)
                {
                    if (
    >= gravados)
                    {
                        
    writer.Write(" ");
                    }
                    else
                    {
                        
    char ch Ascii(bytes[i]);
                        
    writer.Write(ch);
                    }
                }

                
    writer.WriteLine("");

                
    gravados 0;
            }

            public 
    void Fechar()
            {
                
    writer.Close();
            }
        }

    Program.cs
    Código PHP:
    using System;
    using System.IO;

    namespace 
    ConsoleApplication2
    {
        class 
    Program
        
    {
            static 
    void Main(string[] args)
            {
                
    Hexdump dump = new Hexdump(@"c:\dump.txt");
                
    FileStream fs File.OpenRead(@"c:\WINDOWS\system32\notepad.exe");
                while (
    fs.Position fs.Length)
                {
                    
    int b fs.ReadByte();
                    
    dump.GetByte(b);
                }
                
    dump.Fechar();
            }
        }

    Então é isso galere espero que gostem..
    Qualquer dúvida ou problema tamo ae

  2. #2
    Gray Hat Avatar de CoderSc
    Data de Ingresso
    Jan 2011
    Localização
    #!/bin/bash
    Posts
    1.736
    Sou meio iniciante nessa area mas entendi .
    Parabens !!!!!

    ^^Flw !
    Når du føler flove over at se på tras eller bange for at se fremad, se venstre eller højre I be altid ved din side.

    H
    aters Gonna Hate

Permissões de Postagem

  • Você não pode iniciar novos tópicos
  • Você não pode enviar respostas
  • Você não pode enviar anexos
  • Você não pode editar suas mensagens
  •