(57)【特許請求の範囲】
【請求項１】
主処理実行の前にメモリにプロセス空間を割り当てる機能を有し、戻り先が前記プロセス空間の任意の領域に戻ることができるリターン命令を含む処理を行うプロセッサにおいて、
前記プロセス空間内の第１の領域を特定する第１特定情報を取得する手段と、
前記第１特定情報を記憶する第１記憶手段と、
前記処理からリターン命令を予め検出するリターン命令検出手段と、
前記リターン命令によって戻される所を特定するアドレス情報を取得する手段と、
前記第１特定情報に基づき、前記アドレス情報により特定される所が前記第１の領域内にあるか否かを判定する手段と、
前記判定する手段が、前記特定される所が前記第１の領域内にあると判定した場合に、前記処理を中断する手段と、
を備えるプロセッサ。
【請求項２】
前記第１記憶手段は、レジスタを含むこと
を特徴とする請求項１に記載のプロセッサ。
【請求項３】
前記第１の領域は、プロセス空間内であって、テキスト領域又は共有ライブラリ以外の領域であること
を特徴とする請求項１又は請求項２に記載のプロセッサ。
【請求項４】
前記第１の領域は、プロセス空間内であって、スタック領域であること
を特徴とする請求項１又は請求項２に記載のプロセッサ。
【請求項５】
請求項１から請求項４のいずれか１項に記載のプロセッサと、
前記メモリと、
前記プロセッサ及び前記メモリの間を通信可能にする通信手段と、
を備える処理装置。
【請求項６】
主処理実行の前にメモリにプロセス空間を割り当てる機能を有し、戻り先が前記プロセス空間の任意の領域に戻ることができるリターン命令を含む処理を行うプロセッサに行わせる方法が実行可能なプログラムを、コンピュータを用いて作成する方法において、
前記プロセス空間内の第１の領域を特定する第１特定情報を取得するステップと、
前記第１特定情報を記憶するステップと、
前記処理からリターン命令を予め検出するステップと、
前記リターン命令によって戻される所を特定するアドレス情報を取得するステップと、
前記第１特定情報に基づき、前記アドレス情報により特定される所が前記第１の領域内にあるか否かを判定するステップと、
前記判定する手段が、前記特定される所が前記第１の領域内にあると判定した場合に、前記プロセッサが前記処理を中断するステップと、
を前記プロセッサに行わせるように、前記コンピュータが前記リターン命令を書き換えるステップを含む、
プログラム作成方法。
【請求項７】
前記書き換えるステップの前に、前記実行可能なプログラムを前記コンピュータがアセンブリ言語に変換するステップと、
前記書き換えるステップにおいて、前記リターン命令を書き換えるステップは、アセンブリ言語において行われ、
前記書き換えるステップの後に、変換された前記実行可能なプログラムを実行形式に変換するステップと、
を含むことを特徴とする請求項６に記載のプログラム作成方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、バッファオーバーフローによる不正なプログラムの実行を防止する技術に関するものである。
【背景技術】
【０００２】
コンピュータ上でアプリケーションプログラムの主処理が実行される前に、スタートアップルーチンが動作してメモリ上にスタック領域が割り付けられる。スタック領域は関数の戻り値など一時的に使用される変数を格納するためのメモリ領域であるが、スタック領域に割り当てられたバッファ領域の上限をこえてデータが書き込まれることにより、バッファ領域以外のスタック領域のデータが上書きされることがある。これを、バッファオーバーフローという。
また意図的にバッファオーバーフローを生じさせることによりスタック領域に記憶されたリターンアドレスを書き換えることで、書き換えられたリターンアドレスで指示される不正なプログラムを実行させることをバッファオーバーフロー攻撃という。
バッファオーバーフローやバッファオーバーフロー攻撃に対処する技術として次のような技術が開示されている。【０００３】
特許文献１には、バッファオーバーフローするプログラムの修正に必要となる分析情報を収集してプログラム開発者に提供するための分析方法が記載されている。【０００４】
特許文献２には、バッファメモリ領域に隣接する前後のアドレスにダミーメモリ領域を割り当てることによりバッファオーバーフローを検出する方法が記載されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２００６−０５３７６０号公報
【特許文献２】特開２００９−２５９０７８号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
しかしながら、特許文献１のようなバッファオーバーフローするプログラムを修正に必要となる分析情報を収集してプログラムの修正を行う対処方法では、既知の攻撃への対処しか行うことができず未知の攻撃には対処できないことから確実性に課題がある。
加えて、プログラム開発者によるプログラムの修正作業が適宜必要であるとの課題がある。【０００７】
また、特許文献２に記載のバッファメモリ領域に隣接する前後のアドレスにダミーメモリ領域を割り当てることによりバッファオーバーフローを検出する方法では、連続的にメモリ領域を改変する攻撃には有効だが、ピンポイントでリターンアドレスを書き換えるような巧妙な攻撃には対処できないことから確実性に課題がある。
加えて、コンパイルの前にソースプログラムを解析して処理をプログラムに追加するが、このような方法はプログラムの作成に使用される高級言語に依存するために高級言語ごと個別に対応が必要であるとともに高級言語の改変にも追従する必要があるとの課題がある。【０００８】
本発明は、このような事情を鑑みてなされたものであり、対処のためのプログラム開発者によるプログラム修正作業を行うことなく、プログラムに使用される高級言語に依存することなく、バッファオーバーフローによる不正なプログラムの実行を確実に防止する技術を提供することを目的とする。
【課題を解決するための手段】
【０００９】
上記課題を解決するために、本発明は、主処理実行の前にメモリにプロセス空間を割り当てる機能を有し、戻り先が前記プロセス空間の任意の領域に戻ることができるリターン命令を含む処理を行うプロセッサにおいて、前記プロセス空間内の第１の領域を特定する第１特定情報を取得する手段と、前記第１特定情報を記憶する第１記憶手段と、前記処理からリターン命令を予め検出するリターン命令検出手段と、前記リターン命令によって戻される所を特定するアドレス情報を取得する手段と、前記第１特定情報に基づき、前記アドレス情報により特定される所が前記第1の領域内にあるか否かを判定する手段と、前記判定する手段が、前記特定される所が前記第1の領域内にあると判定した場合に、前記処理を中断する手段と、を備えることを特徴とする。【００１０】
また、本発明は、前記第1記憶手段は、レジスタを含むことを特徴とする。【００１１】
また、本発明は、前記第1の領域は、プロセス空間内であって、テキスト領域又は共有ライブラリ以外の領域であることを特徴とする。【００１２】
また、本発明は、前記第1の領域は、プロセス空間内であって、スタック領域であることを特徴とする。【００１３】
上記課題を解決するために、本発明は、前記特徴を有するプロセッサと、前記メモリと、前記プロセッサ及び前記メモリの間を通信可能にする通信手段と、を備える処理装置である。【００１４】
上記課題を解決するために、本発明は、主処理実行の前にメモリにプロセス空間を割り当てる機能を有し、戻り先が前記プロセス空間の任意の領域に戻ることができるリターン命令を含む処理を行うプロセッサに行わせる方法が実行可能なプログラムを、コンピュータを用いて作成する方法において、前記プロセス空間内の第1の領域を特定する第１特定情報を取得するステップと、前記第1特定情報を記憶するステップと、前記処理からリターン命令を予め検出するステップと、前記リターン命令によって戻される所を特定するアドレス情報を取得するステップと、前記第１特定情報に基づき、前記アドレス情報により特定される所が前記第1の領域内にあるか否かを判定するステップと、前記判定する手段が、前記特定される所が前記第1の領域内にあると判定した場合に、前記プロセッサが前記処理を中断するステップと、を前記プロセッサに行わせるように、前記コンピュータが前記リターン命令を書き換えるステップを含む、プログラム作成方法である。【００１５】
また、本発明は、前記書き換えるステップの前に、前記実行可能なプログラムを前記コンピュータがアセンブリ言語に変換するステップと、前記書き換えるステップにおいて、前記リターン命令を書き換えるステップは、アセンブリ言語において行われ、前記書き換えるステップの後に、変換された前記実行可能なプログラムを実行形式に変換するステップと、を含むことを特徴とする。
【発明の効果】
【００１６】
本発明によれば、対処のためのプログラム開発者によるプログラム修正作業を行うことなく、プログラムに使用される高級言語に依存することなく、バッファオーバーフローによる不正なプログラムの実行を確実に防止することができる。
【図面の簡単な説明】
【００１７】
【図１】図１は、C言語により記述されたプログラムがコンピュータ上で動作する場合のプロセス空間の論理的な模式図である。
【図２】図２は、バッファオーバーフローによってリターンアドレスが不正なプログラムのコードのアドレスに書き換えられる例を示したスタック領域の模式図である。
【図３】図３は、Ｌｉｎｕｘ（登録商標）を例としたメモリマップの例である。
【図４】図４は、処理装置の構成を示すブロック図である。（実施例１、実施例２）
【図５】図５は、一般的なコンピュータにおいてハードウェアとアプリケーションプログラムを結び付けるカーネルの概念図である。
【図６】図６は、スタートアップルーチンでのテキスト領域と共有ライブラリの開始アドレスと終了アドレスを取得する手順を示すフローチャートである。（実施例１）
【図７】図７は、演算ユニットが行う処理の手順を示すフローチャートである。（実施例１）
【図８】図８は、スタートアップルーチンでのスタック領域の開始アドレスと終了アドレスを取得する手順を示すフローチャートである。（実施例２）
【図９】図９は、演算ユニットが行う処理の手順を示すフローチャートである。（実施例２）
【図１０】図１０は、処理装置の構成を示すブロック図である。（実施例３、実施例４）
【図１１】図１１は、メモリマップ取得部がテキスト領域と共有ライブラリの開始アドレスと終了アドレスを取得する手順を示すフローチャートである。（実施例３）
【図１２】図１２は、逆アセンブラ、命令挿入部、アセンブラが行う処理の手順を示すフローチャートである。（実施例３）
【図１３】図１３は、逆アセンブラ、命令挿入部、アセンブラが行う処理の手順を示すフローチャートである。（実施例３）
【図１４】図１４は、メモリマップ取得部がスタック領域の開始アドレスと終了アドレスを取得する手順を示すフローチャートである。（実施例４）
【図１５】図１５は、逆アセンブラ、命令挿入部、アセンブラが行う処理の手順を示すフローチャートである。（実施例４）
【発明を実施するための形態】
【００１８】
本発明の実施形態について、図面を参照して説明する。
【００１９】
まず、バッファオーバーフローとバッファオーバーフロー攻撃について説明する。
図１は、C言語により記述されたプログラムがコンピュータ上で動作する場合のプロセス空間の論理的な模式図である。プロセス空間とは、アドレス空間のうちプロセッサ内でのオペレーションシステムの処理によってプロセスに割り当てられた仮想的なアドレス空間をいう。また、アドレス空間とは、一連のメモリアドレスによってアクセス可能なメモリ空間をいう。図1に示すように、プロセス空間は低位アドレスから高位アドレスへ、テキスト領域、静的領域、ヒープ領域、共有ライブラリ、スタック領域が確保される。テキスト領域には、機械語で翻訳されたプログラムが格納される。静的領域には、グローバル変数などの静的変数が格納される。ヒープ領域は、メモリの動的管理で用いられる。共有ライブラリには、複数のプログラムが共通して利用するライブラリが格納される。スタック領域には、関数の戻り値やローカル変数などの関数で一時的に使用されるデータが格納される。
なお、ここではC言語によりプログラムが記述された例を示したが、C言語と同様のメモリ操作を行う他の言語によって記述された場合も同じである。
【００２０】
図２は、バッファオーバーフローによってリターンアドレスが不正なプログラムのコードのアドレスに書き換えられる例を示したスタック領域の模式図である。スタック領域には、ローカル変数などの関数で一時的に使用されるデータを格納するためにバッファ領域が確保されるが、プログラムの動作によってバッファ領域の上限をこえてデータが書き込まれるとバッファ領域以外のスタック領域のデータが上書きされる。これを、バッファオーバーフローという。
【００２１】
バッファ領域に格納されるデータは、ファイルからの入力、ネットワークを経由しての入力、キーボードからの入力など、多くはプログラムの外部から読み込まれる。図２に示すように、不正なプログラムを含むデータを外部からバッファ領域の上限をこえてバッファ領域に読み込ませることで意図的にバッファオーバーフローを生じさせることによりスタック領域に記憶されたリターンアドレスを書き換えて不正なプログラムを実行させることをバッファオーバーフロー攻撃という。
【００２２】
リターンアドレスで指示される先は実行形式のプログラム又はライブラリであるので、図１に説明したように、リターンアドレスはテキスト領域又は共有ライブラリの範囲でなければならない。
一方、バッファオーバーフロー攻撃によって書き換えられたリターンアドレスは本来プログラムが存在すべきではない領域を指示している。本来プログラムが存在すべきではないスタック領域に不正なプログラムが上書きされて実行される例を図２に示す。
【００２３】
本実施形態では、プロセス空間の各領域の開始アドレスと終了アドレスをメモリマップに示される情報から取得する。メモリマップとは、オペレーティングシステムのカーネルにおいてプロセスの状態を示すデータ構造の情報をマッピングしたファイルを指し、例えば、Ｌｉｎｕｘ（登録商標）では、／ｐｒｏｃディレクトリ配下にプロセスＩＤごとに存在する。
【００２４】
図３は、Ｌｉｎｕｘ（登録商標）でのメモリマップの例である。符号ａに開始アドレスが示され、符号ｂに終了アドレスが示される。図１に示すように、スタック領域は、あるアドレスから最高位アドレスまでの連続した領域として設定される（符号ｆ）。また、テキスト領域（符号ｄ）と共有ライブラリ（符号ｅ）は、いずれもアクセス権限（符号ｃ）がｒ−ｘ（読込可、書込不可、実行可）であることから識別ができる。
メモリマップによってプロセス空間の各領域の正確な開始アドレスと終了アドレスを得ることができるために処理の確実性が向上する。
以下、実施例では、オペレーションシステムとしてＬｉｎｕｘ（登録商標）を例として説明するが、メモリマップが取得できる他のオペレーションシステムによるものであってもよい。
【実施例１】
【００２５】
本実施例は、テキスト領域又は共有ライブラリ以外の領域を第１の領域とした処理装置である。スタートアップルーチンを実行することでメモリマップを取得し、メモリマップに示される情報から取得したテキスト領域と共有ライブラリの開始アドレスと終了アドレスを格納する複数組の専用レジスタセットを有し、処理手段を実施する内部命令を有するプロセッサを備えることを特徴とする。
内部命令は、アセンブリ言語のよるリターン命令（ＲＥＴ命令）にニーモニックに対応する図７に示す処理フローを実施する機械語命令である。なお、以下、実施例の記述においては、アセンブリ言語のよるリターン命令をＲＥＴ命令と記述する。【００２６】
図４は、処理装置１の構成を示すブロック図である。本実施例に係るプロセッサ１００は、汎用レジスタ１２１の他にテキスト領域と共有ライブラリの開始アドレスを格納する開始レジスタ１２３と終了アドレスを格納する終了レジスタ１２４の複数組からなる専用レジスタセット１２２を有する。
処理装置１は、図示しないが外部との入出力装置や記憶装置や表示装置などを含むことができる。【００２７】
次に、スタートアップルーチンについて説明する。
図５は、一般的なコンピュータにおいてハードウェアとアプリケーションプログラムを結び付けるカーネルの概念図である。例えば、アプリケーションプログラムがプロセッサにプログラムの実行を指示する際には、システムコールによってカーネルに処理が渡り、処理が終了すると処理を戻す（ｅｘｉｔ）。スタートアップルーチンはカーネルの一種で、アプリケーションプログラムの主処理の実行前にアプリケーションプログラムの実行ファイルにリンクされてスタックの設定やライブラリの初期化などを行う。
本実施例は、スタートアップルーチンによって、アプリケーションプログラムの主処理の実行前にメモリマップに示される情報からメモリ上のテキスト領域と共有ライブラリの開始アドレスと終了アドレスを取得されることを特徴とする。【００２８】
メモリマップに示される情報からテキスト領域と共有ライブラリの開始アドレスと終了アドレスを取得する処理ステップについて説明する。
図６は、図４で示される処理装置１がスタートアップルーチンによりテキスト領域と共有ライブラリの開始アドレスと終了アドレスを取得する手順を示すフローチャートである。本実施例では、テキスト領域と共有ライブラリの開始アドレスと終了アドレスが第１特定情報である。
処理装置１は、アプリケーションプログラムの主処理の実行前にアプリケーションプログラムの実行ファイルにリンクされたスタートアップルーチンを実行することで、アプリケーションプログラムの実行ファイルのメモリマップを取得する（ステップＳ１００）。メモリマップは開始アドレスの低位から高位へ昇順にソートする（ステップＳ１１０）。
メモリマップには図３で示された情報が含まれている。メモリマップの先頭から順に判定を行う（ステップＳ１２０）。アクセス権限がｒ−ｘ（読込可、書込不可、実行可）の場合にテキスト領域又は共有ライブラリと判定し（ステップＳ１３０）、開始アドレスと終了アドレスを同一の専用レジスタセット１２２にある開始レジスタ１２３と終了レジスタ１２４にそれぞれ格納する（ステップＳ１４０）。本実施例では、レジスタセットが第１記憶手段である。【００２９】
次に、図７は、図４に示されるプロセッサ１００において、演算ユニット１２０が行う処理の手順を示すフローチャートである。戻り先がプロセス空間の任意の領域に戻ることができるＲＥＴ命令の処理と比較すると、本実施例でのＲＥＴ命令の処理には図７のａで示される部分の処理が追加されている。【００３０】
次に、ＲＥＴ命令を検出し、その被演算子として指示されるリターンアドレスを取得する処理ステップについて説明する。
図４で示される処理装置１において、外部との入出力装置や記憶装置からロードされたアプリケーションプログラムは機械語に翻訳された実行命令としてメモリ１５０のテキスト領域に格納される。プロセッサ１００の制御ユニット１１０では、フェッチ１１１により実行命令が取得されデコーダ１１２を経て演算ユニット１２０へ制御情報が送られる。この際、演算ユニット１２０がＲＥＴ命令を検出した場合、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得する。【００３１】
次に、リターンアドレスがメモリ上のいずれの領域を指示しているか判定する処理ステップについて説明する。
図４で示される処理装置１の演算ユニット１２０が、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得（ステップＳ２００）した後、同一の専用レジスタセット１２２にある開始レジスタ１２３と終了レジスタ１２４に格納されている開始アドレスと終了アドレスの範囲かどうかの判定（ステップＳ２２０）を行う。【００３２】
次に、リターンアドレスがメモリ上の不正な領域を指示している場合には不正なプログラムの実行を未然に阻止する処理ステップについて説明する。
リターンアドレスの指示先がテキスト領域又は共有ライブラリである場合はリターンアドレスにジャンプ（ステップＳ２５０）し、リターンアドレスの指示先がテキスト領域又は共有ライブラリ以外の領域（第１の領域）の場合はプログラムの実行を強制的に終了する（ステップＳ２４０）。リターンアドレスの指示先がテキスト領域又は共有ライブラリ以外の領域（第１の領域）の場合とは、リターンアドレスがテキスト領域の開始アドレス以上終了アドレス以下の範囲でも共有ライブラリの開始アドレス以上終了アドレス以下の範囲でもない場合である。【００３３】
以上の説明のとおり、本実施例によれば不正にリターンアドレスが書き換えられた場合に、リターンアドレスの指示先がテキスト領域又は共有ライブラリ以外の領域（第１の領域）の場合はプログラムの実行を強制的に終了することでバッファオーバーフローによる不正なプログラムの実行を防止することができる。
また、プロセッサの内部処理で行うために高速な処理が可能であるとともに、アプリケーションプログラム個別の修正作業が不要であり、プログラムの作成に使用される高級言語に依存しない。
【実施例２】
【００３４】
本実施例は、スタック領域を第１の領域とした処理装置である。スタートアップルーチンを実行することでメモリマップを取得し、メモリマップに示される情報から取得したスタック領域の開始アドレスと終了アドレスを格納する一組の専用レジスタセットを有し、処理手段を実施する内部命令を有するプロセッサを備えることを特徴とする。
内部命令は、ＲＥＴ命令にニーモニックに対応する図９に示す処理フローを実施する機械語命令である。【００３５】
図４は、処理装置１の構成を示すブロック図である。本実施例に係るプロセッサ１００は、汎用レジスタ１２１の他にスタック領域の開始アドレスを格納する開始レジスタ１２３と終了アドレスを格納する終了レジスタ１２４の一組からなる専用レジスタセット１２２を有する。スタック領域はひとつの連続した領域なので専用レジスタセット１２２は一組で足りる。
処理装置１は、図示しないが外部との入出力装置や記憶装置や表示装置などを含むことができる。【００３６】
本実施例は、スタートアップルーチンによって、アプリケーションプログラムの主処理の実行前にメモリマップに示される情報からメモリ上のスタック領域の開始アドレスと終了アドレスを取得されることを特徴とする。【００３７】
メモリマップに示される情報からスタック領域の開始アドレスと終了アドレスを取得する処理ステップについて説明する。
図８は、図４で示される処理装置１がスタートアップルーチンによりスタック領域の開始アドレスと終了アドレスを取得する手順を示すフローチャートである。
処理装置１は、アプリケーションプログラムの主処理の実行前にアプリケーションプログラムの実行ファイルにリンクされたスタートアップルーチンを実行することで、アプリケーションプログラムの実行ファイルのメモリマップを取得する（ステップＳ３００）。メモリマップは開始アドレスの低位から高位へ昇順にソートする（ステップＳ３１０）。
メモリマップには図３で示された情報が含まれている。メモリマップの先頭から順に判定を行う（ステップＳ３２０）。スタック領域は最高位アドレスまでの連続した領域として設定されるためにメモリマップの最終行を参照する（ステップＳ３３０）。終了アドレスを終了レジスタ１２４に格納する（ステップＳ３３０）。本実施例では、レジスタセットが第１記憶手段である。
処理装置１は、当該プロセスのスタックサイズ上限値を取得する（ステップＳ３５０）。Ｌｉｎｕｘ（登録商標）の場合はｕｌｉｍｉｔ−ａ（シェルスクリプトがｂａｓｈの場合）などの命令で確認することができる。１６進数の演算により得たスタック領域の終了アドレスからスタックサイズ上限値の差分値（スタック領域下限値）を開始レジスタ１２３にスタック領域の開始アドレスとして格納する（ステップＳ３６０）。
メモリマップに示された開始アドレスをそのまま開始レジスタ１２３に格納しないのはスタック領域のサイズは動的に変更されるが上限値をこえて変更されることはないためである。本実施例では、スタック領域のスタック領域下限値と終了アドレスが第１特定情報である。【００３８】
次に、図９は、図４に示されるプロセッサ１００において、演算ユニット１２０が行う処理の手順を示すフローチャートである。戻り先がプロセス空間の任意の領域に戻ることができるＲＥＴ命令の処理と比較すると、本実施例でのＲＥＴ命令の処理には図９のａで示される部分の処理が追加されている。【００３９】
次に、ＲＥＴ命令を検出し、その被演算子として指示されるリターンアドレスを取得する処理ステップについて説明する。
図４で示される処理装置１において、外部との入出力装置や記憶装置からロードされたアプリケーションプログラムは機械語に翻訳された実行命令としてメモリ１５０のテキスト領域に格納される。プロセッサ１００の制御ユニット１１０では、フェッチ１１１により実行命令が取得されデコーダ１１２を経て演算ユニット１２０へ制御情報が送られる。この際、演算ユニット１２０がＲＥＴ命令を検出した場合、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得する。【００４０】
次に、リターンアドレスがメモリ上のいずれの領域を指示しているか判定する処理ステップについて説明する。
処理装置１の演算ユニット１２０が、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得（ステップＳ４００）した後、開始レジスタ１２３に格納されている開始アドレスとリターンアドレスの値の大小について判定（ステップＳ４１０）を行う。リターンアドレスがスタック領域下限値よりも大きい又は等しいならばスタック領域を指示していると判定する。【００４１】
次に、リターンアドレスがメモリ上の不正な領域を指示している場合には不正なプログラムの実行を未然に阻止する処理ステップについて説明する。
リターンアドレスがスタック領域下限値よりも小さければリターンアドレスにジャンプ（ステップＳ４３０）し、リターンアドレスがスタック領域下限値よりも大きい又は等しいならばプログラムの実行を強制的に終了する（ステップＳ４２０）。【００４２】
以上の説明のとおり、本実施例によれば不正にリターンアドレスが書き換えられた場合に、リターンアドレスの指示先がスタック領域である場合はプログラムの実行を強制的に終了することでバッファオーバーフローによる不正なプログラムの実行を防止することができる。
また、プロセッサの内部処理で行うために高速な処理が可能であるとともに、アプリケーションプログラム個別の修正作業が不要であり、プログラムの作成に使用される高級言語に依存しない。
実施例１と比べると、不正なプログラムがスタック領域に書き込まれている場合に限定されるが、専用レジスタセットが一組で足りるとの特徴を有する。
【実施例３】
【００４３】
本実施例は、テキスト領域又は共有ライブラリ以外の領域を第１の領域とした処理装置である。本実施例は、バッファオーバーフローにより不正にリターンアドレスが書き換えられた場合には不正なプログラムの実行を未然に阻止するようにアプリケーションプログラムのアセンブリコードに命令を追加することを特徴とする。【００４４】
図１０は、本実施例による処理装置３の構成を示すブロック図である。処理装置３は、プロセッサ３００、メモリマップ取得部３１０、逆アセンブラ３２０、リターン命令検出部３３０、命令挿入部３４０、アセンブラ３５０、メモリ３６０を備えた装置である。【００４５】
本実施例はアプリケーションプログラムの実行ファイルが実行される前に動作する。
メモリマップ取得部３１０は、メモリマップに示される情報からテキスト領域と共有ライブラリの開始アドレスと終了アドレスを取得する。本実施例では、テキスト領域と共有ライブラリの開始アドレスと終了アドレスが第１特定情報である。
リターン命令検出部３３０は、ＲＥＴ命令を検出する。
命令挿入部３４０は、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得するためのリターンアドレス取得命令、リターンアドレスがメモリ上のいずれの領域を指示しているか判定するための判定命令、リターンアドレスがメモリ上の不正な領域を指示している場合には不正なプログラムの実行を未然に阻止する強制終了命令を挿入する。【００４６】
図１１は、処理装置３においてメモリマップ取得部３１０がテキスト領域と共有ライブラリの開始アドレスと終了アドレスを取得する手順を示すフローチャートである。【００４７】
処理装置３は、実行しようとするアプリケーションプログラムの実行ファイルのメモリマップを取得する（ステップＳ５００）。メモリマップは開始アドレスの低位から高位へ昇順にソートする（ステップＳ５１０）。メモリマップには図３で示された情報が含まれている。メモリマップの先頭から順に判定を行う（ステップＳ５２０）。アクセス権限がｒ−ｘ（読込可、書込不可、実行可）の場合にテキスト領域又は共有ライブラリと判定し（ステップＳ７２０）、リターンアドレスを保存するための領域をメモリ３６０に確保したうえで開始アドレスと終了アドレスを格納する（ステップＳ５４０）。本実施例では、メモリが第１記憶手段である。【００４８】
図１２及び図１３は、逆アセンブラ３２０、リターン命令検出部３３０、命令挿入部３４０、アセンブラ３５０が行う処理の手順を示すフローチャートである。
処理装置３は、逆アセンブラ３２０によって対象となるアプリケーションプログラムを逆アセンブルする（ステップＳ６００）。
その後、リターン命令検出部３３０ではＲＥＴ命令かを判定する（ステップＳ６２０）。ＲＥＴ命令ならば命令挿入部３４０へ処理を渡す。【００４９】
処理装置３は、命令挿入部３４０ではアプリケーションプログラムのアセンブリコードのＲＥＴ命令の前に次の３つの命令を挿入する。
まず、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得するリターンアドレス取得命令を挿入（ステップＳ６３０）する。
次に、リターンアドレスがテキスト領域又は共有ライブラリを指示しているかを判定する判定命令を挿入（ステップＳ６４０）する。
リターンアドレスがテキスト領域又は共有ライブラリを指示しているかの判定は、リターンアドレスがリターンアドレスを保存するための領域に格納されているテキスト領域及び共有ライブラリの開始アドレスと終了アドレスの範囲かどうかの判定による。
次に、リターンアドレスがテキスト領域又は共有ライブラリを指示していなければプログラムを強制的に終了する強制終了命令を挿入（ステップＳ６５０）する。リターンアドレスの指示先がテキスト領域又は共有ライブラリ以外の領域（第１の領域）の場合とは、リターンアドレスがテキスト領域の開始アドレス以上終了アドレス以下の範囲でも共有ライブラリの開始アドレス以上終了アドレス以下の範囲でもない場合である。【００５０】
図１２に示す手順により命令挿入部３４０により命令が挿入される（ステップＳ６４０及びステップＳ６５０）ことで、テキスト領域が拡張されている。このため、図１３に示すように命令が挿入されたアセンブリコードをアセンブルにより実行ファイルとした後（ステップＳ７００）、再度、逆アセンブルを行ったアセンブルコード（ステップＳ７４０）について再度取得したメモリマップから得たテキスト領域の開始アドレスと終了アドレスで更新を行う（ステップＳ７５０）。その後、アセンブラ３５０によってアセンブルして対象となるアプリケーションプログラムの実行ファイルを完成する（ステップＳ７６０）。【００５１】
以上の説明のとおり、本実施例によれば不正にリターンアドレスが書き換えられた場合に、リターンアドレスの指示先がテキスト領域と共有ライブラリのいずれでもない場合はプログラムの実行を強制的に終了するようにアプリケーションプログラムに命令を追加することでバッファオーバーフローによる不正なプログラムの実行を未然に防止することができるプログラムに変換する。
また、処理装置が、自動的にアセンブリコードへの命令追加を行うために、アプリケーションプログラム個別の修正作業が不要であり、プログラムの作成に使用される高級言語に依存しない。
【実施例４】
【００５２】
本実施例は、スタック領域を第１の領域とした処理装置である。バッファオーバーフローにより不正にリターンアドレスが書き換えられた場合には不正なプログラムの実行を未然に阻止するようにアプリケーションプログラムのアセンブリコードに命令を追加することを特徴とする。【００５３】
図１０は、本実施例による処理装置３の構成を示すブロック図である。処理装置３は、プロセッサ３００、メモリマップ取得部３１０、逆アセンブラ３２０、リターン命令検出部３３０、命令挿入部３４０、アセンブラ３５０、メモリ３６０を備えた装置である。【００５４】
本実施例はアプリケーションプログラムの実行ファイルが実行される前に動作する。
メモリマップ取得部３１０は、メモリマップに示される情報からスタック領域の開始アドレスと終了アドレスを取得する。
リターン命令検出部３３０は、ＲＥＴ命令を検出する。
命令挿入部３４０は、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得するためのリターンアドレス取得命令、リターンアドレスがメモリ上のいずれの領域を指示しているか判定するための判定命令、リターンアドレスがメモリ上の不正な領域を指示している場合には不正なプログラムの実行を未然に阻止する強制終了命令を挿入する。【００５５】
図１４は、処理装置３においてメモリマップ取得部３１０がスタック領域の開始アドレスと終了アドレスを取得する手順を示すフローチャートである。
処理装置３は、実行しようとするアプリケーションプログラムの実行ファイルのメモリマップを取得する（ステップＳ８００）。メモリマップは開始アドレスの低位から高位へ昇順にソートする（ステップＳ８１０）。メモリマップには図３で示された情報が含まれている。メモリマップの先頭から順に判定を行う（ステップＳ８２０）。スタック領域は最高位アドレスまでの連続した領域として設定されるためにメモリマップの最終行を参照する（ステップＳ８３０）。リターンアドレスを保存するための領域をメモリ３６０に確保したうえで終了アドレスを格納する（ステップＳ８４０）。
次に、処理装置３は、当該プロセスのスタックサイズ上限値を取得する（ステップＳ８５０）。Ｌｉｎｕｘ（登録商標）の場合はｕｌｉｍｉｔ−ａ（シェルスクリプトがｂａｓｈの場合）などの命令で確認することができる。１６進数の演算により得たスタック領域の終了アドレスからスタックサイズ上限値の差分値（スタック領域下限値）を保存するための領域をメモリ３６０に確保したうえで格納する（ステップＳ８６０）。本実施例では、メモリが第１記憶手段である。
メモリマップに示された開始アドレスをそのままリターンアドレスを保存するための領域に格納しないのはスタック領域のサイズは動的に変更されるが上限値をこえて変更されることはないためである。本実施例では、スタック領域のスタック領域下限値と終了アドレスが第１特定情報である。【００５６】
図１５は、逆アセンブラ４２０、命令挿入部４３０、アセンブラ４４０が行う処理の手順を示すフローチャートである。
処理装置３は、逆アセンブラ４２０によって対象となるアプリケーションプログラムを逆アセンブルする（ステップＳ９００）。
その後、リターン命令検出部３３０ではＲＥＴ命令かを判定する（ステップＳ９２０）。ＲＥＴ命令ならば命令挿入部４３０へ処理を渡す。
処理装置３は、命令挿入部４３０ではアプリケーションプログラムのアセンブリコードのＲＥＴ命令の前に次の３つの命令を挿入する。
まず、ＲＥＴ命令の被演算子として指示されるリターンアドレスを取得するリターンアドレス取得命令を挿入（ステップＳ９３０）する。
次に、リターンアドレスがスタック領域を指示しているかを判定する判定命令を挿入（ステップＳ９４０）する。
リターンアドレスがスタック領域を指示しているかの判定は、リターンアドレスがスタック領域下限値よりも大きい又は等しいならばリターンアドレスがスタック領域を指示していると判定する。
次に、リターンアドレスがスタック領域を指示していればプログラムを強制的に終了する強制終了命令を挿入（ステップＳ９５０）する。これにより、リターンアドレスがメモリ上の不正な領域を指示している場合には不正なプログラムの実行を未然に阻止する。【００５７】
以上の説明のとおり、本実施例によれば不正にリターンアドレスが書き換えられた場合に、リターンアドレスの指示先がスタック領域である場合はプログラムの実行を強制的に終了するようにアプリケーションプログラムに命令を追加することでバッファオーバーフローによる不正なプログラムの実行を未然に防止することができる。
また、処理装置が、自動的にアセンブリコードへの命令追加を行うために、アプリケーションプログラム個別の修正作業が不要であり、プログラムの作成に使用される高級言語に依存しない。
実施例３と比べると、不正なプログラムがスタック領域に書き込まれている場合に限定されるが、プログラムの実行サイズが小さいので更新処理が速いとの特徴を有する。
【産業上の利用可能性】
【００５８】
バッファオーバーフローによる不正なプログラムの実行を未然に防止できる。
【符号の説明】
【００５９】
１      処理装置
１００  プロセッサ
１１０  制御ユニット
１１１  フェッチ
１１２  デコード
１２０  演算ユニット
１２１  汎用レジスタ
１２２  専用レジスタセット
１２３  開始レジスタ
１２４  修了レジスタ
１２５  演算器
１５０  メモリ
３      処理装置
３００  プロセッサ
３１０  メモリマップ取得部
３２０  逆アセンブラ
３３０  リターン命令検出部
３４０  命令挿入部
３５０  アセンブラ
【要約】
本発明は、バッファオーバーフローによる不正なプログラムの実行を確実に防止する技術を提供することを目的とする。
本発明は、メモリ上の各領域の開始アドレスと終了アドレスを取得し、アセンブリ言語によるリターン命令を検出し、その被演算子として指示されるリターンアドレスを取得し、リターンアドレスがメモリ上のいずれの領域
を指示しているか判定し、リターンアドレスがメモリ上の不正な領域を指示している場合には不正なプログラムの実行を未然に防止する。【図１】
0005777843.tif 000002
【図２】
0005777843.tif 000003
【図３】
0005777843.tif 000004
【図４】
0005777843.tif 000005
【図５】
0005777843.tif 000006
【図６】
0005777843.tif 000007
【図７】
0005777843.tif 000008
【図８】
0005777843.tif 000009
【図９】
0005777843.tif 000010
【図１０】
0005777843.tif 000011
【図１１】
0005777843.tif 000012
【図１２】
0005777843.tif 000013
【図１３】
0005777843.tif 000014
【図１４】
0005777843.tif 000015
【図１５】
0005777843.tif 000016