programing

a인지 확인하려면 어떻게 해야 합니까?NET 어셈블리는 x86 또는 x64용으로 제작되었습니까?

telecom 2023. 5. 15. 21:16
반응형

a인지 확인하려면 어떻게 해야 합니까?NET 어셈블리는 x86 또는 x64용으로 제작되었습니까?

임의의 목록을 가지고 있습니다.NET 어셈블리.

각 DLL이 x86(x64 또는 Any CPU가 아닌)용으로 제작되었는지 프로그래밍 방식으로 확인해야 합니다.이것이 가능합니까?

를 .System.Reflection.AssemblyName.GetAssemblyName(string assemblyFile).

반환된 AssemblyName 인스턴스에서 어셈블리 메타데이터를 검사할 수 있습니다.

PowerShell 사용:

[36] C:\> [reflection.assemblyname]::GetAssemblyName("${pwd})\Microsoft.GLEY.dll) | fl.
이름: 마이크로소프트.신이 남버전: 1.0.0.0문화 정보:CodeBase : file:///C:/projects/powershell/BuildAnalyzer/...
ExcidedCodeBase: 파일:///C:/projects/powershell/BuildAnalyzer/...
프로세서 아키텍처: MSIL플래그: 공용 키해시 알고리즘 : SHA1버전 호환성: 동일한 시스템키 쌍:전체 이름 : Microsoft.글리, 버전=1.0.0.0, 컬쳐=중성...

여기서 프로세서 아키텍처는 대상 플랫폼을 식별합니다.

  • Amd64: x64 아키텍처를 기반으로 하는 64비트 프로세서입니다.
  • : ARM 프로세서입니다.
  • IA64: 64비트 Intel Itanium 프로세서 전용.
  • MSIL: 프로세서 및 워드당 비트 수에 대해 중립적입니다.
  • X86: 기본 또는 64비트 플랫폼(WoW64)의 Windows on Windows 환경에 있는 32비트 Intel 프로세서입니다.
  • 없음: 프로세서와 단어당 비트의 알 수 없거나 지정되지 않은 조합입니다.

이 예제에서는 PowerShell을 사용하여 메서드를 호출합니다.

CorFlags CLI 도구(예: C:\Program Files\Microsoft SDKs\Windows\v7.0)를 사용할 수 있습니다.\Bin\CorFlags.exe)를 사용하여 어셈블리의 상태를 확인합니다. 출력과 이진 자산으로 어셈블리를 여는 것을 기준으로 32B를 결정하기 위해 찾아야 할 위치를 결정할 수 있어야 합니다.IT 플래그가 1(x86) 또는 0(모든 CPU 또는 x64)으로 설정되어 있습니다.PE):

Option    | PE    | 32BIT
----------|-------|---------
x86       | PE32  | 1
Any CPU   | PE32  | 0
x64       | PE32+ | 0

블로그 게시물 x64 개발 with.NET에 대한 몇 가지 정보가 있습니다.corflags.

더 나은 것은, 를 사용하여 어셈블리가PortableExecutableKindsPE32Plus (64µ트),Required32Bit(32비트 및 WoW), 또는ILOnly(모든 CPU) 및 기타 특성.

해명을 위해서죠, CorFlags.exe는 의 일부입니다.NET Framework SDK. 제 컴퓨터에는 개발 도구가 있습니다. DLL이 32비트 전용인지 확인하는 가장 간단한 방법은 다음과 같습니다.

  1. Visual Studio 명령 프롬프트 열기(Windows의 경우 메뉴 시작/프로그램/Microsoft Visual Studio/Visual Studio 도구/Visual Studio 2008 명령 프롬프트)

  2. 문제의 DLL이 들어 있는 디렉터리의 CD

  3. 다음과합니다.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

코멘트에 따라 위의 플래그는 다음과 같이 읽습니다.

  • 모든 CPU: PE = PE32 및 32BIT = 0
  • x86: PE = PE32 및 32BIT = 1
  • 64비트: PE = PE32+ 및 32BIT = 0

그냥 당신 것을 쓰세요.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.

그러나 이 방법을 사용하면 새로운 상수의 가능성을 허용합니다.적합하다고 판단되는 대로 반품을 확인하십시오.

JetBrain의 DotPeek은 smsil(모든 CPU), x86 및 x64를 빠르고 쉽게 볼 수 있는 방법을 제공합니다.

도트피크

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);
    }
}

아래는 코플래그를 실행할 배치 파일입니다.exe는 현재 작업 디렉토리 및 모든 하위 디렉토리의 모든 DLL 파일 및 EXE 파일에 대해 결과를 구문 분석하고 각 대상 아키텍처를 표시합니다.

코플래그 버전에 따라 다릅니다.사용되는 exe, 출력의 라인 항목은 32B를 포함합니다.IT 또는 32BITREQ( 32B)ITPREF).이 두 가지 중 어느 것이 출력에 포함되어 있는지는 Any CPU와 x86구별하기 위해 확인해야 하는 중요한 항목입니다.이전 버전의 corflags.exe(윈도우즈 SDK v8.0A 이전 버전)를 사용하는 경우에는 32B만 사용합니다.다른 사람들이 과거 답변에서 지적했듯이 IT 라인 항목이 출력에 표시됩니다.그렇지 않으면 32BITREQ32BITPREF가 교체합니다.

이것은 코플래그를 가정합니다.exe가 %PATH%에 있습니다.이를 확인하는 가장 간단한 방법은 개발자 명령 프롬프트를 사용하는 것입니다.또는 기본 위치에서 복사할 수 있습니다.

아래 배치 파일이 관리되지 않는 DLL 또는 EXE 파일에 대해 실행되면 Corflags의 실제 출력이므로 x86으로 잘못 표시됩니다.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.

Windows 탐색기에서 어셈블리의 상황에 맞는 메뉴 항목을 추가하여 사용 가능한 모든 정보를 표시하는 매우 편리한 도구를 복제했습니다.

Releases · tebjan/Assembly 정보에서 다운로드합니다.

여기에 이미지 설명 입력

또 다른 방법은 DLL의 Visual Studio 도구에서 덤프빈을 사용하여 적절한 출력을 찾는 것입니다.

dumpbin.exe /HEADERS <your DLL file 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

참고: 위의 출력은 32비트 DLL 파일에 대한 것입니다.

덤빈과 함께 더 유용한 옵션이 있습니다.exe는 /EXPORT입니다.DLL 파일에 의해 노출된 기능이 표시됩니다.

dumpbin.exe /EXPORTS <PATH OF THE DLL FILE>

보다 일반적인 방법 - 파일 구조를 사용하여 비트 및 이미지 유형을 확인합니다.

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
}

설명이 포함된 소스 코드는 깃허브에 있습니다.

의 대상 플랫폼을 확인하는 또 다른 방법입니다.NET 어셈블리가 어셈블리를 검사하는 중입니다.NET 리플렉터...

저는 새로운 버전이 무료가 아니라는 것을 방금 깨달았습니다!의 무료 버전이 있으면 수정합니다.NET 리플렉터는 대상 플랫폼을 확인하는 데 사용할 수 있습니다.

cfeduke는 GetPEKind를 호출할 가능성에 주목합니다.PowerShell에서 이 작업을 수행하는 것은 잠재적으로 흥미롭습니다.

예를 들어 다음은 사용할 수 있는 cmdlet의 코드입니다. https://stackoverflow.com/a/16181743/64257

또는 https://stackoverflow.com/a/4719567/64257 에서는 "PowerShell Community Extensions에 실행 가능한 이미지를 테스트하는 데 사용할 수 있는 Get-PEHeader cmdlet도 있습니다."라고 언급했습니다.

도구는 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

이미 언급된 도구에 대한 대안으로는 어셈블리 이름 옆에 다음과 같은 정보를 표시하는 Telerik JustDem 컴파일러(무료 도구)가 있습니다.

Telerik의 임의 또는 x86 또는 x64 정보

ILSpy 도구가 마음에 듭니다.여기에는 아키텍처뿐만 아니라 대상 프레임워크도 나와 있습니다.

// linq2db, Version=3.0.0.0, Culture=neutral, PublicKeyToken=e41013125f9e410a
// Global type: <Module>
// Architecture: AnyCPU (64-bit preferred)
// Runtime: v4.0.30319
// This assembly is signed with a strong name key.
// This assembly was compiled using the /deterministic option.
// Hash algorithm: SHA1

그래서 그것이 맞는지 판단하는 것이 가능합니다.NET Core 2.1, .NET Framework 4.6 또는 기타 프레임워크:

대상 프레임워크

언급URL : https://stackoverflow.com/questions/270531/how-can-i-determine-if-a-net-assembly-was-built-for-x86-or-x64

반응형