web-dev-qa-db-ja.com

WindowsのDLLファイルをテストして、32ビットか64ビットかを判断するにはどうすればよいですか。

特定のディレクトリ内のすべてのDLLファイルが特定のビルドタイプであることを表明するテストスクリプトまたはプログラムを作成したいと思います。

64ビット版で何らかの形で32ビットのDLLファイルが作成されていないことを確認するために、SDKのビルドプロセスの最後にこれを健全性チェックとして使用します。

DLLファイルを見てその種類を判断する簡単な方法はありますか?

解決策はxp32とxp64の両方で機能するはずです。

247
morechilli

ゴリーの詳細

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ヘッダーがあることを確認してから、IMAGE_DOS_HEADERから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);
105
Paul Dixon

おおまかな方法​​は、各DLLでVisual Studioツールからheadersオプションを指定してdumpbinを呼び出し、適切な出力を探すことです。

 dumpbin/headers my32bit.dll 
 
 PE署名が見つかりました
 
ファイルの種類:DLL 
 
ファイルの見出し値
 14 Cマシン(x86)
 1セクション数
 45499E0A時刻日付スタンプ木曜日02 03:28:10 2006 
 0シンボルテーブルへのファイルポインタ0シンボル数[0]オプションヘッダのE 0サイズ[2] 2102特性[2]実行ファイル[2]ワードマシン[2] DLL [2] ] 
オプションのヘッド値
 10Bマジック#(PE32)

その出力には、Paulが言及した14C値を含む32ビットDLLであることがいくつかわかります。スクリプトで探すのは簡単なはずです。

158
Jeremy

Cygwin がインストールされている場合(さまざまな理由から強くお勧めします)、DLLの 'file'ユーティリティを使用できます。

file <filename>

これは次のような出力になります。

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

Dependency Walkerは、(ほぼ)すべてを伝えます。 http://www.dependencywalker.com/

「インストール」することはありません - それを入手し、それを展開してexecを実行します。それはどんなx32またはx64 windowsモジュールアプリケーションのためにも働きます。

私が思い出したように、すべての依存関係、すなわちdllモジュール、そしてappl以来、見ることはかなり簡単です。完全なx64、x32(x86)、またはそれぞれのビットのどれであるかを確認できる依存関係の合計です。

モジュールが構築されたCPUのタイプは「CPU」列にあります。ほとんどの64ビットのapsはまだそれぞれのビットですが32ビットのap w/bすべてx86です。

オタク/プログラマーのための美しいプログラムとそれは無料です...

45
Ric

私はまさしくそれをする非常に単純なツールを書きました - それは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

38
Nathan Osman