(57)【特許請求の範囲】
【請求項１】
入力または出力のストリームを指定して複数回の関数の呼び出しを行うプログラムの実行によって検査対象の記号列が入力または出力されたことを検出する情報処理装置であって、
複数の状態と、遷移条件としての記号が対応付けられた状態間の遷移と、前記複数の状態の中の受理状態と、を示す状態遷移情報を記憶する記憶手段と、
前記複数回の関数の呼び出しそれぞれが行われるとき、戻り値および引数の少なくとも一方に含まれる記号と、指定されたストリームの識別情報とを抽出する抽出手段と、
ストリーム毎に現在の状態を管理しており、前記複数回の関数の呼び出しそれぞれが行われる毎に、前記複数の状態の中の前記抽出手段で抽出された前記識別情報に応じた現在の状態と前記抽出手段で抽出された記号とから、前記記憶手段に記憶された前記状態遷移情報が示す遷移に従って現在の状態を更新し、更新後の現在の状態が前記受理状態である場合に、前記記号列の検出結果の情報を出力する検出手段と、
を有し、前記複数回の関数の呼び出しのうち一の呼び出しの際に更新された現在の状態は、前記一の呼び出しの次に行われる他の呼び出しの際に引き継がれる、
情報処理装置。
【請求項２】
前記記号列を示す情報を取得し、前記記号列に含まれる各記号が順に抽出された後の現在の状態が前記受理状態になるように前記状態遷移情報を生成する生成手段、
を更に有する請求項１記載の情報処理装置。
【請求項３】
入力または出力のストリームを指定して複数回の関数の呼び出しを行うプログラムの実行によって検査対象の記号列が入力または出力されたことを検出する、コンピュータが実行するソフトウェア検査方法であって、
前記複数回の関数の呼び出しそれぞれが行われるとき、戻り値および引数の少なくとも一方に含まれる記号と、指定されたストリームの識別情報とを抽出し、
複数の状態と遷移条件としての記号が対応付けられた状態間の遷移と前記複数の状態の中の受理状態とを示す状態遷移情報を記憶する記憶手段を参照して、ストリーム毎に現在の状態を管理しており、前記複数回の関数の呼び出しそれぞれが行われる毎に、前記複数の状態の中の抽出された前記識別情報に応じた現在の状態と抽出された記号とから、現在の状態を更新し、
更新後の現在の状態が前記受理状態である場合に、前記記号列の検出結果の情報を出力し、
前記複数回の関数の呼び出しのうち一の呼び出しの際に更新された現在の状態は、前記一の呼び出しの次に行われる他の呼び出しの際に引き継がれる、
ソフトウェア検査方法。
【請求項４】
入力または出力のストリームを指定して複数回の関数の呼び出しを行うプログラムの実行によって検査対象の記号列が入力または出力されたことを検出するソフトウェア検査プログラムであって、コンピュータに、
前記複数回の関数の呼び出しそれぞれが行われるとき、戻り値および引数の少なくとも一方に含まれる記号と、指定されたストリームの識別情報とを抽出し、
複数の状態と遷移条件としての記号が対応付けられた状態間の遷移と前記複数の状態の中の受理状態とを示す状態遷移情報を記憶する記憶手段を参照して、ストリーム毎に現在の状態を管理しており、前記複数回の関数の呼び出しそれぞれが行われる毎に、前記複数の状態の中の抽出された前記識別情報に応じた現在の状態と抽出された記号とから、現在の状態を更新し、
更新後の現在の状態が前記受理状態である場合に、前記記号列の検出結果の情報を出力する、
処理を実行させ、
前記複数回の関数の呼び出しのうち一の呼び出しの際に更新された現在の状態は、前記一の呼び出しの次に行われる他の呼び出しの際に引き継がれる、
ソフトウェア検査プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は情報処理装置、ソフトウェア検査方法およびソフトウェア検査プログラムに関する。
【背景技術】
【０００２】
オペレーティングシステム（ＯＳ：Operating System）やミドルウェアなどのソフトウェア実行環境は、アプリケーションソフトウェアから利用可能なＡＰＩ（Application Programming Interface）を用意しておくことがある。ＡＰＩでは、ファイル入出力や描画処理など、複数のアプリケーションソフトウェアから利用されると考えられる機能が実装されている。アプリケーションソフトウェアは、ＡＰＩにおいて提供される関数（メソッド、手続き、サブルーチンなどと呼ばれることもある）を呼び出すことで、実装された機能を利用することができる。ＡＰＩを利用することで、全ての機能を自前でプログラミングしなくてもよく、アプリケーションソフトウェアを効率的に開発することができる。
【０００３】
ＡＰＩの中には、ファイルからのデータの入力やファイルへのデータの出力など、入力または出力のストリームを扱うものがある。アプリケーションソフトウェアは、例えば、ＡＰＩにおいて提供されるファイル入力用の関数を呼び出すことで、呼び出し毎にデータをファイルから逐次読み込む。また、例えば、ＡＰＩにおいて提供されるファイル出力用の関数を呼び出すことで、呼び出し毎にデータをファイルに逐次書き込む。
【０００４】
なお、ＡＰＩに関する処理の制御方法として、ＡＰＩ呼び出しが検出されると、アプリケーションソフトウェアからＯＳに制御権が渡される前に当該制御権を取得し、処理を継続してよいか判断する方法が提案されている。また、テキストから特定の文字列を検索する方法として、状態機械を複数の分割状態機械に変換し、分割状態機械それぞれが入力記号の一部分の処理を担当することで、メモリ使用量を抑制する方法が提案されている。
【先行技術文献】
【特許文献】
【０００５】
【特許文献１】特開２００７−２８７０７８号公報（段落［００１８］，［００１９］）
【特許文献２】特開２００９−１５１７５７号公報
【発明の概要】
【発明が解決しようとする課題】
【０００６】
ところで、あるアプリケーションソフトウェアが、実行中に特定の記号列を入力または出力したか検査したいことがある。例えば、アプリケーションソフトウェアが、機密情報であるパスワードを扱っているか確認するために、“ｐａｓｓｗｏｒｄ”という記号列がＡＰＩを通じて入力または出力されたか検査することが考えられる。しかし、アプリケーションソフトウェアが入力または出力のストリームを扱うＡＰＩを利用する場合、ストリームに特定の記号列が含まれるか否かの検査を、どのように行えばよいかが問題となる。
【０００７】
入力または出力のストリームでは、検査対象の記号列が複数回の関数呼び出しに分けて入力または出力される可能性がある。例えば、“ｐａｓｓｗｏｒｄ”に含まれる記号が、関数呼び出し毎に１字ずつ入力または出力される可能性がある。このため、関数呼び出し単位で戻り値や引数を検査するだけでは、検出漏れが生じ得る。一方、検査のために、アプリケーションソフトウェアがＡＰＩを通じて入力または出力したデータを全てバッファに保持するようにすると、メモリ消費量や検索負荷が増大するという問題がある。
【０００８】
本発明はこのような点に鑑みてなされたものであり、入力または出力のストリームの検査を効率的に行うことができる情報処理装置、ソフトウェア検査方法およびソフトウェア検査プログラムを提供することを目的とする。
【課題を解決するための手段】
【０００９】
複数回の関数の呼び出しを行うプログラムの実行によって検査対象の記号列が入力または出力されたことを検出する情報処理装置が提供される。当該情報処理装置は、記憶手段と抽出手段と検出手段とを有する。記憶手段は、複数の状態と遷移条件としての記号が対応付けられた状態間の遷移と複数の状態の中の受理状態とを示す状態遷移情報を記憶する。抽出手段は、複数回の関数の呼び出しそれぞれが行われるとき、戻り値および引数の少なくとも一方に含まれる記号を抽出する。検出手段は、抽出手段で記号が抽出されると、複数の状態の中の現在の状態と抽出された記号とから、記憶手段に記憶された状態遷移情報が示す遷移に従って現在の状態を更新し、更新後の現在の状態が受理状態であるか否かに応じて、記号列の検出結果の情報を出力する。
【００１０】
また、複数回の関数の呼び出しを行うプログラムの実行によって検査対象の記号列が入力または出力されたことを検出する、コンピュータが実行するソフトウェア検査方法が提供される。当該ソフトウェア検査方法では、複数回の関数の呼び出しそれぞれが行われるとき、戻り値および引数の少なくとも一方に含まれる記号を抽出する。記号が抽出されると、複数の状態と遷移条件としての記号が対応付けられた状態間の遷移と複数の状態の中の受理状態とを示す状態遷移情報を記憶する記憶手段を参照して、複数の状態の中の現在の状態と抽出された記号とから、現在の状態を更新する。更新後の現在の状態が受理状態であるか否かに応じて、記号列の検出結果の情報を出力する。また、コンピュータに実行させるソフトウェア検査プログラムが提供される。
【発明の効果】
【００１１】
上記情報処理装置、ソフトウェア検査方法およびソフトウェア検査プログラムによれば、入力または出力のストリームの検査を効率的に行うことができる。
【図面の簡単な説明】
【００１２】
【図１】第１の実施の形態の情報処理装置を示す図である。
【図２】情報処理装置のハードウェア例を示すブロック図である。
【図３】オートマトンの例を示す図である。
【図４】情報処理装置の機能を示すブロック図である。
【図５】通常遷移テーブルの例を示す図である。
【図６】ｆａｉｌｕｒｅ遷移テーブルの例を示す図である。
【図７】受理状態テーブルの例を示す図である。
【図８】状態管理テーブルの例を示す図である。
【図９】プログラム制御の手順例を示すフローチャートである。
【図１０】オートマトン生成の手順例を示すフローチャートである。
【図１１】オートマトン生成の手順例を示すフローチャート（続き）である。
【図１２】ＡＰＩフッキングの第１の方法を示す図である。
【図１３】ＡＰＩフッキングの第１の実装例を示す図である。
【図１４】ＡＰＩフッキングの第２の方法を示す図である。
【図１５】ＡＰＩフッキングの第２の実装例を示す図である。
【図１６】文字列検出の手順例を示すフローチャートである。
【図１７】検出情報の例を示す図である。
【発明を実施するための形態】
【００１３】
以下、本実施の形態を図面を参照して説明する。
［第１の実施の形態］
図１は、第１の実施の形態の情報処理装置を示す図である。情報処理装置１０は、複数回の関数の呼び出しを行うプログラムの実行によって検査対象の記号列が入力または出力されたことを検出することができる。情報処理装置１０は、記憶手段１１、抽出手段１２および検出手段１３を有する。記憶手段１１は、ＲＡＭ（Random Access Memory）やＨＤＤ（Hard Disk Drive）などの任意の記憶装置を用いて実現できる。抽出手段１２および検出手段１３は、例えば、ＣＰＵ（Central Processing Unit）およびＲＡＭを用いて、ソフトウェア検査プログラムを実行することで実現できる。
【００１４】
記憶手段１１は、状態遷移情報１１ａを記憶する。状態遷移情報１１ａには、複数の状態と、遷移条件としての記号が対応付けられた状態間の遷移と、複数の状態の中の受理状態を示す情報が含まれる。状態遷移情報１１ａが示す状態遷移関係は、検査対象の記号列に対応している。情報処理装置１０は、検査対象の記号列を示す情報が入力されると、当該記号列に含まれる各記号が順に抽出されると現在の状態が受理状態になるように、状態遷移情報１１ａを生成して記憶手段１１に格納するようにしてもよい。
【００１５】
抽出手段１２は、関数の呼び出しそれぞれが行われるとき、戻り値および引数の少なくとも一方に含まれる記号を抽出する。記号の抽出を行う対象の関数には、入力または出力のストリームを扱うＡＰＩにおいて提供される関数が含まれる。関数は、メソッド、手続きまたはサブルーチンと呼ばれるものであってもよい。抽出手段１２は、例えば、入力ストリームの場合、入力された記号を戻り値から抽出し、出力ストリームの場合、出力される記号を引数から抽出する。また、検査対象のプログラムが複数のストリームを扱う可能性がある場合、各ストリームを識別するための識別情報を更に抽出してもよい。
【００１６】
検出手段１３は、記憶手段１１に記憶された状態遷移情報１１ａを参照して、現在の状態を管理する。検出手段１３は、抽出手段１２で記号が抽出されると、現在の状態と抽出された記号とから、状態遷移情報１１ａが示す遷移に従って現在の状態を更新する。検査対象のプログラムが複数のストリームを扱う可能性がある場合、抽出手段１２で抽出された識別情報に基づいて、ストリーム毎に現在の状態を管理してもよい。
【００１７】
また、検出手段１３は、更新後の現在の状態が、状態遷移情報１１ａが示す受理状態であるか否かに応じて、記号列の検出結果を示す情報を出力する。例えば、現在の状態が受理状態になると、検査対象の記号列が検出されたと判断し、検出された記号列を示す情報を出力する。情報処理装置１０は、検出手段１３により出力された検出結果の情報を、ファイルに書き込んでもよいし、コンソール画面に表示してもよい。
【００１８】
例えば、検査対象の記号列が“ＡＢＣ”であるとする。また、記号“Ａ”を受けて状態＃０（初期状態）から状態＃１に遷移し、記号“Ｂ”を受けて状態＃１から状態＃２へ遷移し、記号“Ｃ”を受けて状態＃２から状態＃３（受理状態）に遷移することが、状態遷移情報１１ａに定義されているとする。また、検査対象のプログラムにより、引数として与えられた記号を１字ずつ出力する関数ｗｒｉｔｅが呼び出されるとする。
【００１９】
関数呼び出しｗｒｉｔｅ（Ａ）が行われると、抽出手段１２が引数から記号“Ａ”を抽出し、検出手段１３が現在の状態を状態＃０から状態＃１に更新する。続いて、関数呼び出しｗｒｉｔｅ（Ｂ）が行われると、抽出手段１２が引数から記号“Ｂ”を抽出し、検出手段１３が現在の状態を状態＃２に更新する。続いて、関数呼び出しｗｒｉｔｅ（Ｃ）が行われると、抽出手段１２が引数から記号“Ｃ”を抽出し、検出手段１３が現在の状態を状態＃３に更新する。そして、検出手段１３は、状態＃３が受理状態であるため、出力ストリーム内に記号列“ＡＢＣ”が検出されたことを示す情報を出力する。
【００２０】
第１の実施の形態の情報処理装置１０によれば、複数回の関数の呼び出しそれぞれが行われるとき、戻り値および引数の少なくとも一方に含まれる記号を抽出する。記号が抽出されると、複数の状態と遷移条件としての記号が対応付けられた状態間の遷移と複数の状態の中の受理状態とを示す状態遷移情報１１ａを記憶する記憶手段１１を参照して、複数の状態の中の現在の状態と抽出された記号とから、現在の状態を更新する。更新後の現在の状態が受理状態であるか否かに応じて、記号列の検出結果の情報を出力する。
【００２１】
これにより、入力または出力のストリームの検査を効率的に行うことができる。情報処理装置１０は、複数回の関数呼び出しを通して状態遷移情報１１ａに基づく状態の管理を行うため、複数回に分けて入力または出力された記号列を検出できる。また、抽出された記号に基づいて現在の状態を順次更新すればよく、入力または出力された記号をバッファに記憶しておかなくてもよいため、メモリ消費量や検索負荷を抑制できる。また、関数呼び出しを監視することで記号列を検出するため、操作される対象（ファイルなど）を予め具体的に特定しなくても、検査を行うことが可能となる。
【００２２】
また、情報処理装置１０は、入力または出力のストリーム毎に現在の状態を管理することで、複数のストリームを扱うプログラムを適切に検査することができる。例えば、記号を１字ずつ出力するためのストリーム＃１，＃２が生成され、ストリーム＃１によって記号列“ＡＢＤ”が出力され、ストリーム＃２によって記号列“ＣＥＦ”が出力されるとする。ストリーム＃１，＃２を区別しないと、各記号が出力されるタイミング次第では、記号列“ＡＢＣ”が出力されたと判断されてしまう可能性がある。一方、ストリーム毎に現在の状態を管理することで、記号列“ＡＢＤ”と記号列“ＣＥＦ”を区別できる。
【００２３】
［第２の実施の形態］
次に、第２の実施の形態を説明する。第２の実施の形態に係る情報処理装置は、Ｊａｖａ（登録商標）などのプログラミング言語を用いて記述されたアプリケーションプログラムを実行する。また、この情報処理装置は、アプリケーションプログラムの実行中、入力または出力のストリームを扱うＡＰＩの呼び出しを検出し、ストリームに含まれる文字列を検査する。ＡＰＩ呼び出しが行われたときに制御権を取得して検査などの処理が行われるようにすることを、ＡＰＩフッキングと呼ぶことがある。以下の説明では、Ｊａｖａを用いて記述されたプログラムの例を挙げている。ただし、第２の実施の形態のソフトウェア検査方法は、適用対象を特定のプログラミング言語に限定するものではない。
【００２４】
図２は、情報処理装置のハードウェア例を示すブロック図である。情報処理装置１００は、ＣＰＵ１０１、ＲＡＭ１０２、ＨＤＤ１０３、画像信号処理部１０４、入力信号処理部１０５、ディスクドライブ１０６および通信部１０７を有する。上記ユニットは、情報処理装置１００内でバスに接続されている。
【００２５】
ＣＰＵ１０１は、情報処理を制御する演算装置である。ＣＰＵ１０１は、ＨＤＤ１０３に記憶されたプログラムやデータの少なくとも一部を読み出し、ＲＡＭ１０２に展開してプログラムを実行する。
【００２６】
ＲＡＭ１０２は、ＣＰＵ１０１が扱うプログラムやデータを一時的に記憶する揮発性メモリである。ただし、情報処理装置１００は、他の種類のメモリを備えてもよい。
ＨＤＤ１０３は、ＯＳプログラムやアプリケーションプログラムなどのプログラム、および、ＣＰＵ１０１の処理に用いられるデータを記憶する不揮発性の記憶装置である。ＨＤＤ１０３は、内蔵の磁気ディスクに対し読み書きを行う。ただし、情報処理装置１００は、他の種類の不揮発性の記憶装置を備えてもよい。
【００２７】
画像信号処理部１０４は、ＣＰＵ１０１の命令に従って、情報処理装置１００に接続されたディスプレイ２１に画像を表示する。ディスプレイ２１として、例えば、ＣＲＴ（Cathode Ray Tube）ディスプレイや液晶ディスプレイを用いることができる。
【００２８】
入力信号処理部１０５は、情報処理装置１００に接続された入力デバイス２２から入力信号を取得し、ＣＰＵ１０１に出力する。入力デバイス２２として、例えば、マウスなどのポインティングデバイスやキーボードを用いることができる。
【００２９】
ディスクドライブ１０６は、記録媒体２３に記録されたプログラムやデータを読み取る駆動装置である。記録媒体２３として、例えば、フレキシブルディスク（ＦＤ：Flexible Disk）などの磁気ディスク、ＣＤ（Compact Disc）やＤＶＤ（Digital Versatile Disc）などの光ディスク、光磁気ディスク（ＭＯ：Magneto-Optical disk）を用いることができる。ディスクドライブ１０６は、例えば、ＣＰＵ１０１の命令に従って、記録媒体２３から読み取ったプログラムやデータをＲＡＭ１０２またはＨＤＤ１０３に出力する。
【００３０】
通信部１０７は、ネットワーク２４に接続して通信を行う通信インタフェースである。ネットワーク２４への接続方法は、有線でも無線でもよい。すなわち、通信部１０７は、有線通信インタフェースでも無線通信インタフェースでもよい。
【００３１】
図３は、オートマトンの例を示す図である。情報処理装置１００は、オートマトンを用いて、入力または出力のストリームに含まれる文字列の中から特定の文字列を検出する。オートマトンは、仮想的な自動機械であり、複数の状態の間の遷移関係を定義している。
【００３２】
第２の実施の形態では、オートマトンとして、エイホ・コラシックアルゴリズムに従って生成される決定性有限オートマトンを用いる場合を考える。エイホ・コラシックアルゴリズムについては、例えば、文献“Alfred V. Aho and Margaret J. Corasick, Efficient String Matching: An Aid to Bibliographic Search, Communications of the ACM, Vol. 18, Number 6, pp. 333-340, June 1975”に記載されている。ただし、文字列の検出は、他の種類のオートマトンを用いて実現することも可能である。
【００３３】
文字列“ｐａｓｓｗｏｒｄ”および“ａｓｓｅｔ”を検出することを考える。図３のオートマトンの例では、状態＃０〜＃１３の１４個の状態が定義されている。状態＃０〜＃１３のうち、状態＃０が初期状態であり、状態＃８，＃１３が受理状態である。状態＃０から開始し、オートマトンに文字が入力されると遷移が発生する。状態＃８は、文字列“ｐａｓｓｗｏｒｄ”が検出されたことを意味する。状態＃１３は、文字列“ａｓｓｅｔ”が検出されたことを意味する。
【００３４】
遷移には、通常遷移（図３の実線の矢印）とｆａｉｌｕｒｅ遷移（図３の点線の矢印であり、ｓｕｆｆｉｘリンクと呼ぶことがある）が含まれる。通常遷移が発生する条件は、当該遷移に対応付けられた文字が入力されたことである。ｆａｉｌｕｒｅ遷移が発生する条件は、入力された文字が何れの通常遷移の条件にも合致しないことである。ｆａｉｌｕｒｅ遷移は、条件に合致する通常遷移が見つかるまで連鎖的に発生する。すなわち、オートマトンに文字が入力されると、ｆａｉｌｕｒｅ遷移が発生せずに通常遷移が１回発生するか、または、１回以上のｆａｉｌｕｒｅ遷移が発生した後に通常遷移が１回発生する。
【００３５】
例えば、状態＃４のとき“ｗ”が入力されると、通常遷移に従って、現在の状態が状態＃５に遷移する。状態＃４のとき“ｅ”が入力されると、ｆａｉｌｕｒｅ遷移に従って、現在の状態が状態＃１１に遷移し、更に通常遷移に従って、状態＃１２に遷移する。状態＃４のとき“ｗ”，“ｅ”以外の文字が入力されると、２回のｆａｉｌｕｒｅ遷移に従って、現在の状態が状態＃０に戻る。なお、図３では、状態＃０，＃２，＃３，＃４以外の状態から状態＃０へのｆａｉｌｕｒｅ遷移の記載を省略している。
【００３６】
オートマトンにｆａｉｌｕｒｅ遷移を定義することで、ストリームの中から複数の文字列を効率的に検出することができる。例えば、ストリームから抽出された文字列が“ｐａｓｓ”である場合、現在の状態は状態＃４である。この時点において、検出が期待される文字列は“ｐａｓｓｗｏｒｄ”である。しかし、次に“ｅ”が抽出され、ストリームから抽出された文字列が“ｐａｓｓｅ”になると、現在の状態が状態＃１２に遷移する。この時点において、検出が期待される文字列が“ａｓｓｅｔ”に変化する。
【００３７】
図４は、情報処理装置の機能を示すブロック図である。情報処理装置１００には、ＣＰＵ１０１がプログラムを実行することで、プログラム記憶部１１０、状態情報記憶部１２０、検出情報記憶部１３０、ＡＰＩフッキング部１４０、オートマトン生成部１５０、解析部１６０および検出部１７０が実現される。ただし、上記ユニットの一部または全部を専用の電子回路として実現することも可能である。
【００３８】
プログラム記憶部１１０は、検査対象のプログラムを記憶する。例えば、バイトコードを含むＪａｖａのクラスファイルを記憶する。プログラム記憶部１１０は、例えば、ＲＡＭ１０２またはＨＤＤ１０３上に確保された記憶領域として実現できる。
【００３９】
状態情報記憶部１２０は、生成されたオートマトンに関する状態遷移情報を記憶する。状態遷移情報には、通常遷移を示す情報、ｆａｉｌｕｒｅ遷移を示す情報、受理状態を示す情報、および、現在の状態を示す情報が含まれる。状態情報記憶部１２０は、例えば、ＲＡＭ１０２またはＨＤＤ１０３上に確保された記憶領域として実現できる。
【００４０】
検出情報記憶部１３０は、文字列の検出結果に関する検出情報を記憶する。検出情報には、入力または出力のストリームから検出された文字列や、当該ストリームを扱うＡＰＩを示す情報が含まれる。検出情報記憶部１３０は、例えば、ＲＡＭ１０２またはＨＤＤ１０３上に確保された記憶領域として実現できる。
【００４１】
ＡＰＩフッキング部１４０は、ユーザ操作によりプログラムを実行するコマンドが入力されると、コマンドで指定されたプログラムをプログラム記憶部１１０から取得する。そして、プログラムの中から所定のＡＰＩ呼び出しを行うコードを検索し、ＡＰＩ呼び出しの際に、呼び出されるＡＰＩの処理に加えて解析部１６０による処理が実行されるようにコードを書き換える。例えば、ＡＰＩフッキング部１４０は、ＲｅａｄｅｒやＷｒｉｔｅｒなどのＡＰＩのメソッドを呼び出すコードを、解析部１６０に相当するプログラムを呼び出すコードに書き換える。または、メソッド呼び出しのコードの直後に、解析部１６０に相当するプログラムが実行されるようなコードを挿入する。
【００４２】
オートマトン生成部１５０は、ユーザ操作により検査対象の文字列を示すパターン情報が入力されると、検査対象の文字列に対応するオートマトンを生成し、状態遷移情報を状態情報記憶部１２０に格納する。パターン情報は、例えば、プログラムを実行するコマンドと併せて入力される。検査対象の文字列は、正規表現など、任意の表現形式で記載することができる。例えば、検査対象の文字列が“ｐａｓｓｗｏｒｄ”と“ａｓｓｅｔ”である場合、“ｐａｓｓｗｏｒｄ｜ａｓｓｅｔ”というテキストが入力される。
【００４３】
解析部１６０は、ＡＰＩフッキング部１４０により書き換えられたプログラムから呼び出される。解析部１６０は、ストリームを扱うＡＰＩが呼び出された際、ＡＰＩ呼び出しを解析し、戻り値または引数に含まれる文字とストリームを識別するためのストリーム識別子とを抽出し、検出部１７０に出力する。文字およびストリーム識別子の抽出方法は、ＡＰＩの種類によって異なる。解析部１６０は、ＡＰＩの種類毎に、ＡＰＩ呼び出しから文字およびストリーム識別子を抽出するモジュールを備える。
【００４４】
例えば、解析部１６０は、Ｒｅａｄｅｒ解析部１６１とＷｒｉｔｅｒ解析部１６２を有する。Ｒｅａｄｅｒ解析部１６１は、Ｒｅａｄｅｒクラスのｒｅａｄメソッドが呼び出されると、入力された文字を戻り値から抽出し、Ｒｅａｄｅｒクラスのインスタンス（オブジェクト）の識別子を抽出する。Ｗｒｉｔｅｒ解析部１６２は、Ｗｒｉｔｅｒクラスのｗｒｉｔｅメソッドが呼び出されると、出力された文字を引数から抽出し、Ｗｒｉｔｅｒクラスのインスタンスの識別子を抽出する。
【００４５】
なお、ＡＰＩフッキング部１４０がＡＰＩのメソッドを呼び出すコードを書き換える場合、解析部１６０は、検査対象のプログラムに代わってＡＰＩのメソッドを呼び出す。例えば、Ｒｅａｄｅｒ解析部１６１は、Ｒｅａｄｅｒクラスのｒｅａｄメソッドを呼び出し、その後に戻り値を解析する。一方、Ｗｒｉｔｅｒ解析部１６２は、Ｗｒｉｔｅｒクラスのｗｒｉｔｅメソッドを呼び出す前または呼び出した後に、引数を解析する。
【００４６】
検出部１７０は、ストリーム毎に現在の状態を管理し、検査対象の文字列が検出されたか判断する。検出部１７０は、解析部１６０から文字とストリーム識別子を取得すると、ストリーム識別子に対応する現在の状態を検索する。そして、状態情報記憶部１２０に記憶された状態遷移情報に基づいて、現在の状態と取得した文字から、現在の状態を更新する。検出部１７０は、更新後の現在の状態が受理状態であれば、検査対象の文字列が検出されたと判断し、検出情報を生成して検出情報記憶部１３０に出力する。ただし、検出部１７０は、検出情報を、コンソール画面などのユーザ操作画面に表示してもよい。
【００４７】
なお、状態情報記憶部１２０は、第１の実施の形態の記憶手段１１の一例である。ＡＰＩフッキング部１４０および解析部１６０は、第１の実施の形態の抽出手段１２の一例である。検出部１７０は、第１の実施の形態の検出手段１３の一例である。
【００４８】
図５は、通常遷移テーブルの例を示す図である。通常遷移テーブル１２１は、オートマトン生成部１５０によって生成され、状態情報記憶部１２０に格納される。通常遷移テーブル１２１は、前状態、入力および後状態の項目を含む。前状態の項目には、遷移前の状態を示す状態ＩＤ（図３の例では、０〜１３の何れか）が登録される。入力の項目には、遷移条件である文字または１またはそれ以上の文字を含む論理式が登録される。後状態の項目には、遷移後の状態を示す状態ＩＤが登録される。
【００４９】
前状態の項目が示す状態のときに入力の項目に合致する文字が入力されると、前状態の項目が示す状態から後状態の項目が示す状態への通常遷移が発生する。図５のテーブルの例は、図３のオートマトンの例に対応し、１４個の通常遷移を含む。なお、通常遷移テーブル１２１は、ハッシュテーブルとして実装してもよい。例えば、ＪａｖａのＨａｓｈＭａｐクラスを用いることが考えられる。その場合、ハッシュテーブルには、前状態と入力の組がキーとして登録され、後状態がエントリとして登録される。ハッシュテーブルは、例えば、ＲＡＭ１０２上に確保された領域に記憶される。
【００５０】
図６は、ｆａｉｌｕｒｅ遷移テーブルの例を示す図である。ｆａｉｌｕｒｅ遷移テーブル１２２は、オートマトン生成部１５０によって生成され、状態情報記憶部１２０に格納される。ｆａｉｌｕｒｅ遷移テーブル１２２は、前状態および後状態の項目を含む。通常遷移テーブル１２１と同様、前状態の項目には、遷移前の状態を示す状態ＩＤが登録される。後状態の項目には、遷移後の状態を示す状態ＩＤが登録される。
【００５１】
現在の状態と解析部１６０で抽出された文字の組に対応する通常遷移が、通常遷移テーブル１２１に登録されていないとき、現在の状態から後状態の項目が示す状態へのｆａｉｌｕｒｅ遷移が発生する。図６のテーブルの例は、１３個のｆａｉｌｕｒｅ遷移を含む。なお、ｆａｉｌｕｒｅ遷移テーブル１２２は、通常遷移テーブル１２１と同様、ハッシュテーブルとして実装してもよい。その場合、ハッシュテーブルには、前状態がキーとして登録され、後状態がエントリとして登録される。
【００５２】
図７は、受理状態テーブルの例を示す図である。受理状態テーブル１２３は、オートマトン生成部１５０によって生成され、状態情報記憶部１２０に格納される。受理状態テーブル１２３は、受理状態および文字列の項目を含む。受理状態の項目には、受理状態を示す状態ＩＤが登録される。文字列の項目には、現在状態が受理状態になったときに検出されたと判断される、検査対象の文字列が登録される。
【００５３】
例えば、図３のオートマトンの場合、受理状態＝８，文字列＝ｐａｓｓｗｏｒｄという情報、および、受理状態＝１３，文字列＝ａｓｓｅｔという情報が、受理状態テーブル１２３に登録される。なお、受理状態テーブル１２３は、通常遷移テーブル１２１と同様に、ハッシュテーブルとして実装してもよい。その場合、ハッシュテーブルには、受理状態がキーとして登録され、文字列がエントリとして登録される。
【００５４】
図８は、状態管理テーブルの例を示す図である。オートマトン生成部１５０によって、空の状態管理テーブル１２４が生成され、状態情報記憶部１２０に格納される。また、検出部１７０によって、状態情報記憶部１２０に記憶された状態管理テーブル１２４が更新される。状態管理テーブル１２４は、ストリーム識別子および状態の項目を含む。ストリーム識別子の項目には、解析部１６０で抽出された識別子が登録される。図８の例では、ストリーム識別子として、Ｊａｖａクラスのインスタンスの識別子を用いている。状態の項目には、現在の状態を示す状態ＩＤが登録される。
【００５５】
例えば、検査対象のプログラムによってＲｅａｄｅｒやＷｒｉｔｅｒなどのクラスのインスタンスが生成され、当該インスタンスを指定してｒｅａｄやｗｒｉｔｅなどのメソッドが呼び出されると、状態管理テーブル１２４にインスタンスの識別子が追加される。また、当該メソッドが呼び出される毎に、現在の状態が更新される。状態管理テーブル１２４は、検査対象のプログラムの実行が終了すると破棄される。
【００５６】
ただし、検査対象のプログラムの実行中に、不要となったストリームの情報を状態管理テーブル１２４から削除するようにしてもよい。例えば、インスタンスを指定してストリームを閉じるメソッド（例えば、ｃｌｏｓｅ）が呼び出されたときに、当該インスタンスに対応する情報を状態管理テーブル１２４から削除するようにする。または、ガーベッジコレクションの機能を利用して、インスタンスが消滅すると、当該インスタンスに依存する情報が状態管理テーブル１２４から自動的に削除されるようする。
【００５７】
図９は、プログラム制御の手順例を示すフローチャートである。
（ステップＳ１）オートマトン生成部１５０は、検査対象となる１またはそれ以上の文字列を示すパターン情報（例えば、正規表現により文字列のパターンを記載したもの）を取得する。そして、オートマトン生成部１５０は、パターン情報が示す文字列を検出するためのオートマトンを生成する。
【００５８】
（ステップＳ２）ＡＰＩフッキング部１４０は、検査対象のプログラムの中のコード（例えば、Ｊａｖａのバイトコード）を書き換えることで、入力または出力のストリームを扱うＡＰＩが呼び出される際に、解析部１６０が制御権を取得できるようにする。
【００５９】
（ステップＳ３）情報処理装置１００は、ＡＰＩフッキング部１４０により書き換えられたプログラムの実行を開始する。例えば、書き換えられたプログラムをＲＡＭ１０２上の適切な領域に展開し、当該プログラムのｍａｉｎメソッドを呼び出す。
【００６０】
（ステップＳ４）情報処理装置１００は、入力または出力のストリームを扱うＡＰＩが呼び出されたか判断する。ＡＰＩが呼び出された場合、処理をステップＳ５に進める。呼び出されていない場合、処理をステップＳ６に進める。
【００６１】
（ステップＳ５）解析部１６０は、ＡＰＩ呼び出しにおける戻り値または引数から、当該ＡＰＩを通して入力または出力される文字を抽出する。検出部１７０は、オートマトンと抽出された文字とに基づいて、ストリームの現在の状態を更新する。検出部１７０は、更新後の現在の状態が受理状態であれば、検出された文字列を示す検出情報を出力する。
【００６２】
（ステップＳ６）情報処理装置１００は、検査対象のプログラムの実行が終了したか判断する。終了した場合、文字列の検出の処理も終了する。終了していない場合、処理をステップＳ４に進める。なお、検査対象のプログラムの実行が終了するとき、情報処理装置１００は、状態情報記憶部１２０に記憶された状態遷移情報を消去してもよい。
【００６３】
以下では、ステップＳ１で実行されるオートマトン生成の処理、ステップＳ２で実行されるＡＰＩフッキングの処理、および、ステップＳ５で実行される文字列検出の処理それぞれについて、更に説明を加える。
【００６４】
図１０は、オートマトン生成の手順例を示すフローチャートである。図１０に示す処理は、前述のステップＳ１の中で実行される。なお、図１０に示すオートマトンの生成手順は一例であり、他の手順によってオートマトンを生成することも可能である。
【００６５】
（ステップＳ１１）オートマトン生成部１５０は、パターン情報から１またはそれ以上の文字列を抽出する。例えば、正規表現で記載された文字列パターン“ｐａｓｓｗｏｒｄ｜ａｓｓｅｔ”から、文字列“ｐａｓｓｗｏｒｄ”と“ａｓｓｅｔ”を抽出する。
【００６６】
（ステップＳ１２）オートマトン生成部１５０は、初期状態（状態＃０）を追加する。
（ステップＳ１３）オートマトン生成部１５０は、ステップＳ１１で抽出した１またはそれ以上の文字列の中から、文字列を１つ選択する。
【００６７】
（ステップＳ１４）オートマトン生成部１５０は、現在の状態を状態＃０とする。
（ステップＳ１５）オートマトン生成部１５０は、ステップＳ１３で選択した文字列の先頭側から、文字を１つ抽出する。
【００６８】
（ステップＳ１６）オートマトン生成部１５０は、現在の状態が遷移元でありステップＳ１５で抽出した文字が遷移条件である通常遷移が存在するか判断する。存在する場合、処理をステップＳ１８に進める。存在しない場合、処理をステップＳ１７に進める。
【００６９】
（ステップＳ１７）オートマトン生成部１５０は、オートマトンに新たな状態を追加すると共に、現在の状態から当該新たな状態への通常遷移を追加する。また、追加した通常遷移に、ステップＳ１５で抽出した文字を遷移条件として対応付ける。
【００７０】
（ステップＳ１８）オートマトン生成部１５０は、現在の状態を、ステップＳ１６で見つかった通常遷移の遷移先、または、ステップＳ１７で追加した状態に遷移させる。
（ステップＳ１９）オートマトン生成部１５０は、ステップＳ１５で抽出した文字が、文字列の末尾の文字であるか判断する。末尾の文字である場合、処理をステップＳ２０に進める。末尾の文字でない場合、処理をステップＳ１５に進める。
【００７１】
（ステップＳ２０）オートマトン生成部１５０は、現在の状態を受理状態に指定する。
（ステップＳ２１）オートマトン生成部１５０は、ステップＳ１３で選択した文字列が最後の文字列であるか判断する。最後の文字列である場合、処理をステップＳ２２に進める。最後の文字列でない場合、処理をステップＳ１３に進める。
【００７２】
（ステップＳ２２）オートマトン生成部１５０は、通常遷移として、状態＃０から状態＃０に遷移する自己遷移をオートマトンに追加する。また、当該自己遷移に、他の何れの通常遷移の遷移条件にも合致しないことを示す論理式を対応付ける。例えば、文字“ｐ”が対応付けられた状態＃０から状態＃１への通常遷移と、文字“ａ”が対応付けられた状態＃０から状態＃９への通常遷移とが存在する場合、“ｎｏｔ（ｐまたはａ）”という論理式が、遷移条件として自己遷移に対応付けられる。
【００７３】
図１１は、オートマトン生成の手順例を示すフローチャート（続き）である。図１１に示す処理は、図１０に示す処理に続いて、前述のステップＳ１の中で実行される。なお、図１１に示すオートマトンの生成手順は一例であり、他の手順によってオートマトンを生成することも可能である。
【００７４】
（ステップＳ２３）オートマトン生成部１５０は、各状態の深さを算出する。深さは、初期状態（状態＃０）を起点として通常遷移を辿った場合のホップ数とする。図３の例の場合、状態＃０の深さは０、状態＃８の深さは８、状態＃１３の深さは５である。
【００７５】
（ステップＳ２４）オートマトン生成部１５０は、深さ１の状態（図３の例の場合、状態＃１，＃９）から状態＃０へのｆａｉｌｕｒｅ遷移を、オートマトンに追加する。
（ステップＳ２５）オートマトン生成部１５０は、変数ｎ＝２に設定する。
【００７６】
（ステップＳ２６）オートマトン生成部１５０は、深さｎの状態Ｓnを選択する。以下のステップＳ２７〜Ｓ３０の処理を、状態Ｓnそれぞれについて実行する。
（ステップＳ２７）オートマトン生成部１５０は、前状態＝Ｓn-1，入力＝ｘ，後状態＝Ｓnである通常遷移を抽出する（Ｓn-1は深さｎ−１の状態であり、ｘは任意の１文字である）。また、オートマトン生成部１５０は、前状態＝Ｓn-1，後状態＝Ｓtであるｆａｉｌｕｒｅ遷移を抽出する（Ｓtは任意の状態である）。
【００７７】
（ステップＳ２８）オートマトン生成部１５０は、前状態＝Ｓt，入力＝ｘ，後状態＝Ｓuである通常遷移が存在するか判断する（Ｓuは任意の状態である）。存在する場合、処理をステップＳ２９に進める。存在しない場合、処理をステップＳ３０に進める。
【００７８】
（ステップＳ２９）オートマトン生成部１５０は、状態Ｓnから状態Ｓuへのｆａｉｌｕｒｅ遷移を、オートマトンに追加する。
（ステップＳ３０）オートマトン生成部１５０は、状態Ｓnから状態＃０へのｆａｉｌｕｒｅ遷移を、オートマトンに追加する。
【００７９】
（ステップＳ３１）オートマトン生成部１５０は、ステップＳ２９またはステップＳ３０で追加したｆａｉｌｕｒｅ遷移の前状態と後状態の間で、受理状態を統合する。
（ステップＳ３２）オートマトン生成部１５０は、ｎを１だけ増加させる。
【００８０】
（ステップＳ３３）オートマトン生成部１５０は、ｎがオートマトンの深さの最大値（図３の例の場合は８）より大きいか判断する。条件を満たす場合、処理を終了する。条件を満たさない場合、処理をステップＳ２６に進める。
【００８１】
以上のステップＳ１１〜Ｓ３３の処理により、オートマトン生成部１５０は、オートマトンを生成することができる。次に、ＡＰＩフッキングの実装例を説明する。
図１２は、ＡＰＩフッキングの第１の方法を示す図である。第１の方法では、解析部１６０が、検査対象のプログラムに代わってＡＰＩ呼び出しを行う。
【００８２】
例えば、ＡＰＩフッキング部１４０は、Ｊａｖａのｉｎｓｔｒｕｍｅｎｔａｔｉｏｎ機能を用いて、検査対象のプログラムのロード時に、ＲｅａｄｅｒクラスまたはＷｒｉｔｅｒクラスのメソッドを呼び出す命令（ｉｎｖｏｋｅｖｉｒｔｕａｌ，ｉｎｖｏｋｅｓｐｅｃｉａｌ，ｉｎｖｏｋｅｓｔａｔｉｃ，ｉｎｖｏｋｅｉｎｔｅｒｆａｃｅなど）を検索する。そして、ＡＰＩフッキング部１４０は、検索した命令を、Ｒｅａｄｅｒ解析部１６１またはＷｒｉｔｅｒ解析部１６２を呼び出す命令に書き換える。
【００８３】
Ｒｅａｄｅｒ解析部１６１は、検索対象のプログラムからの呼び出しの際に、Ｒｅａｄｅｒクラスのインスタンスへの参照を取得する。そして、当該インスタンスを指定して、ｒｅａｄメソッドを呼び出す。Ｒｅａｄｅｒ解析部１６１は、ｒｅａｄメソッドの戻り値から文字を抽出し、抽出した文字を検出部１７０に出力する。また、Ｒｅａｄｅｒクラスのインスタンスの識別子を、ストリーム識別子として検出部１７０に出力する。
【００８４】
Ｗｒｉｔｅｒ解析部１６２は、検索対象のプログラムからの呼び出しの際に、Ｗｒｉｔｅｒクラスのインスタンスへの参照と引数を取得する。そして、当該インスタンスを指定し、当該引数を用いてｗｒｉｔｅメソッドを呼び出す。Ｗｒｉｔｅｒ解析部１６２は、引数から文字を抽出し、抽出した文字を検出部１７０に出力する。また、Ｗｒｉｔｅｒクラスのインスタンスの識別子を、ストリーム識別子として検出部１７０に出力する。
【００８５】
なお、ＡＰＩ呼び出しのコードを書き換える方法として、文献“Galen Hunt and Doug Brubacher, Detours: Binary Interception of Win32 Functions, Proceedings of the 3rd USENIX Windows NT Symposium, July 1999”に記載された方法を用いてもよい。
【００８６】
図１３は、ＡＰＩフッキングの第１の実装例を示す図である。図１３に示すようなプログラムによって、解析部１６０を実現できる。Ａｎａｌｙｚｅｒクラスが、解析部１６０に対応する。ＡｎａｌｙｚｅｒクラスのｒｅａｄメソッドがＲｅａｄｅｒ解析部１６１に対応し、ｗｒｉｔｅメソッドがＷｒｉｔｅｒ解析部１６２に対応する。また、Ｄｅｔｅｃｔｏｒクラスが、検出部１７０に対応する。
【００８７】
検査対象のプログラムでは、Ｒｅａｄｅｒクラスのｒｅａｄメソッドを呼び出すコードが、Ａｎａｌｙｚｅｒクラスのｒｅａｄメソッドを呼び出すコードに書き換えられる。Ａｎａｌｙｚｅｒクラスのｒｅａｄメソッドが呼び出されると、検査対象のプログラムに代わってＲｅａｄｅｒクラスのｒｅａｄメソッドが呼び出され、文字（ｓｔｒｅａｍＤａｔａ）とストリーム識別子（ｓｔｒｅａｍＩＤ）が抽出される。
【００８８】
また、検査対象のプログラムでは、Ｗｒｉｔｅｒクラスのｗｒｉｔｅメソッドを呼び出すコードが、Ａｎａｌｙｚｅｒクラスのｗｒｉｔｅメソッドを呼び出すコードに書き換えられる。Ａｎａｌｙｚｅｒクラスのｗｒｉｔｅメソッドが呼び出されると、検査対象のプログラムに代わってＷｒｉｔｅｒクラスのｗｒｉｔｅメソッドが呼び出され、文字とストリーム識別子が抽出される。なお、Ｗｒｉｔｅｒクラスのｗｒｉｔｅメソッドの呼び出しを、文字とストリーム識別子の抽出の後に行うようにしてもよい。
【００８９】
図１４は、ＡＰＩフッキングの第２の方法を示す図である。第２の方法では、検査対象のプログラムによってＡＰＩ呼び出しが行われた後に、解析部１６０の処理が行われる。
例えば、ＡＰＩフッキング部１４０は、検査対象のプログラムのロード時に、ＲｅａｄｅｒクラスまたはＷｒｉｔｅｒクラスのメソッドを呼び出す命令を検索する。そして、検索した命令の直後にＲｅａｄｅｒ解析部１６１またはＷｒｉｔｅｒ解析部１６２の処理が実行されるように、検査対象のプログラムにコードを挿入する。コード挿入は、ＢＣＥＬ（Byte Code Engineering Library）などのライブラリを用いて実現してもよい。また、ＡｓｐｅｃｔＪのＬｏａｄＴｉｍｅＷｅａｖｉｎｇ機能を利用して実現してもよい。
【００９０】
Ｒｅａｄｅｒ解析部１６１は、検査対象のプログラムによってＲｅａｄｅｒクラスのｒｅａｄメソッドが呼び出された直後に、戻り値とＲｅａｄｅｒクラスのインスタンスへの参照を取得する。Ｒｅａｄｅｒ解析部１６１は、戻り値から文字を抽出し、抽出した文字を検出部１７０に出力する。また、Ｒｅａｄｅｒクラスのインスタンスの識別子を、ストリーム識別子として検出部１７０に出力する。
【００９１】
Ｗｒｉｔｅｒ解析部１６２は、検査対象のプログラムによってＷｒｉｔｅｒクラスのｗｒｉｔｅメソッドが呼び出された直後に、引数とＷｒｉｔｅｒクラスのインスタンスへの参照を取得する。Ｗｒｉｔｅｒ解析部１６２は、引数から文字を抽出し、抽出した文字を検出部１７０に出力する。また、Ｗｒｉｔｅｒクラスのインスタンスの識別子を、ストリーム識別子として検出部１７０に出力する。
【００９２】
図１５は、ＡＰＩフッキングの第２の実装例を示す図である。図１５に示すようなプログラムによって、ＡＰＩフッキング部１４０および解析部１６０を実現できる。図１５のプログラム例では、Ｊａｖａのｉｎｓｔｒｕｍｅｎｔａｔｉｏｎ機能とＡｓｐｅｃｔＪの機能を利用している。
【００９３】
Ａｇｅｎｔクラスのｐｒｅｍａｉｎメソッドが実行されると、検査対象のプログラムから、アノテーションＡｆｔｅｒＲｅｔｕｒｎｉｎｇのｐｏｉｎｔｃｕｔの条件に合致するコードが検索される。図１５の例では、Ｒｅａｄｅｒクラスを継承しているクラスのｒｅａｄメソッドを呼び出すコードが検索される。そして、検索されたコードの直後に、アノテーションＡｆｔｅｒＲｅｔｕｒｎｉｎｇが付与されたメソッド（図１５の例では、ｒｅａｄメソッド）を呼び出すコードが挿入される。
【００９４】
次に、文字列検出の処理を説明する。
図１６は、文字列検出の手順例を示すフローチャートである。図１６に示す処理は、前述のステップＳ５の中で実行される。
【００９５】
（ステップＳ４１）解析部１６０は、ストリーム識別子を抽出する。また、戻り値または引数から、ＡＰＩを通して入力または出力される文字を抽出する。
（ステップＳ４２）検出部１７０は、解析部１６０で抽出されたストリーム識別子に対応する現在の状態を、状態管理テーブル１２４から検索する。
【００９６】
（ステップＳ４３）検出部１７０は、ストリーム識別子に対応する現在の状態が、状態管理テーブル１２４に登録されているか判断する。登録されている場合、処理をステップＳ４５に進める。登録されていない場合、処理をステップＳ４４に進める。
【００９７】
（ステップＳ４４）検出部１７０は、ストリーム識別子に対応付けて、初期状態を示す状態ＩＤを状態管理テーブル１２４に登録する。
（ステップＳ４５）検出部１７０は、ストリームの現在の状態および解析部１６０で抽出された文字に対応する通常遷移を、通常遷移テーブル１２１から検索する。そして、該当する通常遷移が存在するか判断する。存在する場合、処理をステップＳ４７に進める。存在しない場合、処理をステップＳ４６に進める。
【００９８】
（ステップＳ４６）検出部１７０は、ストリームの現在の状態に対応するｆａｉｌｕｒｅ遷移を、ｆａｉｌｕｒｅ遷移テーブル１２２から検索する。そして、状態管理テーブル１２４に登録された現在の状態を、ｆａｉｌｕｒｅ遷移後の状態に書き換える。その後、処理をステップＳ４５に進める。
【００９９】
（ステップＳ４７）検出部１７０は、状態管理テーブル１２４に登録された現在の状態を、ステップＳ４５で検索された通常遷移後の状態に書き換える。
（ステップＳ４８）検出部１７０は、受理状態テーブル１２３を参照して、ストリームの現在の状態が受理状態であるか判断する。受理状態である場合、処理をステップＳ４９に進める。受理状態でない場合、処理を終了して次のＡＰＩ呼び出しを待つ。
【０１００】
（ステップＳ４９）検出部１７０は、受理状態テーブル１２３を参照して、検出された文字列を判断する。そして、検出情報を生成して検出情報記憶部１３０に格納する。
図１７は、検出情報の例を示す図である。検出部１７０が生成する検出情報には、例えば、検出された文字列、当該文字列が含まれるストリームの識別子、呼び出されたＡＰＩの情報、および、検査対象プログラム中のＡＰＩ呼び出しを記載したコードの位置が含まれる。文字列は、受理状態テーブル１２３から取得できる。ストリーム識別子は、状態管理テーブル１２４から取得できる。ＡＰＩ情報およびコード位置は、例えば、ＴｈｒｅａｄクラスのｇｅｔＳｔａｃｋＴｒａｃｅメソッドを呼び出すことで取得できる。
【０１０１】
例として、検査対象のプログラムによりＲｅａｄｅｒクラスのインスタンスが２つ生成され（オブジェクトＡ，Ｂ）、以下の順序で文字が取得された場合を考える。
（１）オブジェクトＡを通して文字“ｐ”を取得する。
【０１０２】
（２）オブジェクトＢを通して文字“ａ”を取得する。
（３）オブジェクトＡを通して文字“ａ”を取得する。
（４）オブジェクトＢを通して文字“ｐ”を取得する。
【０１０３】
（５）オブジェクトＡを通して文字“ｓ”を取得する。
（６）オブジェクトＡを通して文字“ｓ”を取得する。
（７）オブジェクトＡを通して文字“ｅ”を取得する。
【０１０４】
（８）オブジェクトＡを通して文字“ｔ”を取得する。
１番目の文字が抽出されると、検出部１７０は、まずオブジェクトＡの識別子と状態＃０を状態管理テーブル１２４に登録する。次に、入力ｐによる通常遷移が発生するため、検出部１７０は、オブジェクトＡの状態を状態＃０から状態＃１に更新する。状態＃１は受理状態でないため、検出情報を出力せずに次の文字が抽出されるのを待つ。
【０１０５】
２番目の文字が抽出されると、検出部１７０は、まずオブジェクトＢの識別子と状態＃０を状態管理テーブル１２４に登録する。次に、入力ａによる通常遷移が発生するため、検出部１７０は、オブジェクトＢの状態を状態＃０から状態＃９に更新する。状態＃９は受理状態でないため、検出情報を出力せずに次の文字が抽出されるのを待つ。
【０１０６】
３番目の文字が抽出されると、検出部１７０は、状態管理テーブル１２４を参照して、オブジェクトＡの状態が状態＃１であると判断する。入力ａによる通常遷移が発生するため、検出部１７０は、オブジェクトＡの状態を状態＃１から状態＃２に更新する。状態＃２は受理状態でないため、検出情報を出力せずに次の文字が抽出されるのを待つ。
【０１０７】
４番目の文字が抽出されると、検出部１７０は、状態管理テーブル１２４を参照して、オブジェクトＢの状態が状態＃９であると判断する。ここではｆａｉｌｕｒｅ遷移が発生するため、検出部１７０は、オブジェクトＢの状態を状態＃９から状態＃０に更新する。更に、入力ｐによる通常遷移が発生するため、検出部１７０は、オブジェクトＢの状態を状態＃０から状態＃１に更新する。状態＃１は受理状態でないため、検出情報を出力せずに次の文字が抽出されるのを待つ。
【０１０８】
５番目の文字が抽出されると、検出部１７０は、状態管理テーブル１２４を参照して、オブジェクトＡの状態が状態＃２であると判断する。入力ｓによる通常遷移が発生するため、検出部１７０は、オブジェクトＡの状態を状態＃２から状態＃３に更新する。状態＃３は受理状態でないため、検出情報を出力せずに次の文字が抽出されるのを待つ。
【０１０９】
６番目の文字が抽出されると、検出部１７０は、状態管理テーブル１２４を参照して、オブジェクトＡの状態が状態＃３であると判断する。入力ｓによる通常遷移が発生するため、検出部１７０は、オブジェクトＡの状態を状態＃３から状態＃４に更新する。状態＃４は受理状態でないため、検出情報を出力せずに次の文字が抽出されるのを待つ。
【０１１０】
７番目の文字が抽出されると、検出部１７０は、状態管理テーブル１２４を参照して、オブジェクトＡの状態が状態＃４であると判断する。ここではｆａｉｌｕｒｅ遷移が発生するため、検出部１７０は、オブジェクトＡの状態を状態＃４から状態＃１１に更新する。更に、入力ｅによる通常遷移が発生するため、検出部１７０は、オブジェクトＡの状態を状態＃１１から状態＃１２に更新する。状態＃１２は受理状態でないため、検出情報を出力せずに次の文字が抽出されるのを待つ。
【０１１１】
８番目の文字が抽出されると、検出部１７０は、状態管理テーブル１２４を参照して、オブジェクトＡの状態が状態＃１２であると判断する。入力ｔによる通常遷移が発生するため、検出部１７０は、オブジェクトＡの状態を状態＃１２から状態＃１３に更新する。状態＃１３は受理状態であるため、検出部１７０は、検出情報を生成し出力する。なお、オブジェクトＡを通して更に文字が取得された場合、状態＃１３を遷移元とする通常遷移が存在しないため、ｆａｉｌｕｒｅ遷移が発生して状態＃０に戻ることになる。
【０１１２】
以上の説明では、文字を１字ずつ入力または出力するＡＰＩの例を示したが、１回のメソッド呼び出しで複数の文字を入力または出力できるＡＰＩについても、同様の方法で文字列の検出を行うことができる。その場合、例えば、検出部１７０は、抽出された複数の文字を順にオートマトンに入力すればよい。また、以上の説明では、文字列を検出する例を示したが、文字以外の記号を含む記号列やバイトパターンを検出してもよい。また、情報処理装置１００は、ストリームで用いられている文字コードを判断し、文字コードに応じて、検出するバイトパターンを決定するようにしてもよい。
【０１１３】
第２の実施の形態の情報処理装置１００によれば、入力または出力のストリームの検査を効率的に行うことができる。複数回のＡＰＩ呼び出しを通してオートマトンに基づいて状態管理を行うため、複数回に分けて入力または出力される文字列を検出できる。また、抽出された文字に基づいて現在の状態を順次更新すればよく、入力または出力された文字列をバッファに記憶しておかなくてもよいため、メモリ消費量や検索負荷を抑制できる。また、ＡＰＩ呼び出しを監視することで文字列を検出するため、ファイルなどの操作対象を予め具体的に特定しなくても、検査を行うことが可能となる。また、入力または出力のストリーム毎に現在の状態を管理するため、複数のストリームを適切に検査できる。
【０１１４】
なお、前述の通り、第２の実施の形態のソフトウェア検査方法は、コンピュータとしての能力を備える情報処理装置１００に、ソフトウェア検査プログラムを実行させることで実現できる。当該プログラムは、コンピュータ読み取り可能な記録媒体（例えば、記録媒体２３）に記録しておくことができる。記録媒体として、例えば、磁気ディスク、光ディスク、光磁気ディスク、半導体メモリなどを使用できる。磁気ディスクには、ＨＤＤおよびＦＤが含まれる。光ディスクには、ＣＤ、ＣＤ−Ｒ（Recordable）／ＲＷ（Rewritable）、ＤＶＤおよびＤＶＤ−Ｒ／ＲＷが含まれる。
【０１１５】
プログラムを流通させる場合、例えば、当該プログラムを記録した可搬記録媒体が提供される。また、プログラムを他の情報処理装置の記憶装置に格納しておき、ネットワーク２４経由で当該プログラムを配布することもできる。情報処理装置１００は、例えば、可搬記録媒体に記録されたプログラムまたは他の情報処理装置から受信したプログラムを、ＨＤＤ１０３などの記憶装置に格納し、記憶装置からプログラムを読み込んで実行する。ただし、可搬型記録媒体からプログラムを直接読み込んで実行してもよい。また、他の情報処理装置からプログラムを受信する毎に逐次、受信したプログラムを実行してもよい。
【符号の説明】
【０１１６】
１０  情報処理装置
１１  記憶手段
１１ａ  状態遷移情報
１２  抽出手段
１３  検出手段
【図１】
0005728979.tif 000002
【図２】
0005728979.tif 000003
【図３】
0005728979.tif 000004
【図４】
0005728979.tif 000005
【図５】
0005728979.tif 000006
【図６】
0005728979.tif 000007
【図７】
0005728979.tif 000008
【図８】
0005728979.tif 000009
【図９】
0005728979.tif 000010
【図１０】
0005728979.tif 000011
【図１１】
0005728979.tif 000012
【図１２】
0005728979.tif 000013
【図１３】
0005728979.tif 000014
【図１４】
0005728979.tif 000015
【図１５】
0005728979.tif 000016
【図１６】
0005728979.tif 000017
【図１７】
0005728979.tif 000018