¿Cómo puedo convertir un archivo binario a otra representación binaria, como una imagen?

Quiero tomar un archivo binario (exe, msi, dll, lo que sea) y ser capaz de “ver” el código binario o la base que desee (hexadecimal). Imaginé que la forma más sencilla sería simplemente enviar el código en un txt para que pueda examinarlo.

¿Cuál es la forma mejor y más fácil 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 parecen ser los lenguajes de progtwigción más rápidos y pensé que esto podría llevar algún tiempo. Supongo que estoy más interesado en una respuesta en C, pero principalmente estoy buscando algo de lógica detrás de esto.

Aquí hay una forma de empaquetar los bytes en una imagen … la parte divertida es que si registra la longitud del archivo original y usa un formato de imagen sin pérdida, podría extraer los datos binarios de manera segura más adelante.

Embalado 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); } 

Embalado en blanco y negro binario …

 var width = (int)Math.Sqrt(fi.Length * 8); width = width + 8 - (width % 8); var length = (int)(fi.Length * 8 / width); Func 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 ruido

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

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 quieres convertirlo a HexaDecimal ver aquí .

Ya hecho por ti! Muy convenientemente, un archivo binario ya está almacenado en binario!

Solo desencadenado por tu pregunta, llego un poco tarde en la discusión, pero me pregunté qué tan fácil podría ser. Aquí hay una implementación mínima que le da la salida binaria del ensamblaje que se ejecuta actualmente (es decir, su EXE actual en ejecución):

 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 StringBuilder contenido de StringBuilder , verá lo siguiente (que es mi ejecutable de prueba) para los primeros bytes:

 5A 90 00 03 00 00 00 04 00 00 00 FF FF 00 00 B8 
 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 00 00 00 00 00 00 00 00 00 00 00 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 50 

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

 #include  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; } 

Puedes construirlo y ejecutarlo en la línea de comando de esta manera:

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

Luego emitirá sus 1's y 0's a printer.txt.