血腥细节
DLL 使用 PE 可执行格式,从文件中读取该信息并不难。
请参阅此MSDN article on the PE File Format 了解概览。您需要阅读 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 来执行此操作- 使用LoadImage 加载DLL,您将获得一个LOADED_IMAGE 结构,其中包含指向IMAGE_NT_HEADERS 结构的指针。使用 ImageUnload 释放 LOADED_IMAGE。
...或者改编这个粗略的 Perl 脚本
这是完成工作的粗略 Perl 脚本。它检查文件是否有 DOS 头,然后将 IMAGE_DOS_HEADER 60 字节的 PE 偏移量读取到文件中。
然后它寻找 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);