.NET 어셈블리가 x86 또는 x64 용으로 빌드되었는지 확인하는 방법


Answers

CorFlags CLI 도구 (예 : C : \ Program Files \ Microsoft SDKs \ Windows \ v7.0 \ Bin \ CorFlags.exe)를 사용하여 어셈블리의 출력을 기준으로 어셈블리의 상태를 확인하고 어셈블리를 바이너리 자산을 사용하려면 32BIT 플래그가 1 ( x86 ) 또는 0 ( PE 에 따라 모든 CPU 또는 x64 )으로 설정되었는지 확인해야 할 위치를 결정할 수 있어야합니다.

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

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

더 좋게는 Module.GetPEKind사용 하여 다른 속성과 함께 PortableExecutableKindsPE32Plus (64 비트), Required32Bit (32 비트 및 WOW) 또는 ILOnly (모든 CPU)인지 여부를 확인할 수 있습니다 .

Question

.NET 어셈블리의 임의 목록이 있습니다.

각 DLL이 x64 또는 모든 CPU와는 반대로 x86 용으로 빌드되었는지 프로그래밍 방식으로 확인해야합니다. 이것이 가능한가?




JetBrians의 DotPeek은 msil (anycpu), x86, x64를 빠르고 쉽게 볼 수있는 방법을 제공합니다




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

예를 들어, 사용할 수있는 cmdlet 코드는 다음과 같습니다. https://.com/a/16181743/64257

또는 https://.com/a/4719567/64257 에서 "실행 가능 이미지를 테스트하는 데 사용할 수있는 PowerShell 커뮤니티 확장 에 Get-PEHeader cmdlet도 있습니다."




그냥 자기 자신을 쓰는 건 어때? 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))
                {
                    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.

그러나이 방법을 사용하면 새로운 상수의 가능성을 고려할 수 있습니다.




한 가지 더 많은 방법은 DLL의 Visual Studio 도구에서 dumpbin을 사용하여 적절한 출력을 찾는 것입니다

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입니다.

dumpbin.exe의 유용한 옵션은 / EXPORTS입니다. dll에 의해 노출 된 함수를 보여줍니다

dumpbin.exe /EXPORTS <PATH OF THE DLL>



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