代码之家  ›  专栏  ›  技术社区  ›  morechilli

如何测试Windows DLL文件以确定它是32位还是64位?[复制品]

  •  240
  • morechilli  · 技术社区  · 15 年前

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

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

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

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

    5 回复  |  直到 6 年前
        1
  •  98
  •   phuclv    6 年前

    血淋淋的细节

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

    看到这个 MSDN article on the PE File Format 以获取概述。您需要读取MS-DOS头,然后读取 IMAGE_NT_HEADERS 结构。它包含 IMAGE_FILE_HEADER 结构,其中包含计算机成员中需要的信息,该计算机成员包含以下值之一

    • 图像文件机器
    • 图像文件机器(0x0200)
    • 图像文件机AMD64(0x8664)

    这些信息应该在文件中有固定的偏移量,但是我仍然建议遍历文件并检查MS-DOS头和图像头的签名,以确保您能够处理将来的任何更改。

    使用ImageHelp读取邮件头…

    您也可以使用 ImageHelp API 为此-加载DLL LoadImage 你会得到一个 LOADED_IMAGE 结构,其中包含指向图像标题结构的指针。使用IMAGEUNLOAD释放加载的_映像。

    …或者改编这个粗糙的Perl脚本

    下面是完成任务的粗略Perl脚本。它检查文件是否有DOS头,然后将图像\DOS头的PE偏移量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
  •  155
  •   Jeremy    15 年前

    一种简单的方法是使用每个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,包括保罗提到的14C值。应该很容易在脚本中查找。

        3
  •  99
  •   user2441511    7 年前

    如果你有 Cygwin 已安装(出于各种原因,我强烈建议您使用dll上的“文件”实用程序

    file <filename>
    

    这样的输出:

    icuuc36.dll: MS-DOS executable PE  for MS Windows (DLL) (GUI) Intel 80386 32-bit
    
        4
  •  44
  •   Ric    13 年前

    依赖性沃克告诉所有人(几乎是这样)。 http://www.dependencywalker.com/

    它不“安装”——只需获取它,提取它并运行exec。 它适用于任何x32或x64 Windows模块应用程序。

    我记得,查看所有依赖项(即DLL模块)和自应用程序以来都非常简单。是依赖项的总和,可以确定它是完整的x64、x32(x86)还是每个都有一点。

    为其生成模块的CPU类型在“CPU”列中。大多数64位AP仍然是一个位,但32位AP都是x86。

    为极客/程序员设计的漂亮程序,它是免费的…

        5
  •  35
  •   Nathan Osman    8 年前

    我写了一个非常简单的工具,它就是所谓的PE解构器。

    只需启动它并加载您的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