370 Stimmen

Wie kann ich feststellen, ob eine .NET-Assembly für x86 oder x64 erstellt wurde?

Ich habe eine willkürliche Liste von .NET-Assemblies.

Ich muss programmatisch prüfen, ob jede DLL für x86 (im Gegensatz zu x64 oder Any CPU) erstellt wurde. Ist dies möglich?

2voto

Ayush joshi Punkte 307

Eine weitere Möglichkeit wäre, dumpbin aus den Visual Studio Tools auf DLL zu verwenden und nach der entsprechenden Ausgabe zu suchen

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

Hinweis: Die obigen Angaben gelten für 32bit dll

Eine weitere nützliche Option von dumpbin.exe ist /EXPORTS. Sie zeigt die Funktionen an, die von der Dll zur Verfügung gestellt werden

dumpbin.exe /EXPORTS <PATH OF THE DLL>

2voto

BlackGad Punkte 51

Allgemeinere Methode - Verwendung der Dateistruktur zur Bestimmung von Bitdichte und Bildtyp:

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

Aufzählung der Kompilierungsmodi

[Flags]
public enum CompilationMode
{
    Invalid = 0,
    Native = 0x1,
    CLR = Native << 1,
    Bit32 = CLR << 1,
    Bit64 = Bit32 << 1
}

Quellcode mit Erklärung unter GitHub

1voto

jdearana Punkte 1061

Eine weitere Möglichkeit, die Zielplattform einer .NET-Assembly zu überprüfen, ist die Inspektion der Assembly mit .NET-Reflektor ...

@#~#€~! Ich habe gerade festgestellt, dass die neue Version nicht kostenlos ist! Also, Korrektur, wenn Sie eine kostenlose Version von .NET Reflektor haben, können Sie es verwenden, um die Zielplattform zu überprüfen.

1voto

Chris Punkte 9706

Cfeduke weist auf die Möglichkeit hin, GetPEKind aufzurufen. Es ist potenziell interessant, dies von der PowerShell aus zu tun.

Hier ist zum Beispiel der Code für ein Cmdlet, das verwendet werden könnte: https://stackoverflow.com/a/16181743/64257

Alternativ, unter https://stackoverflow.com/a/4719567/64257 wird darauf hingewiesen, dass "es auch das Cmdlet Get-PEHeader in der PowerShell-Gemeinschaftserweiterungen die zum Testen auf ausführbare Bilder verwendet werden können."

0voto

Eine Alternative zu den bereits erwähnten Tools ist Telerik JustDecompile (kostenloses Tool), das die Informationen neben dem Namen der Baugruppe anzeigt:

Any or x86 or x64 information in Telerik

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X