开发者

How can I convert a binary file to another binary representation, like an image

I want to take a binary file (exe, msi, dll, whatever) and be able to actually "see" the binary code or whatever base I'd like (hexadecimal whatever). Figured the easiest way would be just to output the code into a txt so I can examine it.

Whats the best and easiest way to do this? Basically I am looking to convert the binary code into a picture for a project of mine.

Similarly, it would be nice if I could take some binary code, and then convert it into a binary file.

What are your methods for doing this, I listed C, C++, and C# because these seem to b开发者_如何学Pythone the fastest programming languages and I figured this may take some time. I guess I am more interested in an answer in C, but I am mostly looking for some logic behind this.


Here's a way to pack the bytes into an image... the fun part is if you record the original file length and use a lossless image format you could safely extract the binary data later.

Packed as 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);
}

Packed as Black & White Binary...

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

... and yeah, it looks like noise


I'm not quite sure what you are trying to do, but it sounds a bit like you're looking for a hex editor.


You can read all bytes of a file in C# or any .NET language by calling the static method ReadAllBytes.

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

It will put all the bytes into an array.

If you want to covert it to HexaDecimal see here.


Already done for you! Very convieniently a binary file is already stored in binary!


Just triggered by your question, I come in a bit late in the discussion, but wondered how easy it could be done. Here's a minimal implementation that gives you the binary output of the currently executing assembly (i.e. your current running 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");

}

If you output the StringBuilder contents, you see the following (which is my test executable) for the first some 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 


Here's the code to print out the bytes at 1's and 0's in 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;
}

You can build and run it on the command line like this:

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

It will then output it's 1's and 0's to printer.txt.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜