我有一个任意的。net程序集列表。
我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。这可能吗?
我有一个任意的。net程序集列表。
我需要以编程方式检查每个DLL是否为x86构建(而不是x64或任何CPU)。这可能吗?
当前回答
你自己写就行了。PE架构的核心自从在Windows 95中实现以来就没有发生过重大变化。
下面是一个c#的例子:
public static ushort GetPEArchitecture(string pFilePath)
{
ushort architecture = 0;
try
{
using (System.IO.FileStream fStream = new System.IO.FileStream(pFilePath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
{
using (System.IO.BinaryReader bReader = new System.IO.BinaryReader(fStream))
{
// Check the MZ signature
if (bReader.ReadUInt16() == 23117)
{
// Seek to e_lfanew.
fStream.Seek(0x3A, System.IO.SeekOrigin.Current);
// Seek to the start of the NT header.
fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin);
if (bReader.ReadUInt32() == 17744) // Check the PE\0\0 signature.
{
// Seek past the file header,
fStream.Seek(20, System.IO.SeekOrigin.Current);
// Read the magic number of the optional header.
architecture = bReader.ReadUInt16();
}
}
}
}
}
catch (Exception) { /* TODO: Any exception handling you want
to do, personally I just take 0
as a sign of failure */
}
// If architecture returns 0, there has been an error.
return architecture;
}
}
现在的常数是:
0x10B - PE32 format.
0x20B - PE32+ format.
但是用这种方法,它允许新常数的可能性。只要验证你认为合适的返回。
其他回答
您可以使用CorFlags命令行工具(例如,C:\Program Files\Microsoft sdk \Windows\v7.0\Bin\CorFlags.exe)来确定程序集的状态,根据其输出并将程序集作为二进制资产打开,您应该能够确定您需要在哪里查找,以确定32位标志是否设置为1 (x86)或0(任何CPU或x64,取决于PE):
Option | PE | 32BIT
----------|-------|---------
x86 | PE32 | 1
Any CPU | PE32 | 0
x64 | PE32+ | 0
博客文章x64 Development with . net有一些关于corflags的信息。
更好的是,您可以使用Module。GetPEKind来确定程序集是否为portableexecutabletypes值PE32Plus(64位)、Required32Bit(32位和WoW)或ILOnly(任何CPU)以及其他属性。
[TestMethod]
public void EnsureKWLLibrariesAreAll64Bit()
{
var assemblies = Assembly.GetExecutingAssembly().GetReferencedAssemblies().Where(x => x.FullName.StartsWith("YourCommonProjectName")).ToArray();
foreach (var assembly in assemblies)
{
var myAssemblyName = AssemblyName.GetAssemblyName(assembly.FullName.Split(',')[0] + ".dll");
Assert.AreEqual(ProcessorArchitecture.MSIL, myAssemblyName.ProcessorArchitecture);
}
}
一个工具是sigcheck:
sigcheck c:\Windows\winhlp32.exe
输出:
Sigcheck v2.71 - File version and signature viewer
Copyright (C) 2004-2018 Mark Russinovich
Sysinternals - www.sysinternals.com
c:\windows\winhlp32.exe:
Verified: Signed
Signing date: 20:05 02.05.2022
Publisher: Microsoft Windows
Company: Microsoft Corporation
Description: Windows Winhlp32 Stub
Product: Microsoft® Windows® Operating System
Prod version: 10.0.19041.1
File version: 10.0.19041.1 (WinBuild.160101.0800)
MachineType: 32-bit
sigcheck -nobanner c:\Windows\HelpPane.exe
输出:
c:\windows\HelpPane.exe:
Verified: Signed
Signing date: 00:42 23.04.2022
Publisher: Microsoft Windows
Company: Microsoft Corporation
Description: Microsoft Help and Support
Product: Microsoft® Windows® Operating System
Prod version: 10.0.19041.1151
File version: 10.0.19041.1151 (WinBuild.160101.0800)
MachineType: 64-bit
JetBrains的DotPeek提供了一个快速简单的方法来查看msil(任何CPU), x86和x64:
查看System.Reflection.AssemblyName。assemblyFile GetAssemblyName(字符串)。
您可以从返回的AssemblyName实例中检查程序集元数据:
使用PowerShell:
[36] C:\> [reflection.assemblyname]::GetAssemblyName("${pwd}\Microsoft.GLEE.dll") | fl Name : Microsoft.GLEE Version : 1.0.0.0 CultureInfo : CodeBase : file:///C:/projects/powershell/BuildAnalyzer/... EscapedCodeBase : file:///C:/projects/powershell/BuildAnalyzer/... ProcessorArchitecture : MSIL Flags : PublicKey HashAlgorithm : SHA1 VersionCompatibility : SameMachine KeyPair : FullName : Microsoft.GLEE, Version=1.0.0.0, Culture=neut...
在这里,ProcessorArchitecture标识目标平台。
Amd64:基于x64架构的64位处理器。 Arm: Arm处理器。 IA64:仅支持64位Intel Itanium处理器。 MSIL:对于处理器和每字比特数来说是中性的。 X86:一种32位的Intel处理器,本机的或在64位平台(WoW64)上的Windows on Windows环境中。 None:未知或未指定的处理器和每字位数的组合。
在本例中,我使用PowerShell来调用该方法。