Tôi đã có một danh sách các cụm .NET tùy ý.
Tôi cần kiểm tra theo chương trình nếu mỗi DLL được xây dựng cho x86 (trái ngược với x64 hoặc Any CPU). Điều này có thể không?
Tôi đã có một danh sách các cụm .NET tùy ý.
Tôi cần kiểm tra theo chương trình nếu mỗi DLL được xây dựng cho x86 (trái ngược với x64 hoặc Any CPU). Điều này có thể không?
Câu trả lời:
Nhìn vào System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile)
Bạn có thể kiểm tra siêu dữ liệu lắp ráp từ phiên bản hội đồng được trả về:
Sử dụng PowerShell :
[36] C: \> [Reflection.assinstallname] :: GetAss lanhName ("$ {pwd} \ Microsoft.GLEE.dll") | fl Tên: Microsoft.GLEE Phiên bản: 1.0.0.0 Văn hóa Thông tin: CodeBase: file: /// C: / dự án / powershell / BuildAnalyzer / ... EscopedCodeBase: file: /// C: / dự án / powershell / BuildAnalyzer / ... ProcessorArch architecture: MSIL Cờ: PublicKey Thuật toán băm: SHA1 Phiên bản tương thích: SameMachine KeyPair: Tên đầy đủ: Microsoft.GLEE, Phiên bản = 1.0.0.0, Văn hóa = trung tính ...
Ở đây, ProcessorArch architecture xác định nền tảng đích.
Tôi đang sử dụng PowerShell trong ví dụ này để gọi phương thức.
[reflection.assemblyname]::GetAssemblyName("${pwd}\name.dll")
đôi khi thư mục hiện tại của tiến trình không giống với nhà cung cấp hiện tại (đó là nơi tôi cho rằng DLL là dành cho bạn)
// DevDiv 216459: This code originally used Assembly.GetName(), but that requires FileIOPermission, which isn't granted in medium trust. However, Assembly.FullName *is* accessible in medium trust.
Đáng buồn thay, không có cách nào để đọc ProcessorArch architecture mà không sử dụng GetName instance method
; sử dụng AssemblyName constructor
, trường luôn được đặt thành None
.
Bạn có thể sử dụng công cụ CorFlags CLI (ví dụ: C: \ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Bin \ CorFlags.exe) để xác định trạng thái của một hội đồng, dựa trên đầu ra của nó và mở một tổ hợp thành một tài sản nhị phân bạn sẽ có thể xác định nơi bạn cần tìm để xác định xem cờ 32BIT được đặt thành 1 ( x86 ) hay 0 ( Bất kỳ CPU hoặc x64 , tùy thuộc vào PE
):
Option | PE | 32BIT
----------|-------|---------
x86 | PE32 | 1
Any CPU | PE32 | 0
x64 | PE32+ | 0
Bài đăng blog x64 Phát triển với .NET có một số thông tin về corflags
.
Thậm chí tốt hơn, bạn có thể sử dụngModule.GetPEKind
để xác định xem một tổ hợp là PortableExecutableKinds
giá trị PE32Plus
(64 bit), Required32Bit
(32 bit và WOW) hay ILOnly
(bất kỳ CPU nào) cùng với các thuộc tính khác.
Chỉ cần làm rõ, CorFlags.exe là một phần của .NET Framework SDK . Tôi có các công cụ phát triển trên máy của mình và cách đơn giản nhất để tôi xác định liệu DLL có phải là 32 bit hay không là:
Mở Dấu nhắc lệnh của Visual Studio (Trong Windows: menu Start / Programs / Microsoft Visual Studio / Visual Studio Tools / Visual Studio 2008 Command Prompt)
CD vào thư mục chứa DLL trong câu hỏi
Chạy corflags như thế này:
corflags MyAssembly.dll
Bạn sẽ nhận được kết quả như thế này:
Microsoft (R) .NET Framework CorFlags Conversion Tool. Version 3.5.21022.8
Copyright (c) Microsoft Corporation. All rights reserved.
Version : v2.0.50727
CLR Header: 2.5
PE : PE32
CorFlags : 3
ILONLY : 1
32BIT : 1
Signed : 0
Theo nhận xét, các cờ ở trên sẽ được đọc như sau:
32BITREQ
và 32BITPREF
thay vì một 32BIT
giá trị duy nhất .
Làm thế nào về bạn chỉ viết bạn sở hữu? Cốt lõi của kiến trúc PE đã không bị thay đổi nghiêm trọng kể từ khi triển khai trong Windows 95. Dưới đây là ví dụ về 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))
{
if (bReader.ReadUInt16() == 23117) //check the MZ signature
{
fStream.Seek(0x3A, System.IO.SeekOrigin.Current); //seek to e_lfanew.
fStream.Seek(bReader.ReadUInt32(), System.IO.SeekOrigin.Begin); //seek to the start of the NT header.
if (bReader.ReadUInt32() == 17744) //check the PE\0\0 signature.
{
fStream.Seek(20, System.IO.SeekOrigin.Current); //seek past the file header,
architecture = bReader.ReadUInt16(); //read the magic number of the optional header.
}
}
}
}
}
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;
}
}
Bây giờ các hằng số hiện tại là:
0x10B - PE32 format.
0x20B - PE32+ format.
Nhưng với phương pháp này, nó cho phép các khả năng của các hằng số mới, chỉ cần xác nhận lợi nhuận khi bạn thấy phù hợp.
Hãy thử sử dụng CorFlagsReader từ dự án này tại CodePlex . Nó không có tài liệu tham khảo cho các hội đồng khác và nó có thể được sử dụng như là.
[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);
}
}
Dưới đây là một tệp bó sẽ chạy corflags.exe
với tất cả dlls
và exes
trong thư mục làm việc hiện tại và tất cả các thư mục con, phân tích kết quả và hiển thị kiến trúc đích của mỗi thư mục.
Tùy thuộc vào phiên bản của corflags.exe
mà được sử dụng, các chi tiết đơn trong đầu ra một trong hai sẽ bao gồm 32BIT
, hoặc 32BITREQ
(và 32BITPREF
). Bất kỳ mục nào trong hai mục này được bao gồm trong đầu ra là mục hàng quan trọng phải được kiểm tra để phân biệt giữa Any CPU
và x86
. Nếu bạn đang sử dụng phiên bản cũ hơn corflags.exe
(trước Windows SDK v8.0A), thì chỉ có 32BIT
chi tiết đơn hàng sẽ xuất hiện trong đầu ra, như những người khác đã chỉ ra trong các câu trả lời trước đây. Nếu không 32BITREQ
và 32BITPREF
thay thế nó.
Giả định corflags.exe
này là trong %PATH%
. Cách đơn giản nhất để đảm bảo điều này là sử dụng a Developer Command Prompt
. Ngoài ra, bạn có thể sao chép nó từ vị trí mặc định của nó .
Nếu tệp bó bên dưới được chạy không được quản lý dll
hoặc exe
, nó sẽ hiển thị không chính xác vì x86
, vì đầu ra thực tế Corflags.exe
sẽ là một thông báo lỗi tương tự như:
corflags: error CF008: Tệp được chỉ định không có tiêu đề được quản lý hợp lệ
@echo off
echo.
echo Target architecture for all exes and dlls:
echo.
REM For each exe and dll in this directory and all subdirectories...
for %%a in (.exe, .dll) do forfiles /s /m *%%a /c "cmd /c echo @relpath" > testfiles.txt
for /f %%b in (testfiles.txt) do (
REM Dump corflags results to a text file
corflags /nologo %%b > corflagsdeets.txt
REM Parse the corflags results to look for key markers
findstr /C:"PE32+">nul .\corflagsdeets.txt && (
REM `PE32+` indicates x64
echo %%~b = x64
) || (
REM pre-v8 Windows SDK listed only "32BIT" line item,
REM newer versions list "32BITREQ" and "32BITPREF" line items
findstr /C:"32BITREQ : 0">nul /C:"32BIT : 0" .\corflagsdeets.txt && (
REM `PE32` and NOT 32bit required indicates Any CPU
echo %%~b = Any CPU
) || (
REM `PE32` and 32bit required indicates x86
echo %%~b = x86
)
)
del corflagsdeets.txt
)
del testfiles.txt
echo.
Một cách nữa là sử dụng dumpbin từ các công cụ Visual Studio trên DLL và tìm đầu ra thích hợp
dumpbin.exe /HEADERS <your dll path>
FILE HEADER VALUE
14C machine (x86)
4 number of sections
5885AC36 time date stamp Mon Jan 23 12:39:42 2017
0 file pointer to symbol table
0 number of symbols
E0 size of optional header
2102 characteristics
Executable
32 bit word machine
DLL
Lưu ý: Trên o / p là cho dll 32 bit
Một tùy chọn hữu ích hơn với dumpbin.exe là / XUẤT KHẨU, Nó sẽ hiển thị cho bạn chức năng được hiển thị bởi dll
dumpbin.exe /EXPORTS <PATH OF THE DLL>
Cách chung hơn - sử dụng cấu trúc tệp để xác định độ bit và loại hình ảnh:
public static CompilationMode GetCompilationMode(this FileInfo info)
{
if (!info.Exists) throw new ArgumentException($"{info.FullName} does not exist");
var intPtr = IntPtr.Zero;
try
{
uint unmanagedBufferSize = 4096;
intPtr = Marshal.AllocHGlobal((int)unmanagedBufferSize);
using (var stream = File.Open(info.FullName, FileMode.Open, FileAccess.Read))
{
var bytes = new byte[unmanagedBufferSize];
stream.Read(bytes, 0, bytes.Length);
Marshal.Copy(bytes, 0, intPtr, bytes.Length);
}
//Check DOS header magic number
if (Marshal.ReadInt16(intPtr) != 0x5a4d) return CompilationMode.Invalid;
// This will get the address for the WinNT header
var ntHeaderAddressOffset = Marshal.ReadInt32(intPtr + 60);
// Check WinNT header signature
var signature = Marshal.ReadInt32(intPtr + ntHeaderAddressOffset);
if (signature != 0x4550) return CompilationMode.Invalid;
//Determine file bitness by reading magic from IMAGE_OPTIONAL_HEADER
var magic = Marshal.ReadInt16(intPtr + ntHeaderAddressOffset + 24);
var result = CompilationMode.Invalid;
uint clrHeaderSize;
if (magic == 0x10b)
{
clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 208 + 4);
result |= CompilationMode.Bit32;
}
else if (magic == 0x20b)
{
clrHeaderSize = (uint)Marshal.ReadInt32(intPtr + ntHeaderAddressOffset + 24 + 224 + 4);
result |= CompilationMode.Bit64;
}
else return CompilationMode.Invalid;
result |= clrHeaderSize != 0
? CompilationMode.CLR
: CompilationMode.Native;
return result;
}
finally
{
if (intPtr != IntPtr.Zero) Marshal.FreeHGlobal(intPtr);
}
}
Bảng liệt kê chế độ biên dịch
[Flags]
public enum CompilationMode
{
Invalid = 0,
Native = 0x1,
CLR = Native << 1,
Bit32 = CLR << 1,
Bit64 = Bit32 << 1
}
Mã nguồn với lời giải thích tại GitHub
Tôi đã nhân bản một công cụ siêu tiện dụng có thêm mục trình đơn ngữ cảnh cho các cụm trong trình thám hiểm windows để hiển thị tất cả thông tin có sẵn:
Tải xuống tại đây: https://github.com/tebjan/AssuggingIn information / release
Một cách khác để kiểm tra nền tảng đích của lắp ráp .NET là kiểm tra lắp ráp bằng .NET Reflector ...
@ # ~ # € ~! Tôi mới nhận ra rằng phiên bản mới không miễn phí! Vì vậy, điều chỉnh, nếu bạn có một phiên bản .NET Reflector miễn phí, bạn có thể sử dụng nó để kiểm tra nền tảng đích.
cfeduke lưu ý khả năng gọi GetPEKind. Nó có khả năng thú vị để làm điều này từ PowerShell.
Ví dụ, đây là mã cho một lệnh ghép ngắn có thể được sử dụng: https://stackoverflow.com/a/16181743/64257
Ngoài ra, tại https://stackoverflow.com/a/4719567/64257 lưu ý rằng "cũng có lệnh ghép ngắn Get-PEHeader trong Tiện ích mở rộng cộng đồng PowerShell có thể được sử dụng để kiểm tra các hình ảnh thực thi."
Một ứng dụng nâng cao hơn mà bạn có thể tìm thấy ở đây: CodePlex - ApiChange
Ví dụ:
C:\Downloads\ApiChange>ApiChange.exe -CorFlags c:\Windows\winhlp32.exe
File Name; Type; Size; Processor; IL Only; Signed
winhlp32.exe; Unmanaged; 296960; X86
C:\Downloads\ApiChange>ApiChange.exe -CorFlags c:\Windows\HelpPane.exe
File Name; Type; Size; Processor; IL Only; Signed
HelpPane.exe; Unmanaged; 733696; Amd64
Một thay thế cho các công cụ đã được đề cập là Telerik JustDecompile (công cụ miễn phí) sẽ hiển thị thông tin bên cạnh tên lắp ráp: