- Вопрос или проблема
- 32-бит:
- 64-бит:
- Дополнительная информация:
- Как использовать:
- Как добавить тест на 32/64 бита в контекстное меню
- Ответ или решение
- 1. Проверка с помощью текстового редактора
- 2. Использование команды dumpbin
- 3. Использование PowerShell
- 4. Использование команды sigcheck из Sysinternals
- 5. Использование утилиты file из Cygwin или MSYS2
- 6. Использование Графических Утилит
- 7. Контекстное меню
- Заключение
Вопрос или проблема
Есть ли простой способ проверить, является ли бинарный файл 32-битным или 64-битным на Windows? Мне нужно проверить это, прежде чем переместить программу на 32-битную машину и столкнуться с внезапным отказом.
После изучения значений заголовка из ответа Ричарда я пришел к решению, которое быстрое, простое и требует только текстового редактора. Даже встроенный блокнот Windows notepad.exe подойдет.
-
Откройте исполняемый файл в текстовом редакторе. Возможно, вам придется перетащить файл или использовать диалоговое окно
Открыть...
, потому что Windows не показывает опциюОткрыть с помощью...
в контекстном меню для исполняемых файлов. -
Проверьте первые печатные символы после первого вхождения
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-битным.
Опция Дополнительная информация
предоставляет множество полезной информации о файле.
Метод запуска исполняемого файла и последующей проверки в Process Explorer или аналогичном инструменте имеет некоторые очевидные недостатки:
- Мы должны выполнить процесс.
- Для краткоживущих процессов (таких как 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)
Откройте исполняемый файл и посмотрите архитектуру сборки
Если вы находитесь на 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:
Основываясь на ответе: Как проверить, является ли бинарный файл 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 в названии папки.
Я нашел решение по ссылке ниже полезным.
$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 подойдут лучше всего.