マカフィー株式会社 公式ブログ

McAfee Labs] 2010年6月15日 更新

Windows 7解剖 - 1:「カーネルAPIの修正」について

 

昨年10月の発売以来、マイクロソフト社のWindows 7の販売本数は9,000万本に達しており、Windows販売史上最速という記録を更新しているといわれています。今回は、Windows 7で新たに強化された内部構造に関し、2回に渡って取り上げる予定です。まず第1回目は、多くの人が興味を示している、新軽量カーネル「MinWin」について紹介したいと思います。

多くの人が新軽量カーネル「MinWin」に大きな関心を寄せている一方で、大半の人が「MinWin」を正しく理解していません。中には、「MinWin」と「Server Core」を混同している人も少なくありません。では、「MinWin」とは、正確に何を指すのでしょうか?

正常にインストールできたXPMでは、「Enhanced Mode」、「Basic Mode」、「Virtual Applications Mode」の3種類のモードが使用可能です。Windows XPのデスクトップをそのまま表示して使う「Enhanced Mode」と「Basic Mode」は、通常のVirtual PCを使う場合と、見た目は全く変わらず、Virtual PCとWindows XP仮想マシンが表示されます。

過去、マイクロソフト社がWindows Server 2008で実現したものの1つに、「Server Core」(旧名称:「Server Foundation」)がありました。これは、ADやDNS、DHCPサーバー、インターネットインフォメーションサービス(IIS)といった一般的なサーバー機能の動作に必要なコンポーネントを集めた、Windows OSのサブセット製品でした。一方「MinWin」は、上位層のコンポーネントに依存しない、独立型の小規模なOSです。一般的には、Windows 7に付属して出荷される、最小構成の独立型Windowsコンポーネントセットとしてよく知られています。

マイクロソフト社のあるWindows開発者は、「MinWin」を「アーキテクチャの階層に沿ったコードの修正」と説明しています。実際、初の「MinWin」ベースのOSと言われるWindows Vista以降(Windows Vistaではすでに複数のコンポーネント化と修正が行われています)は、OSのどのコンポーネントにも、他のコンポーネントとの依存関係を表す「階層番号」が割り振られており、OSのコアに近いコンポーネントほど、小さな番号が割り当てられています。「コード修正」はコアのアーキテクチャチームが行い、この修正によって、下位層のコンポーネントが上位層のコンポーネントに依存する、という依存関係の問題を解決しました。次に、Windows 7における「階層化」と「コード修正」の方法を、例を使って説明しましょう。

ApiSet Stub DLLs:
api-ms-win-core-console-l1-1-0.dll
api-ms-win-core-datetime-l1-1-0.dll
api-ms-win-core-debug-l1-1-0.dll
api-ms-win-core-delayload-l1-1-0.dll
api-ms-win-core-errorhandling-l1-1-0.dll
api-ms-win-core-fibers-l1-1-0.dll
api-ms-win-core-file-l1-1-0.dll
api-ms-win-core-handle-l1-1-0.dll
api-ms-win-core-heap-l1-1-0.dll
api-ms-win-core-interlocked-l1-1-0.dll
api-ms-win-core-io-l1-1-0.dll
api-ms-win-core-libraryloader-l1-1-0.dll
api-ms-win-core-localization-l1-1-0.dll
api-ms-win-core-localregistry-l1-1-0.dll
api-ms-win-core-memory-l1-1-0.dll
api-ms-win-core-misc-l1-1-0.dll
api-ms-win-core-namedpipe-l1-1-0.dll
api-ms-win-core-processenvironment-l1-1-0.dll
api-ms-win-core-processthreads-l1-1-0.dll
api-ms-win-core-profile-l1-1-0.dll
api-ms-win-core-rtlsupport-l1-1-0.dll
api-ms-win-core-string-l1-1-0.dll
api-ms-win-core-synch-l1-1-0.dll
api-ms-win-core-sysinfo-l1-1-0.dll
api-ms-win-core-threadpool-l1-1-0.dll
api-ms-win-core-util-l1-1-0.dll
api-ms-win-core-xstate-l1-1-0.dll
api-ms-win-security-base-l1-1-0.dll
api-ms-win-security-lsalookup-l1-1-0.dll
api-ms-win-security-sddl-l1-1-0.dll
api-ms-win-service-core-l1-1-0.dll
api-ms-win-service-management-l1-1-0.dll
api-ms-win-service-management-l2-1-0.dll
api-ms-win-service-winsvc-l1-1-0.dll

これを見ると、「Kernel32!OpenProcess」が実際には大した働きをせず、単に、スタブDLLの1つ(api-ms-win-core-synch-l1-1-0.dll)からインポートされる「OpenProcess_0」へジャンプしているだけ、ということがわかります。

IDA ProとDependency Walkerを使えば、この依存関係はひと目でわかります。しかし、「api-ms-win-core-synch-l1-1-0!OpenProcess」を逆アセンブルしたコードをより詳しく見てみると、驚いたことにこの関数は実際には空で、単に0を返してくるにすぎません。しかもエクスポートした関数のうち、引数が3のものはすべて、同じ関数スタブ(下図参照)を共有していることが分かるでしょう。では、「Kernel32!OpenProcess」は結局のところ空関数なのに、なぜうまく機能するのでしょうか?

その秘密は、このDLLのロードプロセスにあります。デバッガWindbgの出力結果から、「Kernel32!OpenProcess」は実行中に「api-ms-win-core-synch-l1-1-0!OpenProcess」にジャンプしないことがわかります。さらに、「OpenProcess」のインポートテーブル・エントリーは、実際には「Kernelbase!OpenProcess」のアドレスで埋められていて、「api-ms-win-*.dll」はいずれもプロセスアドレス空間(!pebの出力を参照)にロードされないことがわかりました。

実際に動作するコードは、「Kernel32!OpenProcess」から「Kernelbase!OpenProcess」(下図参照)に移動し、そこでさらに「Ntdll!ZwOpenProcess」を実行しています。ちなみに、「アーキテクチャの階層に沿ったコードの修正」では、「OpenProcess」だけでなくほとんどのWin32 APIがその対象となりました。

次回では、Windows 7の新機能である、仮想化とリモート・アプリケーションを組み合わせた「Windows XP Mode(XPM)」について取り上げたいと思います。

関連記事

※本ページの内容はMcAfee Blogの抄訳です。
原文:Windows 7 - Kernel API Refactoring

Also Find Us On

マカフィーは、インテルコーポレーション(NASDAQ:INTC)の完全子会社であり、企業、官公庁・自治体、個人ユーザーが安全にインターネットの恩恵を享受できるよう、世界中のシステム、ネットワーク、モバイルデバイスを守るプロアクティブで定評のあるセキュリティソリューションやサービスを提供しています。詳しくは、http://www.mcafee.com/jp/をご覧ください。

 

Copyright © 2003-2014 McAfee, Inc. All Rights Reserved.