1. ホーム
  2. ウィンドウズ

[解決済み】WindowsのDLLファイルが32ビットか64ビットかを判断するためのテスト方法は?[重複]。

2022-04-02 01:30:45

質問

あるディレクトリにあるすべてのDLLファイルが特定のビルドタイプであることを保証するテストスクリプトまたはプログラムを書きたいのですが、どうすればいいですか?

SDKのビルドプロセスの最後に、64ビットバージョンに32ビットDLLファイルが含まれていないか、またはその逆になっていないかを確認するためのサニティチェックとして使用したいのです。

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

解決策は、xp32とxp64の両方で動作するはずです。

どのように解決するのですか?

詳細

DLLはPE実行形式を使用しており、ファイルからその情報を読み出すのはそれほど厄介なことではありません。

こちらをご覧ください PEファイルフォーマットに関するMSDN記事 をご覧ください。MS-DOSのヘッダーを読み、次に 画像_nt_headers 構造体です。これには 画像_ファイル_ヘッダー 構造体には、次の値のいずれかを含む 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をロードします。 ロードイメージ を表示させれば LOADED_IMAGE 構造体はIMAGE_NT_HEADERS構造体へのポインタを含んでいます。LOADED_IMAGEはImageUnloadで解放します。

...または、次の荒い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);