কোনও নেটিভ ডিএলএল ফাইল x64 বা x86 হিসাবে সংকলিত আছে কীভাবে তা আবিষ্কার করবেন?


133

কোনও নির্ধারিত কোড অ্যাপ্লিকেশন ( সি # ) থেকে কোনও নেটিভ এসেম্বলি x64 বা x86 হিসাবে মেনে চলা হয়েছে কিনা তা আমি নির্ধারণ করতে চাই ।

আমি মনে করি এটি অবশ্যই পিই শিরোনামের কোথাও থাকা উচিত যেহেতু ওএস লোডারকে এই তথ্যটি জানা দরকার, তবে আমি এটি খুঁজে পাইনি। অবশ্যই আমি এটি পরিচালিত কোডে করতে পছন্দ করি তবে এটির প্রয়োজন হলে আমি স্থানীয় সি ++ ব্যবহার করতে পারি।


স্পষ্টতই, প্রশ্নে থাকা ডেলটিও একটি। নেট সমাবেশ? আপনি পোস্টের শিরোনামে নেটিভ ডিএলএল বলছেন, তবে বর্ণনায় দেশীয় সমাবেশ ... আপনি যদি এখনও 09 থেকে এই পোস্টটি সক্রিয়ভাবে দেখছেন :)
বিকাশ গুপ্ত


উত্তর:


143

আপনি ডাম্পবিনও ব্যবহার করতে পারেন । তালিকাভুক্ত প্রথম ফাইল শিরোনাম /headersবা /allপতাকা এবং ব্যবহার করুন ।

dumpbin /headers cv210.dll

64-বিট

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-বিট

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

'সন্ধান' জীবনকে কিছুটা সহজ করে তুলতে পারে:

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

4
কিছুটা বেশি ব্যবহারকারী বান্ধব;)
এন্টি

4
ডাম্পবিন। নেট এক্সের জন্য কাজ করে না। আমার কাছে একটি -৪-বিট। নেট এক্সই রয়েছে যে ডাম্পবিন বলে 32-বিট ("14 সি মেশিন (x86)"), তবে কর্ফ্ল্যাগস বলে যে কোনও সিপিইউ ("পিই: পিই 32, 32 বিআইটি: 0")। নির্ভরতা ওয়াকারও এটিকে ভুল ব্যাখ্যা করে।
পিয়েরে

2
এটি প্রয়োজনীয় mspdb100.dll:(
দিমিত্রি

1
@ অ্যালটাভারন আমার একই সমস্যা ছিল, তবে ডিএলএল ফাইলটি mspdb100.dllযেখানে ফোল্ডারে রয়েছে সেখানে অনুলিপি করে সমাধান করেছি dumpbin.exeDUMPBINতার পরে দৌড়াতে পারে। আমার জন্য, EXE এর এ <Visual Studio Install folder>\VC\binএবং ডিএলএল হয় <Visual Studio Install folder>\Common7\IDE
এডিটিসি

DUMPBIN ভিজ্যুয়াল স্টুডিও ইনস্টল করা ব্যক্তিদের জন্য ভিজ্যুয়াল স্টুডিও কমান্ড প্রম্পট থেকে উপলব্ধ
অ্যালান ম্যাকডোনাল্ড

55

CorFlags দিয়ে এটি করার একটি সহজ উপায় রয়েছে । ভিজ্যুয়াল স্টুডিও কমান্ড প্রম্পটটি খুলুন এবং "কর্ফ্ল্যাগগুলি [আপনার সমাবেশ]" টাইপ করুন। আপনি এই জাতীয় কিছু পাবেন:

c: \ প্রোগ্রাম ফাইলগুলি (x86) \ মাইক্রোসফ্ট ভিজ্যুয়াল স্টুডিও 9.0 \ ভিসি> "সি: \ উইন্ডোজ \ মাইক্রোসফট.নেট \ ফ্রেমওয়ার্ক \ v2.0.50727 \ System.Data.dll"

মাইক্রোসফ্ট (আর)। নেট ফ্রেমওয়ার্ক রূপান্তর সরঞ্জাম। সংস্করণ 3.5.21022.8 কপিরাইট (সি) মাইক্রোসফ্ট কর্পোরেশন। সমস্ত অধিকার সংরক্ষিত.

সংস্করণ: v2.0.50727 সিএলআর শিরোনাম: 2.5 পিই: PE32 CorFlags: 24 অলৌকিক: 0 32 বিআইটি: 0 স্বাক্ষরিত: 1

আপনি বিশেষত পিই এবং 32 বিআইটি খুঁজছেন।

  • যে কোনও সিপিইউ :

    পিই: পিই
    32 32 বিআইটি: 0

  • x86 :

    পিই: পিই
    32 32 বিআইটি: 1

  • x64:

    পিই: পিই
    32 + 32 বিআইটি: 0


18
@ ব্লগান আপনার উপরের স্টিভেন বেহঙ্কে আমার মন্তব্যটি লক্ষ্য করা উচিত। আমি কর্পফ্লাগস ইউটিলিটি সম্পর্কে সচেতন তবে এটি স্থানীয় অ্যাসেমব্লিতে কাজ করে না।
ওহাদ হোরেশ

7
কর্পফ্লাগস আউটপুটগুলি কী আধুনিক সংস্করণে পরিবর্তিত হয়েছে (উইন্ডোজ এসডিকে 8 বা তার বেশি)। এখন 32BIT এর পরিবর্তে এর 32BITREQUIRED এবং 32BITPREFERRED রয়েছে। CorHdr.h অবস্থিত সি তে বর্ণনা দেখুন: Files প্রোগ্রাম ফাইলগুলি (x86) \ উইন্ডোজ কিটস \ 8.0 \ অন্তর্ভুক্ত \ um \ CorHdr.h। আমি যা বলতে পারি তা থেকে 32 বিট্রেইভারিডিটি 32 বিটি প্রতিস্থাপন করে। এছাড়াও এই প্রশ্নের উত্তর দেখুন ।
ওয়েজ

37

এই কৌশলটি কাজ করে এবং কেবল নোটপ্যাডের প্রয়োজন।

একটি টেক্সট সম্পাদক (নোটপ্যাডের মতো) ব্যবহার করে dll ফাইলটি খুলুন এবং স্ট্রিংটির প্রথম উপস্থিতি সন্ধান করুন PE। Dll 32 বা 64 বিট হলে নিম্নলিখিত অক্ষরটি সংজ্ঞা দেয়।

32 বিট:

PE  L

64 বিট:

PE  d

25

এর Magicক্ষেত্রটি IMAGE_OPTIONAL_HEADER(যদিও উইন্ডোজ এক্সিকিউটেবল ইমেজগুলিতে হেডার সম্পর্কে aboutচ্ছিক কিছু নেই (ডিএলএল / এক্সই ফাইল)) আপনাকে পিই এর আর্কিটেকচারটি জানিয়ে দেবে।

এখানে একটি ফাইল থেকে আর্কিটেকচার দখল করার উদাহরণ।

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

এই মুহুর্তে কেবলমাত্র দুটি আর্কিটেকচার ধ্রুবক:

0x10b - PE32
0x20b - PE32+

চিয়ার্স

আপডেট আমি এই উত্তরটি পোস্ট করার পরে একটি সময় হয়ে গেছে, তবুও আমি এখনও দেখতে পাচ্ছি যে এটি এখন এবং বার কয়েকটি উর্ধ্বতন পেয়েছে তাই আমি বুঝতে পেরেছিলাম যে এটি আপডেট করার মতো। আমি একটি Portable Executableচিত্রের আর্কিটেকচার পেতে একটি উপায় লিখেছি , যা এটি যেমনটি সংকলিত হয়েছে তা পরীক্ষা করে দেখুন AnyCPU। দুর্ভাগ্যক্রমে উত্তরটি সি ++ এ রয়েছে, তবে কাঠামোগুলি সন্ধান করতে যদি আপনার কাছে কয়েক মিনিট থাকে তবে সি # তে পোর্ট করা খুব কঠিন হবে না WinNT.h। লোকেরা আগ্রহী হলে আমি সি # তে একটি বন্দর লিখব, তবে লোকেদের আসলে এটি না চাইলে আমি এ সম্পর্কে জোর দিয়ে বেশি সময় ব্যয় করব না।

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

ফাংশনটি একটি ইন-মেমোরি পিই ইমেজের পয়েন্টারটিকে গ্রহণ করে (যাতে আপনি এটি কীভাবে তা পান করতে পারেন তা আপনার বিষ চয়ন করতে পারেন; মেমরি-ম্যাপিং বা পুরো জিনিসটি মেমোরিতে পড়ুন ... যাই হোক না কেন)।


খুব আকর্ষণীয় তবে যখন আমি কোনও সিপিইউ দিয়ে একটি অ্যাপ্লিকেশন সংকলন করেছি তখন ফলাফলটি 0x10 বি হয়। এটি ভুল কারণ আমার অ্যাপ্লিকেশনটি একটি x 64 সিস্টেমে চালিত। অন্য কোন পতাকা চেক আছে?
স্যামুয়েল

3
যেকোন সিসিপিইউ এর অর্থ হ'ল: যেকোন সিসিপিইউ, তাই এটি 32-বিটের সাথে পিছনে সামঞ্জস্যের জন্য পিই শিরোনামে 0x10B হিসাবে তালিকাভুক্ত। এটির সাথে সরাসরি 32-বিটের মধ্যে পার্থক্যটি পরীক্ষা করতে, আপনাকে খুঁজে বের করতে হবে যে করফ্ল্যাজগুলি 32BITপিই থেকে কোথায় তার পতাকাটি পেয়েছে, আমি আমার মাথার উপরের অংশটি জানি না।
জেসন লার্ক 0

@ জেসন লার্কে আমি এখানে একটি গুগল অনুসন্ধান থেকে অবতরণ করেছি এবং আপনার কোড স্নিপেট আমাকে সহায়তা করেছিল। অনেক ধন্যবাদ!
প্যারাগ ডোক

যে কোনও এসিপিইউ পতাকাটি পরীক্ষা করতে সামুয়েল আপডেট হয়েছে।
জেসন লার্ক

যে সি # কোড 32 বিট অ্যাসেমব্লিগুলি চেক করার সময় একটি 64 বিট প্রক্রিয়াতে কাজ করে? উদাহরণস্বরূপ, Module.GetPEKind msdn.microsoft.com/en-us/library/... ব্যর্থ
Kiquenet

14

একটি পরিচালনা না করা ডিএলএল ফাইলের জন্য, আপনাকে প্রথমে এটি পরীক্ষা করতে হবে এটি কোনও 16-বিট ডিএলএল ফাইল কিনা (আশা করি না)। তারপরে IMAGE\_FILE_HEADER.Machineক্ষেত্রটি পরীক্ষা করুন ।

ইতিমধ্যে এটির কাজ করার জন্য অন্য কেউ সময় নিয়েছে, তাই আমি এখানে কেবল পুনরাবৃত্তি করব:

৩২-বিট এবং -৪-বিট পিই ফাইলের মধ্যে পার্থক্য রাখতে আপনার IMAGE_FILE_HEADER.Machine ক্ষেত্রটি পরীক্ষা করা উচিত। নিচে মাইক্রোসফট PE এবং COFF স্পেসিফিকেশন উপর ভিত্তি করে, আমি এই ক্ষেত্রের জন্য সব সম্ভাব্য মান আউট তালিকাভুক্ত করেছেন: http://download.microsoft.com/download/9/c/5/9c5b2167-8017-4bae-9fde-d599bac8184a/ pecoff_v8.doc

IMAGE_FILE_MACHINE_UNKNOWN 0x0 এই ক্ষেত্রের বিষয়বস্তু যে কোনও মেশিন প্রকারের জন্য প্রযোজ্য বলে ধরে নেওয়া হচ্ছে

IMAGE_FILE_MACHINE_AM33 0x1d3 মাতুষিতা AM33 33

IMAGE_FILE_MACHINE_AMD64 0x8664 x64

IMAGE_FILE_MACHINE_ARM 0x1c0 এআরএম ছোট এন্ডিয়ান

IMAGE_FILE_MACHINE_EBC 0xebc EFI বাইট কোড

IMAGE_FILE_MACHINE_I386 0x14c ইন্টেল 386 বা তারপরের প্রসেসর এবং সামঞ্জস্যপূর্ণ প্রসেসর

IMAGE_FILE_MACHINE_IA64 0x200 ইন্টেল ইটানিয়াম প্রসেসর পরিবার

IMAGE_FILE_MACHINE_M32R 0x9041 মিতসুবিশি M32R ছোট এন্ডিয়ান

IMAGE_FILE_MACHINE_MIP16 0x266 MIP16

আইএমপিএফএফএল_MACHINE_MIPSFPU 0x366 এমপিএস এফপিইউ সহ

আইএমপিএফএইফএল_MACHINE_MIPSFPU16 0x466 এমআইপিএস 16 এফপিইউ সহ

IMAGE_FILE_MACHINE_POWERPC 0x1f0 পাওয়ার পিসি ছোট এন্ডিয়ান

ভাসমান পয়েন্ট সমর্থন সহ IMAGE_FILE_MACHINE_POWERPCFP 0x1f1 পাওয়ার পিসি

IMAGE_FILE_MACHINE_R4000 0x166 MIP সামান্য এন্ডিয়ান

IMAGE_FILE_MACHINE_SH3 0x1a2 হিটাচি এসএইচ 3

IMAGE_FILE_MACHINE_SH3DSP 0x1a3 হিটাচি এসএইচ 3 ডিএসপি

IMAGE_FILE_MACHINE_SH4 0x1a6 হিটাচি এসএইচ 4

IMAGE_FILE_MACHINE_SH5 0x1a8 হিটাচি এসএইচ 5

IMAGE_FILE_MACHINE_THumb 0x1c2 থাম্ব

IMAGE_FILE_MACHINE_WCEMipsV2 0x169 এমআইপিএস ছোট-এন্ডিয়ান ডাব্লুসিই v2

হ্যাঁ, আপনি IMbitFILE_MACHINE_AMD64 | AGE_৪ বিটের জন্য IMAGE_FILE_MACHINE_IA64 এবং 32 বিটের জন্য IMAGE_FILE_MACHINE_I386 পরীক্ষা করতে পারেন।


আপনার দ্বিতীয় লিঙ্কটি মারা গেছে: s
gpalex



3

HxD এর মতো একটি হেক্স সম্পাদক দিয়ে dll খুলুন

নবম লাইনে যদি "ডিটি" থাকে তবে তা 64 বিট।

যদি একটি "এল" থাকে নবম লাইনে এটি 32 বিট


"ডিটি" এবং "এল" খুঁজে পাচ্ছেন না "ফার ম্যানেজার" এইচএক্স দর্শকের উপর।
দিমিত্রি

হিসাবে দেখানো হয়েছে ডি। এবং এল।
জ্যাক্স

1

আমি পাওয়ারশেল স্ক্রিপ্টের প্রথম উত্তরে সি ++ সমাধান পুনরায় লিখেছিলাম। স্ক্রিপ্ট এই ধরণের .exe এবং .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  

এই সমাধানের Corflags.exe এবং সিডিতে এসেম্বলির মাধ্যমে লোডিং অ্যাসেমবিলির কিছু সুবিধা রয়েছে - সি # তে লড করুন - আপনি কখনই অবৈধ শিরোলেখ সম্পর্কে BadImageformatException বা বার্তা পাবেন না।

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

ব্যবহারের উদাহরণ:

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

আপনার যদি বিশদটি দেখার প্রয়োজন না হয় তবে আপনি দ্বিতীয় প্যারামিটার বাদ দিতে পারেন


1

এটি করার একটি দ্রুত এবং সম্ভবত নোংরা উপায় এখানে বর্ণিত হয়েছে: https://superuser.com/a/889267 । আপনি একটি সম্পাদকে ডিএলএল খুলুন এবং "পিই" অনুক্রমের পরে প্রথম অক্ষরগুলি পরীক্ষা করে দেখুন।


0

দৃশ্যত আপনি এটি পোর্টেবল এক্সিকিউটেবলের শিরোনামে খুঁজে পেতে পারেন। Corflags.exe ইউটিলিটি আপনাকে x64 লক্ষ্য করে কিনা তা আপনাকে দেখাতে সক্ষম। আশা করি এটি আপনাকে এ সম্পর্কে আরও তথ্য সন্ধান করতে সহায়তা করে।


3
ধন্যবাদ স্টিভেন কিন্তু কর্পফ্লাগস.এক্সে নেটিভ অ্যাসেমব্লির সাথে কাজ করে না।
ওহাদ হরেশ

1
উইন্ডোজ 10:>corflags libzmq.dll \n\n ... corflags : error CF008 : The specified file does not have a valid managed header
গ্রাট
আমাদের সাইট ব্যবহার করে, আপনি স্বীকার করেছেন যে আপনি আমাদের কুকি নীতি এবং গোপনীয়তা নীতিটি পড়েছেন এবং বুঝতে পেরেছেন ।
Licensed under cc by-sa 3.0 with attribution required.