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

этот вопрос уже есть ответ здесь:

  • как определить, для какой платформы компилируется исполняемый файл? 10 ответов

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

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

есть ли простой способ посмотреть на DLL-файл и определить его тип?

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

5 ответов


подробности

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

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

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

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

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

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

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

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

затем он стремится к началу части 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);

грубым способом было бы вызвать dumpbin с опцией headers из средств 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, которое упоминает пол. Должно быть легко найти в сценарии.


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

file <filename>

который дал бы такой результат:

icuuc36.dll: MS-DOS executable PE  for MS Windows (DLL) (GUI) Intel 80386 32-bit

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

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

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

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

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


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

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

enter image description here

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

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

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