Làm thế nào để tìm một tập tin DLL gốc được biên dịch thành x64 hoặc x86?


133

Tôi muốn xác định nếu một hội đồng gốc được tuân thủ là x64 hoặc x86 từ một ứng dụng mã được quản lý ( C # ).

Tôi nghĩ rằng nó phải ở đâu đó trong tiêu đề PE vì trình tải hệ điều hành cần biết thông tin này, nhưng tôi không thể tìm thấy nó. Tất nhiên tôi thích làm điều đó trong mã được quản lý, nhưng nếu cần, tôi có thể sử dụng C ++ gốc.


Để rõ ràng, dll trong câu hỏi cũng là một hội đồng .Net? Bạn nói DLL gốc trong tiêu đề của bài đăng, nhưng hội thảo gốc trong phần mô tả ... nếu bạn vẫn đang tích cực xem bài đăng này từ 09 :)
Vikas Gupta

1
Bạn cũng có thể muốn kiểm tra cái này: check-if-unmanaged-dll-is-32-bit-or-64-bit .
Matt

Câu trả lời:


143

Bạn cũng có thể sử dụng DUMPBIN . Sử dụng /headershoặc /allcờ và tiêu đề tệp đầu tiên được liệt kê.

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

'Tìm' có thể làm cho cuộc sống dễ dàng hơn một chút:

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

4
Người dùng thân thiện hơn một chút;)
Ant

4
DUMPBIN không hoạt động cho .NET EXE. Tôi có .NET EXE 64 bit mà DUMPBIN nói là 32 bit ("máy 14C (x86)"), nhưng corflags nói là Bất kỳ CPU nào ("PE: PE32, 32BIT: 0"). Walker phụ thuộc cũng chẩn đoán sai nó.
Pierre

2
Nó yêu cầu mspdb100.dll:(
Dmitry

1
@Altaveron Tôi gặp vấn đề tương tự, nhưng đã giải quyết nó bằng cách sao chép tệp DLL mspdb100.dllvào thư mục dumpbin.exenằm ở đâu. DUMPBINcó thể chạy sau đó Đối với tôi, EXE là tại <Visual Studio Install folder>\VC\binvà DLL là tại <Visual Studio Install folder>\Common7\IDE.
ADTC

DUMPBIN có sẵn từ dấu nhắc lệnh của Visual Studio cho những người đã cài đặt Visual Studio
Alan Macdonald

55

Có một cách dễ dàng để làm điều này với CorFlags . Mở Dấu nhắc lệnh của Visual Studio và gõ "corflags [your assembly]". Bạn sẽ nhận được một cái gì đó như thế này:

c: \ Tệp chương trình (x86) \ Microsoft Visual Studio 9.0 \ VC> corflags "C: \ Windows \ Microsoft.NET \ Framework \ v2.0.50727 \ System.Data.dll"

Microsoft (R) .NET Framework Công cụ chuyển đổi CorFlags. Phiên bản 3.5.21022.8 Bản quyền (c) Tập đoàn Microsoft. Đã đăng ký Bản quyền.

Phiên bản: v2.0.50727 Tiêu đề CLR: 2.5 PE: PE32 CorFlags: 24 ILONLY: 0 32BIT: 0 Đã ký: 1

Bạn đang xem PE và 32BIT cụ thể.

  • Bất kỳ CPU :

    PE: PE32
    32BIT: 0

  • x86 :

    PE: PE32
    32 BIT: 1

  • x64:

    PE: PE32 +
    32BIT: 0


18
@BLogan bạn nên xem bình luận của tôi cho Steven Behnke ở trên. Tôi biết về tiện ích corflags nhưng nó không hoạt động trên các hội đồng gốc.
Ohad Horesh

7
Những gì đầu ra Corflags đã thay đổi trong các phiên bản sau (Windows SDK 8 trở lên). Bây giờ thay vì 32BIT, nó có 32BITREQUIRED và 32BITPREFERRED. Xem mô tả trong CorHdr.h có vị trí C: \ Chương trình tệp (x86) \ Windows Kits \ 8.0 \ Bao gồm \ um \ CorHdr.h. Từ những gì tôi có thể nói 32BITREQUIRED thay thế 32BIT. Cũng xem câu trả lời cho câu hỏi này .
Wes

37

Thủ thuật này hoạt động và chỉ yêu cầu Notepad.

Mở tệp dll bằng trình soạn thảo văn bản (như Notepad) và tìm lần xuất hiện đầu tiên của chuỗi PE. Ký tự sau định nghĩa nếu dll là 32 hoặc 64 bit.

32 bit:

PE  L

64 bit:

PE  d

25

Các Magiclĩnh vực IMAGE_OPTIONAL_HEADER(mặc dù không có gì là không bắt buộc về tiêu đề trong Windows hình ảnh thực thi (file DLL / EXE)) sẽ cho bạn biết kiến trúc của PE.

Đây là một ví dụ về lấy kiến ​​trúc từ một tập tin.

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

Hai hằng số kiến ​​trúc duy nhất tại thời điểm này là:

0x10b - PE32
0x20b - PE32+

Chúc mừng

CẬP NHẬT Đã được một thời gian kể từ khi tôi đăng câu trả lời này, nhưng tôi vẫn thấy rằng nó nhận được một vài upvote bây giờ và vì vậy tôi nhận thấy nó đáng để cập nhật. Tôi đã viết một cách để có được kiến ​​trúc của một Portable Executablehình ảnh, cũng kiểm tra xem nó có được biên dịch thành không AnyCPU. Thật không may, câu trả lời là trong C ++, nhưng không quá khó để chuyển sang C # nếu bạn có vài phút để tìm kiếm các cấu trúc trong đó WinNT.h. Nếu mọi người quan tâm tôi sẽ viết một cổng bằng C #, nhưng trừ khi mọi người thực sự muốn nó, tôi sẽ không dành nhiều thời gian để nhấn mạnh về nó.

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

Hàm chấp nhận một con trỏ tới hình ảnh PE trong bộ nhớ (vì vậy bạn có thể chọn chất độc của mình về cách lấy nó; ánh xạ bộ nhớ hoặc đọc toàn bộ vào bộ nhớ ... bất cứ điều gì).


Rất thú vị nhưng khi tôi có một ứng dụng được biên dịch với Any CPU, kết quả là 0x10B. Điều này là sai vì ứng dụng của tôi được chạy trong hệ thống x64. Có cờ nào khác để kiểm tra không?
Samuel

3
AnyCPU có nghĩa là: AnyCPU, do đó, nó được liệt kê là 0x10B trong tiêu đề PE để tương thích ngược với 32 bit. Để kiểm tra sự khác biệt giữa 32 bit và thẳng, bạn cần tìm xem CorFlags lấy 32BITcờ từ đâu trong PE, tôi không biết trên đỉnh đầu.
Jason Larke

@JasonLarke Tôi đã đến đây từ một tìm kiếm google và đoạn mã của bạn đã giúp tôi. Cảm ơn nhiều!
Parag Doke

@Samuel Cập nhật để kiểm tra cờ AnyCPU.
Jason Larke

mã C # có hoạt động trong quy trình 64 bit khi kiểm tra các cụm 32 bit không? Ví dụ: Module.GetPEKind msdn.microsoft.com/en-us/l Library / không thành công
Kiquenet

14

Đối với tệp DLL không được quản lý, trước tiên bạn cần kiểm tra xem đó có phải là tệp DLL 16 bit không (hy vọng là không). Sau đó kiểm tra hiện IMAGE\_FILE_HEADER.Machinetrường.

Một số người khác đã dành thời gian để giải quyết vấn đề này, vì vậy tôi sẽ chỉ nhắc lại ở đây:

Để phân biệt giữa tệp PE 32 bit và 64 bit, bạn nên kiểm tra trường IMAGE_FILE_HEADER.Machine. Dựa trên thông số kỹ thuật của Microsoft PE và COFF bên dưới, tôi đã liệt kê tất cả các giá trị có thể có cho trường này: http://doad.microsoft.com/doad/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/ pecoff_v8.doc

IMAGE_FILE_MACHINE_UNKNOWN 0x0 Nội dung của trường này được giả sử là có thể áp dụng cho mọi loại máy

IMAGE_FILE_MACHINE_AM33 0x1d3 Matsushita AM33

IMAGE_FILE_MACHINE_AMD64 0x8664 x64

IMAGE_FILE_MACHINE_ARM 0x1c0 ARM endian nhỏ

IMAGE_FILE_MACHINE_EBC 0xebc Mã byte EFI

IMAGE_FILE_MACHINE_I386 0x14c Bộ xử lý Intel 386 trở lên và bộ xử lý tương thích

IMAGE_FILE_MACHINE_IA64 0x200 Họ bộ xử lý Intel Itanium

IMAGE_FILE_MACHINE_M32R 0x9041 Mitsubishi M32R chút cuối

IMAGE_FILE_MACHINE_MIPS16 0x266 MIPS16

IMAGE_FILE_MACHINE_MIPSFPU 0x366 MIPS với FPU

IMAGE_FILE_MACHINE_MIPSFPU16 0x466 MIPS16 với FPU

IMAGE_FILE_MACHINE_POWERPC 0x1f0 Cấp nguồn cho máy tính nhỏ

IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 Máy tính có hỗ trợ điểm nổi

IMAGE_FILE_MACHINE_R4000 0x166 MIPS 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 WCE v2 nhỏ cuối

Có, bạn có thể kiểm tra IMAGE_FILE_MACHINE_AMD64 | IMAGE_FILE_MACHINE_IA64 cho 64 bit và IMAGE_FILE_MACHINE_I386 cho 32 bit.


liên kết thứ hai của bạn đã chết: s
gpalex



3

Mở dll bằng trình soạn thảo hex, như HxD

Nếu có "dt" trên dòng thứ 9 thì nó là 64 bit.

Nếu có "L" trên dòng thứ 9 là 32 bit.


Không thể tìm thấy "dt" và "L." trên trình xem HEX "Far Manager".
Dmitry

Hiển thị như d. và L.
Zax

1

Tôi viết lại giải pháp c ++ trong câu trả lời đầu tiên trong tập lệnh powershell. Script có thể xác định các loại tệp .exe và.

#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  

giải pháp này có một số lợi thế so với corflags.exe và tải lắp ráp thông qua hội đồng. Tải trong C # - bạn sẽ không bao giờ nhận được BadImageFormatException hoặc thông báo về tiêu đề không hợp lệ.

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

ví dụ sử dụng:

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

bạn có thể bỏ qua tham số thứ hai nếu bạn không cần xem chi tiết



0

Rõ ràng bạn có thể tìm thấy nó trong tiêu đề của tệp thực thi di động. Tiện ích corflags.exe có thể cho bạn biết liệu nó có nhắm mục tiêu x64 hay không. Hy vọng điều này sẽ giúp bạn tìm thêm thông tin về nó.


3
Cảm ơn Steven nhưng corflags.exe không hoạt động với các hội đồng gốc.
Ohad Horesh

1
Windows 10:>corflags libzmq.dll \n\n ... corflags : error CF008 : The specified file does not have a valid managed header
Grault
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.