WOW64 実装の詳細
WOW64 エミュレーターはユーザー モードで実行されます。 32 ビット バージョンのNtdll.dllとプロセッサのカーネルの間のインターフェイスを提供し、カーネル呼び出しをインターセプトします。 WOW64 エミュレーターは、次の DLL で構成されます。
- Wow64.dllは、コア エミュレーション インフラストラクチャと、Ntoskrnl.exeエントリ ポイント関数のサンクを提供します。
- Wow64Win.dllは、Win32k.sysエントリ ポイント関数のサンクを提供します。
- (x64 のみ) Wow64Cpu.dllは、x64 で x86 プログラムを実行するためのサポートを提供します。
- (Intel Itanium のみ)IA32Exec.bin には、x86 ソフトウェア エミュレーターが含まれています。
- (Intel Itanium のみ) Wowia32x.dllは、IA32Exec.bin と WOW64 の間のインターフェイスを提供します。
- (ARM64 のみ) xtajit.dll x86 ソフトウェア エミュレーターが含まれています。
- (ARM64 のみ) wowarmw.dllは、ARM64 で ARM32 プログラムを実行するためのサポートを提供します。
これらの DLL と 64 ビット バージョンのNtdll.dllは、32 ビット プロセスに読み込むことができる唯一の 64 ビット バイナリです。 ARM のWindows 10では、CHPE (コンパイル済みハイブリッド ポータブル実行可能ファイル) バイナリを x86 32 ビット プロセスに読み込むこともできます。
起動時に、Wow64.dllは x86 バージョンのNtdll.dll (または有効な場合は CHPE バージョン) を読み込み、必要なすべての 32 ビット DLL を読み込む初期化コードを実行します。 ほとんどの 32 ビット DLL は 32 ビット Windows バイナリの変更されていないコピーですが、一部はパフォーマンス上の理由から CHPE として読み込まれます。 これらの DLL の一部は、WOW64 で動作が 32 ビット Windows とは異なる動作をするように記述されています。通常、メモリは 64 ビット システム コンポーネントと共有されるためです。 32 ビット制限を超えるすべてのユーザー モード アドレス空間は、システムによって予約されます。 詳細については、「 WOW64 のパフォーマンスとメモリ消費量」を参照してください。
x86 システム サービス呼び出しシーケンスを使用する代わりに、システム呼び出しを行う 32 ビット バイナリが、カスタム呼び出しシーケンスを使用するように再構築されます。 この呼び出しシーケンスは、WOW64 が完全にユーザー モードのままであるため、インターセプトが安価です。 カスタム呼び出しシーケンスが検出されると、WOW64 CPU はネイティブ 64 ビット モードに戻り、Wow64.dllに呼び出します。 サンキングは、64 ビット カーネルへの影響を軽減し、カーネル モードのクラッシュ、データ破損、またはセキュリティ ホールを引き起こす可能性があるサンクのバグのリスクを軽減するために、ユーザー モードで実行されます。 サンクは、32 ビット スタックから引数を抽出し、64 ビットに拡張してから、ネイティブ システム呼び出しを行います。
環境変数
32 ビット プロセスが 64 ビット プロセスによって作成される場合、または 64 ビット プロセスが 32 ビット プロセスによって作成される場合、WOW64 は次の表に示すように、作成されたプロセスの環境変数を設定します。
Process | 環境変数 |
---|---|
64 ビット プロセス |
PROCESSOR_ARCHITECTURE=AMD64 または PROCESSOR_ARCHITECTURE=IA64 または PROCESSOR_ARCHITECTURE=ARM64 ProgramFiles=%ProgramFiles% ProgramW6432=%ProgramFiles% CommonProgramFiles=%CommonProgramFiles% CommonProgramW6432=%CommonProgramFiles% Windows Server 2008、Windows Vista、Windows Server 2003、Windows XP: ProgramW6432 および CommonProgramW6432 環境変数は、Windows 7 および Windows Server 2008 R2 以降で追加されました。 |
32 ビット プロセス |
PROCESSOR_ARCHITECTURE=x86 PROCESSOR_ARCHITEW6432=%PROCESSOR_ARCHITECTURE% ProgramFiles=%ProgramFiles(x86)% ProgramW6432=%ProgramFiles% CommonProgramFiles=%CommonProgramFiles(x86)% CommonProgramW6432=%CommonProgramFiles% |
グローバル フック
次の条件が満たされた場合、 SetWindowsHookEx 関数を使用して DLL を別のプロセスに挿入できます。
- 32 ビット DLL は 32 ビット プロセスにのみ挿入でき、64 ビット DLL は 64 ビット プロセスにのみ挿入できます。 32 ビット DLL を 64 ビット プロセスに挿入することも、その逆もできません。
- 32 ビット DLL と 64 ビット DLL の名前は異なる必要があります。
- DLL とプロセスのアーキテクチャが一致している必要があります。 たとえば、32 ビットの x86 DLL を 32 ビット ARM プロセスに挿入することはできません。
詳細については、「 SetWindowsHookEx」を参照してください。
WH_MOUSE、WH_KEYBOARD、WH_JOURNAL*、WH_SHELL、および低レベルのフックは、フックを処理するスレッドではなく、フックをインストールしたスレッドで呼び出すことができることに注意してください。 これらのフックの場合、32 ビット フックがフック チェーンの 64 ビット フックより先にある場合は、32 ビットと 64 ビットの両方のフックが呼び出される可能性があります。 詳細については、「フックの 使用」を参照してください。