.NET derlemelerinin rasgele bir listesi var.
Programlı olarak her DLL x86 (x64 veya herhangi bir CPU aksine) için inşa edilmiş olup olmadığını denetlemeniz gerekir. Mümkün mü?
.NET derlemelerinin rasgele bir listesi var.
Programlı olarak her DLL x86 (x64 veya herhangi bir CPU aksine) için inşa edilmiş olup olmadığını denetlemeniz gerekir. Mümkün mü?
Yanıtlar:
Bakmak System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile)
Derleme meta verilerini döndürülen AssemblyName örneğinden inceleyebilirsiniz:
PowerShell'i kullanma :
[36] C: \> [yansıma.assemblyname] :: GetAssemblyName ("$ {pwd} \ Microsoft.GLEE.dll") | fl İsim: Microsoft.GLEE Sürüm: 1.0.0.0 CultureInfo: CodeBase: dosya: /// C: / projects / powershell / BuildAnalyzer / ... EscapedCodeBase: dosya: /// C: / projects / powershell / BuildAnalyzer / ... İşlemci Mimarisi: MSIL Bayraklar: PublicKey HashAlgoritma: SHA1 Sürüm Uyumluluğu: SameMachine KeyPair: FullName: Microsoft.GLEE, Sürüm = 1.0.0.0, Kültür = nöt ...
Burada, ProcessorArchitecture hedef platformu tanımlar.
Bu örnekte yöntemi çağırmak için PowerShell kullanıyorum.
[reflection.assemblyname]::GetAssemblyName("${pwd}\name.dll")
bazen sürecin geçerli dizin değil aynı şekilde (Ben DLL size göre farz olan) geçerli sağlayıcısını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.
Ne yazık ki, ProcessorArchitecture kullanmadan okumak için hiçbir yolu yoktur GetName instance method
; kullanarak AssemblyName constructor
, alan her zaman olarak ayarlanır None
.
CorFlags'ı kullanabilirsiniz CLI aracı (örneğin, C: \ Program Files \ Microsoft SDK'leri \ Windows \ v7.0 \ Bin \ CorFlags.exe) durumunu belirlemek için bir montaj, kendi çıkışında ve a olarak montaj bir açılış dayalı 32BIT bayrağının 1 ( x86 ) veya 0 ( bağlı olarak herhangi bir CPU veya x64 ) olarak ayarlanıp ayarlanmadığını belirlemek için nerede aramanız gerektiğini belirleyebilmeniz gerekir PE
:
Option | PE | 32BIT
----------|-------|---------
x86 | PE32 | 1
Any CPU | PE32 | 0
x64 | PE32+ | 0
.NET ile x64 Geliştirme blog yazısı hakkında bazı bilgiler var corflags
.
Daha da iyisi, yapabilirsiniz kullanmakModule.GetPEKind
bir montaj olup olmadığını belirlemek içinPortableExecutableKinds
diğer niteliklerle birlikte değer PE32Plus
(64 bit), Required32Bit
(32 bit ve WOW) veya ILOnly
(herhangi bir CPU) .
Sadece açıklama amacıyla, CorFlags.exe .NET Framework SDK'sının bir parçasıdır . Benim makine geliştirme araçları var ve benim için bir DLL 32-bit olup olmadığını belirlemek için en basit yolu:
Visual Studio Komut İstemi'ni açın (Windows'ta: Başlat / Programlar / Microsoft Visual Studio / Visual Studio Araçları / Visual Studio 2008 Komut İstemi menüsü)
Söz konusu DLL dosyasını içeren dizine CD
Corflags'ı şu şekilde çalıştırın:
corflags MyAssembly.dll
Bunun gibi bir çıktı elde edersiniz:
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
Yorumlara göre yukarıdaki bayraklar aşağıdaki gibi okunmalıdır:
32BITREQ
ve 32BITPREF
yerine tek bir 32BIT
değer.
Sadece kendi yazdığın nasıl? PE mimarisinin çekirdeği Windows 95'teki uygulamasından bu yana ciddi bir şekilde değişmedi. İşte bir C # örneği:
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;
}
}
Şimdi mevcut sabitler:
0x10B - PE32 format.
0x20B - PE32+ format.
Ancak bu yöntemle yeni sabitlerin olasılıklarına izin verir, sadece uygun gördüğünüz gibi dönüşü doğrulayın.
CodePlex bu projeden CorFlagsReader kullanmaya çalışın . Diğer montajlara referansları yoktur ve olduğu gibi kullanılabilir.
[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);
}
}
Aşağıda çalışacak bir toplu iş dosyasıdır corflags.exe
tüm karşı dlls
ve exes
geçerli çalışma dizini ve tüm alt dizinlerde, sonuçlarını ayrıştırmak ve her hedef mimarisini gösterir.
Sürümüne bağlı corflags.exe
olduğunu çıktıda satır öğeleri ya içerecektir kullanılır 32BIT
, ya da 32BITREQ
(ve 32BITPREF
). Bu ikisinden hangisi çıktıya dahil edilirse, Any CPU
ve arasında ayrım yapmak için kontrol edilmesi gereken kritik satır öğesidir x86
. Eski bir corflags.exe
Windows sürümü kullanıyorsanız (Windows SDK v8.0A öncesi), 32BIT
geçmiş yanıtlarda belirtildiği gibi, çıktıda yalnızca satır öğesi bulunur. Aksi halde 32BITREQ
ve 32BITPREF
değiştirin.
Bu varsayar corflags.exe
içindedir %PATH%
. Bunu sağlamanın en basit yolu a kullanmaktır Developer Command Prompt
. Alternatif olarak, varsayılan konumundan kopyalayabilirsiniz .
Aşağıdaki toplu iş dosyası yönetilmeyen bir dosyaya karşı çalıştırılırsa dll
veya exe
hatalı olarak görüntülenir x86
, çünkü gerçek çıktı Corflags.exe
, aşağıdakine benzer bir hata iletisi olacaktır:
corflags: hata CF008: Belirtilen dosyanın geçerli bir yönetilen başlığı yok
@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.
Başka bir yol DLL üzerinde Visual Studio araçlarından dumpbin kullanmak ve uygun çıktı aramak için olurdu
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
Not: o / p üstü 32bit dll içindir
Dumpbin.exe ile bir başka kullanışlı seçenek / EXPORTS, dll tarafından maruz bırakılan işlevi gösterecektir
dumpbin.exe /EXPORTS <PATH OF THE DLL>
Daha genel bir yol - bitlik ve görüntü türünü belirlemek için dosya yapısını kullanın:
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);
}
}
Derleme modu numaralandırması
[Flags]
public enum CompilationMode
{
Invalid = 0,
Native = 0x1,
CLR = Native << 1,
Bit32 = CLR << 1,
Bit64 = Bit32 << 1
}
GitHub'da açıklamalı kaynak kodu
Windows Gezgini'nde mevcut tüm bilgileri göstermek için derlemeler için bir bağlam menüsü girişi ekleyen süper kullanışlı bir araç klonladım:
Buradan indirin: https://github.com/tebjan/AssemblyInformation/releases
Bir .NET derlemesinin hedef platformunu denetlemenin başka bir yolu, derlemeyi .NET Reflector ile denetlemektir ...
@ # ~ # € ~! Yeni sürümün ücretsiz olmadığını fark ettim! Yani, düzeltme, .NET reflektörün ücretsiz bir sürümüne sahipseniz, bunu hedef platformu kontrol etmek için kullanabilirsiniz.
cfeduke GetPEKind'i arama olasılığını not eder. Bunu PowerShell'den yapmak ilginç olabilir.
Örneğin, kullanılabilecek bir cmdlet'in kodu: https://stackoverflow.com/a/16181743/64257
Alternatif olarak, https://stackoverflow.com/a/4719567/64257 adresinde " PowerShell Topluluk Uzantıları'nda yürütülebilir görüntüleri test etmek için kullanılabilecek Get-PEHeader cmdlet'inin de bulunduğu" belirtilmektedir .
Bunun için daha gelişmiş bir uygulama burada bulabilirsiniz: CodePlex - ApiChange
Örnekler:
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
Daha önce bahsedilen araçlara bir alternatif , montaj adının yanındaki bilgileri görüntüleyecek Telerik JustDecompile (ücretsiz araç):