(57)【要約】      （修正有）【課題】同一の論理アドレスへのコード及びデータの取り込みを異なる物理アドレスに経路指定するＭＭＵ（メモリ管理ユニット）攻撃等の攻撃を打破する。【解決手段】プログラムコードは、コード及びデータのメモリアクセス／取り込みが同期される場合、すなわちデータ及びコードのアクセス／取り込みがコンピュータメモリにおいて同一の物理アドレスに経路指定される場合にのみ正しく動作するように改変される。プログラムコードは、コード（「修復対象」）のうちの１つ以上のセクションが意図的に破壊されるためにプログラムコードが正しく実行しないように改変され、修復対象は、修復対象が実行される前に実行時に正しいコードに置換される。【選択図】図５
2015043221.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータプログラムコードを保護する方法であって、
コード及びデータのメモリアクセス／取り込みが同期される場合、すなわちデータ及びコードのアクセス／取り込みがコンピュータメモリにおいて同一の物理アドレスに経路指定される場合にのみ正しく動作するように、プログラムコードを改変することをコンピュータプログラムコードを保護する方法。
【請求項２】
同一の論理アドレスへのコード及びデータのメモリアクセス／取り込みが異なる物理アドレスに経路指定されるＭＭＵ攻撃等の攻撃を間接的に打破するために使用されることを特徴とする請求項１に記載の方法。
【請求項３】
前記プログラムコードは、前記コード（「修復対象」）のうちの１つ以上のセクションが意図的に破壊されるために前記プログラムコードが正しく実行しないように改変され、前記修復対象は、前記修復対象が実行される前に実行時に正しいコードに置換されることを特徴とする請求項１又は２に記載の方法。
【請求項４】
新しいコードセクション（「修復プローブ」）が前記プログラムコードに注入され、これらの修復プローブは実行される前に実行時に前記修復対象を修復し、この修復処理は、前記プログラムに対する攻撃が前記同一の論理アドレスへのコード及びデータの取り込みを異なる物理アドレスに経路指定しようとする場合には効果的でないことを特徴とする請求項３に記載の方法。
【請求項５】
前記修復対象が実行された後、新しいコードセクション（「損傷プローブ」）は前記プログラムコードに注入され、これらの損傷プローブは、元の間違った値等の前記間違った値又は値の新しい集合を事前に修復された修復対象に書き込むことを特徴とする請求項４に記載の方法。
【請求項６】
「修復ノード」を共に形成する修復対象、１つ以上の修復ゾーン及びゼロ以上の修復プローブが存在することを特徴とする請求項５に記載の方法。
【請求項７】
人により手動で検出すること及び取り除くことを時間がかかり且つ非現実的なものにするために、多くの修復ノードを使用するステップを含むことを特徴とする請求項６に記載の方法。
【請求項８】
自動で検出すること及び取り除くことを困難にするために、コード生成方法を介して修復ノードが全て一意であることを保証するステップを含むことを特徴とする請求項６又は７に記載の方法。
【請求項９】
自動で検出することをより困難にするために、時間的・空間的に関連する修復ノードの構成要素（修復対象、修復プローブ及び損傷プローブ）を互いから分離することを特徴とするステップを含むことを特徴とする請求項６乃至８のいずれか１項に記載の方法。
【請求項１０】
シミュレーションに基づく検出を妨害するために、修復ノードをあまり頻繁に実行されないコードに配置するステップを含むことを特徴とする請求項６乃至９のいずれか１項に記載の方法。
【請求項１１】
前記修復対象に書き込み、前記書き込まれたデータのうちのいくつかを再度読み取って再度それを書き込む種類の修復プローブが存在し、データの読み取り、データの書き込み及び命令の読み取りが全て同一の場所に経路指定される場合にのみ結果として得られるデータが一貫するように、前記処理においてそれを移動すること及び／又は改変することであることを特徴とする請求項４乃至１０のいずれか１項に記載の方法。
【請求項１２】
前記修復対象がある他の場所において前記プログラムの動作をプロキシし、且つデータの書き込み及び命令の読み取りが全て同一の場所に経路指定される場合にのみ前記他の場所においてその代わりに前記修復対象において実行するようにされた結果として生じるコードが一貫するように、コード及び／又はデータを書き込む種類の修復プローブ（「プロキシ修復プローブ」）が存在することを特徴とする請求項４乃至１１に記載の方法。
【請求項１３】
同一の論理アドレスへのコード及びデータの取り込みが異なる物理アドレスに経路指定されるＭＭＵ攻撃等の攻撃を検出するために使用されることを特徴とする請求項１乃至１２のいずれか１項に記載の方法。
【請求項１４】
改変後の修復対象が存在し、前記改変後の修復対象に配置された間違ったコードは、プログラムの不具合を引き起こさないが、前記攻撃が存在することを示すためにフラグを設定する等の応答機構を実行させることを特徴とする請求項１３に記載の方法。
【請求項１５】
（ｉ）実行時にのみ知られるプログラム変数への割り当てに対して前記コードを識別するステップと；
（ｉｉ）前記割り当てられた値が前記正しいランタイム値と等しい可能性が低い即値であるように、そこの前記コード（「動的な修復対象」）を改変するステップと；
（ｉｉｉ）前記元の割り当ての適正値を含むように前記コードにおいて前記即値を改変する前記動的な修復対象の前に新しいコード（「動的な修復プローブ」）を注入するステップであり、この改変は、攻撃が存在する場合に実際に実行中の前記コードのバージョンにおいて反映されないステップとを含むことを特徴とする請求項６、又は、請求項６に従属する場合の請求項７乃至１４のいずれか１項に記載の方法。
【請求項１６】
（ｉ）修復ノードを含むように選択された機能に渡された前記パラメータを識別するステップ及びこれらのパラメータのうちの１つがありふれたデータの種類の渡された値であり且つ前記機能のコード内で使用されるようにそれを選択するステップと；
（ｉｉ）前記コード自体に組み込まれた即値を代わりに使用するために前記選択された機能パラメータ（「動的な修復対象」）を使用する１つのコードを改変するステップと；
（ｉｉｉ）実行される前に前記選択された機能パラメータの値を含むように前記コードにおいて前記即値を改変する前記動的な修復対象の前に新しいコード（「動的な修復プローブ」）を注入するステップであり、この改変は、攻撃が存在する場合に実際に実行中の前記コードのバージョンにおいて反映されないステップとを含むことを特徴とする請求項１５に記載の方法。
【請求項１７】
前記動的な修復対象及び動的な修復プローブの構成要素を独立した機能に分離するステップを含むことを特徴とする請求項１５又は１６に記載の方法。
【請求項１８】
前記動的な修復対象が実行された後、新しいコードセクション（「動的な損傷プローブ」）は前記プログラムコードに注入され、これらの動的な損傷プローブは、元の間違った値等の前記間違った値又は値の新しい集合を事前に修復された動的な修復対象に書き込むことを特徴とする請求項１５又は１６に記載の方法。
【請求項１９】
コンピュータプログラムコードを保護するコンピュータシステムであって、請求項１乃至１８のいずれか１項に記載の方法を実行する可能であることを特徴とするコンピュータシステム。
【請求項２０】
コンピュータ上で実行された場合、請求項１乃至１８のいずれか１項に記載の方法を前記コンピュータに実行させることを可能にするコンピュータ可読媒体上に格納されたことを特徴とするコンピュータソフトウエアプログラム。
【請求項２１】
請求項１９記載のコンピュータにより実現されたシステムにより改変されたコンピュータソフトウエアプログラムか又は同一の論理アドレスへのコード及びデータの取り込みが異なる物理アドレスに経路指定される攻撃を継続して回避することを特徴とする請求項２０に記載のコンピュータソフトウエアプログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コンピュータプログラムコードを保護する方法に関する。本発明は、例えば同一の論理アドレスへのコード及びデータの取り込みを異なる物理アドレスに経路指定するＭＭＵ攻撃等の攻撃を打破するために使用される。
【背景技術】
【０００２】
ソフトウエア改竄防止技術の分野では、「自己検査」と呼ばれる技術は、多くの場合プログラムコードがどのような方法でも改変されていないことを保証するために使用される。自己検査システムは、特にメモリ内のコードに対してランタイムチェックサム（又はハッシュ）を実行し、プログラムの改変前のバージョンから得られたように実行結果を予測チェックサムと比較する。チェックサム又はハッシュは「ダイジェスト」の例である。従って、一般的な場合には、自己検査システムは、メモリ中のコードのダイジェストを生成し、実行結果をコードの改変前のバージョンと比較する。ダイジェストは、データの小さな変化がダイジェストの大きな変化となるデータセットの（特に小さな）表現である。代表的なダイジェストのサイズは３２ビットから２０４８ビットである。図１は他のコードを検査するコードを使用した自己検査システムを示す。
【０００３】
自己検査はかなり効果的な方法ではあるが、ＭＭＵ（メモリ管理ユニット）攻撃又はＴＬＢ（トランスレーションルックアサイドバッファ）攻撃と呼ばれる最近の技術は、コンピュータが実際に改変された（すなわち、ハッキングされた）コピーを実行する一方、自己検査システムを騙してプログラムコードの改変前のコピーを検査させることにより検査システムを完全に打破する方法を示す。この攻撃は、異なる処理をする異なる種類のメモリアクセスを実行できる最も多くのプロセッサ（すなわち、中央処理装置（ＣＰＵ）、グラフィック処理装置（ＧＰＵ）等）の特徴を以下のように使用する。この攻撃では、データアクセスとコードアクセスとが区別され、これらアクセスが同一の論理アドレスを共有しているときでさえアクセスを別の物理アドレスに再経路指定する。この特徴は常にメモリ管理ユニット（ＭＭＵ）に実現されている。しかし、この特徴はＭＭＵと同等のシステムに実現してもよい。例えば一部のＣＰＵは、ＭＭＵと呼ばれないが上述した必要な特徴を提供するより簡単な回路網を有してもよい。通常は、より古いＣＰＵ等の一部のシステムではコプロセッサとして存在できる。
【０００４】
プロセッサは、データのアクセス（「取り込み（フェッチ）」としても知られる）と、コードのアクセス又は取り込みとを区別できる。更なる詳細については付録１を参照されたい。コードの取り込みではなくデータの取り込みを使用したチェックサムを実行しているので、自己検査システムは攻撃を受けやすい。尚、コードの取り込みはその処理中にコードだけを取り込めるので、コードの取り込みから自己検査機構を構築する方法がない。すなわち、自己検査機構を構築する取り込みは常にデータの取り込みである。ＭＭＵ攻撃は、データの取り込みと関連する物理場所においてコードのハッキング前であって改変前のバージョンを生成することによりこの攻撃の受けやすさを利用する。従って、自己検査システムがチェックサムを実行している時に、システムはコードのハッキング前のバージョンに対してチェックサムを実行する。しかし、実行されるコードはハッキング後のコードであり、データの取り込みではなくコードの取り込みを使用してのみアクセスされる。自己検査システムは、ハッカにより改変されたコードの並列化・実行可能なバージョンの存在を完全に認識していない。攻撃は時には他の方法、すなわちコードの取り込みを再経路指定しデータの取り込みだけをそのまま残す方法によりなされる。実際には、コード及びデータの取り込みとをともに再経路指定する。
【０００５】
ＭＭＵ攻撃を実現する最も簡単な方法は第１の記載、すなわち検査される改変前のコピーを作成し、元のコードを改変（ハッキング）することである。これは、実行されるコードを移動する他の困難さによるものである。しかし、これらの困難さは、解消することができ且つあるプログラム及び／又はＣＰＵ上には存在しない。従って、コピーを改変して実行し、元のバージョンを検査される未変更のものとすることが妥当なものとなる。
【０００６】
どのバージョンもコピーである場合、共にコピーであること、すなわち元のバージョンは使用せず、改変前のコピー（検査される）と、実行される改変後（ハッキング後）のコピーとを有することも妥当である。
【０００７】
コード及びデータの取り込みを別々に処理するＣＰＵ（又は他の形態の演算装置）の特徴を使用して再生するために、ＭＭＵ攻撃は、プログラムコードの改変前のコピーを保持する別の記憶場所にデータの取り込みを再経路指定することにより簡単に実現できる。自己検査システムは改竄を検出するようにコードに対してチェックサムを実行するためにデータの取り込みを使用するので、検査中のコードは、実際に実行されているコードはなくこの改変前のコピーである。これは、実行中のコードは、コードの改変後（ハッキング後）のバージョンに経路指定されるコードの取り込みを使用するからである。図２は、自己検査システムを妨害するデータの取り込みの再経路指定を示す。
【０００８】
ＭＭＵ攻撃の概念は比較的簡単ではあるが、既存のオペレーティングシステム（ＯＳ）はＭＭＵにこのような方法で構成を通常許容しないので、この概念を実際に実現するのは明らかなことではない。この結果、この種の攻撃は通常カーネル改変を必要とし、あるコンテキストでこの種の攻撃の有用性を制限するエンドユーザにデプロイメント負荷を課すことになる。しかし、マシン仮想化の普及に伴い、エンドユーザはホストＯＳを汚染することなくゲストＯＳに対する攻撃をデプロイできるので、このデプロイメント負荷は減少したままである。ホストＯＳは、「入れ子」仮想化の導入とともにぼやけた感があるが、機器上で実行されるプライマリＯＳである。ゲストＯＳは仮想化の下で実行されるＯＳである。
【０００９】
マシン仮想化は、通常、プラットフォーム仮想化と呼ばれ、「全仮想化」、「ハードウエア支援仮想化」及び「準仮想化(Para-virtualization)」を含むいくつかの実現方法がある。これらの方法は通常、マシンを仮想化する階層により異なる。本明細書の目的のためには、マシン仮想化を実現するこれら異なる方法の相違は特に重要な問題でない。これは、本明細書がマシン仮想化のこれらの実現方法に基づくシステム構成においてある階層に存在するハードウエア特徴を取り扱うからである。
【００１０】
この種の攻撃に伴う大きな問題は、改竄防止システムがＭＭＵを上述したように構成していることを直接検出できない可能性が高いことである。たとえ検出が可能だったとしても、ハッカは、どの特定の改竄防止システムもこの構成を検出不可能であるように個別にこの構成に成りすますのである。「直接検出」は、プログラムコードにより使用されたメモリページがデータアクセス及びコードアクセスを異なる物理場所に経路指定するように設定されていることを判定するためにＭＭＵの状態をクエリすることを意味する。これは、ＭＭＵアクセスを取得するためにＯＳアプリケーション・プログラミング・インタフェース（ＡＰＩ）の使用及び／又はＣＰＵレジスタの使用、並びにＭＭＵによりページマッピングを実現するために使用するメモリ内データ構造のアクセスを含む。この種のマッピングは通常殆どのＯＳにより支持されていないので、ＭＭＵ攻撃が存在することを判定するプログラムに対する必要な情報を提供するＯＳ  ＡＰＩが存在しないようである。
【００１１】
全般的な広い視点からは、ＭＭＵ攻撃を回避することができない。参考文献は、Ｇ．  Ｗｕｒｓｔｅｒ，  Ｐ．  Ｃ．  ｖａｎ  Ｏｏｒｓｃｈｏｔ，  Ａ．  Ｓｏｍａｙａｊｉ：  ”Ａ  ｇｅｎｅｒｉｃ  ａｔｔａｃｋ  ｏｎ  ｃｈｅｃｋｓｕｍｍｉｎｇ−ｂａｓｅｄ  ｓｏｆｔｗａｒｅ  ｔａｍｐｅｒ  ｒｅｓｉｓｔａｎｃｅ”．  Ｔｅｃｈｎｉｃａｌ  Ｒｅｐｏｒｔ  ＴＲ−０４−０９，  Ｃａｒｌｅｔｏｎ  Ｕｎｉｖｅｒｓｉｔｙ，  ２００４年１１月である。  Ｇ．  Ｗｕｒｓｔｅｒ，  Ｐ．  Ｃ．  ｖａｎ  Ｏｏｒｓｃｈｏｔ  ａｎｄ  Ａ．  Ｓｏｍａｙａｊｉ：  ”Ａ  ｇｅｎｅｒｉｃ  ａｔｔａｃｋ  ｏｎ  ｃｈｅｃｋｓｕｍｍｉｎｇ−ｂａｓｅｄ  ｓｏｆｔｗａｒｅ  ｔａｍｐｅｒ  ｒｅｓｉｓｔａｎｃｅ  −  Ｓｌｉｄｅｓ”  Ｉｎ  ＩＥＥＥ  Ｓｙｍｐｏｓｉｕｍ  ｏｎ  Ｓｅｃｕｒｉｔｙ  ａｎｄ  Ｐｒｉｖａｃｙ，  ２００５年５月，  １２７〜１３８ページ；  及びＰ．  Ｃ．  ｖａｎ  Ｏｏｒｓｃｈｏｔ，  Ａ．Ｓｏｍａｙａｊｉ  ａｎｄ  Ｇ．  Ｗｕｒｓｔｅｒ：  ”Ｈａｒｄｗａｒｅ−ａｓｓｉｓｔｅｄ  ｃｉｒｃｕｍｖｅｎｔｉｏｎ  ｏｆ  ｓｅｌｆ−  ｈａｓｈｉｎｇ  ｓｏｆｔｗａｒｅ  ｔａｍｐｅｒ  ｒｅｓｉｓｔａｎｃｅ”  ＩＥＥＥ  Ｔｒａｎｓａｃｔｉｏｎｓ  ｏｎ  Ｄｅｐｅｎｄａｂｌｅ  ａｎｄ  Ｓｅｃｕｒｅ  Ｃｏｍｐｕｔｉｎｇ，  ２００５年４月〜６月も参照されたい。
【００１２】
他の背景概念
リバースエンジニアリングを困難にするか又はユーザの製造業者の意に反した改変（例えば、使用法に関する制限を取り除くこと）を防止する手段を含む場合には、ソフトウエアは改竄を防止できると言われている。共通に使用される方法の一つはコードの難読化（code obfuscation）である。
【００１３】
難読化コードは、通常、意図的に読んだり理解したりすることが非常に困難なソースコード又は中間言語である。ある言語は他の言語より難読化の傾向が強い。Ｃ、Ｃ＋＋及びＰｅｒｌは容易な難読化言語である。標準言語構文及び文法をコードの本体からマスクすることによって難読コードを作成するプリプロセッサが通常使用される。
【００１４】
難読化プログラムは、主にリバースエンジニアリング、逆アセンブル又は逆コンパイルを阻止する目的でソースコード及び／又はオブジェクトコードを処理する。リバースエンジニアリングを防止する難読化コードは、通常ソースコードへの非認証アクセスから生じる危険性を管理するために実行される。これらの危険性は、知的財産の損失、アプリケーションの脆弱性の厳密な調査及びアプリケーションがリーバースエンジニアリングされ、計量又は使用料制御を回避するように改変され且つ再コンパイルされた結果である総収入の損出を含む。難読化コードはこれら危険性を管理するための補償制御コードである。
【００１５】
しかし、ソフトウエアの効果的な改竄防止は、ソフトウエア環境がエミュレーションの使用により殆ど任意に操作されるので、ハードウエアのものより困難である。
【００１６】
トラスティッド・コンピューティング（ＴＣ）はＴｒｕｓｔｅｄ  Ｃｏｍｐｕｔｉｎｇ  Ｇｒｏｕｐにより開発・推進された技術である。用語は、トラスティッド・システムの分野から取られ、特別な意味を持つ。トラスティッド・コンピューティングを使用して、コンピュータは特定の方法で一貫して挙動し、これらの挙動はハードウエア及びソフトウエアにより実施される。このトラスティッド挙動の実施は、一意のＩＤ及び一意のマスタキーでハードウエアをロードし且つコンピュータの知識の所有者や自身のマスタキーの制御さえ否定することにより達成される。ハードウエアが所有者にとってただ単に安全なものではないので、トラスティッド・コンピューティングは論争の的になるが、トラスティッド挙動の実施は所有者に対して安全であるという意味を持つ。
【００１７】
ユーザはリモート認証やシールドストレージをバイパスするためにトラストチップをハッキングして偽証明書を発行する必要があるので、トラスティッド・コンピューティングが実施されると、トラスティッド・コンピューティングは少なくともハードウエア改竄と同様に困難な保護プログラムのソフトウエア改竄を実行することになる。しかし、現在の仕様では、トラストチップが非常に複雑なあらゆる物理的攻撃に対して改竄防止する期待ができないのは明らかである。すなわちトラストチップは改竄防止装置と同様の安全性を確保するものではない。
【発明の概要】
【発明が解決しようとする課題】
【００１８】
本発明は、コードアクセス及びデータアクセス／取り込みが同期している時のみプログラムコードを改変して正しく実行するように、すなわちデータアクセス及びコードアクセス／取り込みがコンピュータメモリの同一物理アドレスに経路指定されるようにコンピュータプログラムコードを保護する方法である。
【課題を解決するための手段】
【００１９】
一実現例において、本発明は、同一の論理アドレスへのコード及びデータのメモリアクセス／取り込みが異なる物理アドレスに経路指定されるＭＭＵ攻撃を間接的に打破する方法である。データアクセス及びコードアクセスが同一の物理メモリアドレスに経路指定される時のみ正しい挙動を示すように動作させるために保護されるプログラムを改変することにより上記の方法は達成される。ＭＭＵ攻撃で発生することではあるが、データアクセス及びコードアクセスが異なる物理アドレスに経路指定される場合、プログラムは間違った挙動を取ることになる（完全なクラッシュの可能性を含む）。防御によりＯＳ又は直接ハードウエアクエリを介してあらゆるＭＭＵ情報に特定的にアクセスしないため、「間接的」という方法はＭＭＵ攻撃を打破する。間違った挙動は、ユーザが気が付かない微妙なバグから完全な修復不可能なプログラムクラッシュまであらゆるものを含む。ＭＭＵ攻撃の検出を議論する時に、間違った動作を行うコードは、クラッシュに関与しているのではなく、ＭＭＵ攻撃の存在を示すための信号値（又は非信号値）を記憶場所に書き込ませる（又は書き込ませない）。
【００２０】
この挙動を達成するために、そのままでは動作しないプログラムを作成するために１つ以上のコードセクションを改変するように、すなわちこれらのコードセクション（修復対象と呼ばれる）を意図的に破壊するようにプログラムを改変する。プログラムに修復プローブを注入してこれらの改変後のコードセクションを実行時に正しいコードに置換する。各置換は実行中の関連する修復対象より前のある時間に行われる。「コード」という用語を使用する場合、コードは、Ｊａｖａ（登録商標）及びＣ＃のバイトコードやスクリプト言語のソースコードと同様にあらゆる実行可能な２値コードを含む。また、コードを「注入する」とは、ソースコードへの注入を意味するが、実行可能な２値バイトコード又はその他の適切なプログラム表現形態への注入も含むように一般化される。
【００２１】
修復対象及び修復プローブを使用する技術は共有ライブラリ保護方式の一部としても使用される。多くのＯＳを使用して、アプリケーションは、実行時に動的にロードされ且つアプリケーションに結合される共有ライブラリにコードの一部を配置する。Ｗｉｎｄｏｗｓ（登録商標）では、これらの共有ライブラリはダイナミックリンクライブラリ（ＤＬＬ）と呼ばれ、Ｕｎｉｘ（登録商標）／Ｌｉｎｕｘ（登録商標）では、ダイナミックシェアドオブジェクト（ＤＳＯ）と呼ばれる。共有ライブラリでコードを保護する場合、１つの方法は、検査を実行しているコードが別のモジュール（メイン実行可能な又は別の共有ライブラリ）に存在するメモリのこの共有ライブラリの内容を検査することである。
【００２２】
ハッカは単一のモジュールよりも独立したモジュール間のリンクを悪用する機会が多いため、このようなリンクにわたり検査されているコードがこれからも実行されることを保証する必要がある。
【００２３】
同一の修復・損傷ノード機構は、このようなリンク上のいかなるコードもＭＭＵ防御について記載されたと同様な方法で実行中・検査中のコードである。
【００２４】
動的な修復ノード（後述）は改竄防止システムと組み合わせることができるが、より適切には本発明の改竄防止システムと組み合わせることができる。本明細書中で上述したように、動的な修復ノードは、ハッカによる修復の静的解決法を妨害する手段として関数パラメータをコード改変体に変換する。同様に、本発明の改竄防止システムは、チェックサムが正しい場合にコードが正しく実行するように、チェックサム結果をコードの書き込みに変換できる。これらの２つの方式は、コードの書き込みが同時に２つの目的となるように組み合わせることができる。
【００２５】
これにより、プログラムは通常の環境で正しく機能するだろう。しかし、プログラムがＭＭＵ攻撃を受けた場合、コード置換はプログラムの改変前実行不能コピーにのみ経路指定される。従って、実行中のハッキングされたコードは置換されず、プログラムは誤動作する。これは、正しいコードが実行中のハッキングされたコードの中にないためである。これは、コード置換がコードの取り込みではなくデータの取り込みを使用しデータを取り込むがコードの改変前のバージョンに経路指定されたためである。
【００２６】
データの読み取りが元の改変前のコードに経路指定され、データの書き込みがハッカのプログラムの改変後のコピーに経路指定され、これにより実際に実行中のコードに対して修復がなされるように、メモリアクセスを分割し且つデータの書き込み及び読み取りを分割することにより本発明の防御を妨害しようとするＭＭＵ攻撃（すなわち、これはハッカが本発明の防御に直面した時に試みることである）に対する拡張もまた想像できる。本発明の解決方法は拡張された攻撃法に対する防御を更に含む。
【００２７】
要するに、本発明の解決方法によれば、ＭＭＵ攻撃をデプロイしたいハッカは以下のオプションを利用できる。
・ハッカの改変後のコピーが正常に動作しているコードに基づくようにプログラムの改変後のコピーにコード置換を構築できる方法を探し出すこと．
○  これが可能であったとしても、本発明によりこれを技術の組み合わせで達成することは実際に困難となる。
・２つのコピー上の修復対象が同時に修復されるように、プログラムの２つのコピーへのデータの書き込みを経路指定できる機構を実現すること．
○  既存のＭＭＵハードウエアがそのような機能性を提供することは知られていない。従って、プログラムの２つのコピーに同一のデータを書き込み可能とする例外をプログラムメモリページへのデータの書き込みで生成することによりソフトウエアにこの機能性を現時点では実現する必要がある。これは通常プログラム実行速度に大きな影響を及ぼし、本明細書中ではそれを実際の攻撃とは考えないこととする。
【００２８】
本発明の解決方法を拡張し以下のものを支持する。
・本発明の間接的な非検出機構を介してＭＭＵ攻撃を実際に検出すること．
・静的コード置換によりシミュレート不可能であるためハッカにより取り除くのが困難になる動的な修復ノード」である特別な種類の修復ノード．
【００２９】
本発明は、設計及び実現するのに使用した原理・方法という意味で更に新規なものである。改竄防止の分野で使用される代表的な方法は「検出及び応答」解決方法を考案することである。検出及び応答方法は言葉上は簡単に思える：攻撃又は望ましくない挙動を検出すること及びプログラムを停止するか又はその他の報復行為を取ることにより応答すること。本明細書ではこれを実施しない。その代わりに、本発明の原理によれば、ハッカが攻撃を実現するために必要とされるリソースを使用するか又はプログラムがある基本的なレベルで攻撃と相いれない方法でプログラムを挙動させることより、ハッカが自分の攻撃をデプロイし難くする第１の調査方法が導出される。リソースは、プログラムにより使用可能なレジスタ、割込み、命令、メモリ及びＯＳコード等を含むハードウエア及びソフトウエアである計算リソースである。攻撃とは相いれない方法でプログラムを挙動させることは、本発明の好適な実現例として記載した特定の形態を含む多くの形態を取ることができる。実際には、リソースの使用（前者の方法）がこの形態であると議論できる。
【００３０】
この場合最も効果的であることが判明した後者の方法によれば、同一の物理アドレスに経路指定中のコードアクセス及びデータアクセスに頼る方法でプログラムを挙動させることにより、プログラムを基本的にＭＭＵ攻撃による挙動変化とは相いれないものとする。従って、本明細書中に例示される更なる発明は、（ａ）攻撃を実現するのに必要なリソースを使用するステップと（ｉｉ）攻撃とは相いれない方法でプログラムを挙動させるステップとを含むソフトウエアプログラム改竄防止技術である。
【００３１】
技術的利点の概要
１．  本明細書で説明した方法はＭＭＵ攻撃に対する一意の公知の防御である。全ての自己検査改竄防止システムは効果を持続するためにこのような（又は類似の機能を有する）防御を必要とする。
２．  本明細書中で説明した方法は間接的にＭＭＵ攻撃を打破する。これによりハッカは防御を容易に除去できる範囲がなくなる。（例えば成りすましは使用できなくなる。成りすましは、ハッカが正規のリソースのプログラム使用をハッカ自身のコードを介して再経路指定し、且つリソースを使用する方法を改変し且つ／又はリソースから戻るあらゆる情報を改変するハッカ共通の技術である。例えば、ハッカはＯＳの関数が他の日付を戻すように、今日の日付を返すＯＳ関数に対して成りすましている。）
３．  本明細書で説明した方法は、現時点では実際に見られないＭＭＵ攻撃の可能な拡張形態を打破する。
４．  本明細書で説明した方法の障害点は単一ではない。すなわち機構は時間的・空間的に効果的に分散され、ハッカはＭＭＵ攻撃を再度有効にするために全ての段階で改竄を有効にする必要がある。
５．  防御機構はＭＭＵ攻撃を間接的に打破するが、この機構は攻撃を検出するために使用される。
６．  ＭＭＵ攻撃に対する全ての可能な具体的な防御は基本的にはこの方法に類似する。この方法は、プログラム自身に対するプログラムの低レベルの意味に対するＭＭＵ攻撃の影響の基本的性質を使用する。ＭＭＵ攻撃はデータ及びコードの取り込みを分離させるので、これらが分離された場合にコードが正しく構築されず間違って挙動するように、コードをデータの取り込みを使用して構築する。換言すれば、ＭＭＵ攻撃が存在する場合に機器のメモリサブシステムの低レベル挙動を開示するために、データ及びコードの取り込みを同一の記憶場所で文字通り使用する。同様な開示を達成する目的の他の機構は、取り込みの詳細な構成が異なるが同一の記憶場所にデータ及びコードの同期した取り込みの形態を使用する必要がある。これらの機構は本発明の範囲に含まれる。ＭＭＵ攻撃を検出したり防御したりする全ての他の考え得る方法（上述の開示を使用しない）は、ＭＭＵ攻撃が存在し且つハッカがいかなる方法をも打破すると思われる場合には、機器の挙動と基本的に相いれない性質を持たない。これらの方法は実際の防御を構成するとは思われない。
【００３２】
本発明の他の態様は以下の通りである。
・システムが上述の方法を実行するように動作可能であるコンピュータプログラムコードを保護するコンピュータにより実現されたシステム．
・コンピュータ上で実行された場合、上述の方法をコンピュータに実行させることを可能にするコンピュータ可読媒体上に格納されたコンピュータソフトウエアプログラム．
・上述したコンピュータにより実現されたシステムによる改変されたコンピュータソフトウエアプログラムか又は同一の論理アドレスへのコード及びデータの取り込みが異なる物理アドレスに経路指定される攻撃を継続して回避するような上述のコンピュータソフトウエアプログラム．
【図面の簡単な説明】
【００３３】
【図１】図１は、他のコードを検査するコードを使用した自己検査システムを示す図である。
【図２】図２は、自己検査システムを妨害するためのデータの取り込みの再経路指定を示す図である。
【図３Ａ】、
【図３Ｂ】図３Ａ及び図３Ｂは、通常の実行環境、並びにコードアクセス及びデータアクセスがそれぞれに経路指定される環境におけるコードの影響を示す図である。
【図４】図４は、汎用コード上の修復ノード（修復対象及び修復プローブ）の構造を示す図である。
【図５】図５は、基本防御を打破するためのデータの読み取り及び書き込み分離を示す図である。
【図６】図６は、ＭＭＵ攻撃の打破を説明するシーケンスを示す図である。
【図７】図７は、修復の発生前後に得られる種々のチェックサムを使用した修復対象を範囲に含む自己検査システムを示す図である。
【図８】図８は、修復ノードを検査することにより、拡張ＭＭＵ攻撃がどのように打破されるかを示す図である。
【図９】図９は、修復対象を回避する検査を示す図である。
【図１０】図１０は、複数の関数から呼び出される修復対象を含む関数を示す図である。
【図１１】図１１は、関数Ａ及びＢに対する呼び出しを示す図であり、関数Ａは実行されなくてもよいが関数Ｂは実行される。
【図１２】図１２は、修復ノード及び導出された静的呼び出し順序を示す図である。
【図１３】図１３は、修復ノード及びその損傷プローブの位置を示す図である。
【図１４】図１４は、フラグを設定する「間違った」コード対修復されたコードを示す図である。
【図１５】図１５は、動的な修復ノードを示す図である。
【発明を実施するための形態】
【００３４】
基本
ＭＭＵ攻撃に対する防御は、攻撃が何らかの基本的な方法で（攻撃が明白な高水準の影響を全く及ぼさない場合であっても）保護プログラムの挙動を変化させる必要があるため、プログラムをそのような変化と相いれないものにさせることができなければならないという概念に基づいて動作する。
【００３５】
ＭＭＵ攻撃の場合、プログラムが実行する処理環境は、同一の論理アドレスのコードアクセス及びデータアクセスが互いに異なる物理アドレスに経路指定されるように変化する。「処理環境」という用語は、プログラムが実行中のコンピュータシステムの基本状態を意味する。この変化は、代表的なプログラムの明白な挙動に影響を及ぼさないが、異なる低水準の挙動には影響を及ぼす。上述したように、ＭＭＵ攻撃を受けている間、自己検査システムにより使用されたデータアクセスがハッキング前のコードに経路指定されるため、自己検査は改竄を示せない。しかし、実行中のコードにおいて使用されたコードアクセスは、ハッキング後のコードの代わりに経路指定される。しかし、挙動におけるそのような変化と相いれないプログラム、すなわち同一の論理アドレスのコードアクセス及びデータアクセスが互いに異なる物理アドレスに経路指定されるプログラムを構成できる。
【００３６】
一例として、次に示すＩｎｔｅｌ  ｘ８６命令（「ｘ８６」はＣＰＵのそのファミリーに対して共通に使用される用語であるが、「Ｉｎｔｅｌ  ｘ８６」アセンブリ言語に関するあらゆる記載は、一般にＩｎｔｅｌ  ８０３８６及びそれ以降のＣＰＵを意味する）について考える。
ｍｏｖｅ  ｅａｘ，  ＡＢＣＤ１２３４ｈ
【００３７】
この命令は、１６進数の値であるＡＢＣＤ１２３４をｅａｘレジスタに移動させるものである。使用するための命令及び値の双方は、コードの取り込み（データの取り込みとは対照的に）としてＣＰＵにより取り込まれる。命令は、ＭＭＵ攻撃を受けている間も通常の実行環境下と同じように挙動する。
【００３８】
論理アドレスから物理アドレスへのどんなマッピングが上記のコードと関連する場合でも、本明細書においてコードの取り込みのみが発生するため、そのマッピングにおける命令の取り込み部分のみが使用される。ＭＭＵ攻撃が存在し、且つこの命令の論理アドレスのデータの取り込みをコードの取り込みにより使用されたものとは異なる物理アドレスにマッピングした場合であっても、本明細書においてデータの取り込みを伴わないため、ＭＭＵ攻撃は全く影響を及ぼさない。
【００３９】
さて、ここで以下のコードについて考察する。
ｍｏｖ  ｅｂｘ，  ＦＦＦＦ００００ｈ
ｌｅａ  ｅｓｉ，  ＤＷＯＲＤ  ＰＴＲ［ｌａｂｅｌ  ＋  １］
ｍｏｖ  ＤＷＯＲＤ  ＰＴＲ［ｅｓｉ］，  ｅｂｘ
ｌａｂｅｌ：
ｍｏｖｅ  ｅａｘ  ＡＢＣＤ１２３４ｈ
【００４０】
以前からのｍｏｖ命令が依然として存在するが（最後の命令として）、そのｍｏｖ命令を実行する前に、ｍｏｖ命令前のコードがＡＢＣＤ１２３４ではなくＦＦＦＦ００００の値を使用する命令を改変するため、命令がＦＦＦＦ００００をｅａｘに移動させるようにする。コードの最初の３行は、最後の命令の実際のプログラムコードを改変することになる。これは、通常「自己改変コード」と呼ばれる。
【００４１】
このコードが通常の実行環境下で実行される場合、ｅａｘがこのコードの最後に値ＦＦＦＦ００００を含むことが予想される。しかし、データアクセス（コードアクセスとは対照的に）が実行されないプログラムの別のコピーに経路指定されるように実行環境が改変されている場合、最後に実際に実行される命令は改変されておらず、且つｅａｘはプログラムが実行するように設計されたものではない値ＡＢＣＤ１２３４を与えられるだろう。命令を改変するために使用されたデータの書き込みが、実行しようとしているコードのコピーではなくコードの他のコピーに経路指定されているため、命令は改変されていないだろう。従って、実際に実行するコードにおいてではないが、改変は発生する。ＭＭＵ攻撃が存在する場合に使用されるものであり、且つこの場合は間違った値であるＡＢＣＤ１２３４の値を元のコードが使用したため、異なる値を使用するためにそれを改変したかった。結果として得られる間違った値は、プログラムの挙動に僅かに影響を及ぼすか又は値がどのように使用されるかに依存して壊滅的な影響を及ぼす可能性がある。
図３Ａ及び図３Ｂは、通常の実行環境、並びにコードアクセス及びデータアクセスがそれぞれ経路指定される環境におけるコードの影響を示している。この例により、コードアクセス及びデータアクセスが分離されているため同期されていない環境、すなわち異なる物理アドレスが同一の論理アドレスを共有するコードアクセス及びデータアクセスに対して使用される環境においてプログラムが実行される場合、単一の形態の自己改変コードがどのようにプログラムに障害を起こすかを示す。この技術は、ＭＭＵ攻撃に対する防御の基礎を形成する。コードアクセス及びデータアクセスは、本発明の実現例において同期される必要がある。すなわち、物理アドレスと論理アドレスとの間のマッピングは適合しなければならない。ＭＭＵ攻撃において発生するように、物理アドレスと論理アドレスとの間のマッピングが適合しない場合、実行され且つハッキングされたコードは正しく実行しないだろう。明確にするために、論理アドレス及び物理アドレスは互いに適合する必要はない（実際には殆ど適合しない）が、論理アドレスと物理アドレスとの間のマッピングは、データの取り込みに対するものと同一のコードの取り込みでなければならない。
【００４２】
例えば、４００，０００の論理アドレスは、８００，０００の物理アドレスにマッピングしてもよい。しかし、それがコードの取り込みに対してのみ当てはまる場合、論理アドレス４００，０００におけるデータの取り込みは９００，０００の物理アドレスにマッピングされるが、その２つは本発明の定義では「同期」されない。
【００４３】
技術の一般化
全てのプログラムコードが単にデータの形態であることを認識することにより、上記の簡単な例において使用された技術を一般化した。ｍｏｖ命令において使用された値を改変したが、代わりに命令自体を改変できたかもしれない。実際に、命令の元のコピーがｍｏｖ命令である必要は全くない。すなわち、命令の元のコピーは、実行される前に正しい命令に置換されるため、ランダムデータで構成されてもよい。「ランダムデータ」という用語は、特に乱数又は擬似乱数発生器により生成されたデータではなく、「あらゆるデータセットの値」を意味する。
【００４４】
これを念頭において、自己改変コード技術の内容を殆ど考慮せずにその技術をあらゆるプログラムコードに対して使用できる。あらゆる所定のコードに対して、コードのあるバイト数に間違った値を上書きし（コードを修復対象と呼ぶ）、修復対象が実行される前のある時間にこれらの間違った値を実行時に正しい値に置換する別のコード、すなわち修復プローブを注入する（プローブ配置は後で更に詳細に説明される）。間違った値は、正しい値（明らかに）又は同一の影響を及ぼす（すなわち、いくつかのＣＰＵ上の同一の機能性を表現する複数の方法がある場合）コードの実行をもたらす値を除くあらゆる値であってもよい。この修復対象と修復プローブとの組合せ（及び他のあらゆる関連要素）を修復ノードと呼ぶ。
【００４５】
図４は、汎用コード上の修復ノード（修復対象及び修復プローブ）の構造を示す。この一般化された方法を使用することにより、対象プログラム内のあらゆる場所で技術を何回でも簡単に適用できる。
【００４６】
ＭＭＵの読み取り及び書き込み区別の処理
データの読み取りと書き込みとを区別できるＭＭＵを含み、且つデータの読み取り及び書き込みを別個の物理場所に再経路指定するためにこれを使用するコンピュータシステム上において、上述したような修復ノード方式は、ＭＭＵ攻撃の拡張形態でハッカにより回避動作される。
【００４７】
このため、ハッカは、データの書き込みを命令（すなわち、コード）の取り込みと同一の物理場所に経路指定し、引き続きデータの読み取りをプログラムの改変前のコピーに経路指定する。修復プローブは、このマッピングを用いてハッカのプログラムの改変後のコピーを修復する。これが実行中のプログラムのコピーであるため、プログラムは正しく実行する。図５は、基本防御を打破するためのデータの読み取り及び書き込み分離を示す。
【００４８】
元の防御を誘発した同一の原理を使用して、この攻撃に対して防御するように方式を拡張した。プログラムが正しく動作するためにデータアクセス及びコード／命令アクセスが同一の物理場所に経路指定されることのみを要求するのではなく、プログラムが正しく動作するためにデータの読み取り、データの書き込み及び命令の取り込みが全て互いに同一の物理場所に経路指定されるという更に特定の要求を課す。これは、基本的な見識であり且つ本発明の方法の一態様である。
【００４９】
目的を達成するために、プログラムコードを読み取り且つ書き込む修復プローブの変形例を導入することによりこれを達成する。この場合、書き込みのうちの少なくとも１つは読み取りのうちの１つに依存する。
【００５０】
例えば、サイズが２バイトの修復対象を有する場合、簡単な方法は、関連する修復プローブが２バイトの正しいコードを逆順序で修復対象に書き込み、その後２バイトの修復対象メモリに対して後続の逆動作を実行することだろう（修復対象メモリは、「修復対象」とも呼ばれる）。これを実行することにより、データの読み取り及び書き込みの双方が経路指定される場所に依存して最後に修復対象に配置されるコードを作成する。データの読み取りが元の改変前のコードに経路指定されるが、データの書き込みがハッカのコードの改変後のコピーに経路指定される場合、上記の例に対して以下のことが発生する。
１．  ２つの正しいバイトの最初の書き込みは、ハッカのコードのコピーに経路指定される。これらは逆順序であるため、この時点では間違っている。
２．  最後の逆動作に対する２バイトの読み取りは、ハッカのコードのコピーにおける（正確であり且つ逆にされた）２バイトからではなく、元の（未定の）コードから２バイトを取り込む。
３．  逆動作後の２バイトの最後の書き込みは、２バイトの元の（未定の）コードをハッのコードのコピーに書き込む。
４．  ハッカのコードのコピーは、正しく実行できない。
【００５１】
図６は、ＭＭＵ攻撃の打破を説明するシーケンスである。説明するバイト逆動作は、あるコードを修復対象に書き込み、同一のコードのうちの一部を再度読み取り且つそれを再度書き込む（場合によっては異なる場所に、場合によっては何らかの方法で改変されて）ことにより、データの読み取り及び書き込みの双方が保存される値に対して同一の物理場所に経路指定されることを要求する書き込み後読み取りシーケンスに依存して、最後のコードのうちの一部を修復対象に書き込ませるために本明細書において使用される基本原理の単なる一例である。実際には、ハッカがパターンに基づく探索を介して修復プローブを探し出すのを阻止するために、この方式のより多くの変形例を使用する。
【００５２】
本明細書におけるメタ規則は、最初の書き込みは最後の（正しい）データを含んではならないというものである。すなわち、これは、後続の読み取り書き込み動作において構築されなければならない。逆動作は、最初にバイトを間違った位置に書き込み、次にそれらを再度読み取り且つ正しい位置に書き込むことで逆にすることにより、これを保証する。
【００５３】
バイトを逆にすることと同様に、データを再度読み取り且つ正しい順序で再度書き込むことにより後続されたあらゆる間違った順序の書き込みは、同一の効果を達成する。例には、奇数バイトと偶数バイト（あるいは、ワードレベル又はビットレベル等のあらゆるサイズ）とを入れ替えてそれらを修復すること、及びそれらを不規則な順序で書き込んで修復することが含まれる。
【００５４】
最初に間違った順序を使用するのではなく、データは、間違って書き込まれ、次に後続の読み取り改変−書き込みパスに修復される。例えば、それを書き込む前に書き込まれた各値から１を減算し、データの部分毎に正しい値が得られるようにそれを１で増分して（増分は、値を読み取り、改変及び書き込みする必要がある）各値にわたり第２のパスを実行する。そのような改変の他の例には、各値からあらゆる数（又は一連の数）を減算し且つ後続のパスにおいて減算された量を再度加算すること、同様に加算して加算された量を再度減算すること、それを書き込む前に各値であらゆる数を排他的論理和演算し（ｘｏｒ）、後続のパス上で再度値をｘｏｒすること（あらゆる値を用いて２重にｘｏｒすることにより、元の値が得られる）、書き込まれた各値においてこれらのビットをフリップし且つその後後続のパスにおいて１つ以上のビットをアンフリップすること、それを書き込む前に各値に適用された他のあらゆる可逆的算術演算、論理演算又はビット演算を行い且つその後事前に格納された値を読み取り、改変及び書き込むことにより動作を逆にする後続パスが続くことが含まれる。上記の方法のあらゆる組み合せは、単一の修復ノード内で更に使用される。
【００５５】
改竄防止システムとの対話
改竄防止システムは、主に修復ノードが依存する種類のプログラム改変を阻止するように設計されるため、修復ノードを改竄防止システムにより保護されたプログラムに単純に注入することにより、プログラム機能に伴う問題が発生する可能性が高い。従って、殆どの場合において、基礎となる改竄防止方式が修復ノードを支持するように改変されることが必要である。
【００５６】
メモリにおけるコードの内容を予測値と比較する（他の比較方式が更に使用されてもよいが、通常はチェックサム比較を介して）ことによりコードの保全性を判定する自己検査改竄防止方式がある状態で方法が実現されてもよい。この種のあらゆる方式の場合、一般にプログラムコードは合法的に改変されないことが仮定される。修復プローブ（及び損傷プローブ）がコードを変化させるため、この仮定は、修復ノードによりアドレス指定されるコードのこれらの領域に対して偽である。従って、代表的な自己検査改竄防止方式は、修復ノードがその内で動作する場合に違法なプログラム変更を検出する。尚、これは必ずしも保証されない。自己検査システムに依存して、全てのコード変更が即座に検出されず、ある一時的なコード変更は、非常に短期間である場合には全く検出されなくてもよい。図７は、修復の発生前後に得られる種々のチェックサムを使用した修復対象を範囲に含む自己検査システムを示す。
【００５７】
この問題に対して、以下のことを含む多数の解決方法がある。
１．  修復対象を含むコードの領域が、一方が修復される前のコードを範囲に含み且つ他方が修復された後のコードを範囲に含む２つのチェックサムに適合できるように自己検査システムを拡張する。
２．  自己検査方式があらゆる所定の修復対象に対して修復前又は修復後のコードのいずれかのみを確認するように、連係して自己検査方式及び修復ノード方式を構築する。
３．  修復対象を範囲に含まないように自己検査方式を構築することにより、修復対象に含まれたコードが自己検査機構をトリガせずに任意に変更できるようにする。
【００５８】
第１の解決方法の場合、２つの有効なチェックサムのうちのいずれかが適合することにより、コードが有効であることを自己検査システムに納得させる。検査されたメモリの領域内の単一の修復対象の場合、これは、公知の限られたコストを使用した妥当な解決方法のように思われる。しかし、各修復対象が２つの値を有するため、修復対象を検査されたメモリの領域にそれぞれ追加することにより、検査対象の有効なチェックサムの数が倍増する。これは、メモリの領域内の各修復対象がそのメモリの領域において他の修復対象に関係なく修復された／修復されていない状態にあると仮定する。これは、実際に有効な仮定である可能性が高い。
【００５９】
従って、検査されたメモリのあらゆる領域内に存在する修復対象の数が可能な限り少なく保持されること、可能であれば単一の修復対象と同じくらい少なく保持されることが重要である。これに対処するために、自己検査機構は、検査するメモリの領域が少数の修復対象のみを含むように修復対象の場所を認識できなければならない。
【００６０】
全ての自己検査機構がこの制限に対処するようにされるわけではない。使用する機構はこれを可能にするが、機構は、自己検査機構により使用された検査領域の数及びサイズに影響を及ぼし、その結果、生成する自己検査トポロジの品質に悪影響を及ぼす。例えば本発明の自己検査機構は、検査されたメモリの単一の領域内でいくつかの関数（又は多数の関数）を範囲に含むのはどれかを検査する。これらのいくつかの関数のうちの各々が修復対象を含む場合、検査されたメモリの領域毎の修復対象の数を１に制限する場合にそれらに対してそのように多機能検査するのは不可能だろう。
【００６１】
このため、この特定の解決方法を本発明の特定の自己検査機構と共に使用するのは好ましくないが、他の自己検査機構と共に使用するのは適切な解決方法である可能性があることを提案する。
【００６２】
第２の解決方法の場合、自己検査システムが、関連するコードが予測状態（修復されたか又は修復されていないかのいずれか）にあることが保証される場合にのみ検査が行われるように更なる関数順序保証を導入すること、あるいは検査を実行する（修復／損傷プローブのコピーを検査に効果的に配置する）前に自己検査システムが関連するコードを予測状態にするようにさせることのいずれかを要求する修復前又は修復後のコードのみを見ることを保証する。前者の方法は、アプリケーション全体にわたる関数実行順序の広範囲にわたる確実な知識を必要とするため、実際に実現するには複雑すぎるだろう。対照的に、後者の方法は、関数順序についてはそれ程考慮しないため、実現するのがより簡単である。しかし、修復／損傷プローブを検査に配置することによりハッカがそれらを見つけやすくなる可能性があり、方式全体の有効性が著しく低下する。
【００６３】
前者の方法の複雑な性質及び後者の方法の有効性への未知の影響は、これらの方法が好ましくないことを意味する。ただ、後者の方法を用いると有効性がそれ程低下しない可能性があるため、この解決方法を提案する。
【００６４】
興味深いことに、検査のために読み取られるコードのバージョンに修復が書き込まれず、そのため修復後のコードが自己検査システムにより見られないため、第２の解決方法は、データの読み取り及び書き込みを分割する拡張ＭＭＵ攻撃の影響を受けない（しかし、自己検査方式が修復後のコードを見ることを予測する場合のみ）という１つの利点を有する。これは有用な性質であるが、これを最も魅力的な解決方法にするにはそれ自体では不十分である。図８は、修復ノードを検査することにより、拡張ＭＭＵ攻撃がどのように打破されるかを示す。
【００６５】
第３の解決方法（修復対象を検査するのを回避すること）は比較的簡単であるため、本発明の自己検査改竄防止方式においてそれを好適な解決方法として使用する。この解決方法を使用して、修復対象をスキップすることにより又は自己検査機構により検査されたメモリの領域をあらゆる修復対象のいずれかの側面上で終了させるように配置することにより、自己検査機構が修復対象を検査しないように自己検査機構を改変する。尚、この解決方法は、防御機構実現例に対する変更ではなく、自己検査方式（いかなる自己検査方式であってもよい）に対する変更を要求することが重要である。他の２つの解決方法は、防御機構実現例に対する変更に加えて、自己検査方式に対する変更を更に要求する。
【００６６】
尚、好適な解決方法は、自己検査機構（考え得るあらゆる自己検査機構であってもよい）に対する変更を要求する。実際には、好適な解決方法は、自己検査機構が修復対象を検査するのを回避するという知識において、修復対象を望み通りに簡単に使用する本明細書において説明された方法ではなく、自己検査機構に対する変更のみを要求する（すなわち、修復対象を検査することを回避しなければならない）。
【００６７】
自己検査システムが防御機構ではない自己検査システムのドメインにおいて動作する解決方法を説明しているため、この点が示される。実際、防御機構があらゆる自己検査機構に適用されるため、自己検査機構は、本発明の特定の自己検査機構のドメインになくてもよい。図９は、修復対象を回避する検査を示す。
【００６８】
この方法に対して向けられる可能性のある１つの批判は、この方法は修復対象におけるコードから改竄防止保護を効果的に取り除くが、これは修復機構自体により反撃されるというものである。すなわち、修復対象におけるコードに対して（ハッカにより）成されたあらゆる違法な改変は、それが実行される直前に修復プローブにより（元のコードに）置換されるため、修復対象はいずれにしても効果的に改変の影響を受けない。
【００６９】
この解決方法に伴う別の潜在的な問題は、修復対象を「スキップする」こと又は検査中の領域の構造にいくらか制限を加える可能性がある修復対象の周囲に組み入れられるように検査中の領域を構造化することのいずれかを解決方法が自己検査方式に要求することである。しかし、これらのうちのどちらも本発明の自己検査方式に対して大きな問題を実証していない。実際に、本発明の自己検査方式は、コードの部分が他の理由のためにスキップされるように既に構築されており、自己検査方式の強度をあらゆる顕著な方法で損なっていない。
【００７０】
例えば、本発明の自己検査システムにより、チェックサム中のメモリが単純な隣接するメモリのブロックではなく、メモリ領域の最後に到達するまであるバイト数に対してチェックサムを行い、ある他のバイト数をスキップし且つある他のバイト数を検査等するインタリーブドメモリ領域を使用できる。検査され且つスキップされたバイト数は、メモリ領域にわたり一定であってもよく、ある場合においては不規則に変動してもよく、他の場合においては構築中の現在のチェックサム値に依存して変動してもよい。
【００７１】
この機構を使用して、単に当該修復対象がインタリービング処理の一部として偶然スキップされるように開始アドレス及び／又はインタリービングパラメータを調整することにより、１つ以上の修復対象をスキップする検査対象のインタリーブドメモリ領域を構築する。当然、本発明の自己検査システムを用いてこの種のインタリーブを実行するため、修復対象を更に回避するためにそれを使用することにより、達成するコード検査の有効範囲に大きな影響を及ぼさない。
【００７２】
攻撃に対する障害許容力
要するに、本発明の解決法によれば、ＭＭＵ攻撃をデプロイしたいハッカは以下のオプションを利用できる。
・ハッカの改変後のコピーが正常に動作しているコードに基づくようにプログラムの改変後のコピーにコード置換を構築できる方法を探し出すこと．
・２つのコピー上の修復対象が同時に修復されるように、プログラムの２つのコピーへのデータの書き込みを経路指定できる機構を実現すること．
例えば以下により、これらの残りの攻撃オプションを多数の方法で達成しにくくする。
１．  多数の修復ノードを使用すること。
２．  各修復プローブを相対的固有にさせること。
３．  修復対象に配置された間違ったコードが周囲のコードと調和するようにそれを区別すること。
４．  修復プローブが関連する修復対象の直前ではなく少し前に実行されるようにそれらを配置すること。
５．  あまり頻繁に実行されないコードにある割合の修復ノードを配置すること。
６．  修復対象が実行された後、修復プローブにより行われた修復を取り消す「損傷プローブ」を追加すること。
【００７３】
多数の修復ノード
プログラム全体にわたって分散された多数の修復ノードを使用することにより、ハッカが手動でそれらを除去するのを困難にする。例えば、各ノードが除去されるのに１０分（例えば）必要な場合、１０００ノードは、ハッカ側に対してかなり非現実的なレベルの手動労力を要求するだろう。
【００７４】
更に、多数の修復ノードを使用することにより、プログラムの２つのコピーへのデータの書き込みを経路指定することを性能上の理由のため非現実的にさせる。既存のＣＰＵがこれを直接支持することは知られていないため、ハッカは、当該メモリが書き込まれる場合にトリガされる例外ハンドラ内部のソフトウエアにおいて重複を実現しなければならないだろう。すなわち、これにより、これが要求された各例に大きな性能オーバヘッドが導入されるだろう。より一般的に、例外ハンドラは、ある形態の例外ハンドラ又は割込みハンドラ、あるいは当業者に既知のある他の処理に置換される。ハッカが例外ハンドラを介してプログラムコードを含むメモリページへの全ての書き込みを経路指定しなければならないため、プログラム全体にわたって分散された多数の修復ノードは、この種の攻撃を非常に非現実的にさせる。これは、各メモリページが少なくとも１つの修復ノードを含むことを本発明の修復ノード分散が保証すると仮定する。種々のハードウエア／ＯＳが種々のページサイズを有することにより、必要な分散に影響を及ぼすだろう。
【００７５】
一意の修復プローブ
多数の修復ノードが与えられたとすると、ハッカは、保護されたプログラムが実行するのに必要なコード置換を判定し且つハッカのプログラムの改変後のコピーが更に正しく動作するようにそれを修復するのにコード置換を使用するために、全てのノードを自動的に探し出し且つ解析するツールを作成しようとする可能性が高い。
【００７６】
プローブに対するパターンに基づく探索が全てのプローブを確実に探し出さないように修復プローブ毎に一意のコードを生成することにより、これを非常に困難にさせる。パターンに基づく探索は、これらの署名が公知の例（この場合は修復プローブの例）の解析（通常手動であるが、自動も除外されない）から構築された１つ以上の「署名」パターンに対して探索空間を走査する。１つ以上の特定の構成において十分なパターン適合を含む探索空間のセクション（通常、予測された適合の順序及び／又は適合した部分間の依存関係として規定される）は、探索対象のデータに対する適合であると仮定される。
【００７７】
例えば単一の修復プローブは、コードセクションにおいて場所のアドレスを取得し且つ１つ以上の即値をそのアドレス及び後続のアドレスに書き込み始めるコードから構成されてもよく、これらの同一の場所に対して即値を使用する別の一連の動作により後続される（この最後の部分は、前に説明された読み取り−改変／移動−書き込みパスである）。これらの命令自体はいずれも特に顕著ではないが、コードアドレスの取得は、いくつかのプラットフォーム上の通常のコードにおいては少し珍しいだろう。しかし、これらの命令は、互いに近接して且つ説明された不規則な順序で観察される場合に非常により顕著になるだろう。例えば、コードセクションにおいて即値をアドレスに書き込むことの組み合わせは、通常のアプリケーションコードにおいて発生する可能性が低いため、コードが修復プローブであるという強力な信号を提供してもよい。異なる順序であるが同一の命令の集合又は命令間の依存関係がコードセクションへの書き込みを明確に提案しない同一の命令の集合は、通常、修復プローブの強力な信号ではなく一致する可能性がより高い。
【００７８】
パターンに基づく探索の効果は、探索空間において探索中のデータの冗長性に大きく依存する。探索されるデータの全ての例が一意である場合、パターン規格が全てのどの場合に対してもパターン署名を含む必要があるため、探索点を打破する。すなわち、パターン署名を探し出すためのパターンを構築するために手渡す全ての場合を有する必要がある場合、それらを探し出す必要はない。
【００７９】
例えば、プローブに対して一意のコードを生成するために、組み合わされた場合に完全な修復プローブを形成するコードフラグメントのライブラリからそれらを構築する。不規則な選択を介してフラグメントを組み合わせること及びフラグメントが互いに対して配置される順序を変動することにより、修復プローブ変形例の組み合わせの拡張を達成し、単一のプログラム内の２つのプローブが同一ではないことを保証する。実際に、非常に多数のプローブ変形例を使用することにより、２つのプログラムがいずれの共通の修復プローブを共有しないことをかなり確実に更に保証できる。
【００８０】
損傷プローブ（後で説明される）は、修復プローブと同様に更に一意に生成されてもよい。
【００８１】
プローブ配置
最も簡単な可能な修復プローブ方式は、プログラムが開始する際に全ての修復プローブが実行されるようにそれらをプログラムに注入することである。これは、全ての修復対象のいずれかが発生する前にそれらが修復されることを保証する。しかし、ハッカは、プローブが実行された直後にプログラムのコピーをディスクにダンプすることにより、完全に修復されたコードのコピーを簡単に取得できるため、そのような方式は比較的簡単にハッカに攻撃される。
【００８２】
ハッカは、プログラムをディスクにダンピングする前に全ての修復プローブが実行されることを保証しなければならず、それは著しくより困難なタスクである。従って、これは、プローブが関連する修復対象の直前に配置されなければならないことを提案するだろう。しかし、修復プローブコードと未定の修復対象コードとが互いに隣接して存在することにより、パターンに基づく探索がより実際的になるため、これもハッカが攻撃を構築するのをより容易にするだろう（未定の修復対象コードを偽装してこの可能性を低下させるが）。
【００８３】
このため、一般に、修復プローブが置換する修復対象の直前に修復プローブを配置しない（配置できるが）。これを実行する最も単純な方法は、修復プローブを関数の開始に近接して配置し、且つ同一の関数の下部に近接するどこかに修復対象を選択することである。これを達成するのは非常に些細なことであるが、このレベルの分離は依然として攻撃を受けやすいだろう。従って、本発明の方式は、修復プローブを含む関数が関連する修復対象を含む関数の直前に常に入力されるように、種々の関数においてそれらを配置しようとすることである。プローブ及び対象は、更に同一の関数において存在する。
【００８４】
そのような関数順序を判定するのは非常に困難である。実際に、修復対象を含むあらゆる所定の関数に対して、その直前に常に入力される単一の他の関数は存在しないだろう。すなわち、修復対象を含む関数が呼び出される回数に依存して、いくつかのそのような関数が存在してもよい。図１０は、いくつかの関数から呼び出される修復対象を含む関数を示す。
【００８５】
関数順序の判定に伴う別の問題は、特定の関数を呼び出すあらゆるコードが常に実行されるという保証がないことである。例えば、関数Ａを呼び出し、その後関数Ｂを呼び出す関数Ｘを有する場合、関数Ａに対する呼び出しが常に実行されることを保証できないため、修復プローブを注入するのに関数Ａが適切な場所であることを関数Ｂに配置された修復対象に対して確実に推論できない。例えば、関数Ｘが関数Ａを呼び出さないようにさせてもよいという明らかな論理が関数Ｘに存在しない場合、関数Ａが呼び出されないか又は修復プローブコードを実行しない方法があり、殆どの最新の言語における例外機構はそのような効果をもたらす。図１１は、関数Ａ及びＢに対する呼び出しを示し、関数Ａは実行されなくてもよいが関数Ｂは実行される。
【００８６】
これらの問題を解決するために、以下のことを実行する。
１．  入れ子関数呼び出しのみを介して関数順序を判定する。すなわち、関数Ａが関数Ｂを呼び出す場合にのみ、関数Ａが関数Ｂの前に常に入力されると考える（又は関数Ａが呼び出すあらゆる関数があらゆるレベルの入れ子に対してそのように実行する）。
２．  修復対象を含むあらゆる所定の関数に対して、この関数を呼び出し且つ関連する修復プローブを各関数に注入する全ての関数を判定する。これは、修復対象に対する全ての経路指定が修復プローブにより範囲に含まれることを保証する。
【００８７】
図１２は、本明細書において説明された方式に対する修復ノード及び導出された静的呼び出し順序を示す。
【００８８】
あまり頻繁に実行されないコードにおける修復ノード
ハッカは、パターンに基づく探索を介してプログラムにおいて全ての修復ノードを探し出せない場合、挙動解析を介してそれらを探し出そうとする可能性が最も高い。これを実行する１つの方法は、プログラムコードへの全てのメモリの書き込みが検出及び解析されるシミュレーション環境においてプログラムを実行することである。これを実行する方法は多数あり、その範囲はエミュレーション（超低速）から専用のハードウエア解析器（超高速）にわたる。
【００８９】
この方法に伴うハッカが有する大きな問題は、シミュレーションが全ての修復ノードを探し出したかを知るのが困難なことである。プログラムにおいて最も頻繁に実行されない関数に修復ノードを意図的に配置することにより、これを更に困難にする。それにより、必要な演算時間及びプログラムに含まれた全ての可能な実行をハッカが実行するのに必要な労力の双方の点で、全ての修復ノードを実行する（及び従って明らかにする）のに必要なシミュレーション労力が大幅に増加する。
【００９０】
プログラムにおいて最も頻繁に実行されない関数を判定するために、プログラムの各部分において費やされた時間を測定する一般的な種類のツールである性能観測装置を使用する。殆どの性能観測装置は、各関数が訪問される回数に関する情報を更に提供する。この情報を使用して最も頻繁に実行されない関数を判定する。
【００９１】
損傷プローブ
上述したように、ハッカが修復を行うことを可能にすることによりそのような方式を攻撃し、且つ修復されたコードをディスクにダンプしてコードの改変後のバージョンに対する基礎として使用するため、全ての修復プローブをプログラムの開始時に単に配置しない。
【００９２】
しかし、全ての修復プローブが実行されてコードをダンプすることを保証するのに十分なほど長くハッカがプログラムを実行させる（及び十分なコードの有効範囲で実行させる）場合、同様の問題が発生する。これは実際に達成するのがより困難であり、且つ修復ノードをあまり頻繁に実行されないコードに注入することによりこの攻撃を大幅に緩和するが、それを依然として妥当な攻撃であると考えるため、それをより困難にするするための施策を更に講じる。
【００９３】
この攻撃をより困難にするために、損傷プローブをプログラムに更に注入する。これらは修復プローブに類似するが、間違った値を事前に修復された修復対象に書き込むという逆のタスクを含む。これらは、元の間違った値又は値の新しい集合である。この機構の目的は、全ての修復が実行され且つコードが正常にダンプされるバージョンに最終的に変換するプログラムを阻止することである。プログラムが実行する際に修復を取り消すことにより、プログラムはこの状態に到達できない。
【００９４】
損傷プローブはプログラム動作を補正するのに不可欠ではないため（すなわち、全ての損傷プローブが使用不可であってもプログラムは正しく動作する）、あらゆる所定の修復対象が実行された後に損傷プローブが常に実行することを保証する必要はない。これは、関連する修復対象の前に常に実行されなければならない修復プローブとは対照的である。しかし、修復プローブのように、修復対象の直後に損傷プローブを配置することにより、ハッカがパターンに基づく探索を容易に構築するようになる可能性があるため、これを更に回避する。また、修復プローブ及び関連する損傷プローブを同一の関数に配置することも同一の理由のために望ましくない。
【００９５】
上記を念頭において、一般に、関連する修復プローブを含む関数の上の関数呼び出しパスのどこかに損傷プローブを配置する。すなわち、これは、通常修復プローブより１つ上のレベルであるが、いくつも上のレベルに配置されてもよい。損傷プローブは、修復プローブを含む関数を（最後に）呼び出すコードの後の位置において選択された関数内に配置される。図１３は、修復ノード及びその損傷プローブの位置を示す。
【００９６】
全ての修復ノードが関連の損傷プローブを有する必要はなく且つプローブはわずかなコストを招くため、全ての修復ノードの部分集合に対してのみ損傷プローブを注入する。通常、これらは、パターンを除去するように更に不規則に選択されるが、修復プローブを含むように選択される最も頻繁に実行されない関数の集合におけるノードである。
【００９７】
ＭＭＵ攻撃の検出
本発明の防御機構は、保護されたプログラムを攻撃により課された実行モデルと基本的に相いれないものとすることによりＭＭＵ攻撃を打破する間接的な方式であるが、ある環境においてＭＭＵ攻撃の存在を検出できるようにするのに有用である。間接的な検出は、実現するのが非常に困難であるか又は不可能である可能性が高く、且つハッカが打破するのが非常に容易であるため、本発明の間接的な防御を拡張し、ＭＭＵ攻撃を検出するために使用できるようにした。
【００９８】
このため、本発明の防御が、ＭＭＵ攻撃が存在する場合に間違ったコードを実行させ且つ通常の環境下で正しいコードを実行させることは明らかである。一般に、間違ったコードは、間違ったコードが実行される場合にプログラムが障害を起こすように設計される。ＭＭＵ攻撃を検出するために、間違ったコードの断片が「ＭＭＵ攻撃」フラグ（プログラムの開始時にクリアされる）を設定するように代わりにそれを構築し、プログラムを破壊する間違ったコードの断片の代わりにそれを使用する。ＭＭＵ攻撃が存在する場合、修復対象は正しいコードに置換されず、フラグを設定する間違ったコードが代わりに実行され、フラグを設定する。このフラグは、ＭＭＵ攻撃が存在するかを判定するために読み取られる。図１４は、フラグを設定する「間違った」コード対修復されたコードを示す。
【００９９】
他の同様の方式が可能である。例えば、フラグを設定するのではなく、間違ったコードは、存在するＭＭＵ攻撃に応答する関数に対する呼び出しを含んでもよい。その最も一般的な形態において、攻撃が存在する場合にのみ間違ったコードが実行されるため、機構は、ＭＭＵ攻撃を示すか又はＭＭＵ攻撃に応答するために使用される間違ったコードに対してあらゆるコードを使用する。
【０１００】
動的な修復ノード
上述したように、種々の手段を介して本発明の修復ノード方式を打破するのを困難にするが、十分長くシミュレータを介してそれを実行すること（及び全てのコードパスを実行すること）により、保護されたプログラムにより必要とされる全てのコード置換をハッカが取得できる可能性が依然としてある。
【０１０１】
これを根絶するため、別の種類の修復ノード、すなわち動的な修復ノードを含むように方式を拡張した。これは、一般的な修復ノードに類似するが、静的に規定された間違ったコードセクションを正しいコードに置換するのではなく、プログラムが正しく動作するのに必要なプログラムコードに対して動的な置換を行う。これらの変化が動的であるため、ハッカは、シミュレータにおいてそれら全てを簡単に集約できず、動的な修復ノードに対して正しいコードが１つもないために全ての間違ったコードセクションを正しいコードに静的に置換する。
【０１０２】
これを実行する１つの方法は、パラメータを使用するコードが直接（通常実行されるように）関数にアクセスするのではなく、パラメータの場所において使用される変数又はレジスタに同一の値をロードするように改変されたコードを介して値を取得するように、関数に渡されたパラメータを変換することである。この機構は、正しい値を供給するようにコードが改変されることを要するため、修復プローブに類似する機構を示す。従って、この機構は、ＭＭＵ攻撃が存在する場合に間違ったコードを実行させることにより、ＭＭＵ攻撃を更に打破する。
【０１０３】
これがどのように動作するかを確認するため、以下の関数（Ｉｎｔｅｌ  ｘ８６アセンブリ言語で書いている）を考察する。
ｐｕｓｈ  ｅａｘ
ｐｕｓｈ  ｏｆｆｓｅｔ  ｓｔｒｉｎｇ  ”％ｄ＼ｎ”
ｃａｌｌ  ＤＷＯＲＤ  ＰＴＲ  ［ｐｒｉｎｔｆ］
ａｄｄ  ｅｓｐ，  ８
ｒｅｔ
【０１０４】
この簡単な関数は、単一の整数パラメータを取得し、「ｐｒｉｎｔｆ」関数を使用してそれを画面に対して印刷する。この場合のパラメータは、ｅａｘレジスタにおいて関数に渡される。このコードを同一の結果を達成するためにコード改変を使用する形態に変換するために、即値を代わりにスタックにプッシュするコード（本発明の修復対象）でパラメータの使用（ｅａｘをプログラムスタックにプッシュする「ｐｕｓｈ  ｅａｘ」行）を置換し、本明細書において示されたようなｅａｘの値を含むようにこの即値（コード自体の一部である）を改変する関数（本発明の修復プローブ）の開始時にコードを注入する。
ｌｅａ  ｅｓｉ  ＤＷＯＲＤ  ＰＴＲ［ｌａｂｅｌ  ＋  １］
ｍｏｖ  ＤＷＯＲＤ  ＰＴＲ［ｅｓｉ］，  ｅａｘ
ｌａｂｅｌ：
ｐｕｓｈ  ０
ｐｕｓｈ  ｏｆｆｓｅｔ  ｓｔｒｉｎｇ  ”％ｄ＼ｎ”
ｃａｌｌ  ｄｗｏｒｄ  ｐｔｒ  ［ｐｒｉｎｔｆ］
ａｄｄ  ｅｓｐ，  ８
ｒｅｔ
【０１０５】
「ｐｕｓｈ  ０」行は、最初にゼロをスタックにプッシュするように設定する本発明の置換プッシュ命令である。すなわち、これは、この関数に対する殆どの呼び出しに対して間違っている（変動値で呼び出されると仮定する）。
【０１０６】
このプッシュ命令の上の行は、プッシュ命令においてゼロの値のアドレスを取得し、ｅａｘの内容をこの場所に書き込む。次に、プッシュ命令が実行される場合、プッシュ命令はゼロの代わりにｅａｘの値を含み、関数に対する全ての呼び出しに対して正しい結果を得る。
【０１０７】
本明細書において与えられた例はＩｎｔｅｌ  ｘ８６アセンブリ言語で書き込まれる。しかし、厳密な実現例の詳細は異なるが、同一の中核の機能があらゆる言語で書き込まれたコードに対して使用される。図１５は、本明細書において説明された動的な修復ノード機構を示す。
【０１０８】
本明細書における重要な概念は、プログラム変数（上記の例においては、関数パラメータ）の直接使用を代わりに値を供給するコード改変に変換するため、プログラムが正しく動作するようにコード改変が正常に実行されることを要求することである。ＭＭＵ攻撃が存在する場合、コード改変は、実際に実行中のプログラムのバージョンを含むメモリに経路指定されないため、プログラムは適切に実行できない。
【０１０９】
ハッカがそれらを除去するのを阻止するため、静的修復ノードにより使用された対策のうちの全てではなく２つを動的な修復ノードに提示する。
１．  修復対象を含む関数に入力するまでコードに書き込むパラメータ値は常に認識されないため、修復プローブ及び修復対象を別々な関数に分離しない。それらを正常に分離することが更に可能であってもよい。
２．  関数が呼び出される度に修復対象に書き込まれたコードが変化するため、損傷プローブは必要とされない。実質的に、コードは、いずれにしても関数に対する今後の呼び出しに対してほぼ疑いなく間違っているため、修復する必要がある。これは、選択したパラメータが偶然あまり頻繁に変化しないか又は全く変化しない関数には当てはまらない。パラメータは殆どの場合で変化するがこれは保証されないことを現時点で仮定する。
【０１１０】
修復プローブと関連する修復対象との間の分離の欠如は、静的修復ノードと比較して動的な修復ノードにおいていくらか欠点を構成するように見える（すなわち、それらは、パターンに基づく探索を介して探し出すのがいくらか容易である）。しかし、単に置換コードをハッカのプログラムの改変後のコピーにコピーすることにより除去が達成されないため、動的な修復ノードが探し出されたらそれを自動的に除去することが静的修復ノードに対する場合よりも著しく困難な場合もある。その代わりに、ハッカは、コード改変を介してではなく直接パラメータを使用する形態にコードを再度変換する方法を探し出す必要がある。ハッカはこれを手動で実行できるが、数千の修復ノードに対してこの処理を自動化できるツールを作成するのは非常に困難だろう。一意の変形例を使用することにより、これは更に困難となる。
【０１１１】
従って、双方の方式を共に使用することでより適切な防御を構成する可能性が高いが、動的な修復ノードは静的修復ノードよりもＭＭＵ攻撃に対してより強力な防御を構成する。双方の方式を使用する主な理由は、各々が僅かに異なる欠点を有するため、それらの組み合わせを使用することにより、全体としてそれぞれの欠点がシステムに及ぼす潜在的な影響を低減する。例えば、動的な修復ノードは、除去するのはより困難であるが静的修復ノードより探し出すのが容易であるため、無視できない欠点を構成する。従って、静的修復ノード（探し出すのがより困難である）を更に有することにより、ハッカが（探し出すのがより困難である）静的修復ノードを更に探し出すようにさせることで欠点を補償する。欠点の暴露を減らすために方式を組み合わせるこの方法に対する一意の警告は、各方式の各要素の数を減少すること自体が欠点を持ち出すことになるため、方式毎に使用された要素の数をこれを改善するほど十分に増やすのが好ましいというものである。
【０１１２】
プロキシ修復ノード
上述したように、本発明の修復ノード方式は、ハッカがＭＭＵ攻撃を使用する場合にプログラムが正しく機能するのを中止することを意味する。しかし、ハッカは、アプリケーションへの変更をローカライズするためにＭＭＵシステムの細分性を使用できるため、考慮すべき修復対象の数を制限できる。
【０１１３】
ハッカがアプリケーションに対してローカライズされた改変のみを作成したい場合、ＭＭＵを使用して再度マッピングされる必要があるのは、これらの改変を含む制限された数のメモリページだけである。従って、潜在的に、少数の修復ノードのみが考慮される必要がある。
【０１１４】
これをなくすために、別の種類の修復ノード、すなわちプロキシ修復ノード又はプローブを含むように方式を拡張した。これは通常の修復ノード／プローブに類似するが、２つの状態（修復された及び「破壊された」）を有する修復対象ではなく、複数（Ｎ）のそれらのうちのいずれか１つにおいて存在する。これらは、それぞれ、通常メモリレイアウトの点で対象から適切に分離され、ある他の場所においてプログラムの動作をプロキシするために存在する。
【０１１５】
一実施形態において、これらの他の場所は修復プローブの場所である。各プローブは、自身に隣接するコードが実行すべき動作をプロキシするように対象においてコードを変化させる。対象において改変されたコードは、呼び出され、プロキシ動作を実行し、プローブにおいてプログラム実行を継続するように戻る。
【０１１６】
ここに、プロキシ修復ノードを注入する前の２つのコードを示す（Ｉｎｔｅｌ  ｘ８６アセンブリ言語で書かれている）。
コード１：
ｘｏｒ  ｅａｘ，  ｅａｘ
ｐｕｓｈ  ｏｆｆｓｅｔ  ｓｔｒｉｎｇ  ”％ｄ＼ｎ”
ｃａｌｌ  ｄｗｏｒｄ  ｐｔｒ  ［ｐｒｉｎｔｆ］
コード２：
ｘｏｒ  ｅｃｘ，  ｅｃｘ
ｍｏｖ  ｅｄｘ，  ＡＢＣＤ１２３４ｈ
ｃａｌｌ  ｄｗｏｒｄ  ｐｔｒ  ［ｐｒｏｃｅｓｓ＿ｖａｌｕｅ］
並びに、注入後：
プローブ１：
ｌｅａ  ｅｓｉ，  ＤＷＯＲＤ  ＰＴＲ  ［ｌａｂｅｌ］
ｍｏｖ  ＤＷＯＲＤ  ＰＴＲ［ｅｓｉ］，  ９０Ｃ３Ｃ０３３ｈ    ／／  ｘｏｒ  ｅａｘ，  ｅａｘ；  ｒｅｔ；  ｎｏｐ；に対するオペコード
ｃａｌｌ  ｌａｂｅｌ    ／／  ｘｏｒ  ｅａｘ，  ｅａｘ；  ｒｅｔ；を実行
ｐｕｓｈ  ｏｆｆｓｅｔ  ｓｔｒｉｎｇ  ”％ｄ＼ｎ”
ｃａｌｌ  ｄｗｏｒｄ  ｐｔｒ  ［ｐｒｉｎｔｆ］
プローブ２：
ｌｅａ  ｅｓｉ，  ＤＷＯＲＤ  ＰＴＲ  ［ｌａｂｅｌ］
ｍｏｖ  ＤＷＯＲＤ  ＰＴＲ［ｅｓｉ］，  ９０Ｃ３Ｃ９３３ｈ    ／／  ｘｏｒ  ｅｃｘ，  ｅｃｘ；  ｒｅｔ；のオペコード
ｎｏｐ；
ｃａｌｌ  ｌａｂｅｌ    ／／  ｘｏｒ  ｅｃｘ，  ｅｃｘ；  ｒｅｔ；を実行
ｍｏｖ  ｅｄｘ，  ＡＢＣＤ１２３４ｈ
ｃａｌｌ  ｄｗｏｒｄ  ｐｔｒ  ［ｐｒｏｃｅｓｓ＿ｖａｌｕｅ］
Ｔａｒｇｅｔ（対象）：
ｌａｂｅｌ：
ｎｏｐ
ｎｏｐ
ｎｏｐ
ｎｏｐ
【０１１７】
このように及びこれらのうちの多くをアプリケーションに挿入することにより、多数の対象と多数のプローブを乗算したものとの間の相互接続された依存関係の複雑なウェブが存在する。動的な修復ノードと同様に、全ての使用を満たす対象に対してハッカが作成できる静的修復は１つも存在しない。また、必要な変化自体がアプリケーション全体にわたって分散されることをプローブと対象との間の実質的な非局所的関係が意味するため、ハッカは少数のＭＭＵページに対して変更をローカライズできない。これらの技術は、例えば「ＭＭＵの読み取り及び書き込み区別の処理」の節において説明された技術を含むように容易に拡張される。
【０１１８】
付録１
以下の説明は、本明細書の開示内容を解釈するのに有用だろう。
【０１１９】
メモリ
最新のＯＳは、主にハードメモリを制限することなく又は互いにクラッシュすることなく多くの処理が共存できるように、仮想メモリ（ディスクにページングされるメモリを含む）及びメモリ保護を提供する。
【０１２０】
これを容易にするために、最新のＣＰＵは、論理アドレスのブロック（アプリケーション／処理により使用された）を物理ＲＡＭ場所に再マッピングする方法を提供する。これらのマッピングは、論理アドレスを物理アドレスに変換するためにＭＭＵにより直接使用されるテーブルにおいて保持される。「ページ」と呼ばれることもあるこれらのブロックは、一般に、機器のＲＡＭ全体より非常に小さいサイズである。一般的なＷｉｎｄｏｗｓ（登録商標）に基づく機器上で、それらは４キロバイトのサイズである。マッピングは、通常、ページ毎の細分性で可能である。各マッピングは、論理アドレスの関連するブロックを考慮した種類のアクセスと更に関連付けられる。間違った種類のアクセスが試みられる場合、例外が発生し、処理するためにＯＳに渡される。いくつかの場合において、間違ったアクセスは単なる誤りであり、ＯＳは処理を終了してもよく、例えば実行可能な場所又はマッピングされていない場所への書き込みは通常殆どのＯＳにおいて誤りであることをユーザに通知してもよい。ディスクページングメモリに対して、ディスクにスワップアウトされているブロックはアクセス不可として示され、これらがアクセスされる場合に発生する例外は、これらのブロックを再度メモリにロードしてアクセスが継続できるようにするために使用される。
【０１２１】
論理ブロックは、（一般に）読み取り可能、書き込み可能及び／又は実行可能である。一般にこれらのうちのある特定の組み合わせのみが有用であるが、ＣＰＵは通常全ての組み合わせを支持する。すなわち、ＯＳは、一般にそれらを有用な組み合わせ（すなわち、ＭＭＵ攻撃を実現するために言及するカーネル改変）に制限する。
【０１２２】
付録２
本明細書において開示された概念のうちのいくつかは、以下の通り要約されてもよい。
・プログラムの異なる改変後のコピーを実行しながら自己検査改竄防止システムに保護されたプログラムの改変前のコピーを検査させることによりそのような自己検査機構を打破する自己検査改竄防止システム上の攻撃（「ＭＭＵ攻撃」）に対する防御方法であり、防御は以下のことを含む：
ａ．この状態で実行される場合にプログラムに障害を起こさせる間違ったコード（「修復対象」）でプログラムコードの多数の小さな部分を置換すること．
ｂ．間違ったコード（修復対象）が実行される前にそれらを修復するが、ＭＭＵ攻撃が存在する場合は実際に実行中のプログラムのコピーを修復しないプログラム（「修復プローブ」）に新しいコードを注入すること．
ｃ．必要に応じて、実行される前に修復対象におけるコードを間違ったコードに置換するプログラム（「損傷プローブ」）に新しいコードを注入すること．
ｄ．「修復ノード」を形成するための修復対象、１つ以上の修復プローブ及びゼロ以上の損傷プローブから構成される組み合わせ．
ｅ．修復対象に書き込み、書き込まれたデータのうちのいくつかを再度読み取って再度それを書き込む種類の修復プローブであり、データの読み取り、データの書き込み及び命令の読み取りが全て同一の場所に経路指定される場合にのみ結果として得られるデータが一貫するように、処理においてそれを移動すること及び／又は改変すること．
ｆ．データの書き込み及び命令の読み取りが全て同一の場所に経路指定される場合にのみ実行された結果として生じるコードが一貫するように、修復対象に書き込んでそこでコードを実行する種類の修復プローブ．
【０１２３】
・ハッカにより検出され且つ取り除かれる防御方法を阻止する一連の方法は以下のことを含む：
ａ．人により手動で検出すること及び取り除くことを時間がかかり且つ非現実的なものにするために、多くの修復ノードを使用すること．
ｂ．自動で検出すること及び取り除くことを困難にするために、コード生成方法を介して修復ノードが全て一意であることを保証すること．
ｃ．自動で検出することをより困難にするために、時間的・空間的に関連する修復ノードの構成要素（修復対象、修復プローブ及び損傷プローブ）を互いから分離すること（通常、独立した関数に）．
ｄ．シミュレーションに基づく検出を妨害するために、修復ノードをあまり頻繁に実行されないコードに配置すること．
【０１２４】
・実現するために重要であり且つハッカが打破するのが容易である直接検出方法を用いずに、防御方法を介してＭＭＵ攻撃の存在を検出する方法は以下を含む。
【０１２５】
ａ．修復対象に配置された間違ったコードがプログラムの不具合を引き起こさないが、ＭＭＵ攻撃が存在することを示すためにフラグを設定する等の応答機構を実行させる改変後の修復対象．
・動的なコード置換（「動的な修復ノード」）を使用して、ハッカにより取り除かれることに対する防御を更に強化する主な防御方法への拡張は以下のことを含む．
ａ．実行時にのみ知られるプログラム変数への割り当てに対してコードを識別すること．
ｂ．割り当てられた値が正しいランタイム値と等しい可能性が低い即値であるように、コード（「動的な修復対象」）を改変すること．
ｃ．元の割り当ての適切な値を含むようにコードにおいて即値を改変する動的な修復対象の前に新しいコード（「動的な修復プローブ」）を注入することであり、この改変は、攻撃が存在する場合に実際に実行中のコードのバージョンにおいて反映されない．
【０１２６】
・動的なコード置換（「動的な修復ノード」）を使用して、ハッカにより取り除かれることに対する防御を更に強化する主な防御方法への拡張は以下のことを含む：
ａ．修復ノードを含むように選択された関数に渡されたパラメータを識別すること及びこれらのパラメータのうちの１つがありふれたデータの種類の渡された値であり且つ関数のコード内で使用されるようにそれを選択すること．
ｂ．コード自体に組み込まれた即値を代わりに使用するために選択された関数パラメータ（「動的な修復対象」）を使用する１つのコードを改変すること．
ｃ．実行される前に選択された関数パラメータの値を含むようにコードにおいて即値を改変する動的な修復対象の前に新しいコード（「動的な修復プローブ」）を注入すること。この改変は、ＭＭＵ攻撃が存在する場合に実際に実行中のコードのバージョンにおいて反映されない．
ｄ．動的な修復ノードに対して通常の修復ノードを検出すること及び取り除くことを阻止するために使用された方法を適用することであるが、以下のことを含まない：
ｉ．動的な修復ノードの構成要素を独立した関数に分離すること．
ii．必要とされない「動的な損傷プローブ」を使用すること．
ｅ．動的な修復ノードに対してデータの読み取りと書き込みとを区別するＭＭＵを含むコンピュータシステム上で継続した防御を可能にするために通常の修復ノードを用いて使用された方法を適用すること．
【０１２７】
・自己検査改竄防止システム上で「ＭＭＵ攻撃」に対する解決方法が提供される。「ＴＬＢ攻撃」としても知られるこの攻撃は、自己検査システムを騙して、実行されているプログラムではなくプログラムの改変前のコピーを検査させることにより、そのシステムを無効にしようとする。コード及びデータのメモリアクセスが同期される場合にのみプログラムを正しく動作させることにより、この攻撃を間接的に打破する。
【図１】
2015043221.tif 000003
【図２】
2015043221.tif 000004
【図３Ａ】
2015043221.tif 000005
【図３Ｂ】
2015043221.tif 000006
【図４】
2015043221.tif 000007
【図５】
2015043221.tif 000008
【図６】
2015043221.tif 000009
【図７】
2015043221.tif 000010
【図８】
2015043221.tif 000011
【図９】
2015043221.tif 000012
【図１０】
2015043221.tif 000013
【図１１】
2015043221.tif 000014
【図１２】
2015043221.tif 000015
【図１３】
2015043221.tif 000016
【図１４】
2015043221.tif 000017
【図１５】
2015043221.tif 000018
【手続補正書】
【提出日】平成26年10月20日(2014.10.20)
【手続補正１】
【補正対象書類名】特許請求の範囲
【補正対象項目名】全文
【補正方法】変更
【補正の内容】
【特許請求の範囲】
【請求項１】
コンピュータメモリにおけるデータとコードのアクセス／取り込みが異なる物理的アドレスを経由するコンピュータにおいて実行可能なコンピュータプログラムを保護するためのコンピュータ実装方法であって、
ここで前記プログラムにおけるプログラムコードは、コードとデータのメモリアクセス／取り込みが同期された場合のみ、すなわち、データとコードのアクセス／取り込みがコンピュータメモリの同一の物理的アドレスを経由する場合にのみ、そのプログラムの実行時に正しく実行するために修復され、もしデータとコードのアクセス／取り込みがコンピュータメモリの異なる物理的アドレスを経由する場合には、前記プログラムは正しく機能しなくなる、
前記方法は、
（ｉ）変更手段が、前記プログラムコードが正しく実行されないようにするために、当該プログラムコードの１以上のセクションを修復対象として意図的に破壊するように、当該プログラムコードを変更する変更ステップと、
（ii）前記プログラムの実行時であって、データとコードのアクセス／取り込みがコンピュータメモリの同一物理的アドレスを経由する場合、修復プローブと称する前記プログラムのコードセクションが、前記修復対象を実行する以前に当該修復対象を正しいコードで置き換える置き換えステップと、
を有し、複数の修復プローブで構成されるグループにおける修復プローブそれぞれは、同じ第１の修復対象を正しいコードで置き換える前記置き換えステップを実行し、前記第１の修復対象における前記正しいコードをコールする、
ここで前記正しいコードは、或るアクションを実行し、該当する修復プローブにおけるプログラムの実行を継続するために復帰する
ことを特徴とする方法。
【請求項２】
攻撃の場合、同じ論理アドレスに対するコードとデータのメモリのアクセス／取り込みは、異なる物理アドレスに経路指定されることを特徴とする請求項１に記載の方法。
【請求項３】
損傷プローブのコードセッションが前記プログラムコードに注入されており、
前記損傷プローブは、前記修復対象が実行された後、当該修復された修復対象に、正しくないコードを書き込むことを特徴とする請求項１に記載の方法。
【請求項４】
修復ノードを共に形成する修復対象、１つ以上の修復ゾーン及びゼロ以上の修復プローブが存在することを特徴とする請求項１に記載の方法。
【請求項５】
前記変更ステップは、複数の修復ノードを構成することを特徴とする請求項１に記載の方法。
【請求項６】
保証手段が、自動で検出すること及び取り除くことを困難にするために、コード生成方法を介して修復ノードが全て異なることを保証するステップを含むことを特徴とする請求項４又は５に記載の方法。
【請求項７】
分離手段が、自動で前記修復ノードの検出することをより困難にするために、時間的・空間的に関連する前記修復ノードの構成要素（修復対象、修復プローブ及び損傷プローブ）を互いに分離するステップを含むことを特徴とする請求項４乃至６のいずれか１項に記載の方法。
【請求項８】
前記修復対象に書き込み、前記書き込まれたデータのうちのいくつかを再度読み取って再度それを書き込む種類の修復プローブが存在し、データの読み取り、データの書き込み及び命令の読み取りが全て同一の場所に経路指定される場合にのみ結果として得られるデータが一貫するように、前記処理においてそれを移動すること及び／又は改変することであることを特徴とする請求項１乃至７のいずれか１項に記載の方法。
【請求項９】
変更された修復対象に配置された正しくないコードは、プログラムの不具合を引き起こさないが、応答機構を実行させることを特徴とする請求項１に記載の方法。
【請求項１０】
（i）識別手段が、実行時にのみ知られる値を、プログラム変数への割り当てるコードを識別する識別ステップと；
（ii）改変手段が、前記割り当てられた値が前記正しいランタイム値と等しくない即値となるように、識別された前記コード（「動的な修復対象」）を改変する改変ステップと；
（iii）注入手段が、前記元の割り当ての正しいランタイム値を含むように前記コードにおいて前記即値を改変する前記動的な修復対象の前に新しいコード（「動的な修復プローブ」）を注入するステップと、ここで、この改変は、攻撃が存在する場合に実際に実行中の前記コードのバージョンにおいて反映されないことを特徴とする請求項１乃至９のいずれか１項に記載の方法。
【請求項１１】
（i）第２の識別手段が、修復ノードを含むように選択された機能に渡された前記パラメータを識別し、これらのパラメータのうちの１つがありふれたデータの種類の渡された値であり且つ前記機能のコード内で使用されるようにそれを選択するステップと；
（ii）第２の改変手段が、前記コード自体に組み込まれた即値を代わりに使用するために前記選択された機能パラメータ（「動的な修復対象」）を使用する１つのコードを改変するステップと；
（iii）第２の注入手段が、実行される前に前記選択された機能パラメータの値を含むように前記コードにおいて前記即値を改変する前記動的な修復対象の前に新しいコード（「動的な修復プローブ」）を注入するステップと、ここで、この改変は、攻撃が存在する場合に実際に実行中の前記コードのバージョンにおいて反映されないことを特徴とする請求項１０に記載の方法。
【請求項１２】
分離手段が、前記動的な修復対象及び動的な修復プローブの構成要素を独立した機能に分離するステップを含むことを特徴とする請求項１０又は１１に記載の方法。
【請求項１３】
新しいコードセクション（「動的な損傷プローブ」）が前記プログラムコードに注入され、
これらの動的な損傷プローブは、前記動的な修復対象が実行された後、元の間違った値等の前記間違った値を事前に修復された動的な修復対象に書き込むことを特徴とする請求項１０又は１１に記載の方法。
【請求項１４】
コンピュータプログラムコードを保護するコンピュータシステムであって、請求項１乃至１３のいずれか１項に記載の方法を実行するプロセッサを含むコンピュータシステム。
【請求項１５】
コンピュータ上で実行された場合、請求項１乃至１３のいずれか１項に記載の方法を前記コンピュータに実行させるための、コンピュータ可読媒体上に格納されたコンピュータソフトウエアプログラム。
【外国語明細書】
2015043221000001.pdf