Как проверить, является ли бинарный файл 32- или 64-битным в Windows?

Вопрос или проблема

Есть ли простой способ проверить, является ли бинарный файл 32-битным или 64-битным на Windows? Мне нужно проверить это, прежде чем переместить программу на 32-битную машину и столкнуться с внезапным отказом.

После изучения значений заголовка из ответа Ричарда я пришел к решению, которое быстрое, простое и требует только текстового редактора. Даже встроенный блокнот Windows notepad.exe подойдет.

  1. Откройте исполняемый файл в текстовом редакторе. Возможно, вам придется перетащить файл или использовать диалоговое окно Открыть..., потому что Windows не показывает опцию Открыть с помощью... в контекстном меню для исполняемых файлов.

  2. Проверьте первые печатные символы после первого вхождения PE. Эта часть, скорее всего, будет окружена как минимум некоторыми пробелами (может быть, даже много), так что это можно сделать визуально.

Вот что вы найдете:

32-бит:

PE  L

64-бит:

PE  d†

Предупреждение: использование стандартного блокнота для больших файлов может быть очень медленным, поэтому лучше не использовать его для файлов размером более одного мегабайта. В моем случае на отображение файла размером 12 Миб ушло около 30 секунд. Однако Notepad++ смог отобразить исполняемый файл размером 120 Миб почти мгновенно.

Это решение может быть полезно, если вам нужно исследовать файл на машине, на которую вы не можете установить дополнительное ПО.

Дополнительная информация:

Если у вас есть HEX-редактор, местоположение подписи PE находится на смещении 0x3C. Подпись PE\0\0 (буквы “P” и “E”, за которыми следуют два нулевых байта), за которой следует два байта типа машины в формате Little Endian.

Подпись обычно находится дальше в файлах MZ.

Соответствующие значения – 0x8664 для 64-битного исполняемого файла и 0x014c для 32-битного (64 86 и 4c 01 соответственно, когда учитывать порядок байтов, но любой приличный HEX-редактор будет автоматически обращаться с порядком байтов, когда вы ищете шестнадцатеричное значение). Есть много других возможных значений, но вы, вероятно, никогда не столкнетесь с ними или не сможете запустить такие исполняемые файлы на вашем Windows ПК.

Полный список типов машин, вместе с остальными спецификациями .exe, можно найти в разделе Спефикации Microsoft PE и COFF Типы машин.

Инструмент SDK dumpbin.exe с опцией /headers включает эту информацию, сравните эти два (я выделил жирным ключевую информацию)

PS [64] E:\ #4> dumpbin /headers C:\Windows\system32\cmd.exe
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  Все права защищены.

Дамп файла C:\Windows\system32\cmd.exe

Подпись PE обнаружена

Тип файла: ИСПОЛНЯЕМЫЙ ОБРАЗ

ЗНАЧЕНИЯ ЗАГОЛОВКА ФАЙЛА
            8664 машина (x64)
               6 количество секций
        4CE798E5 временная метка Сб Ноя 20 09:46:13 2010
               0 указатель файла на таблицу символов
               0 количество символов
              F0 размер необязательного заголовка
              22 характеристики
                   Исполняемый
                   Приложение может обрабатывать большие (>2 ГБ) адреса
[...]

и

PS [64] E:\ #5> dumpbin /headers C:\Windows\syswow64\cmd.exe
Microsoft (R) COFF/PE Dumper Version 10.00.40219.01
Copyright (C) Microsoft Corporation.  Все права защищены.

Дамп файла C:\Windows\syswow64\cmd.exe

Подпись PE обнаружена

Тип файла: ИСПОЛНЯЕМЫЙ ОБРАЗ

ЗНАЧЕНИЯ ЗАГОЛОВКА ФАЙЛА
             14C машина (x86)
               4 количество секций
        4CE78E2B временная метка Сб Ноя 20 09:00:27 2010
               0 указатель файла на таблицу символов
               0 количество символов
              E0 размер необязательного заголовка
             102 характеристики
                   Исполняемый
                   32-битная машина слов
[...]

Если у вас нет или вы не хотите всю Windows SDK или Visual Studio, вы можете использовать sigcheck.exe от SysInternals:

sigcheck.exe C:\Windows\Notepad.exe

Вывод:

Sigcheck v2.1 - Просмотр версии и подписи файла
Copyright (C) 2004-2014 Mark Russinovich
Sysinternals - www.sysinternals.com

c:\windows\notepad.exe:
    Проверено:       Подписано
    Дата подписания:   8:59 AM 22/08/2013
    Издатель:      Microsoft Windows
    Описание:    Блокнот
    Продукт:        Microsoft« Windows« Операционная система
    Версия продукта:   6.3.9600.16384
    Версия файла:   6.3.9600.16384 (winblue_rtm.130821-1623)
    MachineType:    64-бит

Я могу подтвердить, что утилита file (например, из Cygwin) будет различать 32-битные и 64-битные исполняемые файлы. Они отображаются следующим образом:

32.exe: PE32 исполняемый файл (GUI) Intel 80386, для MS Windows
64.exe: PE32+ исполняемый файл (консоль) x86-64, для MS Windows

Как вы можете видеть, различие очень очевидно. Кроме того, она различает исполняемые файлы для консоли и GUI, что также очевидно.

Многие люди имеют установленный отличный 7-zip и добавили папку 7-Zip в свой PATH. 7-zip понимает форматы файлов, отличные от ZIP и RAR, такие как MSI файлы и PE исполняемые файлы. Просто используйте команду 7z.exe для соответствующего PE файла (Exe или DLL):

7z l some.exe | more
7z l some.exe | findstr CPU

Вывод будет включать строки, подобные следующим, при этом строка CPU будет содержать либо x86, либо x64, что и требуется:

Path = C:\Extra\AV\neroAacEnc.exe
Type = PE
CPU = x86
Characteristics = Исполняемый 32-битный

Path = C:\Extra\AV\LAME\lame_enc.dll
Type = PE
CPU = x86
Characteristics = Исполняемая DLL 32-битная

Path = C:\Extra\AV\FFmpeg\bin\ffmpeg.exe
Type = PE
CPU = x64
64-бит = +
Characteristics = Исполняемый большой адрес без повторов без номеров строк без локальных символов без отладочной информации

Path = C:\Extra\AV\FFmpeg\bin\avcodec-56.dll
Type = PE
CPU = x64
64-бит = +
Characteristics = Исполняемая DLL большой адрес без номеров строк без локальных символов без отладочной информации

Простой способ – запустить его (если вы доверяете ему) и посмотреть на вкладку процессов в диспетчере задач. 32-битные процессы будут показывать “* 32” в конце имени процесса. Если это не то, что вы готовы запустить на своем компьютере, вы можете попробовать EXE Explorer. Он покажет множество информации о исполняемых файлах, включая, является ли он 32 или 64 бит.

Вот решение на PowerShell, без внешних зависимостей или чего-либо. Откройте PowerShell, вставьте функцию туда (нажмите Enter дважды, чтобы вернуться к подсказке), а затем используйте ее, как в моих примерах ниже функции:

function Test-is64Bit {
    param($FilePath=“$env:windir\notepad.exe”)

    [int32]$MACHINE_OFFSET = 4
    [int32]$PE_POINTER_OFFSET = 60

    [byte[]]$data = New-Object -TypeName System.Byte[] -ArgumentList 4096
    $stream = New-Object -TypeName System.IO.FileStream -ArgumentList ($FilePath, 'Open', 'Read')
    $stream.Read($data, 0, 4096) | Out-Null

    [int32]$PE_HEADER_ADDR = [System.BitConverter]::ToInt32($data, $PE_POINTER_OFFSET)
    [int32]$machineUint = [System.BitConverter]::ToUInt16($data, $PE_HEADER_ADDR + $MACHINE_OFFSET)
    $stream.Close()

    $result = "" | select FilePath, FileType, Is64Bit
    $result.FilePath = $FilePath
    $result.Is64Bit = $false

    switch ($machineUint) 
    {
        0      { $result.FileType="Native" }
        0x014c { $result.FileType="x86" }
        0x0200 { $result.FileType="Itanium" }
        0x8664 { $result.FileType="x64"; $result.is64Bit = $true; }
    }

    $result
}

Вот пример вывода:

D:\> Test-is64bit

FilePath               FileType Is64Bit
--------               -------- -------
C:\Windows\notepad.exe x64         True

D:\> Test-is64bit 'C:\Program Files (x86)\Mozilla Firefox\firefox.exe'

FilePath                                           FileType Is64Bit
--------                                           -------- -------
C:\Program Files (x86)\Mozilla Firefox\firefox.exe x86        False

64-битная версия Process Explorer может вам помочь. Просто запустите исполняемый файл и откройте окно свойств процесса. На основной вкладке есть запись, которая говорит “Image:32 Bit” или “Image:64 Bit”.

введите описание изображения здесь

Самый простой способ (когда данные не конфиденциальны)

Мне кажется, что Virustotal Подробности файла – самый простой способ узнать, является ли бинарный файл 32-битным или 64-битным.

Опция Дополнительная информация предоставляет множество полезной информации о файле.

Анализ Virustotal


[Virustotal TrID

Метод запуска исполняемого файла и последующей проверки в Process Explorer или аналогичном инструменте имеет некоторые очевидные недостатки:

  1. Мы должны выполнить процесс.
  2. Для краткоживущих процессов (таких как echo hello world) Process Explorer может даже не зарегистрировать, что новый процесс был запущен.

Метод dumpbin.exe может решить эту проблему.

Другой альтернативой было бы использование команды file из Cygwin. Однако я не тестировал это в Windows. Она хорошо работает на Linux.

Usage: file program_under_test.exe

ИЗМЕНЕНИЕ: Только что протестировал file.exe на Windows. Работает отлично. 🙂

Даже исполняемый файл, помеченный как 32-битный, может работать как 64-битный, если, например, это исполняемый файл .NET, который может работать как 32-, так и 64-битный. Для получения дополнительной информации см. https://stackoverflow.com/questions/3782191/how-do-i-determine-if-a-net-application-is-32-or-64-bit, где сказано, что утилита CORFLAGS может использоваться для определения, как будет работать приложение .NET.

Вывод CORFLAGS.EXE

Для 32-битного исполняемого файла:

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 0x3
ILONLY    : 1
32BITREQ  : 1
32BITPREF : 0
Signed    : 0

Для 64-битного исполняемого файла:

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32+
CorFlags  : 0x1
ILONLY    : 1
32BITREQ  : 0
32BITPREF : 0
Signed    : 0

Для исполняемого файла, который может работать как 32-, так и 64-битный и будет работать как 64-битный, когда это возможно:

Version   : v2.0.50727
CLR Header: 2.5
PE        : PE32
CorFlags  : 0x1
ILONLY    : 1
32BITREQ  : 0
32BITPREF : 0
Signed    : 0

Для исполняемого файла, который может работать как 32-, так и 64-битный, но будет работать как 32-битный, если не загружен в 64-битный процесс:

Version   : v4.0.30319
CLR Header: 2.5
PE        : PE32
CorFlags  : 0x20003
ILONLY    : 1
32BITREQ  : 0
32BITPREF : 1
Signed    : 0

Мое мнение: просто скачайте Dependency Walker и проверьте, какая архитектура использовалась в одном из исполняемых файлов.

Как использовать:

Просто скачайте приложение, запустите его, нажмите на иконку открытия → найдите *.exe файл → выберите его, и внизу, после завершения сканирования, вы увидите сетку с данными, где в одном из столбцов будут указаны сведения об “архитектуре” (x86, x64)

Откройте исполняемый файл и посмотрите архитектуру сборки

скриншот Dependency Walker

Если вы находитесь на Windows 7, в проводнике Windows щелкните правой кнопкой мыши на исполняемом файле и выберите Свойства.
В окне свойств выберите вкладку Совместимость.
Если в разделе Совместимость вы видите Windows XP, то это 32-битный исполняемый файл.
Если вы видите Windows Vista, значит, это 64-битный.

Как добавить тест на 32/64 бита в контекстное меню

Создайте текстовый файл с именем exetest.reg и содержащий этот код:

Windows Registry Editor Version 5.00

; Что будет отображаться в контекстном меню при щелчке правой кнопкой мыши на .exe файле
[HKEY_CLASSES_ROOT\exefile\shell\command32_64]
@="Тест 32/64 бит"

; Что с этим делать
; здесь %1 - это файл, переданный как аргумент скрипта
[HKEY_CLASSES_ROOT\exefile\shell\command32_64\command]
@="\"c:\\temp\\x86TestStart.bat\" \"%1\""

Создайте текстовый файл с именем x86TestStart.bat, содержащий всего одну строку кода, и сохраните его в C:\temp:

c:\temp\x86or64.vbs %1

Создайте текстовый файл с именем x86or64.vbs, содержащий этот код, и сохраните его в C:\temp:

rem Чтение двоичного файла в VBScript: http://stackoverflow.com/questions/21249440/modify-first-two-bytes-of-a-file-using-vbscript
rem Информация об исполняемых файлах: https://dmoj.ca/problem/exe

rem Подпись x86/64 расположена динамически; ее местоположение адресовано
rem от байтов в позиции 0x3C-0x3D.

rem Возможные подписи;
rem "PE..L" (шестнадцатеричный код: 50.45.00.00.4C) = 32 бита
rem "PE..d†" (шестнадцатеричный код: 50.45.00.00.64.86) = 64 бита

' ------------------------------------
' Исходный код Jumpkack 2015
' ------------------------------------

' Чтение всех аргументов из командной строки:
Set args = Wscript.Arguments

' Сохраняем первый аргумент (полный путь к файлу)
FileName = args(0)

' Находим адрес подписи исполняемого файла:
FirstChars = readBinary(FileName)
FirstChars = FirstChars
Addr1 = asc(mid(FirstChars,61,1))
Addr2 = asc(mid(FirstChars,62,1))
AddrFinal = Addr2*256 + Addr1 + 1

' Проверяем подпись:
if ucase(hex(asc(mid(FirstChars,AddrFinal+4,2)))) = "4C" then Wscript.Echo Filename & " является 32-битным исполняемым файлом."
if ucase(hex(asc(mid(FirstChars,AddrFinal+4,2)))) = "64" then Wscript.Echo Filename & " является 64-битным исполняемым файлом."

Function readBinary(path)
    Dim a, fso, file, i, ts
    Set fso = CreateObject("Scripting.FileSystemObject")
    Set file = fso.getFile(path)
    If isNull(file) Then
        wscript.echo "Файл не найден: " & path
        Exit Function
    End If
    Set ts = file.OpenAsTextStream()
    'a = makeArray(file.size)
    a=""
    i = 0
    While (Not ts.atEndOfStream) and (i<60000)
       'a(i) = ts.read(1)
       a = a + ts.read(1)
       i = i + 1
    Wend
    ts.close
    readBinary = a
 End Function

Дважды щелкните файл exetest.reg: новый ключ будет добавлен в реестр Windows:

[HKEY_CLASSES_ROOT\exefile\shell\command32_64\command]

Он появится как “Тест 32/64 бит” в контекстном меню при щелчке правой кнопкой мыши на исполняемом файле.

Нажатие на элемент приведет к запуску пакетного файла c:\\temp\\x86TestStart.bat\, который запускает файл VBScript x86or64.vbs, который считывает подпись exe и показывает результат.

Если вы не можете или не хотите изменять реестр, просто скопируйте файл .vbs на панель быстрого запуска и перетащите на него исполняемый файл.

Тем не менее, WSL команда file работает отлично.

file /mnt/c/p/bin/rg.exe выведет:

/mnt/c/p/bin/rg.exe: PE32+ исполняемый файл (консоль) x86-64, для MS Windows

file /mnt/c/p/bin/u.exe выведет:

/mnt/c/p/bin/u.exe: PE32 исполняемый файл (GUI) Intel 80386, для MS Windows, сжато UPX

Столбец платформы в диспетчере задач Windows 10

Windows 7 не имеет столбца платформы. Таким образом, диспетчер задач Windows 7 не покажет это.

В Windows 10 выбор столбцов больше не находится в разделе ‘вид’. В Windows 10 в режиме вкладки “Подробности” щелкните правой кнопкой мыши на заголовке столбца, затем ‘выбрать столбцы’. Затем отметьте флажок для ‘платформы’.

введите описание изображения здесь

введите описание изображения здесь

вы также можете использовать инструмент file из пакета msys2 mingw-w64. Он работает как команда unix. Похожий инструмент file из GNUwin32 тоже работает аналогично.

Самое простое решение заключается в том, что в 32-битной версии вкладка совместимости свойств (надежно протестировано на Windows 7 и 10) исполняемого файла перечисляет Windows XP.

Firefox 32 бита:

введите описание изображения здесь

Firefox 64 бита:

введите описание изображения здесь

Я не видел этого упомянутым. Существует программа просмотра PE под названием CFF Explorer от NTCore, которая может предоставить вам эту информацию. Ее можно скачать и запустить в портативном режиме, но вы также можете установить ее, если хотите.

Щелкните правой кнопкой мыши на бинарном файле (.exe, .dll и т. д.) и выберите “Открыть с помощью CFF Explorer”. Перейдите в Nt Headers -> File Header -> в поле “Characteristics” нажмите “Щелкните здесь”

Если это 32-битная программа, будет установлено флажок “32-битная машина слов”. Например, я установил 32-битную версию Notepad++, как видно на изображении ниже. В противном случае это 64-битный файл.

введите описание изображения здесь

Мое мнение: как разработчик на C++, утилита Dependency Walker (http://www.dependencywalker.com/) очень информативна, она не только отображает 64/32 бита, но также каждую вовлеченную dll:
введите описание изображения здесь

Вы можете увидеть 64 слева от каждого имени файла…

Моя простая версия на PowerShell, на мой взгляд, является на 100% надежной по результатам тестирования.

Clear-Host
$Check32Bit = $null
$Check64Bit = $null

$File = "C:\WINDOWS\system32\notepad.exe"

$ExeData = get-content $File -totalcount 50

$Check32Bit = $ExeData | select-string -Pattern "PE..L" -Quiet
$Check64Bit = $ExeData | select-string -Pattern "PE..d†" -Quiet

if ($Check32Bit) {
"Файл является 32-битным (x86)"
}
elseif ($Check64Bit) {
"Файл является 64-битным (x64)"
}
else {
"Не удалось определить, является ли файл 32-битным или 64-битным"
}

Как указано в комментарии пользователя @user1055604, самый простой способ сделать это “из коробки” на Windows 10:

dumpbin /headers yourfile.lib | findstr "machine"

Эта однострочная команда даст интуитивно понятный результат. Например, на 64-битной библиотеке, которую я только что протестировал, выводится следующее:

8664 машина (x64)

  • запустите приложение
  • откройте диспетчер задач
  • щелкните правой кнопкой мыши и создайте дамп файла
  • запомните путь
  • перейдите по пути и откройте .DMP дамп в Visual Studio
  • там вы получите все детали
  • проверьте архитектуру процесса:

Я знаю, что здесь много ответов, но ни один из них не является по-настоящему портативным и требует какого-то инструмента для использования. Я хотел решить это программным способом для всех платформ. Это будет работать на любом устройстве с компилятором C.

#include <stdio.h>
#include <fstream>      // std::fstream
#include <stdio.h>
#include <string.h>

char Header      [0x200];
char Elf32Magic  [20] = "\x7f\x45\x4c\x46\01";  //7F 45 4C 46  01 // ELF32 
char Elf64Magic  [20] = "\x7f\x45\x4c\x46\02";  //7F 45 4C 46  02 // ELF64
char Win32Magic  [20] = "\x50\x45\x00\x00\x4C\x01";// PE32
char Win64Magic  [20] = "\x50\x45\x00\x00\x64\x86";// PE64

char PeHeader[20] = {};
void CheckWinHeader(){
  int k = 0;
  for (int i = 0; i < 0x200; i++)
  {
   if(Header[i] == 0x50 && Header[i+1] == 0x45) // PE     
     {

      for(int j = i; j < i + 6; j++)
      {
        PeHeader[k] = Header[j];
        k++;
       //printf("%hhx", Header[j]); 
      }
     }
  }
}

int main(){
  std::fstream fs; 
  fs.open ("/home/PATH/TO/YOUR/BINARY", std::fstream::in | std::fstream::out | std::fstream::app);
  fs.read( Header , 0x200);

  if(memcmp ( Header, Elf32Magic, 5 ) == 0 ){
    printf("ELF 32 Match Found ! \n");
  }
  if(memcmp ( Header, Elf64Magic, 5 ) == 0 ){
    printf("Elf 64 Match Found ! \n");
  }

  CheckWinHeader();

  if(memcmp ( &PeHeader, Win32Magic, 6 ) == 0 ){
    printf("Win 32 Match Found ! \n");
  }

  if(memcmp ( &PeHeader, Win64Magic, 6 ) == 0 ){
    printf("Win 64 Match Found ! \n");
  }

 fs.close();
 return 0;
}

Скомпилируйте, используя любой компилятор. Я использовал g++.

g++ Bincheck.cpp -o bincheck
./bincheck

Что-то другое из всех отличных ответов выше, но используйте PowerShell для поиска характерной фразы “Эта программа должна быть запущена в режиме Win32”?

PS C:\Program Files\Snap Inc> ls -R . -filter *.exe | % { $file = $_; Select-String -Path $_ -Encoding 'oem' -Pattern 'under Win32' -SimpleMatch -Quiet } | % { Write-Output "$file является Win32: $_" }

Snap Camera.exe является Win32: Нет
unins000.exe является Win32: Да
installer.exe является Win32: Нет

Это также соответствует результатам трюка с PE L и PE d†.

Вы можете использовать corflags из командной строки VS для изменения типа машины

Изменить тип машины:

corflags d:\abc.exe /32BITREQ- 

Проверьте с помощью corflags:

corflags d:\abc.exe 

32BITREQ : 0 ** 0 означает 64 бита

Если вы хотите просканировать структуру папок на наличие 32/64-битных DLL или исполняемых файлов, вы также можете попробовать бесплатный инструмент под названием ScanFor64bit.
ScanFor64bit позволяет вам ввести букву диска или путь к каталогу и одну или несколько масок файлов для поиска 32- или 64-битных файлов.
Результат – это список, отсортированный по 32-битным файлам в первую очередь, и 64-битным на втором месте.
Я много раз использовал его для проверки компьютеров с Java, чтобы убедиться, что используется 64-битная версия.

Пример вывода ScanFor64bit:

Пример вывода ScanFor64bit:

Основываясь на ответе: Как проверить, является ли бинарный файл 32 или 64 бита на Windows?

  • Язык: VBS
  • ОС: Windows XP+

Реализация: https://github.com/andry81/contools/tree/HEAD/Scripts/Tools/ToolAdaptors/vbs/read_pe_header_bitness.vbs

''' Чтение заголовка PE двоичного файла.

''' ИСПОЛЬЗОВАНИЕ:
'''   read_pe_header_bitness.vbs <FilePath>

''' ОПИСАНИЕ:
'''   <FilePath>
'''     Путь к двичному файлу для считывания.

' Проверьте, является ли двоичный файл (EXE или DLL) 32-битным (x86) или 64-битным (x64)

Sub PrintOrEchoLine(str)
  On Error Resume Next
  WScript.stdout.WriteLine str
  If err = &h80070006& Then
    WScript.Echo str
  End If
  On Error Goto 0
End Sub

Sub PrintOrEchoErrorLine(str)
  On Error Resume Next
  WScript.stderr.WriteLine str
  If err = &h80070006& Then
    WScript.Echo str
  End If
  On Error Goto 0
End Sub

ReDim cmd_args(WScript.Arguments.Count - 1)

Dim objShell : Set objShell = WScript.CreateObject("WScript.Shell")

Dim arg
Dim j : j = 0

For i = 0 To WScript.Arguments.Count-1 : Do ' пустой `Do-Loop`, чтобы имитировать `Continue`
  arg = WScript.Arguments(i)

  ' чтение флагов командной строки здесь...

  cmd_args(j) = arg

  j = j + 1
Loop While False : Next

ReDim Preserve cmd_args(j - 1)

' MsgBox Join(cmd_args, " ")

Dim cmd_args_ubound : cmd_args_ubound = UBound(cmd_args)

If cmd_args_ubound < 0 Then
  PrintOrEchoErrorLine WScript.ScriptName & ": ошибка: аргумент <FilePath> не определен."
  WScript.Quit 1
End If

Dim FilePath : FilePath = cmd_args(0)

Dim objFS : Set objFS = CreateObject("Scripting.FileSystemObject")

Dim FilePathAbs : FilePathAbs = objFS.GetAbsolutePathName(FilePath) ' ВНИМАНИЕ: может изменить регистр символов, если путь существует

' убираем префикс `\\?\`
If Left(FilePathAbs, 4) = "\\?\" Then
  FilePathAbs = Mid(FilePathAbs, 5)
End If

' тест на существование пути, включая длинный путь
Dim IsFileExist : IsFileExist = objFS.FileExists("\\?\" & FilePathAbs)
If Not IsFileExist Then
  PrintOrEchoErrorLine _
    WScript.ScriptName & ": ошибка: файл не существует:" & vbCrLf & _
    WScript.ScriptName & ": информация: FilePath=`" & FilePathAbs & "`"
  WScript.Quit 2
End If

Dim FilePathToOpen

' тест на существование длинного пути
If objFS.FileExists(FilePathAbs) Then
  ' это не длинный путь
  FilePathToOpen = FilePathAbs
Else
  ' перевод в короткий путь

  ' РЕШЕНИЕ:
  '   Мы используем `\\?\`, чтобы обойти ошибку `GetFile`: `Файл не найден`.
  Dim File_ : Set File_ = objFS.GetFile("\\?\" & FilePathAbs)
  Dim FileShortPath : FileShortPath = File_.ShortPath
  If Left(FileShortPath, 4) = "\\?\" Then
    FileShortPath = Mid(FileShortPath, 5)
  End If

  FilePathToOpen = FileShortPath
End If

Dim BinaryStream : Set BinaryStream = CreateObject("ADODB.Stream")

BinaryStream.Type = 1
BinaryStream.Open

BinaryStream.LoadFromFile FilePathToOpen

Function ByteToHex(byte_)
  Dim str : str = Hex(byte_)
  If Len(str) = 1 Then
    str = "0" & str
  End If
  ByteToHex = str
End Function

Dim PeSignature : PeSignature = BinaryStream.Read(3)

Dim ByteCode
Dim PeHexStr

For i = 0 to UBound(PeSignature)
  ByteCode = Ascb(Midb(PeSignature, i + 1, 1))
  PeHexStr = PeHexStr & ByteToHex(ByteCode)
Next

rem сравниваем на последовательность `MZђ`
If PeHexStr <> "4D5A90" Then
  PrintOrEchoErrorLine _
    WScript.ScriptName & ": ошибка: файл не имеет заголовка PE:" & vbCrLf & _
    WScript.ScriptName & ": информация: FilePath=`" & FilePath & "`"
  WScript.Quit 3
End If

BinaryStream.Position = &H3C
Dim PositionSignature : PositionSignature = BinaryStream.Read(4)

Dim PositionHexStr

For i = 0 to UBound(PositionSignature)
    ByteCode = Ascb(Midb(PositionSignature, i + 1, 1))
    PositionHexStr = ByteToHex(ByteCode) & PositionHexStr
Next

BinaryStream.Position = CInt("&H" & PositionHexStr)

Dim BitnessSignature : BitnessSignature = BinaryStream.Read(6)

Dim BitnessHexStr

For i = 0 to UBound(BitnessSignature)
    ByteCode = Ascb(Midb(BitnessSignature, i + 1, 1))
    BitnessHexStr = BitnessHexStr & ByteToHex(ByteCode)
Next

BinaryStream.Close

If BitnessHexStr = "504500004C01" Then
  PrintOrEchoLine "32"
ElseIf BitnessHexStr = "504500006486" Then
  PrintOrEchoLine "64"
End If

Много отличных ответов уже дано, некоторые утверждают “самый простой”, но абсолютно самый простой способ – это проверка пути папки.

C:\Program Files (x86)\ предназначен для 32-битных приложений.

Смотрите, например, этот пост Microsoft:

В версиях Windows, которые поддерживают эмуляцию x86, существуют две директории для программных файлов. Директория C:\Program Files предназначена для программ в родной системе, а директория C:\Program Files (x86) предназначена для программ, которые работают под эмулятором x86-32. Но почему они находятся в отдельных директориях? Почему мы не можем объединить их? …

Конечно, нет 101% гарантии, что никто никогда не положит 64-битные файлы в 32-битную папку, но как первая быстрая проверка полезно взглянуть на X86 в названии папки.

Я нашел решение по ссылке ниже полезным.

https://www.appsloveworld.com/powershell/100/34/is-there-a-way-to-determine-if-an-exe-is-32-or-64-bit

$machine_offset = 4
$pe_pointer_offset = 60
$machinetype = write-output native i386 itanium x64

$filepath = "$env:windir\notepad.exe"
$data = new-object system.byte[] 4096
$stream = new-object system.io.filestream -argumentlist $filepath,open,read
$stream.read($data,0,$pe_pointer_offset) | out-null
$pe_header_addr = [system.bitconverter]::toint32($data, 
$pe_pointer_offset)
$machineuint = [system.bitconverter]::touint16($data, $pe_header_addr + 
$machine_offset)
$machinetype[$machineuint]

Ответ или решение

Чтобы проверить, является ли бинарный файл 32-битным или 64-битным в операционной системе Windows, существует несколько простых и эффективных методов. Вот основные способы, которыми вы можете воспользоваться:

1. Проверка с помощью текстового редактора

Откройте исполняемый файл в текстовом редакторе (например, в Notepad или Notepad++). Вам нужно найти строку, начинающуюся с "PE". В зависимости от следующего символа вы сможете определить разрядность:

  • 32-битный файл: после "PE" вы увидите букву L.
  • 64-битный файл: после "PE" будет d†.

Имейте в виду, что работа с большими файлами может быть медленной в Notepad, поэтому лучше использовать Notepad++.

2. Использование команды dumpbin

Если у вас установлен инструмент из Windows SDK, можно воспользоваться командой:

dumpbin /headers <путь_к_исполняемому_файлу>

После выполнения команды вы увидите информацию о файле, где в строке "machine" будет указано, является ли файл 32 или 64-битным:

  • 014c для 32-битного (x86)
  • 8664 для 64-битного (x64)

3. Использование PowerShell

Вы можете создать функцию в PowerShell, которая проверит разрядность файла. Вот пример функции:

function Test-Is64Bit {
    param($FilePath = "C:\Windows\notepad.exe")

    [int32]$MACHINE_OFFSET = 4
    [int32]$PE_POINTER_OFFSET = 60

    [byte[]]$data = New-Object -TypeName System.Byte[] -ArgumentList 4096
    $stream = New-Object -TypeName System.IO.FileStream -ArgumentList ($FilePath, 'Open', 'Read')
    $stream.Read($data, 0, 4096) | Out-Null

    [int32]$PE_HEADER_ADDR = [System.BitConverter]::ToInt32($data, $PE_POINTER_OFFSET)
    [int32]$machineUint = [System.BitConverter]::ToUInt16($data, $PE_HEADER_ADDR + $MACHINE_OFFSET)
    $stream.Close()

    switch ($machineUint) {
        0x014c { "32-битный файл (x86)" }
        0x8664 { "64-битный файл (x64)" }
        default { "Неизвестная разрядность" }
    }
}

4. Использование команды sigcheck из Sysinternals

Если у вас установлен пакет Sysinternals, вы можете использовать sigcheck следующим образом:

sigcheck <путь_к_исполняемому_файлу>

В выводе будет строка, указывающая на разрядность файла.

5. Использование утилиты file из Cygwin или MSYS2

Если вы используете Cygwin или MSYS2, команда file также может помочь:

file <путь_к_исполняемому_файлу>

Вывод будет содержать информацию о разрядности:

  • PE32 executable для 32-бит
  • PE32+ executable для 64-бит

6. Использование Графических Утилит

Существует множество графических утилит, которые могут помочь определить разрядность bin-файлов:

  • Dependency Walker — загружает файл и показывает его архитектуру.
  • CFF Explorer — можно открыть файл, чтобы проверить разрядность в разделе Nt Headers.

7. Контекстное меню

Вы можете создать элемент контекстного меню, который позволит проверять разрядность напрямую из Windows Explorer, добавив соответствующий скрипт в реестр.

Заключение

Выбор метода будет зависеть от ваших предпочтений и доступных инструментов. Если вам необходимо быстро проверить разрядность в командной строке, dumpbin или PowerShell будут наиболее удобными. Если вы предпочитаете графические интерфейсы, Dependency Walker и CFF Explorer подойдут лучше всего.

Оцените материал
Добавить комментарий

Капча загружается...