如何测试 Windows DLL 文件以确定它是 32 位还是 64 位?

发布于 2024-07-12 03:37:44 字数 198 浏览 4 评论 0原文

我想编写一个测试脚本或程序来断言给定目录中的所有 DLL 文件都属于特定的构建类型。

我会在 SDK 构建过程结束时使用它作为健全性检查,以确保 64 位版本中没有以某种方式获取一些 32 位 DLL 文件,反之亦然。

有没有一种简单的方法来查看 DLL 文件并确定其类型?

该解决方案应该适用于 xp32 和 xp64。

I'd like to write a test script or program that asserts that all DLL files in a given directory are of a particular build type.

I would use this as a sanity check at the end of a build process on an SDK to make sure that the 64-bit version hasn't somehow got some 32-bit DLL files in it and vice versa.

Is there an easy way to look at a DLL file and determine its type?

The solution should work on both xp32 and xp64.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(5

初与友歌 2024-07-19 03:37:44

一种粗略的方法是在每个 DLL 上使用 Visual Studio 工具中的 headers 选项调用 dumpbin 并查找适当的输出:

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,包括 Paul 指出的 14C 值。提到。 应该很容易在脚本中查找。

A crude way would be to call dumpbin with the headers option from the Visual Studio tools on each DLL and look for the appropriate output:

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)

You can see a couple clues in that output that it is a 32 bit DLL, including the 14C value that Paul mentions. Should be easy to look for in a script.

厌味 2024-07-19 03:37:44

如果您安装了 Cygwin (或 MobaXTerm、Windows 版 Git Bash、WSL 或...)(出于多种原因,我强烈建议),您可以在 DLL 上使用“文件”实用程序

file <filename>

,它会给出如下输出:

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

If you have Cygwin (or MobaXTerm, or Git Bash for Windows, or WSL, or...) installed (which I strongly recommend for a variety of reasons), you could use the 'file' utility on the DLL

file <filename>

which would give an output like this:

icuuc36.dll: MS-DOS executable PE  for MS Windows (DLL) (GUI) Intel 80386 32-bit
左岸枫 2024-07-19 03:37:44

血淋淋的细节

DLL 使用 PE 可执行格式,从文件中读取该信息并不困难。

请参阅这篇有关 PE 文件格式的 MSDN 文章,了解概述。 您需要读取 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 结构的指针。 使用 ImageUnload 释放 LOADED_IMAGE。

...或者改编这个粗略的 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);

Gory details

A DLL uses the PE executable format, and it's not too tricky to read that information out of the file.

See this MSDN article on the PE File Format for an overview. You need to read the MS-DOS header, then read the IMAGE_NT_HEADERS structure. This contains the IMAGE_FILE_HEADER structure which contains the info you need in the Machine member which contains one of the following values

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

This information should be at a fixed offset in the file, but I'd still recommend traversing the file and checking the signature of the MS-DOS header and the IMAGE_NT_HEADERS to be sure you cope with any future changes.

Use ImageHelp to read the headers...

You can also use the ImageHelp API to do this - load the DLL with LoadImage and you'll get a LOADED_IMAGE structure which will contain a pointer to an IMAGE_NT_HEADERS structure. Deallocate the LOADED_IMAGE with ImageUnload.

...or adapt this rough Perl script

Here's rough Perl script which gets the job done. It checks the file has a DOS header, then reads the PE offset from the IMAGE_DOS_HEADER 60 bytes into the file.

It then seeks to the start of the PE part, reads the signature and checks it, and then extracts the value we're interested in.

#!/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);
伴我老 2024-07-19 03:37:44

Dependency Walker 告诉了一切(几乎)。
http://www.dependencywalker.com/

它不会“安装” - 只需获取它,解压它并运行执行程序。
它适用于任何 x32 或 x64 windows 模块|应用程序。

我记得查看所有依赖项(即 dll 模块)相当简单,并且自 appl. 是依赖项的总和,可以确定它是完整的 x64、x32(x86) 还是其中的一部分。

模块所针对的 CPU 类型位于“CPU”列中。 大多数 64 位 ap 仍然各有千秋,但 32 位 ap 都是 x86。

适合极客/程序员的漂亮程序,而且是免费的......

Dependency Walker tells all(well almost).
http://www.dependencywalker.com/

It does not "install" -just get it, extract it and run the exec.
It works for any x32 or x64 windows module|application.

As I recall it is fairly straightforward to see all dependencies, i.e. the dll modules, and since the appl. is a sum of the dependencies one can ascertain if it is full x64, x32(x86) or a bit of each.

Type of CPU that the module was built for is in the "CPU" column. Most 64-bit aps are still a bit of each but 32-bit ap w/b all x86.

Beautiful program for geeks/programmers and it is free...

断念 2024-07-19 03:37:44

我写了一个非常简单的工具来完成这个任务——它叫做 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

I have written a very simple tool that does exactly that - it's called PE Deconstructor.

Simply fire it up and load your DLL file:

enter image description here

In the example above, the loaded DLL is 32-bit.

You can download it here (I only have the 64-bit version compiled ATM):
https://files.quickmediasolutions.com/exe/pedeconstructor_0.1_amd64.exe

An older 32-bit version is available here:
https://dl.dropbox.com/u/31080052/pedeconstructor.zip

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文