通过更改校验和更改 PE 可执行文件的散列 header
Change the hash of a PE executable by changing the checksum header
我正在编写一个计算程序 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:
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。对于不是那么高级的用户,有没有更简单的方法来做到这一点?如果这个 class 可以满足我的需要,有人可以向我解释一下我该如何使用它吗?
编辑:我知道文件的 MD5 无法更改,我的目标不是更改实际文件的 MD5,我想向文件添加一些内容来更改 MD5 和通过这样做,我希望文件的功能保持不变。
您不能仅仅决定希望文件具有不同的哈希值,因为哈希值是该文件中存储的数据的直接结果。两个相同的文件,就它们包含的内容而言,将始终产生相同的哈希值,无论它们的名称是什么。
对文件本身内容的任何更改都会导致完全不同的散列值。
MD5 是通过传递字节(例如文件)并以十六进制唯一表示它们来计算的,您不更改文件的 "MD5",结果 MD5 将随着文件的更改而更改。
据我了解,您拥有或想要同一个 PE 可执行文件的两个副本。现在您想更改其中一个或两个文件,以便在计算文件内容的哈希时,它们是不同的。
如果您更改校验和,可执行文件很可能不再 运行。如果您对此表示满意,则可以轻松使用您显示的 class。它似乎假定校验和由两个字节组成,并且在可执行文件中偏移字节 0x12。我现在无法验证它是否正确,但乍一看似乎不是。
无论如何,您可以为每个文件创建唯一的校验和并进行设置:
FileUtils.WriteCheckSum(sourceFile, destFile1, 1);
FileUtils.WriteCheckSum(sourceFile, destFile2, 2);
现在这两个文件将承载不同的内容,因此它们的内容的哈希值将不同。
我正在编写一个计算程序 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:
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。对于不是那么高级的用户,有没有更简单的方法来做到这一点?如果这个 class 可以满足我的需要,有人可以向我解释一下我该如何使用它吗?
编辑:我知道文件的 MD5 无法更改,我的目标不是更改实际文件的 MD5,我想向文件添加一些内容来更改 MD5 和通过这样做,我希望文件的功能保持不变。
您不能仅仅决定希望文件具有不同的哈希值,因为哈希值是该文件中存储的数据的直接结果。两个相同的文件,就它们包含的内容而言,将始终产生相同的哈希值,无论它们的名称是什么。
对文件本身内容的任何更改都会导致完全不同的散列值。
MD5 是通过传递字节(例如文件)并以十六进制唯一表示它们来计算的,您不更改文件的 "MD5",结果 MD5 将随着文件的更改而更改。
据我了解,您拥有或想要同一个 PE 可执行文件的两个副本。现在您想更改其中一个或两个文件,以便在计算文件内容的哈希时,它们是不同的。
如果您更改校验和,可执行文件很可能不再 运行。如果您对此表示满意,则可以轻松使用您显示的 class。它似乎假定校验和由两个字节组成,并且在可执行文件中偏移字节 0x12。我现在无法验证它是否正确,但乍一看似乎不是。
无论如何,您可以为每个文件创建唯一的校验和并进行设置:
FileUtils.WriteCheckSum(sourceFile, destFile1, 1);
FileUtils.WriteCheckSum(sourceFile, destFile2, 2);
现在这两个文件将承载不同的内容,因此它们的内容的哈希值将不同。