我必须从.pdb和.dll文件中提取PDB签名。
这是我用来从文件中提取它的代码.pdb。不幸的是,我没有找到从DLL中提取它的类似方法。
public static string GetPdbSignature(string pdbFilePath)
{
using (var pdbFileStream = File.OpenRead(pdbFilePath))
{
var metadataProvider = MetadataReaderProvider.FromPortablePdbStream(pdbFileStream);
var metadataReader = metadataProvider.GetMetadataReader();
var id = new BlobContentId(metadataReader.DebugMetadataHeader.Id);
return $"{id.Guid.ToString("N")}ffffff";
}
}
我发现 PeNet nuget 包可用于执行提取,但我更愿意在不安装外部依赖项的情况下实现这一点。
此外,我设法使用 dotPeek(屏幕(找到了所需的数据,但由于我需要以编程方式解决问题,它也不能解决我的问题。
我会感谢任何关于如何解决这个问题的提示。通过使用一些内置的dotnet机制或通过一些智能的低级字节提取。
我设法找到了一个官方Microsoft包 - Microsoft.Diagnostics.Tracing.TraceEvent,其中包含PEFile
类,允许提取我需要的确切数据。
public static string GetDllSignature(string dllFilePath)
{
var peFile = new PEFile.PEFile(dllFilePath);
peFile.GetPdbSignature(out string pdbName, out Guid pdbGuid, out int pdbAge);
return $"{pdbGuid.ToString("N")}ffffff";
}
更新:
实际上,System.Reflection.PortableExecutable
命名空间中还有一个PEReader
类,它可以仅使用系统库进行读取。但是,它需要对可移植的可执行格式有一定的了解,因为PEReader
没有提供明确的、用户友好的方法来提取签名,而是只允许获取 PE 文件包含的所有数据类型。
public static string GetDllSignatureV2(string dllFilePath)
{
using (var pdbStream = File.OpenRead(pdbPath))
using (var peReader = new PEReader(pdbStream))
{
var debugDirectory = peReader.ReadDebugDirectory().First(entry => entry.Type == DebugDirectoryEntryType.CodeView);
var codeViewData = peReader.ReadCodeViewDebugDirectoryData(debugDirectory);
return $"{codeViewData.Guid.ToString("N").Replace("-", string.Empty)}FFFFFFFF".ToUpper();
}
}