通过更改校验和头来更改PE可执行文件的哈希值

本文关键字:可执行文件 哈希值 PE 校验和 | 更新日期: 2023-09-27 18:08:49

我正在编写一个计算程序的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,通过这样做,我希望文件在功能上保持不变。

通过更改校验和头来更改PE可执行文件的哈希值

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

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

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

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

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

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

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

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