(57)【要約】【課題】動的にプロセッサの命令列を生成するようなプログラムにも適用可能であり、バッファオーバフローを検出し、プログラムの動作を監視するプログラム実行監視装置を提供する。【解決手段】プログラム実行監視装置１００は、プログラムの実行前に、プログラムの外部からのデータ入力経路と、監視対象となるメモリ領域とを設定する設定手段１０１ａと、プログラムの実行中に、外部からのデータ入力経路を経て入力された値を用いた処理結果をメモリ領域へ格納する格納手段１０１ｂと、メモリ領域へ実行遷移が発生した場合、当該実行遷移を検出する検出手段１０１ｃとを備える。【選択図】図１
2006172003.tif 000002
【特許請求の範囲】
【請求項１】
プログラムの実行を監視するプログラム実行監視装置であって、
前記プログラムの実行前に、前記プログラムの外部からのデータ入力経路と、監視対象となるメモリ領域とを設定する設定手段と、
前記プログラムの実行中に、前記外部からのデータ入力経路を経て入力された値を用いた処理結果を前記メモリ領域へ格納する格納手段と、
前記メモリ領域へ実行遷移が発生した場合、当該実行遷移を検出する検出手段と
を備えることを特徴とするプログラム実行監視装置。
【請求項２】
前記検出手段は、前記メモリ領域の大きさが、予め定めていた大きさより大きい場合に、前記実行遷移を検出することを特徴とする請求項１に記載のプログラム実行監視装置。
【請求項３】
前記メモリ領域内の各アドレスに格納された値が、前記プログラム外部からの入力経路より入力されたデータから派生した値であるか否かを示す汚染情報を保持するプログラム情報保持部を更に備え、
前記検出手段は、前記プログラムの実行に従って、前記汚染情報を更新することを特徴とする請求項１又は２に記載のプログラム実行監視装置。
【請求項４】
プログラムの実行を監視するプログラム実行監視方法であって、
前記プログラムの実行前に、前記プログラムの外部からのデータ入力経路と、監視対象となるメモリ領域とを設定するステップと、
前記プログラムの実行中に、前記外部からのデータ入力経路を経て取得した値を用いた処理結果を前記メモリ領域へ格納するステップと、
前記メモリ領域へ実行遷移が発生した場合、当該実行遷移を検出するステップと
を含むことを特徴とするプログラム実行監視方法。
【請求項５】
プログラムの実行中に、プログラムの外部からのデータ入力経路を経て取得した値を用いた処理結果を、監視対象となるメモリ領域へ格納し、前記メモリ領域へ実行遷移が発生した場合、当該実行遷移を検出するプログラム実行監視装置において実行される前記プログラムを作成するプログラム作成方法であって、
前記プログラムの外部からのデータ入力経路と、前記監視対象となるメモリ領域の更新方法とを予めプログラムファイル内に記述するステップを含むことを特徴とするプログラム作成方法。
【請求項６】
オペレーティングシステムが提供するシステムコールを用いて、前記監視対象となるメモリ領域の更新方法を記述することを特徴とする請求項５に記載のプログラム作成方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、プログラム実行監視装置、プログラム実行監視方法及びプログラム作成方法に関する。
【背景技術】
【０００２】
計算機において実行するプログラムに不備があった場合、悪意のある利用者がこの不備をつき、ソフトウェアの実行を乗っ取り、その計算機に任意の動作をさせることが可能である。このようにプログラムの不備をつき、計算機に任意の動作をさせる行為の代表的なものに、バッファオーバフロー攻撃があるが（例えば、非特許文献１参照。）、これを防止するための数々の技術が提案されている。
【０００３】
バッファオーバフローを防止するための技術としては、例えば、プログラム中に含まれる実行遷移命令の遷移先メモリアドレスが、当該プログラムのソースコードにおいて関数の先頭メモリアドレスであるか否か、リターン命令の戻り先メモリアドレスがコール命令の後ろのメモリアドレスになっているかを確認することで、プログラムの実行を奪うことを防止する方法が開示されている（例えば、特許文献１参照。）。
【０００４】
又、バッファオーバフローは外部より攻撃者が入力したデータの中に命令列が含まれ、そのデータ列に実行遷移することにより成立するが、この点に着目し、バッファオーバフローを防止する方法も開示されている（例えば、非特許文献２参照。）。
【０００５】
具体的には、非特許文献２が開示する方法は、プログラムを実行するプロセッサを改造し、予め、ネットワークや外部のファイルからデータが流入するメモリ領域には印を付加しておき、プログラム実行中、印が付加されたメモリ領域から複製された先のメモリ領域や、印が付加されたメモリ領域を用いた演算結果を格納するメモリアドレスには印をつけることを繰り返して印を伝播していき、印が付加されたメモリ領域に実行遷移しようとしたとき、悪意のあるコードを実行しようとしたとして、バッファオーバフローを検出する方法である。
【特許文献１】US Patent application No.20040133777
【非特許文献１】Smashing The Stack For Fun And Profit, ｗｗｗ．ｐｈｒａｃｋ．ｏｒｇ, Phrack Vol. 49
【非特許文献２】Secure Program Execution via Dynamic Information Flow Tracking, G. Edward Suh, Jae W. Lee, and S. Devadas MIT, ACM Architectural Support for Programming Languages and Operating Systems (asplos) 20044.
【発明の開示】
【発明が解決しようとする課題】
【０００６】
しかしながら、特許文献１及び非特許文献２が開示する方法では、動的に実行コードを生成するようなソフトウェアには適用できないという問題がある。Java（登録商標）のような仮想機械や、Perl/Pythonなどに代表される人間が直接読めるような形式で記述された内容をプロセッサが実行可能な命令列に一旦変換した後に実行するようなスクリプト言語の実行系の場合、外部から流入したデータより命令列を生成してデータ領域に格納し、そのデータ領域に実行遷移する。そのため、特許文献１の方法では、予め定義されない関数への実行遷移であるとして、又、非特許文献１では正常な動作であるにもかかわらず、外部より流入したデータから派生したデータへの実行遷移であるとして、誤検出してしまうため、適用することができない。
【０００７】
そこで、本発明は、上記の課題に鑑み、動的にプロセッサの命令列を生成するようなプログラムにも適用可能であり、バッファオーバフローを検出し、プログラムの動作を監視するプログラム実行監視装置、プログラム実行監視方法及びプログラム作成方法を提供することを目的とする。
【課題を解決するための手段】
【０００８】
上記目的を達成するため、本発明の第１の特徴は、プログラムの実行を監視するプログラム実行監視装置であって、（ａ）プログラムの実行前に、プログラムの外部からのデータ入力経路と、監視対象となるメモリ領域とを設定する設定手段と、（ｂ）プログラムの実行中に、外部からのデータ入力経路を経て入力された値を用いた処理結果をメモリ領域へ格納する格納手段と、（ｃ）メモリ領域へ実行遷移が発生した場合、当該実行遷移を検出する検出手段とを備えるプログラム実行監視装置であることを要旨とする。
【０００９】
第１の特徴に係るプログラム実行監視装置によると、動的にプロセッサの命令列を生成するようなプログラムにも適用可能であり、バッファオーバフローを検出し、プログラムの動作を監視することができる。
【００１０】
又、第１の特徴に係るプログラム実行監視装置の検出手段は、メモリ領域の大きさが、予め定めていた大きさより大きい場合に、実行遷移を検出してもよい。
【００１１】
このプログラム実行監視装置によると、攻撃者が送り込む命令列が攻撃者の意図する通りに計算機を操るためには、相応の長さの命令列が必要であることから、プログラム外部からのデータ入力経路より取得した値を格納し、且つ実行を遷移したメモリ領域の大きさが予め定めておいた大きさより小さい場合には誤検出と判断することで、誤検出率を低減することができる。
【００１２】
又、第１の特徴に係るプログラム実行監視装置は、メモリ領域内の各アドレスに格納された値が、プログラム外部からの入力経路より入力されたデータから派生した値であるか否かを示す汚染情報を保持するプログラム情報保持部を更に備え、検出手段は、プログラムの実行に従って、汚染情報を更新してもよい。
【００１３】
このプログラム実行監視装置によると、監視対象となるメモリ領域を更新することができ、汚染情報を伝播させることができる。
【００１４】
本発明の第２の特徴は、プログラムの実行を監視するプログラム実行監視方法であって、（ａ）プログラムの実行前に、プログラムの外部からのデータ入力経路と、監視対象となるメモリ領域とを設定するステップと、（ｂ）プログラムの実行中に、外部からのデータ入力経路を経て取得した値を用いた処理結果をメモリ領域へ格納するステップと、（ｃ）メモリ領域へ実行遷移が発生した場合、当該実行遷移を検出するステップとを含むプログラム実行監視方法であることを要旨とする。
【００１５】
第２の特徴に係るプログラム実行監視方法によると、動的にプロセッサの命令列を生成するようなプログラムにも適用可能であり、バッファオーバフローを検出し、プログラムの動作を監視することができる。
【００１６】
本発明の第３の特徴は、プログラムの実行中に、プログラムの外部からのデータ入力経路を経て取得した値を用いた処理結果を、監視対象となるメモリ領域へ格納し、メモリ領域へ実行遷移が発生した場合、当該実行遷移を検出するプログラム実行監視装置において実行されるプログラムを作成するプログラム作成方法であって、プログラムの外部からのデータ入力経路と、監視対象となるメモリ領域の更新方法とを予めプログラムファイル内に記述するステップを含むプログラム作成方法であることを要旨とする。
【００１７】
第３の特徴に係るプログラム作成方法によると、プログラムファイルにプログラム外部からのデータ入力経路と、監視対象メモリ領域の更新方法を命令列と同時に格納することができるため、プログラムの実行開始を容易にすることができる。
【００１８】
又、第３の特徴に係るプログラム作成方法において、オペレーティングシステムが提供するシステムコールを用いて、監視対象となるメモリ領域の更新方法を記述してもよい。
【００１９】
このプログラム作成方法によると、システムコールを利用して、プログラムの実行を監視することができる。
【発明の効果】
【００２０】
本発明によると、動的にプロセッサの命令列を生成するようなプログラムにも適用可能であり、バッファオーバフローを検出し、プログラムの動作を監視するプログラム実行監視装置、プログラム実行監視方法及びプログラム作成方法を提供することができる。
【発明を実施するための最良の形態】
【００２１】
次に、図面を参照して、本発明の実施の形態を説明する。以下の図面の記載において、同一又は類似の部分には、同一又は類似の符号を付している。ただし、図面は模式的なものであることに留意すべきである。
【００２２】
（プログラム実行監視装置）
本実施形態に係るプログラム実行監視装置１００は、図１に示すように、命令列を実行するプロセッサ１０１と、実行するプログラムを格納するメモリ１０２と、実行中のプログラムの情報を格納するプログラム情報保持部１０３とを備える。
【００２３】
プロセッサ１０１は、プログラムの実行前に、プログラムの外部からのデータ入力経路と、監視対象となるメモリ１０２領域とを設定する設定手段１０１ａと、プログラムの実行中に、外部からのデータ入力経路を経て入力された値を用いた処理結果をメモリ１０２領域へ格納する格納手段１０１ｂと、メモリ１０２領域へ実行遷移が発生した場合、当該実行遷移を検出する検出手段１０１ｃとを備える。
【００２４】
又、検出手段１０１ｃは、メモリ領域の大きさが、予め定めていた大きさより大きい場合に、実行遷移を検出してもよい。更に、検出手段１０１ｃは、プログラムの実行に従って、後述する汚染情報、保護情報、例外情報を更新する。
【００２５】
メモリ１０２は、プロセッサ１０１から、格納するアドレスと読み込み指示を与えられると、そのアドレスに格納された値を出力してプロセッサ１０１に返す。又、メモリ１０２は、プロセッサ１０１から、格納するアドレスと書き込み指示、及び値を与えられると、格納アドレスに値を格納する。メモリ１０２は、ＤＲＡＭ等の一般的な記憶装置で構成すればよい。
【００２６】
尚、本実施形態においては、３２ビットのアドレスを用い、１アドレスにつき１バイト格納できるものとするが、本発明の趣旨はこのアドレス幅や格納データサイズに限定されるものではない。
【００２７】
プログラム情報保持部１０３は、汚染情報１０４と保護情報１０５と例外情報１０６とを保持する。プログラム情報保持部１０３は、監視中のプログラムから隔離され、その内容を実行中のプログラムより直接参照したり更新したりできないよう、例えばプログラム実行監視装置１００全体の実行を制御するオペレーティングシステムの管轄メモリ空間上などに実現するものとする。
【００２８】
汚染情報１０４は、メモリ１０２内の各アドレスに格納された値が、“プログラム外部からの入力経路より入力されたデータ”から派生した値であるか否かを示す情報である。以下の説明において、“プログラム外部からの入力経路より入力されたデータ”が格納されているメモリアドレスは汚染されていると表現し、汚染情報１０４内に１を、そうでない場合は０を記述するものとする。
【００２９】
従って、汚染情報１０４の実現のためには、メモリ１０２のアドレス毎に汚染されているか否かを表す１ビットを格納できるような領域を用意すればよい。これは、例えば、汚染情報１０４を連続したメモリ空間上に実現した場合、メモリ１０２上のアドレスXが汚染されているか否かの情報を、Yを(X) mod 8、Zを(X-Y)/8とすれば、Zバイト目のYビット目に格納することで実現可能である。
【００３０】
保護情報１０５は、メモリ１０２内の各アドレスが、“プログラム外部からのデータ入力経路より入力されたデータ”を格納することがあってはならないか否かを示す情報である。この保護情報１０５は、プログラム作成者の意図に従って、設定することができる。各ビットの表す意味を先のように解釈すれば、保護情報１０５は、汚染情報１０４と同様の形式で実現可能である。
【００３１】
尚、本実施形態では、汚染情報１０４は、メモリアドレス毎に汚染されている、いないを１ビットで実現しているが、これを複数ビットで表現して伝播させ、プログラム情報保持部１０３内に別途設けたしきい値を用いて汚染されている、いないを判定してもよい。
【００３２】
例えば、メモリアドレス毎に８ビットで表すとし、外部より直接入力されたメモリアドレスの汚染された度合いを0xffとする。値をそのまま複製した場合は、複製した先の汚染された度合いは複製元の汚染度合いをそのまま用いてもよく、他のメモリアドレスの値と演算し、その演算結果を格納する場合は、両方の汚染度合いの平均を演算結果の汚染度合いとしても用いることも可能である。又、演算の複雑度に応じて、論理和演算の場合は、演算結果の汚染度合いは演算元の汚染度合いの高いほうの値、乗算の場合は、演算元の汚染度合いの平均値などと変えることも可能である。
【００３３】
以後、本実施の形態では、外部からのデータ入力経路を経由したデータが格納されることがないと判断されるメモリのアドレスは保護されていると表現し、保護情報１０５の該当するビットに１をいれ、そうでないときは０をいれるものとする。
【００３４】
例外情報１０６は、メモリ１０２内の各アドレスが“プログラム外部からのデータ入力経路より入力されたデータ”を格納している場合、当該メモリ１０２領域の実行を許可するか否かを示す情報である。各ビットの表す意味を先のように解釈すれば、例外情報１０６は、汚染情報１０４と同様の形式で実現可能である。
【００３５】
プロセッサ１０１は、メモリ１０２に蓄積された命令列を実行する。プログラム実行の過程において、メモリ１０２の値を更新する際、汚染情報１０４を更新し、メモリ１０２のアドレスが汚染されているか否かであるかの情報を伝播させる。非特許文献1に示すような構成をプロセッサ１０１がとれば、この汚染されているか否かの情報の伝播の実現は容易であるが、ここでは簡単に汚染されているメモリアドレスから複製もしくはその値を利用した演算を新たなアドレスに格納するときに、新に値を格納されたメモリアドレスも汚染されているとする。
【００３６】
尚、本実施の形態ではひとつのプログラムの実行を監視する手順を説明するが、複数のプログラムを監視する場合、プログラム情報に実行中のプログラムを特定するＩＤを含めて複数のプログラム情報を用意し、複数のプログラムの実行を切り替える際にこのＩＤをもとにプログラム情報を切り替えて利用すればよい。
【００３７】
（プログラム作成方法）
次に、本実施形態に係るプログラム作成方法について、図３及び図４を用いて説明する。上述した、プログラム実行監視装置１００上で実行するプログラムは、以下に説明する方法で作成される。
【００３８】
尚、図３及び図４では、プログラムを実行するためにオペレーティングシステムが新たに１２のシステムコールを提供することを前提としており、このオペレーティングシステムに追加する１２のシステムコールの名称、システムコール番号、機能、実現方法の例を図５に示す。
【００３９】
図５に示す追加システムコールの名称やシステムコール番号は、これらが一意に特定できればよく、異なる名称やシステム番号を用いて実現してもよい。又、１２のシステムコールのうち、sys_startSpuriousRegion()、sys_endSpuriousRegion()、sys_releaseSpuriousRegion()、sys_allocSpuriousRegion()の４つは汚染情報１０４の更新のために用いるが、例えばネットワーク経由やファイル経由で取得したデータを格納する領域は、汚染情報を１にするといった指定を行うようにすれば、これら４つのシステムコールはなくてもよい。
【００４０】
図２に、本実施形態において説明するプログラムのソースコードの例を示す。本実施形態では、ソースコード中に、各変数の格納メモリ領域が保護されているか否か、又は汚染されているか否か、又は外部からのデータ入力経路を経由したデータが格納されるが実行を許可するか否か、という情報を記述する必要がある。この実現形式は幾通りか考えられるが、図２の例ではC言語のコメント文を用い、変数の宣言前にこれらの情報を記述している。 以後、本実施の形態では、/* protected */、というコメント、及び/* spurious */、/* except */というコメントを付加することをそれぞれ、保護注釈、汚染注釈、例外注釈を付加すると呼ぶ。
【００４１】
図３及び図４は一つのソースコードファイルからアセンブラコードを作成する場合の、通常のプログラムの作成方法と本発明のプログラム作成方法の差分のみを示している。本実施の形態において通常のプログラムの作成方法として示す内容や、複数のソースコードから一つのプログラムを作成する方法、アセンブラ言語からバイト列から構成されるプログラムへの変換方法、トークン等の用語については、“Compilers Principles, Techniques, and Tools A.V. Aho, R. Sethi, and J.D. Ullman”（以下において、非特許文献３という。）に詳しい。
【００４２】
まず、図３のステップＳ１０１において、通常のプログラムの作成と同様に、ソースコードを構文解析していき、ソースコードからトークンを読み込む。
【００４３】
次に、ステップＳ１０２において、トークンが空であるか否か判断し、トークンが空である場合、ソースコードの解析が終了したとして、プログラム作成の手続きを終了する。一方、ステップＳ１０２において、トークンが空でない場合、ステップＳ１０３に進み、トークンが関数宣言であるか否か判断する。
【００４４】
ステップＳ１０３において、関数宣言でなく、かつ、ステップＳ１０９において、保護注釈又は汚染注釈が付加された大域変数宣言であるとき、図４に示す手続きを実行し、プログラム実行開始時に宣言された大域変数を格納するメモリアドレスに該当する保護情報、又は汚染情報、又は例外情報を１に変更する。
【００４５】
具体的には、図４のステップＳ２０１において、大域変数をXとし、Xが割り当てられる、メモリ領域における先頭格納アドレスをXa、及びその大きさをXsとする。アドレスXa、大きさXsは、大域変数宣言の型情報から得ることができるため、システムコールsys_allocProtectedRegion(Xa、Xs)やsys_allocSpuriousRegion(Xa、Xs)、sys_allocExceptRegion(Xa、Xs)を呼び出すようにすればよい。つまり、ステップＳ２０２において、Xに保護注釈を付加する場合は、ステップＳ２０３において、プログラムの初期化処理にシステムコールsys_allocProtectedRegion(Xa、Xs)を呼び出すコードを追加する。又、ステップＳ２０４において、Xに汚染注釈を付加する場合は、ステップＳ２０５において、プログラムの初期化処理にシステムコールsys_allocSpuriousRegion(Xa、Xs)を呼び出すコードを追加する。又、ステップＳ２０６において、Xに例外注釈を付加する場合は、ステップＳ２０７において、プログラムの初期化処理にシステムコールsys_allocExceptRegion(Xa、Xs)を呼び出すコードを追加する。
【００４６】
図３のステップＳ１０３において、トークンが関数宣言でなく、かつ、ステップＳ１０９において、注釈が付加された大域変数宣言でない場合、ステップＳ３１１において、通常のコード生成を行う。
【００４７】
一方、ステップＳ１０３において、トークンが関数宣言であった場合、関数内で宣言された変数に対し順次処理を行うため、先頭に宣言された変数をXとする。
【００４８】
次に、ステップＳ１０５において、Xが存在するか否か判断し、Xが存在しない、即ち、関数内で宣言された変数がない場合、ステップＳ１１２において、関数宣言の終了まで通常のコード生成を行う。そして、ステップＳ１１３において、関数宣言が終了する際にシステムコールsys_releaseProtectedRegion()、及びsys_releaseSpuriousRegion()、sys_releaseExeptRegion()を呼び出すコードを生成し、ステップＳ１０１へ戻り、次のトークンを読み込んで処理を継続する。
【００４９】
一方、ステップＳ１０５において、Xが存在する、即ち、関数内に宣言された変数が存在する場合、ステップＳ１０６において、その変数に注釈が付加されているか否かを判断する。
【００５０】
ステップＳ１０６において、注釈が付加されていない場合、変数Xの格納に必要な領域をスタック上に確保するため、ステップＳ１０７において、スタックポインタの値をXの大きさ分、減算するコードを生成する。即ち、Xの大きさ分、スタックポインタを移動し、スタック上にXの格納領域を用意するコードを生成する。そして、ステップＳ１０８において、関数内の次に宣言された変数をXとして、ステップＳ１０５〜１０８の処理を繰り返す。
【００５１】
ステップＳ１０６において、保護注釈又は汚染注釈、例外注釈が付加されている場合、ステップＳ１１４に進み、注釈の種類に応じ、システムコールsys_startXXXXRegion()を呼び出すコードを生成する。その後、ステップＳ３１５において、変数Xの格納に必要な領域をスタック上に確保する。続いて、ステップＳ１１６において、システムコールsys_endXXXXRegion()を呼び出すコードを生成し、ステップＳ１０８へと処理を移す。この時、変数Xに付加された注釈が保護注釈の場合はProtected、汚染注釈の場合はSpurious、例外注釈の場合はExceptとする。
【００５２】
図３および図４に示す手順に従って、図２のプログラムのソースコードをアセンブラコードに変換した例を図６に示す。図６中、関数fulfillの詳細は示していないが、ここでは変数bの内容を引数で与えられた領域へ複製する関数とする。又、本実施の形態においては、システムコールの呼び出しはレジスタ%eaxにシステムコール番号を代入してソフト割り込み80Hで実現するものとする。
【００５３】
このようにしてプログラムのソースコードよりアセンブラコードを生成し、アセンブラコードより、非特許文献３が開示するような方法で更にプログラムへと変換する。プログラムは実行していない段階では、例えば図７に示すような単一のファイルとして格納しておく。図７の構成例ではプログラムファイル７００はプログラムヘッダ７０１とテキスト領域７０２とデータ領域７０３から構成される。
【００５４】
プログラムヘッダ７０１は、テキスト領域７０２およびデータ領域７０３がファイル中どのような位置に格納され、どのくらいの大きさを持ち、実行時にどのメモリ領域に格納されるか、といった情報を格納する。プログラムヘッダ７０１は、例えば、図８に示すように、テキスト領域の先頭が格納されているファイル内のオフセット７０１ａ、テキスト領域の大きさ７０１ｂ、テキスト領域を実行時、メモリにマップしたときの先頭開始アドレス７０１ｃ、データ領域が格納されているファイル内のオフセット７０１ｄ、データ領域の大きさ７０１ｅ、データ領域を実行時、メモリにマップしたときの先頭開始アドレス７０１ｆなどから構成される。
【００５５】
テキスト領域７０２は、図３及び図４に示す手順に従って生成したアセンブラコードより変換された命令列を格納する。
【００５６】
データ領域７０３は、静的に格納アドレスが決定され、初期値が代入されている変数を格納する。
【００５７】
（プログラム実行監視方法）
次に、本実施形態に係るプログラム実行監視方法について、図９を用いて説明する。
【００５８】
まず、ステップＳ３０１において、プログラム実行監視装置１００は、プログラムの実行を開始する際、実行を開始しようとするプログラムファイル７００より、プログラムファイル内のプログラムヘッダ７０１の情報をもとにファイル内のテキスト領域７０２、データ領域７０３をメモリ上にマッピングする。この時、汚染情報１０４と保護情報１０５と例外情報１０６とは初期化し、すべて０にしておく。
【００５９】
次に、ステップＳ３０２において、プログラム実行監視装置１００は、メモリ上にマッピングされたテキスト領域７０２の先頭より、命令列の実行を開始する。テキスト領域７０２の先頭には、プログラムの初期化処理が格納されているが、データ領域７０３に汚染注釈や保護注釈、例外注釈が付加された変数を格納する領域がある場合、初期化処理の命令列中に、汚染情報や保護情報、例外情報の更新処理が含まれる。このため、プログラムの初期化処理において、該当するメモリ領域に該当する汚染情報１０４、および保護情報１０５、例外情報１０６の更新処理も行う。
【００６０】
初期化処理実行終了後、プログラム実行監視装置１００は、プログラム本体の命令列をひとつひとつ取り出して実行する。具体的には、ステップＳ３０３において、テキスト領域７０２の先頭にある命令をXとし、ステップＳ３０４において、命令Xが存在するか否か判断する。命令Xが存在する場合は、ステップＳ３０５に進み、命令Xを実行する。
【００６１】
又、ステップＳ３０５においては、命令Xの実行とともに、汚染情報１０４を更新する。汚染情報１０４の更新を行うには、非特許文献１に示すようなプロセッサ構成を用いればよい。又命令列には、動的に格納アドレスが決定される変数の格納領域を更新するような処理が図３及び図４のプログラム作成方法により含まれているため、保護情報１０５についても逐次更新する。
【００６２】
次に、ステップＳ３０６において、命令Xの実行により、保護領域が汚染されているか否か判断し、汚染されている場合、ステップＳ３０８に進み、実行遷移を検出してプログラム実行監視装置１００の外部に知らせる。保護領域が汚染されていない場合、ステップＳ３０７に進み、命令Xは実行遷移命令であり、実行遷移先は例外領域でなく、汚染されているか否か判断する。該当する場合は、ステップＳ３０８に進み、実行遷移を検出してプログラム実行監視装置１００の外部に知らせる。ステップＳ３０７の条件が成立しなければ、ステップＳ３０９において、テキスト領域より次の命令を取り出して新たにXとし、XがなくなるまでステップＳ３０４以降の処理を繰り返す。
【００６３】
又、ステップＳ３０７において、例えば実行遷移先のメモリアドレスをXとし、Xよりも小さく最も近い汚染されたメモリアドレスをY、Xよりも大きく最も近い汚染されていないメモリアドレスをZとするとZ-Yが予め定めておいた値Nより大きければ検出するとしてもよい。ここで値Nは、プログラム実行監視装置１００が予め保持しておくか、プログラムファイル７００の例えばプログラムヘッダ７０１などに格納しておき、実行時に取得してプログラム情報に加えておけばよい。
【００６４】
次に、テキスト領域７０２として、図６に示すようなアセンブラコードを持つプログラムを図９の手順に基づいて実行したときの正常動作について、具体的に図６および図１０〜１１を用いて説明する。
【００６５】
図１０〜１２は、プログラム実行時のメモリの様子を表しており、図の上側が若いアドレスを表している。メモリの脇に斜め斜線の印がついていればメモリ領域が汚染されていることを表し、格子模様の印がついていれば、保護されていることを表し、横線の印がついていれば例外領域であることを表す。この印はそれぞれ、汚染情報１０４や保護情報１０５、例外情報１０６を説明のために可視化したものである。
【００６６】
まず、プログラムヘッダ７０１の情報にもとづいてメモリ１０２にテキスト領域７０２、データ領域７０３を配置した後、テキスト領域７０２の先頭にある初期化処理を実行する（図６の６０１部分）。ここでは静的に確保される変数bの領域を確保し、変数bに対して汚染注釈が指定されていることから、これを汚染情報１０４に反映する。このときのメモリは図１０（ａ）のようになる。メモリの下層にプログラムスタックが形成され、変数bの格納領域が汚染されていることが汚染情報１０４に記述される。
【００６７】
次に、プログラムの本体であるmain関数を実行していく。スタック上にmain関数の呼び出し元のスタックベースアドレスアドレス%ebpを退避し、変数x、変数bufの領域をスタック上に確保する（図６の６０２、６０３、６０４部分）。このとき変数x、および変数bufにはそれぞれ保護注釈、例外注釈が付加されていることから、保護情報１０５および例外情報１０６の更新を行い、メモリの様子は図１０（ｂ）のようになる。
【００６８】
関数mainの実行を進めると、引数をスタックに積み、関数funcAを呼び出す(図６の６０５部分)。関数funcA内では自身のスタックフレームを保存し（図６の６０６部分）、変数用の領域確保を行う（図６の６０７部分）。関数funcAの中の変数には注釈が付加されていないため、図６の６０７に示すようなアセンブラコードで変数格納用の領域を確保する。このときのメモリの様子は図１１（ａ）のようになる。
【００６９】
関数funcAは、関数fulfillを呼び出すが、関数fulfillは大域変数bより引数が示す領域へと値を複製することより、関数Aの引数として与えたbuf2の格納領域は汚染されていることが汚染情報１０４に反映される。更にbuf2の値をbuf3へと複製するため、buf3の格納領域も汚染され、メモリの様子は図１１（ｂ）のようになる。関数funcAの実行を終了後、スタックから戻りアドレスを取り出して実行遷移する。funcA終了後、bufに格納された命令列を実行する関数runを呼び出す。
【００７０】
次に、上述した動作において、関数funcAから関数fulfillを呼び出したとき、関数fulfill内でバッファオーバフローが発生した動作について、具体的に図１２を用いて説明する。
【００７１】
上述した動作において、関数funcAから関数fulfillを呼び出したとき、関数fulfill内でバッファオーバフローが発生し、変数ptr3の値が改竄され、変数buf内を指すようになったとする。
【００７２】
この場合、図１２（ａ）に示すように、メモリの様子は、保護された領域であるにもかかわらず、汚染される。本実施の形態では、これを検知し、例外が発生したとして外部に知らせる。
【００７３】
もし、ここで保護領域の汚染を検知しない場合、関数fulfillの終了後、変数ptr2が指す領域から変数ptr3が指す領域へと値の複製が行われるが、これは変数ptr3が変数bufを指していることから、buf2からbufへと値が複製されることになる。変数buf2のデータはfulfill内において大域変数bより複製が行われているため、変数buf2、変数bufの格納領域ともに汚染される。このときのメモリの様子は、図１２（ｂ）のようになる。関数fulfillの実行終了後、funcAの処理を終了して、呼び出しに戻り、関数runを実行しようとしても、bufは汚染されているが例外領域であるため実行を継続してしまう。 
（作用及び効果）
本実施形態に係るプログラム実行監視装置１００及びプログラム実行監視方法によると、仮想機械や、スクリプト言語など実行時に動的にプロセッサの命令列を生成するようなプログラムにも適用可能であり、バッファオーバフローを検出し、プログラム作成者の意図通りにプログラムが動作しているか否かを監視することができる。
【００７４】
又、プログラム実行監視装置１００の検出手段１０１ｃは、メモリ領域の大きさが、予め定めていた大きさより大きい場合に、実行遷移を検出することができる。このため、攻撃者が送り込む命令列が攻撃者の意図する通りに計算機を操るためには、相応の長さの命令列が必要であることから、プログラム外部からのデータ入力経路より取得した値を格納し、且つ実行を遷移したメモリ領域の大きさが予め定めておいた大きさより小さい場合には誤検出と判断することで、誤検出率を低減することができる。
【００７５】
又、本実施形態に係るプログラム実行監視装置１００の検出手段１０１ｃは、プログラムの実行に従って、汚染情報、保護情報、例外情報を更新することができる。このため、汚染情報を伝播させることができる。
【００７６】
又、本実施形態に係るプログラム作成方法によると、プログラムファイルにプログラム外部からのデータ入力経路と、監視対象メモリ領域を命令列と同時に格納することができるため、プログラムの実行開始を容易にすることができる。
【００７７】
又、本実施形態に係るプログラム作成方法において、オペレーティングシステムが提供するシステムコールを用いて、監視対象メモリ領域の更新方法を記述することができる。このため、システムコールを利用して、プログラムの実行を監視することができる。
【図面の簡単な説明】
【００７８】
【図１】本実施形態に係るプログラム実行監視装置の構成ブロック図である。
【図２】本実施形態に係るプログラムのソースコードの一例である。
【図３】本実施形態に係るプログラム作成方法を示すフローチャートである（その１）。
【図４】本実施形態に係るプログラム作成方法を示すフローチャートである（その２）。
【図５】本実施形態に係るオペレーティングシステムが提供するシステムコールの追加例である。
【図６】図２のソースコードをアセンブラコードへ変換した例である。
【図７】本実施形態に係るプログラムファイルの構成例である。
【図８】図７のプログラムヘッダの構成例である。
【図９】本実施形態に係るプログラム実行監視方法を示すフローチャートである。
【図１０】本実施形態に係るプログラム実行監視過程のメモリの様子を示す図である（その１）。
【図１１】本実施形態に係るプログラム実行監視過程のメモリの様子を示す図である（その２）。
【図１２】本実施形態に係るプログラム実行監視過程のメモリの様子を示す図である（その３）。
【符号の説明】
【００７９】
１００…プログラム実行監視装置
１０１…プロセッサ
１０１ａ…設定手段
１０１ｂ…格納手段
１０１ｃ…検出手段
１０２…メモリ
１０３…プログラム情報保持部
１０４…汚染情報
１０５…保護情報
１０６…例外情報
７００…プログラムファイル
７０１…プログラムヘッダ
７０２…テキスト領域
７０３…データ領域
【図１】
2006172003.tif 000003
【図２】
2006172003.tif 000004
【図３】
2006172003.tif 000005
【図４】
2006172003.tif 000006
【図５】
2006172003.tif 000007
【図６】
2006172003.tif 000008
【図７】
2006172003.tif 000009
【図８】
2006172003.tif 000010
【図９】
2006172003.tif 000011
【図１０】
2006172003.tif 000012
【図１１】
2006172003.tif 000013
【図１２】
2006172003.tif 000014