Как я могу протестировать DLL файл Windows, чтобы определить, 32 бит или 64 бит?
Я бы хотел написать тестовый script или программу, которая утверждает, что все DLL файлы в заданном каталоге имеют определенный тип сборки.
Я бы использовал это как проверку работоспособности в конце процесса сборки на SDK, чтобы убедиться, что 64-разрядная версия каким-то образом не имеет в ней 32-разрядных DLL файлов и наоборот.
Есть ли простой способ взглянуть на DLL файл и определить его тип?
Решение должно работать как на xp32, так и на xp64.
Ответы
Ответ 1
Сведения о горах
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 script
Здесь грубый Perl script, который выполняет свою работу. Он проверяет, что файл имеет заголовок 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);
Ответ 2
Грубым способом было бы назвать дамббин с опцией заголовков из инструментов 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, которое Павел упоминает. Должно быть легко искать в script.
Ответ 3
Если у вас установлен Cygwin (который я настоятельно рекомендую по целому ряду причин), вы можете использовать утилиту 'file' DLL
file <filename>
который даст такой вывод:
icuuc36.dll: MS-DOS executable PE for MS Windows (DLL) (GUI) Intel 80386 32-bit
Ответ 4
Зависимость Уокер рассказывает все (ну почти).
http://www.dependencywalker.com/
Он не "устанавливает" - просто достаньте его, извлеките и запустите exec.
Он работает для любого приложения x32 или x64 windows.
Насколько я помню, довольно просто увидеть все зависимости, т.е. модули dll, и после приложения. представляет собой сумму зависимостей, которые можно определить, если они полны x64, x32 (x86) или бит каждого.
Тип процессора, для которого был построен модуль, находится в столбце "ЦП". Большинство 64-битных aps по-прежнему немного, но 32-разрядные ap w/b все x86.
Красивая программа для разработчиков/программистов и бесплатна...
Ответ 5
Я написал очень простой инструмент, который делает именно это - он называется PE Deconstructor.
Просто запустите его и загрузите DLL файл:
![enter image description here]()
В приведенном выше примере загруженная DLL 32-разрядная.
Вы можете скачать его здесь (у меня есть только 64-битная версия скомпилированного банкомата):
http://files.quickmediasolutions.com/exe/pedeconstructor_0.1_amd64.exe
Более старая 32-разрядная версия доступна здесь:
http://dl.dropbox.com/u/31080052/pedeconstructor.zip