Bagaimana menemukan apakah file DLL asli dikompilasi sebagai x64 atau x86?

133

Saya ingin menentukan apakah perakitan asli dipenuhi sebagai x64 atau x86 dari aplikasi kode terkelola ( C # ).

Saya pikir itu pasti di suatu tempat di header PE karena loader OS perlu mengetahui informasi ini, tetapi saya tidak dapat menemukannya. Tentu saja saya lebih suka melakukannya dalam kode yang dikelola, tetapi jika perlu, saya bisa menggunakan bahasa asli C ++.

Ohad Horesh
sumber
Agar lebih jelas, dll yang dimaksud juga merupakan .Net assembly? Anda mengatakan DLL asli dalam judul posting, tetapi perakitan asli dalam deskripsi ... jika Anda masih aktif melihat posting ini dari 09 :)
Vikas Gupta
1
Anda mungkin juga ingin memeriksa yang ini: check-if-unmanaged-dll-is-32-bit-or-64-bit .
Matt

Jawaban:

143

Anda dapat menggunakan DUMPBIN juga. Gunakan bendera /headersatau /alldan header file pertama yang terdaftar.

dumpbin /headers cv210.dll

64-bit

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file cv210.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
            8664 machine (x64)
               6 number of sections
        4BBAB813 time date stamp Tue Apr 06 12:26:59 2010
               0 file pointer to symbol table
               0 number of symbols
              F0 size of optional header
            2022 characteristics
                   Executable
                   Application can handle large (>2GB) addresses
                   DLL

32-bit

Microsoft (R) COFF/PE Dumper Version 10.00.30319.01
Copyright (C) Microsoft Corporation.  All rights reserved.


Dump of file acrdlg.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
             14C machine (x86)
               5 number of sections
        467AFDD2 time date stamp Fri Jun 22 06:38:10 2007
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
            2306 characteristics
                   Executable
                   Line numbers stripped
                   32 bit word machine
                   Debug information stripped
                   DLL

'temukan' dapat membuat hidup sedikit lebih mudah:

dumpbin /headers cv210.dll |find "machine"
        8664 machine (x64)
Mark McDonald
sumber
4
Sedikit lebih ramah pengguna;)
Semut
4
DUMPBIN tidak berfungsi untuk .EXE NET. Saya memiliki .NET EXE 64-bit yang DUMPBIN katakan adalah 32-bit ("mesin 14C (x86)"), tetapi corflags mengatakan Any CPU ("PE: PE32, 32BIT: 0"). Dependency Walker juga salah mendiagnosisnya.
Pierre
2
Diperlukan mspdb100.dll:(
Dmitry
1
@Altaveron Saya memiliki masalah yang sama, tetapi menyelesaikannya dengan menyalin file DLL mspdb100.dllke folder di mana dumpbin.exeberada. DUMPBINbisa lari setelah itu. Bagi saya, EXE di <Visual Studio Install folder>\VC\bindan DLL di <Visual Studio Install folder>\Common7\IDE.
ADTC
DUMPBIN tersedia dari Visual Studio command prompt untuk mereka yang Visual Studio terinstal
Alan Macdonald
55

Ada cara mudah untuk melakukan ini dengan CorFlags . Buka Prompt Perintah Visual Studio dan ketik "corflags [perakitan Anda]". Anda akan mendapatkan sesuatu seperti ini:

c: \ Program Files (x86) \ Microsoft Visual Studio 9.0 \ VC> corflags "C: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ System.Data.dll"

Microsoft (R) .NET Framework CorFlags Conversion Tool. Versi 3.5.21022.8 Hak cipta (c) Microsoft Corporation. Seluruh hak cipta.

Versi: v2.0.50727 CLR Header: 2.5 PE: PE32 CorFlags: 24 ILONLY: 0 32BIT: 0 Ditandatangani: 1

Anda sedang melihat PE dan 32BIT secara khusus.

  • CPU apa pun :

    PE: PE32
    32BIT: 0

  • x86 :

    PE: PE32
    32BIT: 1

  • x64:

    PE: PE32 +
    32BIT: 0

Blogan
sumber
18
@BLogan Anda harus melihat komentar saya kepada Steven Behnke di atas. Saya mengetahui utilitas corflags tetapi tidak berfungsi pada majelis asli.
Ohad Horesh
7
Apa keluaran Corflags yang diubah di versi yang terakhir (Windows SDK 8 atau lebih tinggi). Sekarang alih-alih 32BIT, ia memiliki 32BITREQUIRED dan 32BITPREFERRED. Lihat keterangan di CorHdr.h yang terletak C: \ Program Files (x86) \ Windows Kits \ 8.0 \ Sertakan \ um \ CorHdr.h. Dari apa yang saya tahu 32BITREQUIRED menggantikan 32BIT. Lihat juga jawaban untuk pertanyaan ini .
Wes
37

Trik ini berfungsi dan hanya membutuhkan Notepad.

Buka file dll menggunakan editor teks (seperti Notepad) dan temukan kemunculan pertama string PE. Karakter berikut mendefinisikan apakah dll adalah 32 atau 64 bit.

32 bit:

PE  L

64 bit:

PE  d
Zanon
sumber
25

The Magicbidang IMAGE_OPTIONAL_HEADER(meskipun tidak ada opsional tentang header pada Windows gambar executable (file DLL / EXE)) akan memberitahu Anda arsitektur PE.

Berikut adalah contoh mengambil arsitektur dari file.

public static ushort GetImageArchitecture(string filepath) {
    using (var stream = new System.IO.FileStream(filepath, System.IO.FileMode.Open, System.IO.FileAccess.Read))
    using (var reader = new System.IO.BinaryReader(stream)) {
        //check the MZ signature to ensure it's a valid Portable Executable image
        if (reader.ReadUInt16() != 23117) 
            throw new BadImageFormatException("Not a valid Portable Executable image", filepath);

        // seek to, and read, e_lfanew then advance the stream to there (start of NT header)
        stream.Seek(0x3A, System.IO.SeekOrigin.Current); 
        stream.Seek(reader.ReadUInt32(), System.IO.SeekOrigin.Begin);

        // Ensure the NT header is valid by checking the "PE\0\0" signature
        if (reader.ReadUInt32() != 17744)
            throw new BadImageFormatException("Not a valid Portable Executable image", filepath);

        // seek past the file header, then read the magic number from the optional header
        stream.Seek(20, System.IO.SeekOrigin.Current); 
        return reader.ReadUInt16();
    }
}

Dua konstanta arsitektur saat ini adalah:

0x10b - PE32
0x20b - PE32+

Bersulang

PEMBARUAN Sudah lama sejak saya memposting jawaban ini, namun saya masih melihat bahwa itu mendapat beberapa upvotes sekarang dan lagi jadi saya pikir itu layak diperbarui. Saya menulis cara untuk mendapatkan arsitektur Portable Executablegambar, yang juga memeriksa untuk melihat apakah itu dikompilasi AnyCPU. Sayangnya jawabannya adalah dalam C ++, tetapi seharusnya tidak terlalu sulit untuk port ke C # jika Anda memiliki beberapa menit untuk mencari struktur di WinNT.h. Jika orang tertarik, saya akan menulis porta dalam C #, tetapi kecuali orang benar-benar menginginkannya, saya tidak akan menghabiskan banyak waktu untuk menekankannya.

#include <Windows.h>

#define MKPTR(p1,p2) ((DWORD_PTR)(p1) + (DWORD_PTR)(p2))

typedef enum _pe_architecture {
    PE_ARCHITECTURE_UNKNOWN = 0x0000,
    PE_ARCHITECTURE_ANYCPU  = 0x0001,
    PE_ARCHITECTURE_X86     = 0x010B,
    PE_ARCHITECTURE_x64     = 0x020B
} PE_ARCHITECTURE;

LPVOID GetOffsetFromRva(IMAGE_DOS_HEADER *pDos, IMAGE_NT_HEADERS *pNt, DWORD rva) {
    IMAGE_SECTION_HEADER *pSecHd = IMAGE_FIRST_SECTION(pNt);
    for(unsigned long i = 0; i < pNt->FileHeader.NumberOfSections; ++i, ++pSecHd) {
        // Lookup which section contains this RVA so we can translate the VA to a file offset
        if (rva >= pSecHd->VirtualAddress && rva < (pSecHd->VirtualAddress + pSecHd->Misc.VirtualSize)) {
            DWORD delta = pSecHd->VirtualAddress - pSecHd->PointerToRawData;
            return (LPVOID)MKPTR(pDos, rva - delta);
        }
    }
    return NULL;
}

PE_ARCHITECTURE GetImageArchitecture(void *pImageBase) {
    // Parse and validate the DOS header
    IMAGE_DOS_HEADER *pDosHd = (IMAGE_DOS_HEADER*)pImageBase;
    if (IsBadReadPtr(pDosHd, sizeof(pDosHd->e_magic)) || pDosHd->e_magic != IMAGE_DOS_SIGNATURE)
        return PE_ARCHITECTURE_UNKNOWN;

    // Parse and validate the NT header
    IMAGE_NT_HEADERS *pNtHd = (IMAGE_NT_HEADERS*)MKPTR(pDosHd, pDosHd->e_lfanew);
    if (IsBadReadPtr(pNtHd, sizeof(pNtHd->Signature)) || pNtHd->Signature != IMAGE_NT_SIGNATURE)
        return PE_ARCHITECTURE_UNKNOWN;

    // First, naive, check based on the 'Magic' number in the Optional Header.
    PE_ARCHITECTURE architecture = (PE_ARCHITECTURE)pNtHd->OptionalHeader.Magic;

    // If the architecture is x86, there is still a possibility that the image is 'AnyCPU'
    if (architecture == PE_ARCHITECTURE_X86) {
        IMAGE_DATA_DIRECTORY comDirectory = pNtHd->OptionalHeader.DataDirectory[IMAGE_DIRECTORY_ENTRY_COM_DESCRIPTOR];
        if (comDirectory.Size) {
            IMAGE_COR20_HEADER *pClrHd = (IMAGE_COR20_HEADER*)GetOffsetFromRva(pDosHd, pNtHd, comDirectory.VirtualAddress);
            // Check to see if the CLR header contains the 32BITONLY flag, if not then the image is actually AnyCpu
            if ((pClrHd->Flags & COMIMAGE_FLAGS_32BITREQUIRED) == 0)
                architecture = PE_ARCHITECTURE_ANYCPU;
        }
    }

    return architecture;
}

Fungsi ini menerima pointer ke gambar PE dalam memori (sehingga Anda dapat memilih racun Anda tentang cara mendapatkannya; memetakan memori atau membaca semuanya ke dalam memori ... apa pun).

Jason Larke
sumber
Sangat menarik tetapi ketika saya memiliki aplikasi yang dikompilasi dengan CPU Apa pun, hasilnya adalah 0x10B. Ini salah karena aplikasi saya dijalankan di sistem x64. Apakah ada bendera lain untuk diperiksa?
Samuel
3
AnyCPU berarti hanya itu: AnyCPU, jadi terdaftar sebagai 0x10B di header PE untuk kompatibilitas dengan 32-bit. Untuk memeriksa perbedaan antara itu dan langsung 32-bit, Anda harus mencari tahu dari mana CorFlags mendapatkan 32BITbenderanya dari dalam PE, saya tidak tahu dari atas kepala saya.
Jason Larke
@JasonLarke saya mendarat di sini dari pencarian google dan potongan kode Anda membantu saya. Terimakasih banyak!
Parag Doke
@Samuel Diperbarui untuk memeriksa bendera AnyCPU.
Jason Larke
bahwa kode C # bekerja dalam proses 64 bit saat memeriksa rakitan 32 bit? Misalnya, Module.GetPEKind msdn.microsoft.com/en-us/library/… gagal
Kiquenet
14

Untuk file DLL yang tidak dikelola, Anda harus terlebih dahulu memeriksa apakah itu file DLL 16-bit (mudah-mudahan tidak). Kemudian periksa IMAGE\_FILE_HEADER.Machinebidangnya.

Orang lain sudah mengambil waktu untuk menyelesaikan ini, jadi saya hanya akan mengulangi di sini:

Untuk membedakan antara file PE 32-bit dan 64-bit, Anda harus memeriksa bidang IMAGE_FILE_HEADER. Mesin. Berdasarkan spesifikasi Microsoft PE dan COFF di bawah ini, saya telah mencantumkan semua nilai yang mungkin untuk bidang ini: http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/ pecoff_v8.doc

IMAGE_FILE_MACHINE_UNKNOWN 0x0 Isi bidang ini diasumsikan berlaku untuk semua jenis mesin

IMAGE_FILE_MACHINE_AM33 0x1d3 Matsushita AM33

IMAGE_FILE_MACHINE_AMD64 0x8664 x64

IMAGE_FILE_MACHINE_ARM 0x1c0 ARM little endian

IMAGE_FILE_MACHINE_EBC 0xebc kode EFI byte

IMAGE_FILE_MACHINE_I386 0x14c Intel 386 atau lebih baru prosesor dan prosesor yang kompatibel

IMAGE_FILE_MACHINE_IA64 0x200 keluarga prosesor Intel Itanium

IMAGE_FILE_MACHINE_M32R 0x9041 Mitsubishi M32R little endian

IMAGE_FILE_MACHINE_MIPS16 0x266 MIPS16

IMAGE_FILE_MACHINE_MIPSFPU 0x366 MIPS dengan FPU

IMAGE_FILE_MACHINE_MIPSFPU16 0x466 MIPS16 dengan FPU

IMAGE_FILE_MACHINE_POWERPC 0x1f0 Powerian little endian

IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 Daya PC dengan dukungan floating point

IMAGE_FILE_MACHINE_R4000 0x166 MIPS little endian

IMAGE_FILE_MACHINE_SH3 0x1a2 Hitachi SH3

IMAGE_FILE_MACHINE_SH3DSP 0x1a3 Hitachi SH3 DSP

IMAGE_FILE_MACHINE_SH4 0x1a6 Hitachi SH4

IMAGE_FILE_MACHINE_SH5 0x1a8 Hitachi SH5

IMAGE_FILE_MACHINE_THUMB 0x1c2 Ibu jari

IMAGE_FILE_MACHINE_WCEMIPSV2 0x169 MIPS little-endian WCE v2

Ya, Anda dapat memeriksa IMAGE_FILE_MACHINE_AMD64 | IMAGE_FILE_MACHINE_IA64 untuk 64bit dan IMAGE_FILE_MACHINE_I386 untuk 32bit.

ShuggyCoUk
sumber
tautan kedua Anda mati: s
gpalex
3

Buka dll dengan hex editor, seperti HxD

Jika ada "dt" pada baris ke-9 itu adalah 64bit.

Jika ada "L." pada baris ke-9 itu adalah 32bit.

Philip Mc Laughlin
sumber
Tidak dapat menemukan "dt" dan "L." pada penampil HEX "Manajer Jauh".
Dmitry
Ditunjukkan sebagai d. dan L.
Zax
1

Saya menulis ulang solusi c ++ sebagai jawaban pertama dalam skrip PowerShell. Script dapat menentukan jenis file .exe dan .dll ini:

#Description       C# compiler switch             PE type       machine corflags
#MSIL              /platform:anycpu (default)     PE32  x86     ILONLY
#MSIL 32 bit pref  /platform:anycpu32bitpreferred PE32  x86     ILONLY | 32BITREQUIRED | 32BITPREFERRED
#x86 managed       /platform:x86                  PE32  x86     ILONLY | 32BITREQUIRED
#x86 mixed         n/a                            PE32  x86     32BITREQUIRED
#x64 managed       /platform:x64                  PE32+ x64     ILONLY
#x64 mixed         n/a                            PE32+ x64  
#ARM managed       /platform:arm                  PE32  ARM     ILONLY
#ARM mixed         n/a                            PE32  ARM  

solusi ini memiliki beberapa keunggulan dibandingkan corflags.exe dan memuat perakitan melalui Assembly.Load di C # - Anda tidak akan pernah mendapatkan BadImageFormatException atau pesan tentang header yang tidak valid.

function GetActualAddressFromRVA($st, $sec, $numOfSec, $dwRVA)
{
    [System.UInt32] $dwRet = 0;
    for($j = 0; $j -lt $numOfSec; $j++)   
    {   
        $nextSectionOffset = $sec + 40*$j;
        $VirtualSizeOffset = 8;
        $VirtualAddressOffset = 12;
        $SizeOfRawDataOffset = 16;
        $PointerToRawDataOffset = 20;

    $Null = @(
        $curr_offset = $st.BaseStream.Seek($nextSectionOffset + $VirtualSizeOffset, [System.IO.SeekOrigin]::Begin);        
        [System.UInt32] $VirtualSize = $b.ReadUInt32();
        [System.UInt32] $VirtualAddress = $b.ReadUInt32();
        [System.UInt32] $SizeOfRawData = $b.ReadUInt32();
        [System.UInt32] $PointerToRawData = $b.ReadUInt32();        

        if ($dwRVA -ge $VirtualAddress -and $dwRVA -lt ($VirtualAddress + $VirtualSize)) {
            $delta = $VirtualAddress - $PointerToRawData;
            $dwRet = $dwRVA - $delta;
            return $dwRet;
        }
        );
    }
    return $dwRet;
}

function Get-Bitness2([System.String]$path, $showLog = $false)
{
    $Obj = @{};
    $Obj.Result = '';
    $Obj.Error = $false;

    $Obj.Log = @(Split-Path -Path $path -Leaf -Resolve);

    $b = new-object System.IO.BinaryReader([System.IO.File]::Open($path,[System.IO.FileMode]::Open,[System.IO.FileAccess]::Read, [System.IO.FileShare]::Read));
    $curr_offset = $b.BaseStream.Seek(0x3c, [System.IO.SeekOrigin]::Begin)
    [System.Int32] $peOffset = $b.ReadInt32();
    $Obj.Log += 'peOffset ' + "{0:X0}" -f $peOffset;

    $curr_offset = $b.BaseStream.Seek($peOffset, [System.IO.SeekOrigin]::Begin);
    [System.UInt32] $peHead = $b.ReadUInt32();

    if ($peHead -ne 0x00004550) {
        $Obj.Error = $true;
        $Obj.Result = 'Bad Image Format';
        $Obj.Log += 'cannot determine file type (not x64/x86/ARM) - exit with error';
    };

    if ($Obj.Error)
    {
        $b.Close();
        Write-Host ($Obj.Log | Format-List | Out-String);
        return $false;
    };

    [System.UInt16] $machineType = $b.ReadUInt16();
    $Obj.Log += 'machineType ' + "{0:X0}" -f $machineType;

    [System.UInt16] $numOfSections = $b.ReadUInt16();
    $Obj.Log += 'numOfSections ' + "{0:X0}" -f $numOfSections;
    if (($machineType -eq 0x8664) -or ($machineType -eq 0x200)) { $Obj.Log += 'machineType: x64'; }
    elseif ($machineType -eq 0x14c)                             { $Obj.Log += 'machineType: x86'; }
    elseif ($machineType -eq 0x1c0)                             { $Obj.Log += 'machineType: ARM'; }
    else{
        $Obj.Error = $true;
        $Obj.Log += 'cannot determine file type (not x64/x86/ARM) - exit with error';
    };

    if ($Obj.Error) {
        $b.Close();
        Write-Output ($Obj.Log | Format-List | Out-String);
        return $false;
    };

    $curr_offset = $b.BaseStream.Seek($peOffset+20, [System.IO.SeekOrigin]::Begin);
    [System.UInt16] $sizeOfPeHeader = $b.ReadUInt16();

    $coffOffset = $peOffset + 24;#PE header size is 24 bytes
    $Obj.Log += 'coffOffset ' + "{0:X0}" -f $coffOffset;

    $curr_offset = $b.BaseStream.Seek($coffOffset, [System.IO.SeekOrigin]::Begin);#+24 byte magic number
    [System.UInt16] $pe32 = $b.ReadUInt16();         
    $clr20headerOffset = 0;
    $flag32bit = $false;
    $Obj.Log += 'pe32 magic number: ' + "{0:X0}" -f $pe32;
    $Obj.Log += 'size of optional header ' + ("{0:D0}" -f $sizeOfPeHeader) + " bytes";

    #COMIMAGE_FLAGS_ILONLY               =0x00000001,
    #COMIMAGE_FLAGS_32BITREQUIRED        =0x00000002,
    #COMIMAGE_FLAGS_IL_LIBRARY           =0x00000004,
    #COMIMAGE_FLAGS_STRONGNAMESIGNED     =0x00000008,
    #COMIMAGE_FLAGS_NATIVE_ENTRYPOINT    =0x00000010,
    #COMIMAGE_FLAGS_TRACKDEBUGDATA       =0x00010000,
    #COMIMAGE_FLAGS_32BITPREFERRED       =0x00020000,

    $COMIMAGE_FLAGS_ILONLY        = 0x00000001;
    $COMIMAGE_FLAGS_32BITREQUIRED = 0x00000002;
    $COMIMAGE_FLAGS_32BITPREFERRED = 0x00020000;

    $offset = 96;
    if ($pe32 -eq 0x20b) {
        $offset = 112;#size of COFF header is bigger for pe32+
    }     

    $clr20dirHeaderOffset = $coffOffset + $offset + 14*8;#clr directory header offset + start of section number 15 (each section is 8 byte long);
    $Obj.Log += 'clr20dirHeaderOffset ' + "{0:X0}" -f $clr20dirHeaderOffset;
    $curr_offset = $b.BaseStream.Seek($clr20dirHeaderOffset, [System.IO.SeekOrigin]::Begin);
    [System.UInt32] $clr20VirtualAddress = $b.ReadUInt32();
    [System.UInt32] $clr20Size = $b.ReadUInt32();
    $Obj.Log += 'clr20VirtualAddress ' + "{0:X0}" -f $clr20VirtualAddress;
    $Obj.Log += 'clr20SectionSize ' + ("{0:D0}" -f $clr20Size) + " bytes";

    if ($clr20Size -eq 0) {
        if ($machineType -eq 0x1c0) { $Obj.Result = 'ARM native'; }
        elseif ($pe32 -eq 0x10b)    { $Obj.Result = '32-bit native'; }
        elseif($pe32 -eq 0x20b)     { $Obj.Result = '64-bit native'; }

       $b.Close();   
       if ($Obj.Result -eq '') { 
            $Obj.Error = $true;
            $Obj.Log += 'Unknown type of file';
       }
       else { 
            if ($showLog) { Write-Output ($Obj.Log | Format-List | Out-String); };
            return $Obj.Result;
       }
    };

    if ($Obj.Error) {
        $b.Close();
        Write-Host ($Obj.Log | Format-List | Out-String);
        return $false;
    };

    [System.UInt32]$sectionsOffset = $coffOffset + $sizeOfPeHeader;
    $Obj.Log += 'sectionsOffset ' + "{0:X0}" -f $sectionsOffset;
    $realOffset = GetActualAddressFromRVA $b $sectionsOffset $numOfSections $clr20VirtualAddress;
    $Obj.Log += 'real IMAGE_COR20_HEADER offset ' + "{0:X0}" -f $realOffset;
    if ($realOffset -eq 0) {
        $Obj.Error = $true;
        $Obj.Log += 'cannot find COR20 header - exit with error';
        $b.Close();
        return $false;
    };

    if ($Obj.Error) {
        $b.Close();
        Write-Host ($Obj.Log | Format-List | Out-String);
        return $false;
    };

    $curr_offset = $b.BaseStream.Seek($realOffset + 4, [System.IO.SeekOrigin]::Begin);
    [System.UInt16] $majorVer = $b.ReadUInt16();
    [System.UInt16] $minorVer = $b.ReadUInt16();
    $Obj.Log += 'IMAGE_COR20_HEADER version ' + ("{0:D0}" -f $majorVer) + "." + ("{0:D0}" -f $minorVer);

    $flagsOffset = 16;#+16 bytes - flags field
    $curr_offset = $b.BaseStream.Seek($realOffset + $flagsOffset, [System.IO.SeekOrigin]::Begin);
    [System.UInt32] $flag32bit = $b.ReadUInt32();
    $Obj.Log += 'CorFlags: ' + ("{0:X0}" -f $flag32bit);

#Description       C# compiler switch             PE type       machine corflags
#MSIL              /platform:anycpu (default)     PE32  x86     ILONLY
#MSIL 32 bit pref  /platform:anycpu32bitpreferred PE32  x86     ILONLY | 32BITREQUIRED | 32BITPREFERRED
#x86 managed       /platform:x86                  PE32  x86     ILONLY | 32BITREQUIRED
#x86 mixed         n/a                            PE32  x86     32BITREQUIRED
#x64 managed       /platform:x64                  PE32+ x64     ILONLY
#x64 mixed         n/a                            PE32+ x64  
#ARM managed       /platform:arm                  PE32  ARM     ILONLY
#ARM mixed         n/a                            PE32  ARM  

    $isILOnly = ($flag32bit -band $COMIMAGE_FLAGS_ILONLY) -eq $COMIMAGE_FLAGS_ILONLY;
    $Obj.Log += 'ILONLY: ' + $isILOnly;
    if ($machineType -eq 0x1c0) {#if ARM
        if ($isILOnly) { $Obj.Result = 'ARM managed'; } 
                  else { $Obj.Result = 'ARM mixed'; }
    }
    elseif ($pe32 -eq 0x10b) {#pe32
        $is32bitRequired = ($flag32bit -band $COMIMAGE_FLAGS_32BITREQUIRED) -eq $COMIMAGE_FLAGS_32BITREQUIRED;
        $is32bitPreffered = ($flag32bit -band $COMIMAGE_FLAGS_32BITPREFERRED) -eq $COMIMAGE_FLAGS_32BITPREFERRED;
        $Obj.Log += '32BIT: ' + $is32bitRequired;    
        $Obj.Log += '32BIT PREFFERED: ' + $is32bitPreffered 
        if     ($is32bitRequired  -and $isILOnly  -and $is32bitPreffered) { $Obj.Result = 'AnyCpu 32bit-preffered'; }
        elseif ($is32bitRequired  -and $isILOnly  -and !$is32bitPreffered){ $Obj.Result = 'x86 managed'; }
        elseif (!$is32bitRequired -and !$isILOnly -and $is32bitPreffered) { $Obj.Result = 'x86 mixed'; }
        elseif ($isILOnly)                                                { $Obj.Result = 'AnyCpu'; }
   }
   elseif ($pe32 -eq 0x20b) {#pe32+
        if ($isILOnly) { $Obj.Result = 'x64 managed'; } 
                  else { $Obj.Result = 'x64 mixed'; }
   }

   $b.Close();   
   if ($showLog) { Write-Host ($Obj.Log | Format-List | Out-String); }
   if ($Obj.Result -eq ''){ return 'Unknown type of file';};
   $flags = '';
   if ($isILOnly) {$flags += 'ILONLY';}
   if ($is32bitRequired) {
        if ($flags -ne '') {$flags += ' | ';}
        $flags += '32BITREQUIRED';
   }
   if ($is32bitPreffered) {
        if ($flags -ne '') {$flags += ' | ';}
        $flags += '32BITPREFERRED';
   }
   if ($flags -ne '') {$flags = ' (' + $flags +')';}
   return $Obj.Result + $flags;
}

contoh penggunaan:

#$filePath = "C:\Windows\SysWOW64\regedit.exe";#32 bit native on 64bit windows
$filePath = "C:\Windows\regedit.exe";#64 bit native on 64bit windows | should be 32 bit native on 32bit windows

Get-Bitness2 $filePath $true;

Anda dapat menghilangkan parameter kedua jika Anda tidak perlu melihat detailnya

sqladmin
sumber
1

Cara cepat dan mungkin kotor untuk melakukannya dijelaskan di sini: https://superuser.com/a/889267 . Anda membuka DLL dalam editor dan memeriksa karakter pertama setelah urutan "PE".

ohgodnotanotherone
sumber
0

Rupanya Anda dapat menemukannya di header portable executable. Utilitas corflags.exe dapat menunjukkan kepada Anda apakah ia menargetkan x64 atau tidak. Semoga ini membantu Anda menemukan lebih banyak informasi tentang itu.

Steven Behnke
sumber
3
Terima kasih Steven, tetapi corflags.exe tidak bekerja dengan majelis asli.
Ohad Horesh
1
Windows 10:>corflags libzmq.dll \n\n ... corflags : error CF008 : The specified file does not have a valid managed header
Grault