在我的托管PE文件上使用dumpbin,我可以看到它包含可选标头值中的校验和。
我希望能够获得该校验和,以便我可以存储它并确保没有人正在替换我们的构建机器生成的PE文件。我不担心这个校验和是否加密安全,因为我们只使用它来确定某人是否错误地将PE文件放在错误的位置而且我们没有防止故意攻击。我不知道如何从PE文件中获取校验和。 C#是否有用于获取PE文件校验和的托管API?
如果这个diagram是正确的,我可以使用FileStream
并检查PE文件的正确字节,但如果可能的话,我更愿意使用.NET框架来获取这些信息。
以下是命令dumpbin /HEADERS MyDLL.dll
中的字段图像。我在我想要检索的田地周围放了一个黄色方块。
EDIT1: 当我说我可以使用一个不安全的C#项目来读取标题时,我感到很复杂。正如@xanatos所指出的,我只能使用文件流来读取标题的字节。
EDIT2: 我删除了关于这是否是PE32(+)文件的问题,因为我能够确定它只是一个PE32文件。
答案 0 :(得分:0)
所以这是我构建的控制台应用程序,用于从我正在使用的PE文件中获取校验和。
using System;
using System.IO;
using System.Text;
namespace ConsoleApp1
{
class Program
{
public const int PeHeaderOffset = 0x003C;
public const int CheckSumOffset = 0x0058;
static void Main(string[] args)
{
while (true)
{
Console.Write("Path to PE file: ");
string path = Console.ReadLine();
using (FileStream fileStream = new FileStream(path, FileMode.Open, FileAccess.Read))
{
byte[] peHeaderPointer = new byte[4];
byte[] checkSum = new byte[4];
peHeaderPointer = ReadPeHeaderPointer(fileStream);
int checkSumOffSet = BitConverter.ToInt32(peHeaderPointer, 0);
checkSum = ReadChecksum(fileStream, checkSumOffSet);
string hex = ByteArrayToHexString(checkSum);
Console.WriteLine($"Checksum: {hex}");
Console.ReadLine();
}
}
}
//This will not reverse the bytes because the BitConvert.ToInt32 is already reading it in the correct order.
public static byte[] ReadPeHeaderPointer(FileStream fileStream)
{
byte[] bytes = new byte[4];
fileStream.Seek(PeHeaderOffset, SeekOrigin.Begin);
fileStream.Read(bytes, 0, 4);
return bytes;
}
//This reverses the bytes to that this tool will match dumpbin /headers and dotPeek
public static byte[] ReadChecksum(FileStream fileStream, int offSet)
{
byte[] bytes = new byte[4];
fileStream.Seek(offSet + CheckSumOffset, SeekOrigin.Begin);
fileStream.Read(bytes, 0, 4);
bytes = ReverseBytes(bytes);
return bytes;
}
//The PE file seems to be written to the file system in Big Endian
//I need to read them in Small Endian to match dumpbin and dotPeek
public static byte[] ReverseBytes(byte[] bytes)
{
byte[] tempBytes = new byte[4];
tempBytes[0] = bytes[3];
tempBytes[1] = bytes[2];
tempBytes[2] = bytes[1];
tempBytes[3] = bytes[0];
return tempBytes;
}
public static string ByteArrayToHexString(byte[] ba)
{
StringBuilder hex = new StringBuilder(ba.Length * 2);
foreach (byte b in ba)
hex.AppendFormat("{0:x2}", b);
return hex.ToString().ToUpper();
}
}
}
我不完全确定为什么BitConverter使用Little Endian但是dll是用Big Endian编写的。这就是为什么一些字节数组被反转而其中一些没有被反转的原因。