2010-08-04 16 views
5

Quiero tomar un archivo binario (exe, msi, dll, lo que sea) y ser capaz de "ver" realmente el código binario o cualquier base I ' d like (hexadecimal como sea) Pensé que la manera más fácil sería simplemente mostrar el código en un txt para poder examinarlo.Cómo puedo convertir un archivo binario a otra representación binaria, como una imagen

¿Cuál es la mejor y más fácil manera de hacer esto? Básicamente, estoy buscando convertir el código binario en una imagen para un proyecto mío.

Del mismo modo, sería bueno si pudiera tomar algún código binario, y luego convertirlo en un archivo binario.

Cuáles son sus métodos para hacer esto, enumeré C, C++ y C# porque estos parecen ser los lenguajes de programación más rápidos y pensé que esto podría llevar algún tiempo. Creo que estoy más interesado en una respuesta en C, pero básicamente estoy buscando algo de lógica detrás de esto.

+1

¿Qué significa "convertir"? Estos archivos ya son binarios. –

+0

¿Qué? ¿Desea convertir los bytes de un archivo EXE como una imagen? –

+2

Lo siento, probablemente debería haber usado una mejor terminología. Quiero examinar el código binario de un programa, hacer algo con él y convertirlo a un archivo válido. – ParoX

Respuesta

13

Aquí hay una manera de empaquetar los bytes en una imagen ... la parte divertida es que si graba la longitud original del archivo y utiliza un formato de imagen sin pérdida, puede extraer los datos binarios con seguridad más adelante.

lleno como ARGB ...

var exefile = Directory.GetFiles(".", "*.exe").First(); 
var fi = new FileInfo(exefile); 

var dimension = (int)Math.Sqrt((fi.Length + 1d)/4); 

using (var bitmap = new Bitmap(dimension, dimension + 2)) 
{ 
    //store the file length in the first pixel. 
    bitmap.SetPixel(0, 0, Color.FromArgb((int)fi.Length)); 

    var buffer = new byte[fi.Length + 4 - fi.Length % 4]; 
    Array.Copy(File.ReadAllBytes(exefile), buffer, fi.Length); 

    int x = 1, y = 0; 
    for (var offset = 0; offset < buffer.Length; offset += 4) 
    { 
     var colorValue = BitConverter.ToInt32(buffer, offset); 
     bitmap.SetPixel(x, y, Color.FromArgb(colorValue)); 

     x++; 
     if (x >= dimension) 
     { 
      x = 0; 
      y++; 
     } 
    } 

    bitmap.Save(Path.ChangeExtension(exefile, ".png"), ImageFormat.Png); 
} 

lleno como Negro & blanca binario ...

var width = (int)Math.Sqrt(fi.Length * 8); 
width = width + 8 - (width % 8); 
var length = (int)(fi.Length * 8/width); 

Func<byte, int, Color> getcolor = 
     (b, m) => (b & m) == m ? Color.Black : Color.White; 

using (var bitmap = new Bitmap(width, length + 1)) 
{ 
    var buffer = File.ReadAllBytes(exefile); 

    int x = 0, y = 0; 
    foreach (var @byte in buffer) 
    { 
     bitmap.SetPixel(x + 0, y, getcolor(@byte, 0x80)); 
     bitmap.SetPixel(x + 1, y, getcolor(@byte, 0x40)); 
     bitmap.SetPixel(x + 2, y, getcolor(@byte, 0x20)); 
     bitmap.SetPixel(x + 3, y, getcolor(@byte, 0x10)); 

     bitmap.SetPixel(x + 4, y, getcolor(@byte, 0x8)); 
     bitmap.SetPixel(x + 5, y, getcolor(@byte, 0x4)); 
     bitmap.SetPixel(x + 6, y, getcolor(@byte, 0x2)); 
     bitmap.SetPixel(x + 7, y, getcolor(@byte, 0x1)); 

     x += 8; 
     if (x >= width) 
     { 
      x = 0; 
      y++; 
     } 
    } 

    bitmap.Save(Path.ChangeExtension(exefile, ".tif"), ImageFormat.Tiff); 
} 

... y sí, parece que ruido

+0

Sí. Esto es básicamente lo que quiero hacer. – ParoX

+0

+1 por dar un ejemplo rápido y útil de un ejercicio bastante divertido. No vine más allá de crear un visor hexadecimal en ese marco de tiempo :) – Abel

+0

BTW, si quieres modificar esto para que sea binario y en blanco y negro para los bits, debes considerar usar B & W TIFF con compresión RLE. Eso te dará el mayor rendimiento por tu dinero. Pero recuerda que la imagen tendrá 8 veces la cantidad de píxeles ya que el archivo tiene bytes. –

2

Puede leer todos los bytes de un archivo en C# o en cualquier lenguaje .NET llamando al método estático ReadAllBytes.

byte[] allBytes = File.ReadAllBytes("YourPath"); 

Pondrá todos los bytes en una matriz.

Si desea convertirlo a HexaDecimal, vea here.

+0

Esto es lo que quiero. Gracias. Cualquier método para tomar bytes a un archivo. No uso C# ni ninguno de los idiomas .NET (aún). ¿Puedo suponer que File.WriteAllBytes :) – ParoX

7

No estoy muy seguro de lo que estás tratando de hacer, pero suena un poco como si estuvieras buscando hex editor.

+0

Sí, pero puede cambiar de hexadecimal a binario o lo que sea. No pensé que tuvieran "modos binarios" en editores hexadecimales, pero creo que debería buscarlo en Google. Todavía necesito extraer este código en algo con lo que puedo trabajar de manera automatizada (un archivo txt o algo así) – ParoX

+2

¿No puedes cambiar de hexadecimal a binario en tu cabeza? Ese es todo el punto de hexadecimal. Este es literalmente el propósito completo de un editor hexadecimal en la vida, por lo que es casi seguro que lo que quieres. – mquander

+0

OK. Quiero hacer un píxel negro para 1 y un píxel blanco para 0. Es por eso que necesito "ver" el binario. Supongo que podría copiar y pegar el hexadecimal del editor hexadecimal y luego hacer que un programa lo convierta en binario ... pero ... ¿El punto entero para convertirlo en binario en primer lugar? – ParoX

2

¡Ya hecho para ti! ¡Muy convenientemente un archivo binario es ya almacenado en binario!

+0

Lo sé. ¿Cómo puedo ver este código binario y editarlo fácilmente? Supongo que como un editor hexadecimal, pero un editor binario lol. – ParoX

+3

@Brian: Un editor hexadecimal * es * un editor binario: muestra una representación visual del código binario, que se realiza comúnmente en hexadecimal, byte por byte.Cuando edite dentro de un editor hexadecimal, se convertirá nuevamente a la representación binaria subyacente de ese byte. – Abel

+0

No quiero verlo en hexadecimal. Quiero verlo en binario. No lo editaré manualmente, sino que aplicaré una técnica. – ParoX

1

Recién iniciado por su pregunta, llegué un poco tarde a la discusión, pero me pregunté qué fácil podría hacerse. Aquí hay una implementación mínima que le da la salida binaria del ensamblado que se está ejecutando actualmente (es decirsu funcionamiento actual EXE):

byte[] bytes = File.ReadAllBytes(Assembly.GetExecutingAssembly().Location); 

// this can get large, we know how large, so allocate early and try to be correct 
// note: a newline is two bytes 
StringBuilder sb = new StringBuilder(bytes.Length * 3 + (bytes.Length/16) * 4); 

for (int i = 0; i < bytes.Length; i++) 
{ 
    sb.AppendFormat("{0:X2} ", bytes[i]); 
    if (i % 8 == 0 && i % 16 != 0) 
     sb.Append(" "); 
    if (i % 16 == 0) 
     sb.Append("\n"); 

} 

Si salida de los StringBuilder contenidos, consulte los siguientes (que es mi ejecutable de prueba) por primera algunos bytes:

 
5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 B8 
00 00 00 00 00 00 00 40 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 00 
00 00 00 00 00 00 00 00 00 00 00 80 00 00 00 0E 
1F BA 0E 00 B4 09 CD 21 B8 01 4C CD 21 54 68 69 
73 20 70 72 6F 67 72 61 6D 20 63 61 6E 6E 6F 74 
20 62 65 20 72 75 6E 20 69 6E 20 44 4F 53 20 6D 
6F 64 65 2E 0D 0D 0A 24 00 00 00 00 00 00 00 50 
0

Aquí está el código para imprimir los bytes en 1 y 0 en C:

#include <stdio.h> 

void putbits(unsigned char byte) 
{ 
    unsigned char mask = 0x01; 

    for (int bit = 7; bit >= 0; bit--) 
    { 
     if ((mask << bit) & byte) 
     { 
      printf("1"); 
     } 
     else 
     { 
      printf("0"); 
     } 
    } 

    // Uncomment the following line to get each byte on it's own line. 
    //printf("\n"); 
} 

int main (int argc, const char * argv[]) 
{ 
    int c; 

    while ((c = getchar()) != EOF) 
    { 
     putbits(c); 
    } 

    return 0; 
} 

Usted puede construir y ejecutar en la línea de comando como este:

gcc main.c --std=c99 -o printer 
./printer <printer> printer.txt 

Aparecerá su número de 1 y 0 en printer.txt.

Cuestiones relacionadas