WOW64エミュレーターはユーザーモードで実行されます。 Ntdll.dllの32ビットバージョンとプロセッサのカーネル間のインターフェイスを提供し、カーネル呼び出しをインターセプトします。 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(Compiled Hybrid Portable Executable)バイナリもx86 32ビットプロセスにロードできます。
起動時に、Wow64.dllはNtdll.dllのx86バージョン(または有効になっている場合はCHPEバージョン)を読み込み、必要なすべての32ビットDLLを読み込む初期化コードを実行します。ほとんどすべての32ビットDLLは、32ビットWindowsバイナリの変更されていないコピーですが、一部はパフォーマンス上の理由からCHPEとしてロードされます。これらのDLLの一部は、通常64ビットシステムコンポーネントとメモリを共有するため、WOW64での動作が32ビットWindowsでの動作と異なるように記述されています。 32ビット制限を超えるユーザーモードアドレス空間はすべて、システムによって予約されています。詳細については、WOW64でのパフォーマンスとメモリ消費を参照してください。
x86システムサービス呼び出しシーケンスを使用する代わりに、システム呼び出しを行う32ビットバイナリが再構築され、カスタム呼び出しシーケンスを使用します。この呼び出しシーケンスは、完全にユーザーモードのままであるため、WOW64がインターセプトするのに安価です。カスタム呼び出しシーケンスが検出されると、WOW64 CPUはネイティブ64ビットモードに戻り、Wow64.dllを呼び出します。サンクは、64ビットカーネルへの影響を軽減し、カーネルモードのクラッシュ、データ破損、またはセキュリティホールを引き起こす可能性のあるサンクのバグのリスクを軽減するために、ユーザーモードで実行されます。サンクは、32ビットスタックから引数を抽出し、64ビットに拡張してから、ネイティブシステムコールを行います。
環境変数
32ビットプロセスが64ビットプロセスによって作成される場合、または64ビットプロセスが32ビットプロセスによって作成される場合、WOW64は、作成されたプロセスの環境変数を次の表に示すように設定します。
プロセス | 環境変数 |
64ビットプロセス | PROCESSOR_ARCHITECTURE=AMD64 or PROCESSOR_ARCHITECTURE=IA64 or PROCESSOR_ARCHITECTURE=ARM64 ProgramFiles=%ProgramFiles% ProgramW6432=%ProgramFiles% CommonProgramFiles=%CommonProgramFiles% CommonProgramW6432=%CommonProgramFiles% Windows Server 2008, Windows Vista, Windows Server 2003 and Windows XP: The ProgramW6432 and CommonProgramW6432 environment variables were added starting with Windows 7 and 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ビットフックの両方が呼び出される可能性があります。詳細については、フックの使用を参照してください。