मुझे .NET असेंबली की एक मनमानी सूची मिली है।
यदि प्रत्येक DLL x86 (x64 या किसी भी CPU के विपरीत) के लिए बनाया गया था, तो मुझे प्रोग्रामेटिक रूप से जांचने की आवश्यकता है। क्या यह संभव है?
मुझे .NET असेंबली की एक मनमानी सूची मिली है।
यदि प्रत्येक DLL x86 (x64 या किसी भी CPU के विपरीत) के लिए बनाया गया था, तो मुझे प्रोग्रामेटिक रूप से जांचने की आवश्यकता है। क्या यह संभव है?
जवाबों:
की ओर देखें System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile)
आप असेंबली मेटाडेटा को दिए गए असेंबली उदाहरण से जाँच सकते हैं:
PowerShell का उपयोग करना :
[३६] C: \> [प्रतिबिंब.assemblyname] :: GetAssemblyName ("$ {pwd} \ Microsoft.GLEE.dll") | fl नाम: Microsoft.GLEE संस्करण: 1.0.0.0 संस्कृतिइन्फो: CodeBase: फ़ाइल: /// C: / प्रोजेक्ट्स / शक्तियाँ / BuildAnalyzer / ... EscapedCodeBase: फ़ाइल: /// C: / प्रोजेक्ट्स / शक्तियाँ / BuildAnalyzer / ... प्रोसेसरऑर्किटेक्चर: एम.एस.आई.एल. झंडे: PublicKey हशालिअल्मोगम: SHA1 संस्करणकंपनीयता: समानचिन कीपेयर: FullName: Microsoft.GLEE, संस्करण = 1.0.0.0, संस्कृति = न्युट ...
यहाँ, ProcessorArchitecture लक्ष्य प्लेटफ़ॉर्म की पहचान करता है।
मैं इस उदाहरण में PowerShell का उपयोग विधि को कॉल करने के लिए कर रहा हूं।
[reflection.assemblyname]::GetAssemblyName("${pwd}\name.dll")
कभी-कभी प्रक्रिया के साथ प्रयास करें कि वर्तमान निर्देशिका वर्तमान प्रदाता के समान नहीं है (जो कि मुझे लगता है कि DLL आपके लिए है)
// 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.
कि अफसोस की बात है, वहाँ का उपयोग करने के बिना ProcessorArchitecture पढ़ने का कोई तरीका नहीं है GetName instance method
; का उपयोग करते हुए AssemblyName constructor
, क्षेत्र हमेशा के लिए सेट है None
।
आप किसी असेंबली की स्थिति, उसके आउटपुट के आधार पर और असेंबली खोलने के रूप में निर्धारित करने के लिए CorFlags CLI टूल (उदाहरण के लिए, C: \ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Bin \ CorFlags.exe) का उपयोग कर सकते हैं बाइनरी एसेट आपको यह निर्धारित करने में सक्षम होना चाहिए कि आपको यह निर्धारित करने की आवश्यकता है कि क्या 32BIT ध्वज 1 ( x86 ) या 0 ( किसी भी CPU या x64 पर निर्भर करता है PE
) पर सेट है:
Option | PE | 32BIT
----------|-------|---------
x86 | PE32 | 1
Any CPU | PE32 | 0
x64 | PE32+ | 0
.NET के साथ ब्लॉग पोस्ट x64 डेवलपमेंट के बारे में कुछ जानकारी हैcorflags
।
इससे भी बेहतर, आप यह निर्धारित करने के लिए उपयोगModule.GetPEKind
कर सकते हैं कि क्या एक विधानसभा PortableExecutableKinds
मूल्य PE32Plus
(64-बिट), Required32Bit
(32-बिट और वाह), या ILOnly
अन्य विशेषताओं के साथ (किसी भी सीपीयू) है।
स्पष्टीकरण के लिए, CorFlags.exe .NET फ्रेमवर्क एसडीके का हिस्सा है । मेरे पास मेरी मशीन पर विकास उपकरण हैं, और मेरे लिए सबसे सरल तरीका यह निर्धारित करता है कि क्या DLL 32-बिट केवल है:
Visual Studio कमांड प्रॉम्प्ट खोलें (Windows में: मेनू प्रारंभ / कार्यक्रम / Microsoft Visual Studio / विज़ुअल स्टूडियो टूल / विज़ुअल स्टूडियो 2008 कमांड प्रॉम्प्ट)
प्रश्न में DLL युक्त निर्देशिका के लिए सीडी
इस तरह से corflags चलाएँ:
corflags MyAssembly.dll
आपको आउटपुट कुछ इस तरह मिलेगा:
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
टिप्पणियों के अनुसार ऊपर दिए गए झंडे निम्नलिखित हैं:
32BITREQ
और 32BITPREF
एकल 32BIT
मान के बजाय ।
कैसे के बारे में तुम सिर्फ तुम ही लिख? Windows 95 में इसके लागू होने के बाद से PE आर्किटेक्चर के कोर को गंभीरता से नहीं बदला गया है। यहाँ एक 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;
}
}
अब वर्तमान स्थिरांक हैं:
0x10B - PE32 format.
0x20B - PE32+ format.
लेकिन इस पद्धति के साथ यह नए स्थिरांक की संभावनाओं की अनुमति देता है, जैसा कि आप फिट देखते हैं, बस वापसी को मान्य करें।
CodePlex में इस परियोजना से CorFlagsReader का उपयोग करने का प्रयास करें । इसका अन्य विधानसभाओं के लिए कोई संदर्भ नहीं है और इसका उपयोग किया जा सकता है।
[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);
}
}
नीचे एक बैच फ़ाइल है जो corflags.exe
सभी के खिलाफ चलेगी dlls
औरexes
वर्तमान कार्य निर्देशिका और सभी उप-निर्देशिकाओं में , परिणामों को पार्स प्रत्येक के लक्ष्य वास्तुकला को प्रदर्शित ।
corflags.exe
उपयोग किए जाने वाले संस्करण के आधार पर , आउटपुट में लाइन आइटम या तो शामिल होंगे 32BIT
, या 32BITREQ
(और 32BITPREF
)। इन दोनों में से जो भी आउटपुट में शामिल किया गया है वह महत्वपूर्ण लाइन आइटम है जिसे Any CPU
और के बीच अंतर करने के लिए जाँच की जानी चाहिए x86
। यदि आप corflags.exe
(पूर्व विंडोज एसडीके v8.0A) के पुराने संस्करण का उपयोग कर रहे हैं , तो 32BIT
आउटपुट में केवल लाइन आइटम मौजूद होगा, जैसा कि अन्य ने पिछले उत्तरों में संकेत दिया है। अन्यथा 32BITREQ
और32BITPREF
इसे बदलें।
यह मान लिया गया corflags.exe
है %PATH%
। यह सुनिश्चित करने का सबसे सरल तरीका है कि ए का उपयोग करें Developer Command Prompt
। वैकल्पिक रूप से आप इसे डिफ़ॉल्ट स्थान से कॉपी कर सकते हैं ।
यदि नीचे दी गई बैच फ़ाइल किसी अप्रबंधित dll
या के विरुद्ध चलाई जाती है exe
, तो वह इसे गलत तरीके से प्रदर्शित करेगी x86
, क्योंकि वास्तविक आउटपुट इससे मिलता- Corflags.exe
जुलता त्रुटि संदेश होगा:
corflags: त्रुटि CF008: निर्दिष्ट फ़ाइल में एक वैध प्रबंधित हेडर नहीं है
@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.
एक और तरीका यह होगा कि DLL पर विजुअल स्टूडियो टूल्स से डंपबिन का इस्तेमाल किया जाए और उपयुक्त आउटपुट की तलाश की जाए
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
नोट: ऊपर o / p 32 बिट dll के लिए है
डंपबिन। Ex के साथ एक और उपयोगी विकल्प / एक्सपोर्ट है, यह आपको dll द्वारा उजागर फंक्शन को दिखाएगा
dumpbin.exe /EXPORTS <PATH OF THE DLL>
अधिक सामान्य तरीका - बिटनेस और छवि प्रकार निर्धारित करने के लिए फ़ाइल संरचना का उपयोग करें:
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);
}
}
संकलन मोड गणना
[Flags]
public enum CompilationMode
{
Invalid = 0,
Native = 0x1,
CLR = Native << 1,
Bit32 = CLR << 1,
Bit64 = Bit32 << 1
}
GitHub में स्पष्टीकरण के साथ स्रोत कोड
मैंने एक सुपर आसान टूल क्लोन किया है जो सभी उपलब्ध जानकारी को दिखाने के लिए विंडोज़ एक्सप्लोरर में असेंबली के लिए एक संदर्भ मेनू प्रविष्टि जोड़ता है:
यहाँ डाउनलोड करें: https://github.com/tebjan/AssemblyInformation/releases
.NET असेंबली के टारगेट प्लेटफ़ॉर्म की जाँच करने का एक और तरीका .NET रिफ्लेक्टर के साथ असेंबली का निरीक्षण कर रहा है ...
@ # ~ # € ~! मैंने अभी महसूस किया है कि नया संस्करण मुफ्त नहीं है! इसलिए, सुधार, यदि आपके पास .NET रिफ्लेक्टर का मुफ्त संस्करण है, तो आप इसका उपयोग लक्ष्य प्लेटफ़ॉर्म की जांच करने के लिए कर सकते हैं।
cfeduke GetPEKind को कॉल करने की संभावना को नोट करता है। यह संभवतः PowerShell से ऐसा करना दिलचस्प है।
उदाहरण के लिए, एक cmdlet के लिए कोड है जिसका उपयोग किया जा सकता है: https://stackoverflow.com/a/16181743-64647
वैकल्पिक रूप से, https://stackoverflow.com/a/4719567/64257 पर ध्यान दिया जाता है कि "पावरशेल कम्युनिटी एक्सटेंशन में गेट-PEHeader cmdlet भी है जिसका उपयोग निष्पादन योग्य चित्रों के परीक्षण के लिए किया जा सकता है।"
इसके लिए एक और अधिक उन्नत एप्लिकेशन जो आप यहां पा सकते हैं: कोडप्लेक्स - एपिचेंज
उदाहरण:
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
पहले से उल्लेख किए गए टूल का एक विकल्प Telerik JustDecompile (फ्री टूल) है जो विधानसभा नाम के बगल में जानकारी प्रदर्शित करेगा: