Come scoprire se un file DLL nativo viene compilato come x64 o x86?


133

Voglio determinare se un assembly nativo viene rispettato come x64 o x86 da un'applicazione di codice gestito ( C # ).

Penso che debba trovarsi da qualche parte nell'intestazione PE poiché il caricatore del sistema operativo deve conoscere queste informazioni, ma non sono riuscito a trovarle. Ovviamente preferisco farlo nel codice gestito, ma se necessario, posso usare il C ++ nativo.


Per essere chiari, la dll in questione è anche un assembly .Net? Dici DLL nativa nel titolo del post, ma assembly nativo nella descrizione ... se stai ancora attivamente guardando questo post dal 09 :)
Vikas Gupta,

1
Potresti anche voler dare un'occhiata a questo: check-if-unmanaged-dll-is-32-bit-or-64-bit .
Matt,

Risposte:


143

Puoi anche usare DUMPBIN . Utilizzare il flag /headerso /alled è la prima intestazione del file elencata.

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

'trova' può semplificare leggermente la vita:

dumpbin /headers cv210.dll |find "machine"
        8664 machine (x64)

4
Leggermente più user friendly;)
Ant

4
DUMPBIN non funziona per i file EXE .NET. Ho un EXE .NET a 64 bit che DUMPBIN afferma sia a 32 bit ("14C machine (x86)"), ma corflags dice Any CPU ("PE: PE32, 32BIT: 0"). Dipendente Walker anche la diagnosi errata.
Pierre,

2
Richiede mspdb100.dll:(
Dmitry il

1
@Altaveron Ho avuto lo stesso problema, ma risolto copiando il file DLL mspdb100.dllnella cartella in cui dumpbin.exesi trova. DUMPBINpuò correre dopo. Per me, il file EXE è <Visual Studio Install folder>\VC\bine la DLL è <Visual Studio Install folder>\Common7\IDE.
ADTC,

DUMPBIN è disponibile dal prompt dei comandi di Visual Studio per quelli con Visual Studio installato
Alan Macdonald

55

C'è un modo semplice per farlo con CorFlags . Apri il prompt dei comandi di Visual Studio e digita "corflags [il tuo assembly]". Otterrai qualcosa del genere:

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

Strumento di conversione CorFlags di Microsoft (R) .NET Framework. Versione 3.5.21022.8 Copyright (c) Microsoft Corporation. Tutti i diritti riservati.

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

Stai guardando PE e 32BIT in particolare.

  • Qualsiasi CPU :

    PE: PE32
    32BIT: 0

  • x86 :

    PE: PE32
    32BIT: 1

  • x64:

    PE: PE32 +
    32BIT: 0


18
@BLogan dovresti guardare il mio commento a Steven Behnke sopra. Sono a conoscenza dell'utility corflags ma non funziona su assembly nativi.
Ohad Horesh, l'

7
Quali output di Corflags sono stati modificati nelle ultime versioni (Windows SDK 8 o versioni successive). Ora invece di 32BIT ha 32BITREQUIRED e 32BITPREFERRED. Vedi la descrizione in CorHdr.h che si trova in C: \ Programmi (x86) \ Windows Kits \ 8.0 \ Include \ um \ CorHdr.h. Da quello che posso dire 32BITREQUIRED sostituisce 32BIT. Vedi anche la risposta a questa domanda .
Wes,

37

Questo trucco funziona e richiede solo Blocco note.

Apri il file dll usando un editor di testo (come Blocco note) e trova la prima occorrenza della stringa PE. Il carattere seguente definisce se la dll è a 32 o 64 bit.

32 bit:

PE  L

64 bit:

PE  d

25

Il Magiccampo del IMAGE_OPTIONAL_HEADER(sebbene non ci sia nulla di facoltativo nell'intestazione nelle immagini eseguibili di Windows (file DLL / EXE)) ti dirà l'architettura di PE.

Ecco un esempio di come catturare l'architettura da un 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();
    }
}

Le uniche due costanti di architettura al momento sono:

0x10b - PE32
0x20b - PE32+

Saluti

AGGIORNAMENTO È passato un po 'di tempo da quando ho pubblicato questa risposta, eppure vedo ancora che riceve qualche voto di tanto in tanto, quindi ho pensato che valesse la pena aggiornarlo. Ho scritto un modo per ottenere l'architettura di Portable Executableun'immagine, che controlla anche se è stata compilata come AnyCPU. Sfortunatamente la risposta è in C ++, ma non dovrebbe essere troppo difficile portarlo su C # se hai qualche minuto per cercare le strutture WinNT.h. Se le persone sono interessate, scriverò una porta in C #, ma a meno che le persone non lo vogliano davvero, non passerò molto tempo a stressarlo.

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

La funzione accetta un puntatore a un'immagine PE in memoria (quindi puoi scegliere il tuo veleno su come ottenerlo; mappare la memoria o leggere tutto in memoria ... qualunque cosa).


Molto interessante ma quando ho un'applicazione compilata con qualsiasi CPU, il risultato è 0x10B. Questo è sbagliato perché la mia applicazione viene eseguita in un sistema x64. C'è qualche altra bandiera da controllare?
Samuel,

3
AnyCPU significa proprio questo: AnyCPU, quindi è elencato come 0x10B nell'intestazione PE per la compatibilità all'indietro con 32 bit. Per verificare la differenza tra quello e il diritto a 32 bit, dovresti scoprire da dove CorFlags ottiene la sua 32BITbandiera nel PE, non lo so dalla cima della mia testa.
Jason Larke,

@JasonLarke Sono arrivato qui da una ricerca su Google e il tuo frammento di codice mi ha aiutato. Grazie molto!
Parag Doke,

@Samuel Aggiornato per controllare il flag AnyCPU.
Jason Larke,

che codice C # funziona in un processo a 64 bit quando si controllano gli assembly a 32 bit? Ad esempio, Module.GetPEKind msdn.microsoft.com/en-us/library/... fallisce
Kiquenet

14

Per un file DLL non gestito, è necessario prima verificare se si tratta di un file DLL a 16 bit (si spera di no). Quindi controlla il IMAGE\_FILE_HEADER.Machinecampo.

Qualcun altro si è preso il tempo di risolverlo già, quindi ripeterò qui:

Per distinguere tra un file PE a 32 e 64 bit, è necessario selezionare il campo IMAGE_FILE_HEADER.Machine. Sulla base delle specifiche Microsoft PE e COFF riportate di seguito, ho elencato tutti i possibili valori per questo campo: http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/ pecoff_v8.doc

IMAGE_FILE_MACHINE_UNKNOWN 0x0 Si presume che il contenuto di questo campo sia applicabile a qualsiasi tipo di macchina

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 Codice byte EFI 0xebc

IMAGE_FILE_MACHINE_I386 0x14c Processori Intel 386 o successivi e processori compatibili

IMAGE_FILE_MACHINE_IA64 0x200 famiglia di processori Intel Itanium

IMAGE_FILE_MACHINE_M32R 0x9041 Mitsubishi M32R little endian

IMAGE_FILE_MACHINE_MIPS16 0x266 MIPS16

IMAGE_FILE_MACHINE_MIPSFPU 0x366 MIPS con FPU

IMAGE_FILE_MACHINE_MIPSFPU16 0x466 MIPS16 con FPU

IMAGE_FILE_MACHINE_POWERPC 0x1f0 Power PC little endian

IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 Power PC con supporto in virgola mobile

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 Thumb

IMAGE_FILE_MACHINE_WCEMIPSV2 0x169 MIPS little-endian WCE v2

Sì, puoi controllare IMAGE_FILE_MACHINE_AMD64 | IMAGE_FILE_MACHINE_IA64 per 64 bit e IMAGE_FILE_MACHINE_I386 per 32 bit.


il tuo secondo link è morto: s
gpalex,



3

Apri la DLL con un editor esadecimale, come HxD

Se c'è un "dt" sulla nona riga è 64 bit.

Se è presente una "L." sulla nona linea è a 32 bit.


Impossibile trovare "dt" e "L." nel visualizzatore HEX "Far Manager".
Dmitry,

Mostrato come d. e L.
Zax,

1

Ho riscritto la soluzione c ++ nella prima risposta nello script PowerShell. Lo script può determinare questi tipi di file .exe e .dll:

#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  

questa soluzione presenta alcuni vantaggi rispetto a corflags.exe e il caricamento dell'assembly tramite Assembly.Load in C #: non otterrai mai BadImageFormatException o un messaggio sull'intestazione non valida.

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

esempio di utilizzo:

#$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;

puoi omettere il secondo parametro se non hai bisogno di vedere i dettagli



0

Apparentemente puoi trovarlo nell'intestazione dell'eseguibile portatile. L'utilità corflags.exe è in grado di mostrarti se è indirizzata o meno a x64. Spero che questo ti aiuti a trovare maggiori informazioni al riguardo.


3
Grazie Steven ma corflags.exe non funziona con gli assembly nativi.
Ohad Horesh,

1
Windows 10:>corflags libzmq.dll \n\n ... corflags : error CF008 : The specified file does not have a valid managed header
Grault,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.