【问题标题】:How can I convert a binary file to another binary representation, like an image如何将二进制文件转换为另一种二进制表示形式,例如图像
【发布时间】:2011-03-25 10:40:14
【问题描述】:

我想获取一个二进制文件(exe、msi、dll 等)并能够真正“看到”二进制代码或我想要的任何基础(十六进制)。认为最简单的方法是将代码输出到 txt 中,以便我可以检查它。

最好和最简单的方法是什么?基本上我希望将二进制代码转换为我的项目的图片。

同样,如果我能拿一些二进制代码,然后将它转换成二进制文件,那就太好了。

你的方法是什么,我列出了 C、C++ 和 C#,因为这些似乎是最快的编程语言,我认为这可能需要一些时间。我想我对 C 中的答案更感兴趣,但我主要是在寻找这背后的一些逻辑。

【问题讨论】:

  • “转换”是什么意思?这些文件已经是二进制文件了。
  • 抱歉,我可能应该使用更好的术语。我想检查程序的二进制代码,对其进行处理,然后将其转换回有效文件。
  • 哇!全开双彩虹!这是什么意思?
  • @Abel: C-- 确实存在。它是一种类似 C 的语言,但更简单,被设计为介于汇编和高级语言之间的中间语言,易于自动生成和编译。另见en.wikipedia.org/wiki/C--
  • 这个问题因其产生的混乱程度而获胜。

标签: c# c++ c


【解决方案1】:

这是一种将字节打包成图像的方法...有趣的是,如果您记录原始文件长度并使用无损图像格式,您以后可以安全地提取二进制数据。

打包为 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);
}

打包为黑白二进制...

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

...是的,它看起来像噪音

【讨论】:

  • 是的。这基本上是我想做的。
  • +1 为一个相当有趣的练习提供了一个快速而有用的例子。除了在那个时间范围内创建一个 hex-viewer 之外,我并没有走得更远:)
  • 顺便说一句,如果您想将其修改为 B&W 二进制位,您应该考虑将 B&W TIFF 与 RLE 压缩一起使用。这将为您带来最大的收益。但请记住,图像的像素数是文件字节数的 8 倍。
  • @Brian,我刚刚添加了一个黑白版本...图像比我想象的要小。他们看起来很酷。我没有用文件长度打包二进制版本。
  • 我遇到了 var colorValue 的问题-它指出:目标数组的长度不足以复制集合中的所有项目。检查数组索引和长度。很奇怪,因为它制作了一个 8MB 文件的 png,但它在 400KB 文件上令人窒息。我刚刚下载了 Visual C# 2010 express...所以还不确定(还)如何继续。任何帮助表示赞赏:).. 编辑:刚刚注意到你做了一个黑白的(你太棒了)......现在试试......
【解决方案2】:

我不太确定您要做什么,但这听起来有点像您在寻找hex editor

【讨论】:

  • 是的,但可以从十六进制切换到二进制或其他。我不认为他们在十六进制编辑器中有“二进制模式”,但我想我应该谷歌它。我仍然需要将此代码提取到我可以以自动化方式使用的东西(txt 文件或其他东西)
  • 您无法在脑海中从十六进制切换到二进制?这就是十六进制的全部意义。这实际上是十六进制编辑器在生活中的全部目的,所以这几乎肯定是你想要的。
  • 好的。我想为 1 制作一个黑色像素,为 0 制作一个白色像素。这就是我需要“查看”二进制文件的原因。我想我可以从十六进制编辑器中复制并粘贴十六进制,然后让程序将其转换为二进制...但是...首先将其转换为二进制的重点是什么?
  • 哦。我想当时人们会感到困惑。你说你想用二进制“看到”它,但你根本不想看到它;你想用一个程序处理它并用它创建一个位图。我同意上面的答案——你应该使用 File.ReadAllBytes 然后处理字节来制作你的图像。十六进制编辑器对您没有帮助,因为您对手动检查或编辑它不感兴趣。
  • @Brian,好吧......这比我的例子更疯狂。每比特使用一个像素会产生一个巨大的图像。
【解决方案3】:

您可以通过调用静态方法 ReadAllBytes 以 C# 或任何 .NET 语言读取文件的所有字节。

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

它将所有字节放入一个数组中。

如果您想将其转换为 HexaDecimal,请参阅 here

【讨论】:

  • 这就是我想要的。谢谢。将字节写入文件的任何方法。我不使用 c# 或任何 .NET 语言(还)。我可以假设它的 File.WriteAllBytes :)
【解决方案4】:

已经为你完成了!非常方便,一个二进制文件已经以二进制形式存储了!

【讨论】:

  • 我知道。我怎样才能看到这个二进制代码并轻松编辑它。我想像一个十六进制编辑器,但一个二进制编辑器哈哈。
  • @Brian:十六进制编辑器二进制编辑器:它向您显示二进制代码的可视化表示,通常以十六进制逐字节进行。当您在十六进制编辑器中进行编辑时,它将被转换回该字节的底层二进制表示。
  • 我不想看到它的十六进制。我想以二进制形式查看它。我不会手动编辑它,而是应用一种技术。
  • 我想他只是想看看 1 和 0。
  • @Brian:你看不到二进制文件。就像您无法看到数据库中的 BLOB。看到它的唯一方法是使用一些表示。一张图片会告诉你一点,十六进制、八进制、二进制(零/一)是字符串表示。但是你的想法很有趣,没用,但很有趣:制作它的图像是二进制文件(原始 EXE)的另一种二进制格式(图像文件)的另一种非二进制表示(在图片查看器中)。困惑?
【解决方案5】:

刚被你的问题触发,我在讨论中有点晚了,但想知道它有多容易。这是一个最小的实现,它为您提供当前正在执行的程序集(即您当前正在运行的 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");

}

如果您输出 StringBuilder 内容,您会看到前几个字节的以下内容(这是我的测试可执行文件):

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

【讨论】:

    【解决方案6】:

    这是在 C 中打印出 1 和 0 字节的代码:

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

    您可以像这样在命令行上构建和运行它:

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

    然后它会将 1 和 0 输出到 printer.txt。

    【讨论】:

      猜你喜欢
      • 2012-12-15
      • 1970-01-01
      • 2014-08-24
      • 1970-01-01
      • 1970-01-01
      • 2015-12-28
      • 1970-01-01
      • 2018-03-20
      • 1970-01-01
      相关资源
      最近更新 更多