shim とは

shim のしくみ

Microsoft® Windows® オペレーティング システムにおけるアプリケーション エクスペリエンスおよび互換性は、パフォーマンス、信頼性、管理容易性と並んで Windows 開発の基本的な柱となるものです。展開のコストを削減し、導入にかかる時間を短縮するために、Microsoft では、既存のソフトウェアの広範な互換性を確保する考え抜かれたテクニカル ソリューションに投資し、エンジニアリングやリリース プロセスにおける互換性の実現を推進します。

Microsoft Windows Application Compatibility Infrastructure (Shim Infrastructure) は、そのような強力なテクニカル ソリューションの 1 つです。Windows オペレーティング システムは、バージョンが変わるごとに新しいテクノロジをサポートし、バグの修正に対応し、対策の変更を実装することで発展を続けていますが、一部の機能の実装に対する変更が、変更前の実装に依存しているアプリケーションに影響を与える可能性があります。また、ソフトウェアの特性を考慮すると、この互換性の問題を解決するために再度機能を変更することによって、追加のアプリケーションを壊してしまう可能性があります。また、場合によっては、別の実装によって提供される機能改善に関係なく、Windows を同じ状態のままにしなければならなくなります。Windows のソース コードに分岐を直接配置すると、こうした状況を回避できますが、このような対策方法は、Windows オペレーティング システムの有用性や信頼性についての、長期的な時間を要する課題となります。しかし、Shim Infrastructure を使用すると、特定のアプリケーション (通常は、そのアプリケーションの特定のバージョン) に対する具体的なアプリケーションの修正内容を明確にすることができます。これらの修正内容は Windows の主要な関数の外部に格納され、個別に管理されます。

Shim Infrastructure は、アプリケーション プログラミング インターフェイス (API) フックのフォームを実装します。具体的には、リンクの特性を活用して、Windows 自体からの API 呼び出しを代替コード (shim 自体) にリダイレクトします。Windows の移植可能な実行可能ファイル (PE) および Common Object File Format (COFF) の仕様には、いくつかのヘッダーが含まれており、このヘッダーのデータ ディレクトリは、アプリケーションとリンク先のファイル間の間接レイヤーを提供します。外部のバイナリ ファイルの呼び出しは、インポート アドレス テーブル (IAT) を介して実行されます。その結果、システムに対する Windows の呼び出しは図 1 のようになります。

643f2bee-8329-4018-9d90-2ffcc7c76a6c

図 1   アプリケーションから IAT を介した Windows の呼び出し

具体的には、図 2 に示すように、インポート テーブルで解決される Windows 関数のアドレスを変更し、代替 shim コード内にある関数を指すポインターに置き換えることができます。

アート イメージ

図 2   Windows の呼び出し前に shim にリダイレクトされたアプリケーション

この間接的な処理は、アプリケーションが読み込まれるときに、静的にリンクされた .dll ファイルに対して行われます。また、GetProcAddress API をフックすることで、動的にリンクされた .dll ファイルに shim を適用することもできます。

Shim Infrastructure の設計による影響

shim の適用方法を決定するとき、Shim Infrastructure の設計に関連する特定の影響が明らかになる場合があります。

図 2「Windows の呼び出し前に shim にリダイレクトされたアプリケーション」に示すように、shim 内で実行されるコードは、Windows の外側に存在します。その結果、Windows は、shim コードがアプリケーション コード自体と同じセキュリティ制限を適用されるように保持します。実際、Windows の側から見ると、shim コードはアプリケーション コードのように機能します。したがって、shim を使用する場合は、Windows 内にあるセキュリティ メカニズムを回避することはできません。たとえば、shim を使用して、Windows 7 のユーザー アカウント制御 (UAC) のプロンプトを回避し、同時に管理者特権のアクセス許可でアプリケーションを実行することはできません。管理者権限を要求するかどうかは、アプリケーションに shim を適用することで設定できますが、UAC を有効にして管理者権限を取得するには、ユーザーが昇格を承認する必要があります。これは、自分で作成したコードについても同様です。

そのため、企業内での shim の使用がセキュリティに与える影響を評価する際に、新たなセキュリティの脆弱性にさらされることはありません。実際、shim を使用してセキュリティ記述子やセキュリティ ポリシーの緩和を回避することは、多くの場合、より安全な選択肢といえます。たとえば、shim を使用しない場合、特定のディレクトリの ACL を緩和することで互換性の問題を軽減できますが、これによりシステム全体に影響が及びます。shim を使用すると、そのアプリケーションの各ユーザーの場所にファイル アクセスをリダイレクトできます。別の例として、アプリケーションは管理者権限を明示的にチェックする場合があります。shim を使用しない場合、このチェックにパスするには、アプリケーションに管理者権限を付与する必要があります。ただし、このチェックが不要な場合、shim は現在のユーザーが管理者権限を持っているかどうかを単に偽装します。これで、追加のセキュリティ領域を公開せずにチェックにパスすることができます。

また、Shim Infrastructure は、基本的に、アプリケーションが Windows を呼び出す前に、そのアプリケーション内に追加コードを挿入するため、shim を使用して問題を軽減するには、アプリケーション コード自体を変更します。少なくとも、アプリケーションは、Windows API を呼び出す直前に Windows が shim で実装する内容と同様のコードを組み込むことができます。

最後に、shim はユーザー モード アプリケーション プロセス内でユーザー モード コードとして実行されるため、shim を使用してカーネル モード コードを修正することはできません。たとえば、shim を使用して、デバイス ドライバーやその他のカーネル モード コードの互換性の問題を解決することはできません (たとえば、一部のウイルス対策、ファイアウォール、およびスパイウェア対策のコードは、カーネル モードで動作します)。

コミュニティの追加

追加
表示: