(57)【要約】【課題】バッファオーバーフローに関する不正アクセスを確実且つ容易に防止する。【解決手段】メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行う情報機器は、いずれかのプログラムコードの呼び出しをフックしてスタックレイアウトチェック処理を行う。スタックレイアウトチェック処理では、メモリに展開された各プログラムコードのリターンアドレスが順次取得され、各リターンアドレスが示すアドレスの属性情報に基づいてデータ処理が停止される。【選択図】図１
2009199529.tif 000002
【特許請求の範囲】
【請求項１】
メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行う情報機器であって、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示すアドレスの属性情報を取得する属性取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報に基づいて前記データ処理を停止させる停止手段と、
を備える情報機器。
【請求項２】
前記メモリは、各プログラムコードのリターンアドレスを格納するスタック領域を備え、
前記リターンアドレス取得手段は、前記スタック領域に格納されたリターンアドレスをトレースして取得する請求項１に記載の情報機器。
【請求項３】
前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報が、プログラムコードを格納するコード領域を示す情報でない場合に、前記データ処理を停止させる請求項１又は２に記載の情報機器。
【請求項４】
前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報が、データの書き込みが許可された領域を示す情報である場合に、前記データ処理を停止させる請求項１〜３のいずれか一項に記載の情報機器。
【請求項５】
メモリに展開された各プログラムコードを実行するコンピュータを、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示すアドレスの属性情報を取得する属性取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報に基づいて前記各プログラムコードによるデータ処理を停止させる停止手段、
として機能させるためのプログラム。
【請求項６】
メモリに展開された各プログラムコードを実行するコンピュータにおける不正なプログラムコードの実行防止方法であって、
前記いずれかのプログラムコードの呼び出し時を検出し、当該検出されたプログラムコードの呼び出し時において、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得し、当該順次取得されたリターンアドレスが示すアドレスの属性情報を取得し、当該取得された各リターンアドレスが示すアドレスの属性情報に基づいて前記各プログラムコードによるデータ処理を停止させる不正なプログラムコードの実行防止方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、情報機器、プログラム及び不正なプログラムコードの実行防止方法に関する。
【背景技術】
【０００２】
一般的に、ＰＣ（Personal  Computer）やＷＳ（Work  Station）等の情報機器では、ＣＰＵ（Central  Processing  Unit）などの制御部がＲＡＭ（Random  Access  Memory）等の記憶部の作業領域に展開されたプログラムコードを順次実行することで、各種データ処理を実行している。近年、上記情報機器においては、悪意のあるユーザによりプログラムコードの実行時に不正な操作が行われることで、データの盗みだしや改竄などの不正アクセスが発生している。
【０００３】
通常、情報機器が管理するデータにはアクセス権限が設定されている。従って、データへのアクセス権限がなければ、不正アクセスが行われることはない。しかしながら、データへのアクセス権限がある通常のプログラムコードを利用し、不正な操作が実行された場合は、不正アクセスが可能となる。上述したプログラムコードを利用して不正アクセスを可能とする手法としては、プログラムコードの実行時のデータをＲＡＭ等に確保された所定領域からオーバーフローさせる、いわゆるバッファオーバーフローを用いた手法が知られている。
【０００４】
ここで、バッファオーバーフローを用いた不正アクセスについて、正常にプログラムコードが実行された場合と、プログラムコードの実行時に不正が行われた場合と、を比較して詳細に説明する。
【０００５】
先ず、図１１、図１２を参照して正常にプログラムコードが実行された場合を説明する。図１１は、プログラムコードのソースコードを例示する概念図であり、図１２は、プログラムコード実行時におけるスタック領域の概要を例示する概念図である。
【０００６】
図１１に例示されたソースコードによるプログラムコードは、main()関数から開始され、当該main()関数の中でstrcpy_helloworld()関数を呼び出している。このプログラムコードでは、strcpy_helloworld()関数の中で画面などに表示する「hello!」という文字列を用意し、main()関数のprintf()関数でそれを表示させている。関数とは、所定の機能をモジュール化してまとめたサブルーチンやサブプログラムなどであり、メインとなるプログラム内で随時呼び出すことができる。
【０００７】
上記プログラムコードの実行時のデータは、ＲＡＭ等に確保されたスタック領域に格納される。このスタック領域では、後入れ先出し (LIFO: Last In First Out; FILO: First In Last Out) 構造でデータが格納される。具体的には、図１２に示すように、上から下に向かって順次確保された領域へプログラムコードの実行時のデータが格納される。
【０００８】
例えば、図１１に例示したソースコードによるプログラムコードの実行時には、main()関数を処理した際に、ReturnAddress1、ebp  Backup、char  Buf[8]などが１つのスタックフレームとして格納される。次いで、main()関数の中でstrcpy_helloworld()関数が呼び出された際に、ReturnAddress2、ebp  Backup2、int  iなどが一つのスタックフレームとして格納される。
【０００９】
ReturnAddressは、プログラムの終了時に戻るべきアドレス値や、関数などによりサブプログラムが呼び出された場合の当該サブプログラム終了時に戻るべきアドレス値を示す。このReturnAddressは、プログラムの実行直後や関数などによりサブプログラムが呼び出された直後に、ＣＰＵにより自動的にスタック領域へ格納される。
【００１０】
ebpは、ＣＰＵのレジスタの一種であり、現在使用している一時的なメモリ領域のアドレスの直前を示す。図１２の例では、char  Buf[8]、int  iの前のアドレスであり、スタックフレームのReturnAddressが該当する。従って、スタックフレームにおいて、上記レジスタ値をebp  Backupとしてバックアップすることで、当該スタックフレーム内の一領域を一時的なデータ（変数や配列等）を格納するメモリ領域として簡単に使用することが可能となる。
【００１１】
char  Buf[8]は、main()関数で使用される配列であるBufを格納する。このBufは、char型の変数（１バイト）を８個格納する配列であり、８バイト分のデータが格納可能となっている。int  iは、strcpy_helloworld()関数で使用されるint型の変数であるiを格納する。
【００１２】
従って、上記プログラムコードの実行により、スタック領域では、main()関数のスタックフレームが確保され、strcpy_helloworld()関数のスタックフレームが確保される。次いで、int  iの値が順次インクリメントされて、「hello!」という６バイト分の文字列がchar  Buf[8]に格納される。次いで、strcpy_helloworld()関数の終了により、ReturnAddress2が読み出されてmain()関数へ復帰され、main()関数の終了により、ReturnAddress1が読み出されてプログラムは正常終了する。
【００１３】
次に、図１３、図１４を参照してプログラムコードの実行時に不正が行われた場合を説明する。図１３は、プログラムコードのソースコードを例示する概念図であり、図１４は、プログラムコード実行時におけるスタック領域の概要を例示する概念図である。
【００１４】
図１３に例示されたソースコードによるプログラムコードは、前述した図１１と比較すればわかるとおり、配列bufへ「Hello World」という１２バイト分（11文字+文字列終端）のデータを書き込んでいる。
【００１５】
図１４に示すように、スタック領域では、配列bufを格納する領域として８バイト分の領域が確保されている。従って、strcpy_helloworld()関数が実行された際には、確保されているサイズ以上のデータが書き込まれることとなる。このように、メモリに確保されているサイズ以上のデータが書き込まれることをバッファオーバーフローという。また、このバッファオーバーフローがスタック領域で起きる場合をスタックベースのバッファオーバーフローという。
【００１６】
図１４に例示したスタック領域おいて、領域の確保は上から下に向かって順次行われ、その確保された領域へのデータの書き込みは下から上に向かって行われる。従って、ReturnAddress1、ebp  Backupはstrcpy_helloworld()関数が実行された際に、「Hello World」という１２バイト分のデータにより不正に上書き（overwrite）される。上述した上書きにより、ReturnAddress1の内容が実行可能なプログラムコードが置いてあるアドレスに書き換えられた場合は、main()関数の終了によりReturnAddress1が読み出され、その書き換えられたプログラムコードが実行される。
【００１７】
図１３に例示したソースコードでは、「Hello World」という予め定義された文字列によりオーバーフローとなっている。しかしながら、実際には、メールサーバやＷｅｂサーバ等の通信ポートで受信されたデータや、コンソールやファイルから入力されたデータなどが配列bufに格納される場合もある。このような場合は、悪意のあるユーザにより通信、コンソール入力、ファイル入力などを介して任意のプログラムコードが実行され、データの盗みだしや改竄などの不正アクセスが発生する。
【００１８】
上述した不正アクセスを防止するための有用な技術としては、特許文献１、２がある。特許文献１には、ＣＰＵが有するデバッグ機能を使用してプログラムの流れを随時チェックし、不正アクセスを防止することが開示されている。具体的には、プログラムコードにおける実行フローの妥当性をチェックし、妥当でない実行フローに遷移した場合、プログラムコードが攻撃を受けたものとして、その実行を停止もしくは修正する。また、特許文献２には、プログラムコードに随時バッファオーバーフロー検出のプログラムコードを挿入することが開示されている。
【特許文献１】国際公開番号ＷＯ２００５／０２４６３０
【特許文献２】特開２００１−２１６１６１号公報
【発明の開示】
【発明が解決しようとする課題】
【００１９】
しかしながら、上記従来技術では、上述したバッファオーバーフローに関する不正アクセスの防止を十分に行うことができなかった。
【００２０】
例えば、特許文献１では、実行フローの妥当性を定義する必要があるが、その定義は非常に難しい。不正なプログラムコードの実行による場合と正常なプログラムコードによる場合との差異を区別することは困難である。このため、不正アクセスを確実に防止するには十分ではなかった。さらに、この特許文献１に記載の技術を実装するには、ＣＰＵのデバック機能に依存する必要があり、パフォーマンスの低下を招く虞があった。
【００２１】
また、特許文献２では、防御対象となるプログラムコードのソースコードが必要となる。従って、プログラムコードの開発元（提供元）が不正検出用のプログラムコードを挿入しなければならず、実質的に開発元が提供することでしか実施できない。
【００２２】
本発明の課題は、上記従来技術の問題に鑑みてなされたものであり、バッファオーバーフローに関する不正アクセスを確実且つ容易に防止する技術を提供することである。
【課題を解決するための手段】
【００２３】
上記課題を解決するために、請求項１に記載の発明は、メモリに展開された各プログラムコードと中央制御部との協働によりデータ処理を行う情報機器であって、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示すアドレスの属性情報を取得する属性取得手段と、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報に基づいて前記データ処理を停止させる停止手段と、
を備える。
【００２４】
請求項２に記載の発明は、請求項１に記載の発明において、前記メモリは、各プログラムコードのリターンアドレスを格納するスタック領域を備え、
前記リターンアドレス取得手段は、前記スタック領域に格納されたリターンアドレスをトレースして取得する。
【００２５】
請求項３に記載の発明は、請求項１又は２に記載の発明において、前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報が、プログラムコードを格納するコード領域を示す情報でない場合に、前記データ処理を停止させる。
【００２６】
請求項４に記載の発明は、請求項１〜３のいずれか一項に記載の発明において、前記停止手段は、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報が、データの書き込みが許可された領域を示す情報である場合に、前記データ処理を停止させる。
【００２７】
請求項５に記載の発明は、メモリに展開された各プログラムコードを実行するコンピュータを、
前記いずれかのプログラムコードの呼び出し時を検出する検出手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記リターンアドレス取得手段により順次取得されたリターンアドレスが示すアドレスの属性情報を取得する属性取得手段、
前記検出手段により検出されたプログラムコードの呼び出し時に、前記属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報に基づいて前記各プログラムコードによるデータ処理を停止させる停止手段、
として機能させる。
【００２８】
請求項６に記載の発明は、メモリに展開された各プログラムコードを実行するコンピュータにおける不正なプログラムコードの実行防止方法であって、
前記いずれかのプログラムコードの呼び出し時を検出し、当該検出されたプログラムコードの呼び出し時において、前記メモリに展開された各プログラムコードのリターンアドレスを順次取得し、当該順次取得されたリターンアドレスが示すアドレスの属性情報を取得し、当該取得された各リターンアドレスが示すアドレスの属性情報に基づいて前記各プログラムコードによるデータ処理を停止させる。
【発明の効果】
【００２９】
本発明によれば、バッファオーバーフローに関する不正アクセスを確実且つ容易に防止することが可能となる。
【発明を実施するための最良の形態】
【００３０】
以下、本発明の実施の形態について図を参照して説明するが、この発明の範囲は以下の実施の形態に限定されない。
【００３１】
先ず、本実施の形態に係る情報機器の構成について、図１、図２を参照して説明する。図１は、情報機器１の機能的構成を模式的に示すブロック図である。図２は、ＲＡＭ３０のスタック領域を例示する概念図である。
【００３２】
図１に示すように、情報機器１は、ＣＰＵ１０、記憶部２０、ＲＡＭ３０、操作部４０、表示部５０、Ｉ／Ｆ部６０を有する。上記情報機器１の各部はバス７０により電気的に接続されている。具体的には、情報機器１は、ＰＣ、ＷＳ、ＰＤＡ（Personal  Digital  Assistant）、携帯電話などであってよい。
【００３３】
ＣＰＵ１０は、情報機器１の動作を中央制御する。具体的には、ＣＰＵ１０は、記憶部２０に記憶されたプログラムコードや各種データをＲＡＭ３０の作業領域に展開し、当該ＲＡＭ３０に展開されたデータとの協働により各部へ制御信号を出力することで、上記中央制御を行う。
【００３４】
記憶部２０は、プログラムコードや各種設定情報などのデータをＣＰＵ１０から読み書き可能に記憶する。例えば、記憶部２０は、ＨＤＤ（Hard  Disk  Drive）や半導体メモリなどであってよい。また、記憶部２０は、上記データをＲＯＭ（Read  Only  Memory）などに記憶する構成であってもよい。なお、記憶部２０が記憶するプログラムコードとしては、ＯＳ（Operating System）などの基本的なソフトウエアの他、ベンダーが提供した各種アプリケーションプログラム、後述する処理に係るプログラムなどが含まれる。
【００３５】
ＲＡＭ３０には、プログラムコードの実行時のデータを格納するスタック領域が確保される。具体的には、図２に示すようなスタック領域がＲＡＭ３０の所定領域に確保される。このスタック領域では、スタックフレームごとにデータが格納される。一つのスタックフレームには、ReturnAddress、ebp  Backup、プログラムコードの実行時に一時的に使われるデータ（変数や配列等）などのデータが格納される。
【００３６】
ReturnAddressはプログラムコードの戻り先アドレスである。ebp  Backupは一つ前のスタックフレームのebp  Backupを示す。ebp  Backupの直前にはReturnAddressがあるので、ebp  Backupを辿ることでReturnAddressを順次トレースして取得することが可能となる。
【００３７】
上記スタックフレームは、各プログラムコードが順次実行された場合に、そのプログラムコードの実行に伴って順次確保される。例えば、メインとなるプログラムコードが実行され、そのプログラムコード内でサブルーチンに関するプログラムコードが呼び出され、更に別のプログラムコードが呼び出された場合などは、図示したとおり、スタックフレームＦｒ１〜Ｆｒ３の順に各プログラムコードに係る領域が確保される。この各プログラムコードに係る処理が終了した際には、スタックフレームＦｒ１〜Ｆｒ３のReturnAddressが読み出されることで、メインとなるプログラムコードへの復帰や、プログラム終了後の処理が行われる。
【００３８】
操作部４０は、ユーザからの操作入力を受け付け、当該操作に応じた操作信号をＣＰＵ１０へ出力する。例えば、操作部４０は、文字入力キー、数字入力キー、その他各種機能に対応付けられたキーを備えたキーボード、マウス等のポインティングデバイスなどであってよい。
【００３９】
表示部５０は、ＣＰＵ１０から出力された表示制御信号に基づいた画像を表示画面に表示する。例えば、表示部５０は、ＣＲＴ（Cathode  Ray  Tube）、ＬＣＤ（Liquid  Crystal  Display）などであってよい。
【００４０】
Ｉ／Ｆ部６０は、データ通信用ＩＣ（Integrated  Circuit）や接続コネクタなどを備え（いずれも図示しない）、外部機器や通信ネットワークと通信可能に接続する。例えば、Ｉ／Ｆ部６０は、ＵＳＢ（Universal Serial Bus）通信ポートや、ＬＡＮ（Local  Area  Network）、ＷＡＮ（Wide  Area  Network）、インターネットなどと接続するネットワークインターフェイスカード（ＮＩＣ：Network  Interface  Card）であってよい。
【００４１】
次に、情報機器１のＣＰＵ１０の制御の下で実行される処理について、図３〜図１０を参照して詳細に説明する。
【００４２】
図３は、情報機器１のフック処理を示すフローチャートである。図４〜図６は、関数を動的に生成するためのソースコードを例示する概念図である。図７は、通常の関数呼び出しを例示する概念図である。図８は、フックされた関数呼び出しを例示する概念図である。図９は、情報機器１のスタックレイアウトチェック処理を示すフローチャートである。図１０は、情報機器１のスタックレイアウトチェック処理の変形例を示すフローチャートである。
【００４３】
情報機器１において、不正なプログラムコードの実行を防止するためには、当該不正なプログラムコードの実行に必要なＡＰＩ、ライブラリ関数、システムコールなどの検出、すなわち、サブプログラムコードの呼び出しを検出し、不正なプログラムコードの実行の有無をチェックする処理を挿入する必要がある。本実施の形態では、このサブプログラムコードの呼び出し検出と、不正のチェックを行う処理の挿入を、フック（Hook）を用いて実現している。
【００４４】
フックは、プログラム中の特定の箇所に、利用者が独自の処理を追加できるようにする仕組みである。すなわち、フックされる側のプログラムコードを作成したプログラマーと、フックする側のプログラムコードを作成したプログラマーと、が同じプログラマーでなく、互いのプログラムコードに関するソースコードが同一のプログラマーにより作成されない場合に利用される仕組みである。従って、ベンダーが提供するＯＳや関数の機能変更や、任意の処理の追加時に使用される。
【００４５】
なお、フックは、チェック対象となる関数などのサブプログラムをプログラマー自身が修正可能である場合であっても用いてよい。但し、プログラマー自身がサブプログラムを修正可能であり、当該サブプログラムが実行された際に不正のチェックを行うように修正した場合は、フックを使用する必要はなくなるとともに、既存の関数やライブラリをより安全なものとして実装することが可能となる。
【００４６】
先ず、ＡＰＩフック（ライブラリ関数をフック）して不正なプログラムコードの実行の有無をチェックする場合について図３〜図９を参照して説明する。
【００４７】
以下では、ベンダーが用意したWinExec()というライブラリ関数のフックを例示し、当該ライブラリ関数が呼び出された際に実行されるスタックレイアウトチェック処理を例示している。
【００４８】
図３に示すように、WinExec()というライブラリ関数が呼び出されることで、フック処理が開始されると、WinExec()の関数の存在するアドレスが取得される（ステップＳ１）。この関数のアドレス取得は、ベンダーから提供される関数を呼び出すことで可能である。
【００４９】
次いで、ＡＰＩの実行にフックをかける小さな関数（一時的な関数）が動的に生成される（ステップＳ２）。この動的に生成される関数とは、後述するスタックレイアウトチェック処理を呼び出す関数である。
【００５０】
次いで、WinExec()関数の先頭コードの書き換えが行われ、ステップＳ２で生成された関数にジャンプするように変更される（ステップＳ３）。
【００５１】
上述したＡＰＩフック用の関数を動的に生成するためのソースコードを図４〜図６に例示する。図４に示すように、ソースコードＣ１は、フックターゲットのコードを定義する。図５に示すように、ソースコードＣ２は、実際に生成されるコードのテンプレートを出力するTrampolineStdcall_CodeHook()関数である。この関数の中で、0xccccccc1とある部分では、WinExec()関数のアドレスに５バイト加算したアドレスを入力する。また、５つあるnopとある部分では、コード書き換え前のオリジナルのWinExec()関数の先頭５バイトをそのままコピーする。
【００５２】
図６に示すように、ソースコードＣ３は、BuildTrampolineCode_CodeHook()関数である。この関数により、TrampolineStdcall_CodeHook()関数の２つの書き換えが行われる。
【００５３】
情報機器１では、上述したフック処理により、サブプログラムコードの呼び出しを検出し、不正のチェックを行う処理の挿入が可能となっている。通常、関数に係るサブプログラムが呼び出された場合は、図７に示すように、関数ｆ１で呼び出された関数ｆ２、ｆ３や、関数ｆ２で呼び出された関数ｆ４がそのまま実行される。しかしながら、情報機器１では、図８に示すように、関数ｆ１で関数ｆ２が呼び出された場合、関数ｆ２が呼び出される前にスタックレイアウトチェック処理を呼び出すフック関数ｆ２ａが実行される。
【００５４】
図９に示すように、フック処理に次いで、スタックレイアウトチェック処理が開始されると、StackWolk()ライブラリの初期化が行われる（ステップＳ１１）。StackWolk()ライブラリは、ベンダーが用意したスタックトレースを行う関数である。このStackWolk()を利用してトレース位置をインクリメント又はデクリメントすることで、スタック領域に格納されたリターンアドレスを順次取得することが可能となる。
【００５５】
次いで、StackWolk()が呼び出されてスタック領域のスタックフレームを順次呼び出すように、スタックが１つバックトレースされ（ステップＳ１２）、トレース後にリターンアドレスが正しく取得できたか否かが判定される（ステップＳ１３）。
【００５６】
ステップＳ１３において、リターンアドレスが正しく取得できない場合は、正常終了としてチェック対象であるWinExec()の実行が続行される。これは不正アクセス以外の未知の理由などにより、スタックが破壊されており、StackWolk()が正常に動作しない場合等が該当する。なお、本実施の形態では、StackWolk()が正常に動作しない場合に正常終了しているが、このスタックトレースが失敗した場合にも、プログラムの停止や、ユーザに停止するか否かを確認するためのダイアログを表示部５０へ表示してもよい。
【００５７】
ステップＳ１３において、リターンアドレスが正しく取得できた場合は、取得されたリターンアドレスが示すメモリ領域の属性情報が取得される（ステップＳ１４）。この属性情報は、アドレスを指定することで当該アドレスの属性情報を出力する関数などが用いて取得される。
【００５８】
次いで、ステップＳ１３により取得された属性情報に基づいて、リターンアドレスが示すメモリ領域がコード領域であるか否かが判定される（ステップＳ１５）。コード領域とは、プログラムコードが格納されるメモリ領域である。このステップＳ１５において、コード領域であると判定された場合は、リターンアドレスが示すメモリ領域が書き込みが不可であるか否か（又は、書き込みが許可された領域であるか否か）が判定される（ステップＳ１６）。
【００５９】
ステップＳ１６において、書き込みが不可な領域であると判定された場合は、未チェックのリターンアドレスが存在するか否かが判定され（ステップＳ１７）、未チェックのリターンアドレスが存在する場合はステップＳ１２へ戻って、次のリターンアドレスがトレースされる。また、ステップＳ１７において、未チェックのリターンアドレスが存在しない場合は正常終了としてチェック対象であるWinExec()が実行される。
【００６０】
ステップＳ１５においてコード領域でない（データ領域である）と判定された場合、及び、ステップＳ１６において書き込みが不可でない領域（書き込みが許可された領域）と判定された場合は、不正アクセス等の攻撃を検出し、不正なプログラムコードの実行を防止するためにデータ処理を一時的に停止する旨のダイアログが表示部５０に表示され（ステップＳ１８）、プログラムの実行が停止される（ステップＳ１９）。
【００６１】
不正なプログラムコードなどは、データを格納するデータ領域に一旦格納された後、バッファオーバーフローを利用して実行権限を有するプログラムコードによりデータ領域から実行される。従って、情報機器１では、ステップＳ１５において、リターンアドレスが示すメモリ領域がコード領域でない（データ領域である）と判定された場合にプログラムの実行が停止されるため、不正なプログラムコードの実行を防止することが可能となる。
【００６２】
また、不正なプログラムコードなどは、データを格納するデータ領域に一旦格納される必要があるため、データの書き込みが許可された領域に存在する。従って、情報機器１では、ステップＳ１６において、リターンアドレスが示すメモリ領域が書き込みが許可された領域であると判定された場合にプログラムの実行が停止されるため、不正なプログラムコードの実行を防止することが可能となる。
【００６３】
次に、変形例として、システムコールをフックして不正なプログラムコードの実行の有無をチェックする場合について図１０を参照して説明する。
【００６４】
図１０では、何らかのシステムコールが呼び出された際に、カーネルからユーザランドのスタックをチェックするスタックレイアウトチェック処理を例示している。なお、このスタックレイアウチェック処理では、通常のebpを用いた方法でスタックトレースを行っている。
【００６５】
スタックレイアウトチェック処理は、システムコールを処理しているカーネル内の関数をフックすることで、当該システムコール処理の前に実行される。このように、システムコールをフックすることで、スタックレイアウトチェック処理に関するプログラムコードをカーネルモジュールとして作成することが可能となり、カーネル本体のリビルドや改造を必要としない。
【００６６】
従って、カーネルのソースコードが未公開の場合であっても実装可能である。また、ソースコードが提供されている場合であっても、カーネルの入れ替えをする必要がなく、カーネルモジュールをインストールするだけで実装可能である。
【００６７】
図１０に示すように、システムコールが呼び出されることで、スタックレイアウトチェック処理が開始されると、現在のebpの値から最新のebp  backupが取得される（ステップＳ２１）。すなわち、ステップＳ２１では、ＲＡＭ３０のスタック領域における現在の読み出し位置が取得される。
【００６８】
次いで、ebp  backupからその直前にあるリターンアドレスが取得され（ステップＳ２３）、リターンアドレスが正しく取得できたか否かが判定される（ステップＳ２３）。ステップＳ２３において、リターンアドレスが正しく取得できない場合は、前述したステップＳ１３と同様に正常終了となり、呼び出されたシステムコードが実行される。
【００６９】
ステップＳ２３において、リターンアドレスが正しく取得できた場合は、そのリターンアドレスが含まれるスタックフレームがシグナル処理用のスタックフレームであるか否かが判定される（ステップＳ２４）。このスタックフレームの判定は、予め用意されたライブラリ関数（例えばlibunwind関数）の出力結果などに基づいて行われる。
【００７０】
ステップＳ２４において、スタックフレームがシグナル処理用のスタックフレームであると判定された場合は、正常終了となり、呼び出されたシステムコードが実行される。シグナル処理とは、ＯＳの種類や設定によって異なるが、シグナル処理の場合は、プログラムの実行方法が特殊になる場合があり、スタックフレームも特殊なレイアウトになる。したがって、誤検知を避けるために、シグナル処理の場合はチェックを中断し、常に正常終了としている。
【００７１】
ステップＳ２４において、スタックフレームがシグナル処理用のスタックフレームでないと判定された場合は、前述したステップＳ１４〜Ｓ１７と同様の処理が行われる（ステップＳ２６〜Ｓ２８）。なお、ステップＳ２８において、未チェックのリターンアドレスが存在する場合は、ebp  backupから次のebp  backupが取得され（ステップＳ２９）、ステップＳ２２へ戻って、次のリターンアドレスが取得される。
【００７２】
また、ステップＳ２６においてコード領域でない（データ領域である）と判定された場合、及び、ステップＳ２７において書き込みが不可でない領域（書き込みが許可された領域）と判定された場合は、ステップＳ１８、Ｓ１９と同様に、プログラムの実行が停止される（ステップＳ３０、Ｓ３１）。
【００７３】
従って、情報機器１では、システムコールが呼び出された場合も、ステップＳ２６において、リターンアドレスが示すメモリ領域がコード領域でない（データ領域である）と判定された場合にプログラムの実行が停止されるため、不正なプログラムコードの実行を防止することが可能となる。同様に、情報機器１では、ステップＳ２７において、リターンアドレスが示すメモリ領域が書き込みが許可された領域であると判定された場合にプログラムの実行が停止されるため、不正なプログラムコードの実行を防止することが可能となる。
【００７４】
以上のように、情報機器１は、メモリ（ＲＡＭ３０）に展開された各プログラムコードと中央制御部（ＣＰＵ１０）との協働によりデータ処理を行う。また、情報機器１は、いずれかのプログラムコードの呼び出し時を検出する検出手段（ＣＰＵ１０、フック処理）と、検出手段により検出されたプログラムコードの呼び出し時に、メモリに展開された各プログラムコードのリターンアドレスを順次取得するリターンアドレス取得手段（ＣＰＵ１０、ステップＳ１２、Ｓ２２）と、検出手段により検出されたプログラムコードの呼び出し時に、リターンアドレス取得手段により順次取得されたリターンアドレスが示すアドレスの属性情報を取得する属性取得手段（ＣＰＵ１０、ステップＳ１４、Ｓ２５）と、検出手段により検出されたプログラムコードの呼び出し時に、属性取得手段により取得された各リターンアドレスが示すアドレスの属性情報に基づいてデータ処理を停止させる停止手段（ＣＰＵ１０、ステップＳ１９、Ｓ３１）と、を備える。
【００７５】
このため、情報機器１は、プログラムコードの呼び出し時において、メモリに展開された各プログラムコードのリターンアドレスを全てチェックして、データ処理の停止の有無を制御することができる。また、情報機器１は、各プログラムコードを改変する必要がない。従って、１は、バッファオーバーフローに関する不正アクセスを確実且つ容易に防止することが可能となる。
【００７６】
なお、上述した実施の形態における記述は、一例を示すものであり、これに限定するものではない。上述した実施の形態における構成及び動作に関しては、適宜変更が可能である。
【００７７】
例えば、以上の説明では、本発明に係るプログラムのコンピュータ読み取り可能な媒体として記憶部２０やＲＯＭを使用した例を開示したが、この例に限定されない。その他のコンピュータ読み取り可能な媒体として、フラッシュメモリ等の不揮発性メモリ、ＣＤ-ＲＯＭ等の可搬型記録媒体を適用することが可能である。また、本発明に係るプログラムのデータをＩ／Ｆ部６０と接続する通信回線を介して提供する媒体として、キャリアウエーブ(搬送波)も本発明に適用される。
【図面の簡単な説明】
【００７８】
【図１】本実施の形態に係る情報機器の機能的構成を模式的に示すブロック図である。
【図２】ＲＡＭのスタック領域を例示する概念図である。
【図３】情報機器のフック処理を示すフローチャートである。
【図４】関数を動的に生成するためのソースコードを例示する概念図である。
【図５】関数を動的に生成するためのソースコードを例示する概念図である。
【図６】関数を動的に生成するためのソースコードを例示する概念図である。
【図７】通常の関数呼び出しを例示する概念図である。
【図８】フックされた関数呼び出しを例示する概念図である。
【図９】情報機器のスタックレイアウトチェック処理を示すフローチャートである。
【図１０】情報機器のスタックレイアウトチェック処理の変形例を示すフローチャートである。
【図１１】プログラムコードのソースコードを例示する概念図である。
【図１２】プログラムコード実行時におけるスタック領域の概要を例示する概念図である。
【図１３】プログラムコードのソースコードを例示する概念図である。
【図１４】プログラムコード実行時におけるスタック領域の概要を例示する概念図である。
【符号の説明】
【００７９】
１  情報機器
１０  ＣＰＵ
２０  記憶部
３０  ＲＡＭ
４０  操作部
５０  表示部
６０  Ｉ／Ｆ部
７０  バス
Ｃ１〜Ｃ３  ソースコード
Ｆｒ１〜Ｆｒ３  スタックフレーム
【図１】
2009199529.tif 000003
【図２】
2009199529.tif 000004
【図３】
2009199529.tif 000005
【図４】
2009199529.tif 000006
【図５】
2009199529.tif 000007
【図６】
2009199529.tif 000008
【図７】
2009199529.tif 000009
【図８】
2009199529.tif 000010
【図９】
2009199529.tif 000011
【図１０】
2009199529.tif 000012
【図１１】
2009199529.tif 000013
【図１２】
2009199529.tif 000014
【図１３】
2009199529.tif 000015
【図１４】
2009199529.tif 000016