【问题标题】:Change the hash of a PE executable by changing the checksum header通过更改校验和标头来更改 PE 可执行文件的哈希
【发布时间】:2015-08-20 20:10:21
【问题描述】:

我正在编写一个计算程序的 MD5/SHA256 的代码,稍后我希望能够更改它。

我写了计算MD5/SHA256的代码,即:

    using (var md5 = MD5.Create())
    {
        using (var stream = File.OpenRead(textBox1.Text))
        {
            MessageBox.Show(BitConverter.ToString(md5.ComputeHash(stream)).Replace("-", ""));
        }
    }
    using (var sha256 = SHA256.Create())
    {
        using (var stream = File.OpenRead(textBox1.Text))
        {
            MessageBox.Show(BitConverter.ToString(sha256.ComputeHash(stream)).Replace("-", ""));
        }
    }

接下来我希望能够更改指定文件的 MD5/SHA256 的值。我已经搜索过,我发现的只是这个类:

class FileUtils
{
    #region VARIABLES
    private const int OFFSET_CHECKSUM = 0x12;
    #endregion

    #region METHODS
    public static ushort GetCheckSum(string fileName)
    {
        if (!File.Exists(fileName))
            throw new FileNotFoundException("Invalid fileName");
        return GetCheckSum(File.ReadAllBytes(fileName));
    }
    public static ushort GetCheckSum(byte[] fileData)
    {
        if (fileData.Length < OFFSET_CHECKSUM + 1)
            throw new ArgumentException("Invalid fileData");
        return BitConverter.ToUInt16(fileData, OFFSET_CHECKSUM);
    }
    public static void WriteCheckSum(string sourceFile, string destFile, ushort checkSum)
    {
        if (!File.Exists(sourceFile))
            throw new FileNotFoundException("Invalid fileName");
        WriteCheckSum(File.ReadAllBytes(sourceFile), destFile, checkSum);
    }
    public static void WriteCheckSum(byte[] data, string destFile, ushort checkSum)
    {
        byte[] checkSumData = BitConverter.GetBytes(checkSum);
        checkSumData.CopyTo(data, OFFSET_CHECKSUM);
        File.WriteAllBytes(destFile, data);
    }
    #endregion
    }

我不太了解它是如何工作的,只更改了 MD5。对于不那么高级的用户,有没有更简单的方法来做到这一点?如果这个类可以满足我的需要,有人可以向我解释如何使用它吗?

编辑:我知道文件的 MD5 不能更改,我的目标不是更改实际文件的 MD5,我想在文件中添加一些内容来更改 MD5 并通过这样做我希望文件的功能保持不变。

【问题讨论】:

  • 要更改文件的哈希值,只需更改文件即可。
  • 或许您可以告诉我们为什么您想这样做?你到底想达到什么目的?
  • @dandan78 我想更改a文件的MD5/SHA256,所以不一样(重复)。
  • @user5204184 人们试图告诉您您的要求没有意义。散列通常用于确定 a) 两条数据是否相同或 b) 自上次创建散列以来,一条数据已更改。抵消散列没有意义。虽然仍然会给出 b),但不会给出 a)。那么:为什么如果它破坏而不是帮助,你需要这个?
  • @user5204184 这没有任何意义。也许你应该告诉我们你真正的问题是什么,而不是一开始就遵循有缺陷的方法。

标签: c# md5 checksum sha256


【解决方案1】:

据我了解,您拥有或想要同一个 PE 可执行文件的两个副本。现在您想要更改这些文件中的一个或两个,以便在计算文件内容的哈希时,它们是不同的。

如果您更改校验和,则可执行文件可能不再运行。如果您对此感到满意,则可以轻松使用您展示的课程。似乎假设校验和由两个字节组成,并且在可执行文件中的字节 0x12 处偏移。我现在无法验证它是否正确,但乍一看它似乎不是

无论如何,您都可以为每个文件创建唯一的校验和并进行设置:

FileUtils.WriteCheckSum(sourceFile, destFile1, 1);
FileUtils.WriteCheckSum(sourceFile, destFile2, 2);

现在这两个文件将承载不同的内容,因此它们的内容的哈希值将不同。

【讨论】:

  • 感谢您的回答。我有 1 个文件(PE 可执行文件),但如有必要,我可以复制它。我想改变它的哈希值。我需要该文件能够像以前一样运行,而无需进行任何更改,因此如果可能,请更改文件的某些内容,以免影响先前版本的功能。
  • 我想试试你的代码,但是我有两个错误。 1.Cannot implicitly convert type 'int[]' to 'byte[]'.我一定要new byte[]吗?其次,FileUtils 是什么?谢谢。
  • 是的,new byte[]FileUtils 是您展示的课程。
  • 好的,我知道FileUtils 是什么了,这是我发布的课程。我想我做对了,它改变了 MD5。我用的是这个。 byte[] hash1 = new byte[] { 0x00, 0x01 };FileUtils.WriteCheckSum(sourceFile, destFile1, BitConverter.ToUInt16(hash1, 0));。它工作得很好,但我想问,我做错了吗?非常感谢您的帮助。
  • 那不是索引,那是校验和。您可以传递ushort 或 0-65535,这意味着(不包括潜在的冲突)您可以为同一个可执行文件拥有 65536 个不同的校验和,从而导致每个校验和的哈希值不同。使用相同的校验和将产生相同的哈希。
【解决方案2】:

您不能仅仅决定希望文件具有不同的哈希值,因为哈希值是存储在该文件中的数据的直接结果。两个相同的文件,就它们包含的内容而言,总是会产生相同的哈希值,而不管它们的名称是什么。

对文件本身的内容的任何更改都会导致完全不同的哈希值。

【讨论】:

  • 我明白这一点。我的目标是更改文件,但不更改其内容。所以文件保持不变,但是MD5/SHA256改变了。
  • @user 为什么你想要那个?你不能这样做,而且没有意义。
  • @user 不,这没有任何意义。如果两个文件具有相同的内容,则它们相同的。哈希是您根据文件内容计算的东西,而不是与文件一起保存的东西。解释为什么你认为你需要这个,也许有一个更明智的解决方案。
  • @user 在您的问题中解释您的实际问题。也许有一种更明智的方法会奏效。你想要的是不可能的。例如,您可以将文件名添加到您散列的值中。
  • @user "通过更改 PE 文件头的校验和字段" - 所以你 正在 更改文件的内容...请编辑您的问题包括所有相关信息。
【解决方案3】:

MD5 是通过传递字节(例如文件)并以十六进制唯一表示它们来计算的,您不要更改文件的“MD5”,结果 MD5 会随着文件的变化而变化。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2021-01-31
    相关资源
    最近更新 更多