Как я могу протестировать DLL-файл Windows, чтобы определить, является ли он 32-разрядным или 64-разрядным?[дубликат]
-
20-08-2019 - |
Вопрос
На этот вопрос уже есть ответ здесь:
Я хотел бы написать тестовый скрипт или программу, которая утверждает, что все DLL-файлы в данном каталоге относятся к определенному типу сборки.
Я бы использовал это как проверку работоспособности в конце процесса сборки на SDK, чтобы убедиться, что в 64-разряднойверсии каким-то образом нет 32-разрядных DLL-файлов, и наоборот.
Есть ли простой способ просмотреть DLL-файл и определить его тип?
Решение должно работать как на xp32, так и на xp64.
Решение
Кровавые подробности
Библиотека DLL использует исполняемый формат PE, и прочитать эту информацию из файла не так уж сложно.
Видишь это Статья MSDN о формате файла PE для общего обзора.Вам нужно прочитать заголовок MS-DOS, затем прочитать IMAGE_NT_HEADERS_ЗАГОЛОВКИ ИЗОБРАЖЕНИЙ структура.Это содержит IMAGE_FILE_HEADER - ФАЙЛ для ЧТЕНИЯ ИЗОБРАЖЕНИЙ структура, которая содержит необходимую вам информацию в машинном элементе, который содержит одно из следующих значений
- ФАЙЛ_ИЗОБРАЖЕНИЯ_МАШИНЫ_I386 (0x014c)
- ФАЙЛ_ИЗОБРАЖЕНИЯ_МАШИНЫ_IA64 (0x0200)
- IMAGE_FILE_MACHINE_AMD64 (0x8664) ФАЙЛ IMAGE_FILE_MACHINE_AMD64
Эта информация должна находиться в файле с фиксированным смещением, но я бы все же рекомендовал просмотреть файл и проверить подпись заголовка MS-DOS и IMAGE_NT_HEADERS, чтобы быть уверенным, что вы справитесь с любыми будущими изменениями.
Используйте ImageHelp для чтения заголовков...
Вы также можете использовать API ImageHelp для работы с изображениями для этого - загрузите DLL с Загрузочное изображение и вы получите ЗАГРУЖЕННОЕ ИЗОБРАЖЕНИЕ структура, которая будет содержать указатель на структуру IMAGE_NT_HEADERS.Освободите ЗАГРУЖЕННОЕ изображение с помощью 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 tools для каждой библиотеки 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, о котором упоминает Пол.Должно быть легко искать в скрипте.
Если у вас есть Сигвин установленный (который я настоятельно рекомендую по целому ряду причин), вы могли бы использовать утилиту 'file' в DLL
file <filename>
что дало бы такой результат, как этот:
icuuc36.dll: MS-DOS executable PE for MS Windows (DLL) (GUI) Intel 80386 32-bit
Dependency Walker рассказывает все (ну почти).http://www.dependencywalker.com/
Он не "устанавливается" - просто получите его, извлеките и запустите exec.Это работает для любого модуля | приложения Windows x32 или x64.
Насколько я помню, довольно просто просмотреть все зависимости, т. е.модули dll, и поскольку приложение.представляет собой сумму зависимостей, которые можно определить, является ли она полной x64, x32 (x86) или немного каждой из них.
Тип процессора, для которого был создан модуль, указан в столбце "CPU".Большинство 64-разрядных точек доступа по-прежнему немного отличаются друг от друга, но 32-разрядные точки доступа поддерживают все x86.
Прекрасная программа для гиков / программистов, и она бесплатна...
Я написал очень простой инструмент, который делает именно это - он называется PE Deconstructor .
Просто запустите его и загрузите свой DLL-файл:
В приведенном выше примере загруженная DLL является 32-разрядной.
Вы можете скачать его здесь (у меня есть только 64-разрядная версия, скомпилированная ATM):
http://files .quickmediasolutions.com/exe/pedeconstructor_0.1_amd64.exe
Более старая 32-разрядная версия доступна здесь:
http://dl.dropbox.com/u/31080052/pedeconstructor.zip