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

Я хотел бы написать тестовый сценарий или программу, которая утверждает, что все файлы DLL в данном каталоге относятся к определенному типу сборки.

Я бы использовал это как проверку работоспособности в конце процесса сборки SDK, чтобы убедиться, что в 64-битной версии каким-то образом нет 32-битных файлов DLL, и наоборот.

Есть ли простой способ взглянуть на файл DLL и определить его тип?

Решение должно работать как на xp32, так и на xp64.


person morechilli    schedule 30.01.2009    source источник
comment
Я ценю, что как только вы узнаете ответ на этот вопрос и stackoverflow.com/q/197951/5427 поделитесь своим решением. Однако вопросы задавали разные. Один прямо спросил о библиотеках DLL, а другой - о бывших. Этот вопрос получил довольно много положительных отзывов, поэтому я думаю, что он хорошо соответствует проблеме, на которую люди пытаются найти ответ. Подобные мысли о дублировании обсуждаются здесь meta.stackoverflow.com/q/266244/5427   -  person morechilli    schedule 15.01.2016


Ответы (5)


Кровавые подробности

DLL использует исполняемый формат PE, и прочитать эту информацию из файла несложно.

См. статью MSDN о формате файлов PE для обзор. Вам нужно прочитать заголовок MS-DOS, а затем прочитать IMAGE_NT_HEADERS структура. Он содержит структуру IMAGE_FILE_HEADER, которая содержит информацию, которую вы необходимость в элементе Machine, который содержит одно из следующих значений

  • IMAGE_FILE_MACHINE_I386 (0x014c)
  • IMAGE_FILE_MACHINE_IA64 (0x0200)
  • IMAGE_FILE_MACHINE_AMD64 (0x8664)

Эта информация должна иметь фиксированное смещение в файле, но я все же рекомендую просмотреть файл и проверить подпись заголовка MS-DOS и IMAGE_NT_HEADERS, чтобы быть уверенным, что вы справитесь с любыми будущими изменениями.

Используйте ImageHelp для чтения заголовков ...

Вы также можете использовать ImageHelp API для этого. - загрузите DLL с помощью LoadImage, и вы получить структуру LOADED_IMAGE, которая будет содержать указатель на структура IMAGE_NT_HEADERS. Освободите LOADED_IMAGE с помощью ImageUnload.

... или адаптировать этот грубый Perl-скрипт

Вот примерный сценарий Perl, который выполняет свою работу. Он проверяет, имеет ли файл заголовок DOS, затем считывает смещение PE из 60 байт IMAGE_DOS_HEADER в файл.

Затем он ищет начало PE-части, считывает подпись и проверяет ее, а затем извлекает интересующее нас значение.

#!/usr/bin/perl
#
# usage: petype <exefile>
#
$exe = $ARGV[0];

open(EXE, $exe) or die "can't open $exe: $!";
binmode(EXE);
if (read(EXE, $doshdr, 64)) {

   ($magic,$skip,$offset)=unpack('a2a58l', $doshdr);
   die("Not an executable") if ($magic ne 'MZ');

   seek(EXE,$offset,SEEK_SET);
   if (read(EXE, $pehdr, 6)){
       ($sig,$skip,$machine)=unpack('a2a2v', $pehdr);
       die("No a PE Executable") if ($sig ne 'PE');

       if ($machine == 0x014c){
            print "i386\n";
       }
       elsif ($machine == 0x0200){
            print "IA64\n";
       }
       elsif ($machine == 0x8664){
            print "AMD64\n";
       }
       else{
            printf("Unknown machine type 0x%lx\n", $machine);
       }
   }
}

close(EXE);
person Paul Dixon    schedule 30.01.2009
comment
Очень кстати. Я создал перевод вашего кода на Python: github.com/tgandor/meats /blob/master/missing/arch_of.py - person Tomasz Gandor; 29.09.2016
comment
@TomaszGandor отличный материал. К вашему сведению, мне пришлось изменить 'MZ' и 'PE' на b'MZ' и b'PE', чтобы заставить их правильно оценивать. Не уверен, была ли это проблема конкретной платформы или что-то в этом роде. - person valverij; 07.10.2016
comment
Нет, это просто означает, что у вас Python 3.x;) Спасибо, исправлено на GitHub. Я неохотно перехожу на 3.x (пишу на 2.7, пытаясь быть прямой совместимостью). И поэтому я иногда забываю, что файлы, открытые в режиме 'rb', возвращают двоичные строки, такие как b'MZ' (на Py2 bytes - это просто значение по умолчанию str, а str в Py3 - unicode). - person Tomasz Gandor; 08.10.2016
comment
Просто чтобы прояснить ... offset всегда должно быть положительным числом? Учитывая, что файл не был поврежден ... - person cameck; 07.02.2018
comment
Пример распаковывает его как значение со знаком - вы, вероятно, могли бы интерпретировать его как беззнаковое, но это будет означать, что у вас там очень большое смещение. Я думаю, что это было бы необычно, но вы сможете проверить правильность беззнакового смещения, найдя «PE» на смещении. - person Paul Dixon; 07.02.2018
comment
Спасибо за ответ, это полезно! Причина, по которой я спрашиваю, - это заголовок, который я распаковал, имеет значение -1074807361 в качестве смещения. Когда я попытался установить позицию файла, он вернул Invalid argument @ rb_io_set_pos. Итак, чтобы создать охрану, я мог бы убедиться, что это положительное число, или уловить эту ошибку. Просто не был уверен, что обеспечение положительного числа сломается в других случаях, то есть всегда ли PE смещен в прямой позиции от заголовка mz? - person cameck; 07.02.2018
comment
если вы интерпретируете это как беззнаковое, это будет 3220159935, поэтому, если у вас нет EXE размером 3 ГБ, вероятно, что-то не так (либо файл, либо ваш код). Заголовок MZ - это то, что делает PE-файл исполняемым в DOS - он просто отображает сообщение, требующее Windows, но Windows знает, что нужно игнорировать это. Получите шестнадцатеричный дамп первых 100 байтов и приклейте pastebin! - person Paul Dixon; 08.02.2018
comment
pastebin.com/SZ1E4VgX - person cameck; 08.02.2018
comment
Он начинается с MZ, но в остальном выглядит мусором. Вот как вы ожидаете, что это будет выглядеть en.wikibooks.org/wiki/X86_Disassembly / - person Paul Dixon; 09.02.2018
comment
Спасибо большое за вашу помощь! И да, этот файл - мусор. Итак, я адаптировал этот скрипт ruby ​​ и добавил, что смещение должно быть больше / равно 0 . - person cameck; 09.02.2018

Грубым способом было бы вызвать dumpbin с опцией заголовков из инструментов Visual Studio для каждой DLL и искать соответствующий вывод:

dumpbin /headers my32bit.dll

PE signature found

File Type: DLL

FILE HEADER VALUES
             14C machine (x86)
               1 number of sections
        45499E0A time date stamp Thu Nov 02 03:28:10 2006
               0 file pointer to symbol table
               0 number of symbols
              E0 size of optional header
            2102 characteristics
                   Executable
                   32 bit word machine
                   DLL

OPTIONAL HEADER VALUES
             10B magic # (PE32)

В этом выводе вы можете увидеть пару подсказок, что это 32-битная DLL, включая значение 14C, которое упоминает Пол. Должно быть легко искать в сценарии.

person Jeremy    schedule 30.01.2009
comment
ВНИМАНИЕ: этот метод не работает ни с чем. .NET? Возвращает 32-разрядную версию для всех программ .NET .dll или .exe, независимо от того, скомпилированы ли они для x32 или x32 / x64 (все ЦП). Создается впечатление, что каждый исполняемый файл .NET имеет 32-разрядный собственный заголовок и при вызове вызывает соответствующую 32-разрядную или 64-разрядную среду выполнения .NET. - person Contango; 02.03.2011
comment
Интересный. Мне кажется, это нормально, так как AnyCPU DLL может работать на 32-битной машине. А как насчет 64-битных .NET DLL? - person Jeremy; 02.03.2011
comment
@Contango: Это не совсем так (только x64 DLL показывает правильный заголовок, даже если исполняемый файл .NET). Часть Any CPU верна, потому что реальная разрядность будет определяться при загрузке сборки, поэтому ее нельзя жестко запрограммировать в самой сборке. Вы можете использовать corflags утилиту, поставляемую с dumpbin, чтобы просмотреть информацию о исполняемом файле .NET. - person Erti-Chris Eelmaa; 14.10.2014
comment
Пример использования corflags здесь stackoverflow.com/a/2418287/74585 - person Matthew Lock; 04.12.2015
comment
Командная строка программы архива 7-zip может делать нечто подобное. Так что вы можете проверить на ПК, на котором нет DumpBin. (параметр - l, буква перед m) C: \ Program Files \ 7-Zip \ 7z l MyFile.dll - person Paul McCarthy; 20.06.2017

Если у вас установлен Cygwin (что я настоятельно рекомендую по разным причинам), вы можете использовать утилиту 'file' в DLL

file <filename>

что даст такой вывод:

icuuc36.dll: MS-DOS executable PE  for MS Windows (DLL) (GUI) Intel 80386 32-bit
person DevSolar    schedule 30.01.2009
comment
Привет, DevSolar! Пожалуйста, дайте мне знать, как это сделать в Cygwin. Спасибо, Магеш. - person ; 27.01.2011
comment
Эм ... в чем проблема? file <filename>. Я не уверен, является ли file частью основной установки или вам нужно выбрать его для установки, но он определенно доступен в Cygwin, поскольку я использовал его в прошлом. - person DevSolar; 28.01.2011
comment
Любой, кто использует MingW и не осознает этого, это тоже вещь на основе Cygwin, и она тоже есть. - person Warren P; 16.03.2011
comment
Я пробовал это. Все, что он когда-либо возвращает, - это моно даже на 64-битных тестовых dll, которые я скомпилировал. - person BradLaney; 05.04.2012
comment
@BradLaney: Может быть, вы тестировали сборки .NET? Они по своей природе очень сильно отличаются от, например, скомпилированные двоичные файлы C ++. - person DevSolar; 06.04.2012
comment
@BradLaney: Или, иначе говоря: если file сообщает вам, что это код моно / .NET, то это, вероятно, потому, что это код моно / .NET, или возможно какая-то странная ошибка в file (против которой я бы поставил деньги), но, конечно, не повод отвергать меня. - person DevSolar; 06.04.2012
comment
@DevSolar пожал плечами. Я тестировал его на каждой DLL, которую мог найти на своей машине, пока я не устал, и каждый раз это не давало ничего, кроме одного и того же результата. Не работает. И я протестировал его на DLL, которую я скомпилировал специально для 32-битной, 64-битной, но все равно ничего. - person BradLaney; 27.04.2012
comment
@BradLaney: Что забавно, потому что вышеприведенный вывод - это копирование и вставка из моего ящика (WinXP / Cygwin). Тестирование на другом компьютере (Win7) дает мне: MS-DOS executable, NE for MS Windows 3.x (driver) для Windows \ system \ COMMDLG.DLL, PE32 executable for MS Windows (DLL) (GUI) Intel 80386 32-bit для Program Files \ Internet Explorer \ iecompat.dll ... в этот момент я прекратил тестирование и все еще утверждаю, что, если вы все получите является моно, либо вы тестировали только сборки Mono, либо ваша установка Cygwin не работает. - person DevSolar; 01.05.2012
comment
Пример вывода для 64-битной DLL: boost_math_c99f-vc140-mt-1_58.dll: PE32+ executable (DLL) (console) x86-64, for MS Windows - person Nick; 01.07.2015
comment
Если у вас установлен Git для Windows, вместо Cygwin будет работать команда file, доступная из консоли Git Bash. - person Leif Gruenwoldt; 11.05.2017
comment
Команда mingw / msys file работает для файлов dll и exe: exe :: Wireshark / WinPcap_4_1_3.exe: исполняемый файл PE32 (GUI) Intel 80386, для MS Windows, самораспаковывающийся архив установщика Nullsoft Wireshark / Wireshark.exe: исполняемый файл PE32 + (GUI) x86-64, для MS Windows dll: Win10Pcap / Win32 / wpcap.dll: исполняемый файл PE32 (DLL) (GUI) Intel 80386, для MS Windows Win10Pcap / x64 / wpcap.dll: PE32 + исполняемый файл (DLL) (GUI) x86-64 , для MS Windows - person Don Mclachlan; 17.07.2017
comment
GitBash для Windows тоже работает. Пример: - $ file jniwrap.dll jniwrap.dll: PE32 executable (DLL) (GUI) Intel 80386, for MS Windows - person Paramvir Singh Karwal; 18.06.2018
comment
WSL для windows 10 + ubuntu, вы можете использовать ту же команду - person Thesane; 23.08.2018
comment
вы также можете использовать 7z l *.dll | findstr CPU - person phuclv; 21.09.2018

Зависимость Уокера все говорит (ну почти). http://www.dependencywalker.com/

Он не «устанавливает» - просто загрузите его, распакуйте и запустите exec. Он работает для любого модуля x32 или x64 windows | приложения.

Насколько я помню, довольно просто увидеть все зависимости, то есть модули dll, и поскольку файл appl. представляет собой сумму зависимостей, которые можно определить, является ли он полным x64, x32 (x86) или немного того и другого.

Тип процессора, для которого был построен модуль, указан в столбце «CPU». Большинство 64-битных aps по-прежнему немногочисленны, но 32-битные ap w / b все x86.

Красивая программа для гиков / программистов и она бесплатна ...

person Ric    schedule 27.01.2011
comment
Dependency Walker, похоже, не работает с файлами .NET .dll или .exe. Провел быстрый тест с 32-битными и 64-битными консольными приложениями .NET, и не смог отличить. - person Contango; 02.03.2011
comment
@Gravitas Для файлов .Net необходимо использовать CorFlags.exe - person expert; 22.08.2012
comment
Ссылки для скачивания на сайте не работают. - person Jonathan Parker; 13.11.2013
comment
Если я выполню эту работу, я просто позволю пользователю загрузить его / ее файл dll и отобразить информацию, без загрузки каких-либо исполняемых файлов, установки и запуска. - person user2384994; 20.05.2014
comment
Если файл 64-битный, справа будет значок с небольшим 64-битным изображением. Будьте осторожны и смотрите на интересующий файл, а не на его зависимости, потому что, если вы используете x64-версию Depends, он покажет 64-битные зависимости для 32-битного модуля (с красным значком и ошибкой: Модули с другим процессором типы были найдены). - person Maxence; 18.12.2015
comment
Как объяснил Контанго в предыдущем комментарии, это не лучшее решение. - person francogrex; 01.02.2019

Я написал очень простой инструмент, который делает именно это - он называется PE Deconstructor.

Просто запустите его и загрузите свой DLL-файл:

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

В приведенном выше примере загруженная библиотека DLL является 32-разрядной.

Вы можете скачать его здесь (у меня скомпилированная только 64-битная версия ATM):
https://files.quickmediasolutions.com/exe/pedeconstructor_0.1_amd64.exe

Более старая 32-разрядная версия доступна здесь:
https://dl.dropbox.com/u/31080052/pedeconstructor.zip

person Nathan Osman    schedule 01.03.2012
comment
Я пробовал это на исполняемом файле PE Deconstructor amd64, и он сказал, что он 32-битный. - person chrysanhy; 04.08.2012
comment
@chrysanhy: Странно - другие инструменты сообщают, что исполняемый файл 32-битный? - person Nathan Osman; 04.08.2012
comment
9 лет спустя ... Мне написано AMD 64 для исполняемого файла PE Deconstructor. - person Dave Nottage; 19.07.2021