(57)【要約】  適用範囲を限定することなく高精度にコールスタックを再現することを目的として、スタックスキャン部（１１）は、アプリケーションプロセスのメモリ空間内の、コールスタックの取得対象となるスレッドが持つスタック領域から、関数呼び出し命令の直後の命令を示すメモリ空間内の実行可能領域内のアドレスである戻りアドレス候補を抽出する。また、プログラム解析部（１２）が、戻りアドレス候補のそれぞれが示す命令の直前の関数呼び出し命令によって呼び出される関数の内部における分岐命令で構築される制御の流れを示す制御フローを解析し、該制御フローにおいて、現在実行中の命令に到達する経路が存在する場合に、該戻りアドレス候補を戻りアドレスと判定し、該経路が存在しない場合に戻りアドレスではないと判定する。
2019049478.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータのメモリ、もしくは前記メモリの状態を保存したメモリダンプから、前記コンピュータで動作するアプリケーションプロセスを実行しているスレッドのコールスタックを取得するコールスタック取得装置であって、
前記アプリケーションプロセスのメモリ空間内の、前記コールスタックの取得対象となる前記スレッドが持つスタック領域から、関数呼び出し命令の直後の命令を示す前記メモリ空間内の実行可能領域内のアドレスである戻りアドレス候補を抽出する抽出部と、
前記戻りアドレス候補のそれぞれが示す命令の直前の前記関数呼び出し命令によって呼び出される関数の内部における分岐命令で構築される制御の流れを示す制御フローを解析し、該制御フローにおいて、現在実行中の命令に到達する経路が存在する場合に、前記戻りアドレス候補を戻りアドレスと判定し、該経路が存在しない場合に戻りアドレスではないと判定する解析部と、
を備えることを特徴とするコールスタック取得装置。
【請求項２】
前記抽出部は、スタックポインタを用いて前記スタック領域を特定することを特徴とする請求項１に記載のコールスタック取得装置。
【請求項３】
前記解析部は、命令ポインタを用いて前記現在実行中の命令を特定することを特徴とする請求項１に記載のコールスタック取得装置。
【請求項４】
前記解析部は、前記スタック領域の先頭に近い順に前記戻りアドレス候補を処理対象として選定することを特徴とする請求項１に記載のコールスタック取得装置。
【請求項５】
前記解析部が前記戻りアドレス候補を戻りアドレスと判定した場合に、戻りアドレスと判定された戻りアドレス候補が存在する位置の直後を前記スタック領域の先頭の位置とし、戻りアドレスと判定されたアドレスを前記現在実行中の命令の位置として、それぞれ更新する更新部をさらに備えることを特徴とする請求項１に記載のコールスタック取得装置。
【請求項６】
コンピュータのメモリ、もしくは前記メモリの状態を保存したメモリダンプから、前記コンピュータで動作するアプリケーションプロセスを実行しているスレッドのコールスタックを取得するコールスタック取得装置で実行されるコールスタック取得方法であって、
前記アプリケーションプロセスのメモリ空間内の、前記コールスタックの取得対象となる前記スレッドが持つスタック領域から、関数呼び出し命令の直後の命令を示す前記メモリ空間内の実行可能領域内のアドレスである戻りアドレス候補を抽出する抽出工程と、
前記戻りアドレス候補のそれぞれが示す命令の直前の前記関数呼び出し命令によって呼び出される関数の内部における分岐命令で構築される制御の流れを示す制御フローを解析し、該制御フローにおいて、現在実行中の命令に到達する経路が存在する場合に、前記戻りアドレス候補を戻りアドレスと判定し、該経路が存在しない場合に戻りアドレスではないと判定する解析工程と、
を含んだことを特徴とするコールスタック取得方法。
【請求項７】
コンピュータのメモリ、もしくは前記メモリの状態を保存したメモリダンプから、前記コンピュータで動作するアプリケーションプロセスを実行しているスレッドのコールスタックを取得するためのコールスタック取得プログラムであって、
前記アプリケーションプロセスのメモリ空間内の、前記コールスタックの取得対象となる前記スレッドが持つスタック領域から、関数呼び出し命令の直後の命令を示す前記メモリ空間内の実行可能領域内のアドレスである戻りアドレス候補を抽出する抽出ステップと、
前記戻りアドレス候補のそれぞれが示す命令の直前の前記関数呼び出し命令によって呼び出される関数の内部における分岐命令で構築される制御の流れを示す制御フローを解析し、該制御フローにおいて、現在実行中の命令に到達する経路が存在する場合に、前記戻りアドレス候補を戻りアドレスと判定し、該経路が存在しない場合に戻りアドレスではないと判定する解析ステップと、
をコンピュータに実行させるためのコールスタック取得プログラム。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、コールスタック取得装置、コールスタック取得方法およびコールスタック取得プログラムに関する。
【背景技術】
【０００２】
コンピュータとインターネットの普及に伴い、サイバー攻撃もまた高度化・多様化している。特定組織を狙った標的型攻撃では未知のコンピュータウイルス（マルウェア）が用いられることも多く、未然に防ぐことが難しくなっている。そのため、攻撃を受けた後に、原因の特定や被害の最小化等の対応を迅速に行うことが求められている。【０００３】
こうした対応を行うインシデントレスポンスで行われる手法の１つにメモリフォレンジックスと呼ばれる被害端末のメモリ解析がある。コンピュータは、実行する命令（コード）や使用するデータをメモリ上に保存しながら動作する。そのため、メモリには、動いていたアプリケーションの状態、開かれていたファイル、レジストリ等のリソース、実行していたコードや読み書きしたデータ、通信先や送受信データ等、その瞬間の実行状態（動作状態）が含まれている。したがって、メモリに残ったデータを解析することで、そのときに何が起こっていたか把握することができる。【０００４】
しかし、既存のメモリフォレンジックス技術では、動作していた個々のアプリケーションが、具体的にどのような動作をしていたか等を知ることは難しい。アプリケーションの動作状態を知る方法として、例えば、プログラムのデバッグ等で利用されているスタックトレースと呼ばれる技術がある。アプリケーションを実行するスレッドは、各々スタックと呼ばれるデータ領域を持ち、関数が呼び出されるたびに呼び出し元を示すアドレス（戻りアドレス）がスタックに積まれる。スタックに積まれた戻りアドレスは、呼び出された関数の処理を終了する際に、呼び出し元関数へ戻るために利用され、破棄される。【０００５】
スタックトレースは、スタックの構造を解析し、保持されている戻りアドレスを取得していくことで、その時点での関数呼び出しの入れ子状態すなわちコールスタックを明らかにする。したがって、アプリケーションを実行していた各スレッドに対し、メモリダンプからスタックトレースと同等の結果が得られれば、アプリケーションの動作状態の把握が可能になると考えられる。【０００６】
一般的なスタックトレースは、スタック内に保存されたフレームポインタ（もしくはベースポインタ）を辿ることで戻りアドレスを取得して、コールスタックを再現する。ここで、フレームポインタは、スタックの先頭を示すスタックポインタとは別に、現在実行中の関数が使用するスタック内のデータ領域を示している。一般的な関数は、最初に呼び出し元が使用していたフレームポインタの値をスタックに積み、その位置を自身のフレームポインタとして設定する。【０００７】
具体的には、スタックには、フレームポインタが示す位置に、呼び出し元の関数が使用していたフレームポインタの値が存在し、その１つ前のエントリに呼び出し元を示す戻りアドレスが格納されている。そのため、現在のフレームポインタの値から、前のフレームポインタの値と戻りアドレスとの取得を繰り返していくことでスタック内の戻りアドレスを取得できる。【０００８】
このように、一般的なスタックトレースの手法は、各関数がフレームポインタを用いて自らのデータ領域を参照することを利用して実現されている。一方、フレームポインタは関数の実行に不可欠なものではない。コンパイラの最適化によってフレームポインタを使わない実行ファイルが存在する。また、６４ｂｉｔ版Ｗｉｎｄｏｗｓ（登録商標）等のように、実行環境全体としてフレームポインタを使用しないものも存在する。このようにフレームポインタが使われない場合、前述のようにスタック内のフレームポインタを辿って戻りアドレスを取得することができないため、コールスタックを再現できない。【０００９】
ここで、フレームポインタを使用しない関数呼び出しを含むコールスタックを再現するための技術が知られている。例えば、一般的なデバッガは、対象となるプログラムのデバッグシンボルを活用することでコールスタックを再現できる。また、実行中の動作監視によって、フレームポインタを使用しない関数呼び出しを含むコールスタックを再現できる（非特許文献１参照）。また、スタック内の戻りアドレスをスキャンすることによって、フレームポインタを使用しない関数呼び出しを含むコールスタックを再現できる（非特許文献２，３参照）。
【先行技術文献】
【非特許文献】
【００１０】
【非特許文献１】L.Davi，A.R.Sadeghi，M.Winandy,“ROPdefender:A  Detection  Tool  to  Defend  Against  Return-Oriented  Programming  Attacks”，Proceedings  of  the  6th  ACM  Symposium  on  Information,Computer  and  Communications  Security，ASIACCS’11，ACM，pp.40-51，2011
【非特許文献２】S.M.Hejazi，et  al.，“Extraction  of  Forensically  Sensitive  Information  from  Windows  Physical  Memory”，Digital  Investigation  6，Supplement，S121-S131，2009
【非特許文献３】A.R.Arasteh，M.Debbabi，“Forensic  Memory  Analysis:  From  Stack  and  Code  to  Execution  History”，Digital  Investigation  4，Supplement，S114-S125，2007
【発明の概要】
【発明が解決しようとする課題】
【００１１】
しかしながら、従来の技術は、フレームポインタを使用しない関数呼び出しを含むコールスタックを正確に再現できない場合がある。例えば、デバッグシンボルを活用してコールスタックを再現する技術は、デバッグシンボルを取得可能なプログラムに適用範囲が限定されるため、リリースに伴ってシンボルが除去された正規のプログラムや、マルウェア等の悪性プログラムの解析には適用できない。【００１２】
また、実行中の動作監視によってコールスタックを再現する技術では、実行中の動作を監視する必要があるため、この技術の適用範囲は、監視用プログラムを導入している環境で監視対象とされているプログラムに限定される。【００１３】
また、スタック内の戻りアドレスをスキャンすることによって、フレームポインタを使用しない関数呼び出しを含むコールスタックを再現する技術では、戻りアドレスではない関数ポインタ等を誤検知するおそれがある。すなわち、この技術では、スタック領域内に含まれる値のうち、実行可能領域内のアドレスであって、関数呼び出し命令（ｃａｌｌ命令）の直後のアドレスとして解釈できる値を戻りアドレスとして検出する。戻りアドレスではない関数ポインタ等でも上記の条件を満たす場合があるため、戻りアドレスと誤検知する恐れがある。また、過去に戻りアドレスとして使用された値が上書きされずに残っていた場合にも、戻りアドレスとして誤検知される場合がある。【００１４】
本発明は、上記に鑑みてなされたものであって、適用範囲を限定することなく高精度にコールスタックを再現することを目的とする。
【課題を解決するための手段】
【００１５】
上述した課題を解決し、目的を達成するために、本発明に係るコールスタック取得装置は、コンピュータのメモリ、もしくは前記メモリの状態を保存したメモリダンプから、前記コンピュータで動作するアプリケーションプロセスを実行しているスレッドのコールスタックを取得するコールスタック取得装置であって、前記アプリケーションプロセスのメモリ空間内の、前記コールスタックの取得対象となる前記スレッドが持つスタック領域から、関数呼び出し命令の直後の命令を示す前記メモリ空間内の実行可能領域内のアドレスである戻りアドレス候補を抽出する抽出部と、前記戻りアドレス候補のそれぞれが示す命令の直前の前記関数呼び出し命令によって呼び出される関数の内部における分岐命令で構築される制御の流れを示す制御フローを解析し、該制御フローにおいて、現在実行中の命令に到達する経路が存在する場合に、前記戻りアドレス候補を戻りアドレスと判定し、該経路が存在しない場合に戻りアドレスではないと判定する解析部と、を備えることを特徴とする。
【発明の効果】
【００１６】
本発明によれば、適用範囲を限定することなく高精度にコールスタックを再現することができる。
【図面の簡単な説明】
【００１７】
【図１】図１は、コールスタック取得装置の概略構成を例示する模式図である。
【図２】図２は、コールスタック取得装置の処理概要を説明するための説明図である。
【図３】図３は、コールスタック取得処理手順を例示するフローチャートである。
【図４】図４は、コールスタック取得処理手順を例示するフローチャートである。
【図５】図５は、コールスタック取得処理手順を例示するフローチャートである。
【図６】図６は、コールスタック取得装置の実施例を例示する図である。
【図７】図７は、コールスタック取得プログラムを実行するコンピュータを例示する図である。
【発明を実施するための形態】
【００１８】
以下、図面を参照して、本発明の一実施形態を詳細に説明する。なお、この実施形態により本発明が限定されるものではない。また、図面の記載において、同一部分には同一の符号を付して示している。
【００１９】
［コールスタック取得装置の構成］
図１は、コールスタック取得装置の概略構成を例示する模式図である。コールスタック取得装置１０は、コンピュータのメモリ、もしくはメモリの状態を保存したメモリダンプから、そのコンピュータで動作するアプリケーションプロセスを実行しているスレッドのコールスタックを取得する。なお、以下の説明では、ｘ６４アーキテクチャのプロセッサで動作するプログラムを対象にしているが、ＣＰＵ（Central  Processing  Unit）のアーキテクチャやＯＳ環境等は特に限定されない。
【００２０】
コールスタック取得装置１０は、パソコン等の汎用コンピュータで実現され、ＣＰＵ等を用いて実現される制御部が、メモリに記憶された処理プログラムを実行することにより、図１に示すように、スタックスキャン部１１、プログラム解析部１２およびポインタ更新部１３として機能する。なお、これらの機能部は、異なるハードウェアに実装されてもよい。
【００２１】
スタックスキャン部１１は、抽出部として機能する。すなわち、スタックスキャン部１１は、アプリケーションプロセスのメモリ空間内の、コールスタックの取得対象となるスレッドが持つスタック領域から、関数呼び出し命令の直後の命令を示すメモリ空間内の実行可能領域内のアドレスである戻りアドレス候補を抽出する。
【００２２】
具体的には、スタックスキャン部１１は、まず、コールスタックの作成対象のスレッドの動作する仮想メモリ空間を入力として受け付けて、スタック領域を特定する。その際、スタックスキャン部１１は、スタックポインタを入力として受け付けて、スタックポインタを用いてスタック領域を特定する。
【００２３】
なお、仮想メモリ空間とは、実行中のコンピュータのライブメモリに限定されず、仮想メモリ空間を再現可能なメモリダンプでもよい。例えば、物理メモリダンプ、仮想メモリダンプ、コンピュータ休止時に作成される状態保存データ、仮想計算機のサスペンドデータ、スナップショット等でもよい。
【００２４】
また、スタックスキャン部１１は、スタック領域として、スタックポインタから連続する確保済のメモリ領域の範囲を特定する。なお、スタック領域の特定方法はこれに限定されない。例えば、ＯＳ等がコールスタックの範囲を管理している場合には、そのデータ構造からスタック領域を特定してもよい。また、スタックポインタに加えて、スタックの底を示すアドレスのユーザによる指定を受け付けることにより、スタック領域の範囲を特定してもよい。
【００２５】
ここで、図２を参照して、スタックスキャン部１１の処理について説明する。図２は、コールスタック取得装置１０の処理概要を説明するための説明図である。図２（１）は、スレッドのスタック領域を例示している。また、図２（２）は、スレッドの動作するメモリ空間内の実行可能領域の一部を例示している。
【００２６】
スタックスキャン部１１は、図２（１）に例示するように、スタックポインタＲＳＰを用いて特定されたスタック領域をスキャンして、戻りアドレスの候補となる値を抽出する。その際、スタックスキャン部１１は、戻りアドレス候補として、図２（２）に例示するｃａｌｌ命令の直後の命令を示す仮想メモリ空間の実行可能領域内のアドレスを示している値を抽出する。図２に示す例では、Ｐｏｉｎｔｅｒ１およびＰｏｉｎｔｅｒ２が戻りアドレス候補として抽出されている。
【００２７】
プログラム解析部１２は、解析部として機能する。すなわち、プログラム解析部１２は、戻りアドレス候補のそれぞれが示す命令の直前の関数呼び出し命令によって呼び出される関数の内部における分岐命令で構築される制御の流れを示す制御フローを解析する。また、プログラム解析部１２は、該制御フローにおいて、現在実行中の命令に到達する経路が存在する場合に、該戻りアドレス候補を戻りアドレスと判定し、該経路が存在しない場合に戻りアドレスではないと判定する。
【００２８】
具体的には、まず、プログラム解析部１２は、戻りアドレス候補のうち、スタック領域の先頭を示すスタックポインタＲＳＰに近い順に戻りアドレス候補を１つ選定する。次に、プログラム解析部１２は、選定した戻りアドレス候補が示す命令の直前のｃａｌｌ命令によって呼び出される関数について、分岐命令で構築される制御の流れを示す制御フローを解析する。
【００２９】
図２に示す例では、まず、Ｐｏｉｎｔｅｒ１が選定され、図２（２）に示すように、Ｐｏｉｎｔｅｒ１が示す命令の直前のｃａｌｌ命令によって呼び出されるアドレス領域の関数について、図２（３）に例示するように、分岐命令の分岐元と分岐先との関係をグラフ化した制御フローグラフが作成される。
【００３０】
また、プログラム解析部１２は、作成された制御フローグラフを用いて、現在実行中の命令に到達する経路が存在するか否かを検証する。ここで、プログラム解析部１２は、現在実行中の命令を示す命令ポインタＲＩＰを入力として受け付けることにより、命令ポインタＲＩＰを用いて現在実行中の命令を特定する。なお、現在実行中の命令とは、コールスタック取得処理前にスレッドが最後に実行していた命令を意味する。命令ポインタによる特定に限定されず、プログラム解析部１２は、実行コンテキストを示すデータ構造を用いて現在実行中の命令を特定してもよい。
【００３１】
図２には、Ｐｏｉｎｔｅｒ１が示す命令の直前のｃａｌｌ命令によって呼び出される関数の制御フローを解析して検証した結果、現在実行中の命令に到達する経路が存在しないことが示されている。この場合に、プログラム解析部１２は、戻りアドレス候補であるＰｏｉｎｔｅｒ１は戻りアドレスではないと判定する。例えば、過去に戻りアドレスとして使用された値が上書きされずに残っていた場合等が想定される。
【００３２】
そして、プログラム解析部１２は、次にスタックポインタＲＳＰに近い戻りアドレス候補を選定して上記の処理を繰り返す。図２に示す例では、Ｐｏｉｎｔｅｒ２が選定され、上記の処理が繰り返されている。すなわち、図２（２）に示すように、Ｐｏｉｎｔｅｒ２が示す命令の直前のｃａｌｌ命令によって呼び出されるアドレス領域の関数について、図２（３）に例示するように制御フローグラフが作成される。
【００３３】
そして、図２（４）には、作成された制御フローグラフを検証した結果、命令ポインタＲＩＰが示す現在実行中の命令に到達する経路が存在することが示されている。これは、戻りアドレス候補が示す命令を含む関数が現在実行中の関数の呼び出し元として成立することを意味する。この場合に、プログラム解析部１２は、戻りアドレス候補であるＰｏｉｎｔｅｒ２は戻りアドレスであると判定する。
【００３４】
なお、プログラム解析部１２は、実行中のプログラムの全体の制御フローや、制御フローのうち特に関数呼び出しの流れや関係を示すコールフローを解析して、各関数の関係を取得することにより、戻りアドレス候補から適切な戻りアドレスを判定してもよい。
【００３５】
あるいは、プログラム解析部１２は、判定した戻りアドレスや抽出された戻りアドレス候補の先に存在する命令の一部もしくは全てに対して、エミュレーション実行や記号的実行（Symbolic  execution）の手法を適用してよい。これにより、実行中の関数が終了した状態を再現して、正確に戻りアドレスを判定することができる。
【００３６】
ポインタ更新部１３は、更新部として機能する。すなわち、ポインタ更新部１３は、プログラム解析部１２が戻りアドレス候補を戻りアドレスと判定した場合に、戻りアドレスと判定された戻りアドレス候補が存在する位置の直後をスタック領域の先頭の位置とし、戻りアドレスと判定されたアドレスを現在実行中の命令の位置として、それぞれ更新する。
【００３７】
具体的には、ポインタ更新部１３は、プログラム解析部１２が戻りアドレス候補を戻りアドレスと判定した場合に、スタックポインタＲＳＰを、戻りアドレスと判定された戻りアドレス候補が存在する位置の直後のスタック領域の位置に更新し、命令ポインタＲＩＰを戻りアドレスと判定されたアドレスの値に更新する。
【００３８】
図２に示す例では、図２（５）に示すようにスタックポインタがＲＳＰ’に更新され、命令ポインタＲＩＰの値がＰｉｎｔｅｒ２の値に更新される。その後、コールスタック取得装置１０では、上記の処理が繰り返される。
【００３９】
これにより、既に確定した戻りアドレスと戻りアドレス候補との間に呼び出し先と呼び出し元との関係が成立する場合に、その戻りアドレス候補が次に取得すべき戻りアドレスと判定される。したがって、スタック領域の先頭を示すスタックポインタＲＳＰに近い順に、戻りアドレスが確定する。この場合に、コールスタック上で連続する戻りアドレス間で呼び出し元と呼び出し先との関係が成立する。
【００４０】
その後、更新されたスタックポインタがコールスタックの底に到達した場合に、コールスタック取得装置１０は、これまでに判定された戻りアドレスで構成されるコールスタックを、例えば、ディスプレイや外部の管理装置等に出力する。
【００４１】
［コールスタック取得処理］
次に、図３〜図５を参照して、本実施形態に係るコールスタック取得装置１０によるコールスタック取得処理について説明する。図３は、コールスタック取得処理手順を例示するフローチャートである。図３のフローチャートは、例えば、コールスタック取得処理の開始を指示する操作入力をオペレータが行ったタイミングで開始される。
【００４２】
まず、スタックスキャン部１１が、スタックポインタＲＳＰを用いて特定されたスタック領域をスキャンして、戻りアドレス候補を抽出する（ステップＳ１）。次に、プログラム解析部１２が、未検証の戻りアドレス候補があるかを確認し（ステップＳ２）、未検証の戻りアドレス候補がなければ（ステップＳ２，Ｎｏ）、一連のコールスタック取得処理を終了する。
【００４３】
一方、プログラム解析部１２は、未検証の戻りアドレス候補があれば（ステップＳ２，Ｙｅｓ）、この戻りアドレス候補を検証対象として選択する（ステップＳ３）。また、プログラム解析部１２は、戻りアドレス候補が示す命令の直前のｃａｌｌ命令によって呼び出される関数を取得して（ステップＳ４）、この関数の制御（コントロール）フローを解析する（ステップＳ５）。
【００４４】
すなわち、プログラム解析部１２は、現在実行中の命令に到達する経路が存在するか否かを検証する（ステップＳ６）。そして、プログラム解析部１２は、現在実行中の命令に到達する経路が存在しない場合に（ステップＳ７，Ｎｏ）、戻りアドレス候補を戻りアドレスではないと判定し、ステップＳ２に処理を戻す。一方、プログラム解析部１２は、現在実行中の命令に到達する経路が存在する場合に（ステップＳ７，Ｙｅｓ）、戻りアドレス候補を戻りアドレスであると判定し、ステップＳ８に処理を進める。
【００４５】
ステップＳ８の処理では、ポインタ更新部１３が、スタックポインタＲＳＰを、戻りアドレスと判定された戻りアドレス候補が存在する位置の直後のスタック領域の位置に更新し、命令ポインタＲＩＰを戻りアドレスと判定されたアドレスの値に更新する。また、ポインタ更新部１３は、更新されたスタックポインタがコールスタックの底に到達したか否かを確認し（ステップＳ９）、到達していない場合に（ステップＳ９，Ｎｏ）、ステップＳ１に処理を戻す。すなわち、スタックスキャン部１１が、更新後のスタックポインタＲＳＰ’を用いてスタック領域を特定してスキャンし、戻りアドレス候補を抽出した後、上記の処理が繰り返される。
【００４６】
一方、ポインタ更新部１３は、更新されたスタックポインタがコールスタックの底に到達した場合に（ステップＳ９，Ｙｅｓ）、一連のコールスタック取得処理を終了する。
【００４７】
図４も、コールスタック取得処理手順を例示するフローチャートである。図３の処理とは、ステップＳ９の処理のみが異なる。すなわち、ポインタ更新部１３は、更新されたスタックポインタがコールスタックの底に到達したか否かを確認し（ステップＳ９）、到達していない場合に（ステップＳ９，Ｎｏ）、ステップＳ２に処理を戻す。
【００４８】
この場合に、更新前のスタックポインタＲＳＰを用いて特定されたスタック領域のスキャン結果の戻りアドレス候補をそのまま用いて、ステップＳ２以降の処理が繰り返される。したがって、図３の処理と比較して、ステップＳ１の処理の分だけ処理負荷が軽減される。なお、その他の処理は図３の処理と同様なので、説明を省略する。
【００４９】
図５もまた、コールスタック取得処理手順を例示するフローチャートである。図４の処理とは、処理の順序が異なる。すなわち、スタックスキャン部１１が抽出した戻りアドレス候補のそれぞれについて、まず、プログラム解析部１２が、戻りアドレス候補が示す命令の直前のｃａｌｌ命令によって呼び出される関数を取得して（ステップＳ４）、この関数の制御フローを解析する（ステップＳ５）。その後、それぞれの戻りアドレス候補について、現在実行中の命令に到達する経路が存在するか否かの検証（ステップＳ６）と、経路が存在する場合（ステップＳ７，Ｙｅｓ）におけるスタックポインタＲＳＰおよび命令ポインタＲＩＰの更新とが行われる。このように、制御フローの解析と、現在実行中の命令に到達する経路が存在するか否かの検証とを分離して、解析した制御フローの再利用を可能として、処理の効率化を図ることができる。
【００５０】
具体的には、スタックスキャン部１１が、スタックポインタＲＳＰを用いて特定されたスタック領域をスキャンして戻りアドレス候補を抽出（ステップＳ１）した後、プログラム解析部１２が、戻りアドレス候補があるかを確認する（ステップＳ１１）。戻りアドレス候補がなければ（ステップＳ１１，Ｎｏ）、プログラム解析部１２は、一連のコールスタック取得処理を終了する。
【００５１】
一方、プログラム解析部１２は、戻りアドレス候補があれば（ステップＳ１１，Ｙｅｓ）、この戻りアドレス候補を解析対象として選択する（ステップＳ１２）。また、プログラム解析部１２は、戻りアドレス候補が示す命令の直前のｃａｌｌ命令によって呼び出される関数を取得して（ステップＳ４）、この関数の制御（コントロール）フローを解析する（ステップＳ５）。
【００５２】
その後、プログラム解析部１２は、制御フローを未解析の戻りアドレス候補があるかを確認し（ステップＳ１３）、未解析の戻りアドレス候補があれば（ステップＳ１３，Ｙｅｓ）、ステップＳ１２に処理を戻し、制御フローの解析を行う。
【００５３】
一方、プログラム解析部１２は、未解析の戻りアドレス候補がない場合に（ステップＳ１３，Ｎｏ）、未検証の戻りアドレス候補があるかを確認する（ステップＳ２）。そして、プログラム解析部１２は、未検証の戻りアドレス候補がなければ（ステップＳ２，Ｎｏ）、一連のコールスタック取得処理を終了する。
【００５４】
一方、プログラム解析部１２は、未検証の戻りアドレス候補があれば（ステップＳ２，Ｙｅｓ）、ステップＳ５の制御フローの解析結果を用いて、現在実行中の命令に到達する経路が存在するか否かを検証する（ステップＳ６）。そして、プログラム解析部１２は、図４と同様に、現在実行中の命令に到達する経路が存在しない場合に（ステップＳ７，Ｎｏ）、戻りアドレス候補を戻りアドレスではないと判定し、ステップＳ２に処理を戻す。一方、プログラム解析部１２は、現在実行中の命令に到達する経路が存在する場合に（ステップＳ７，Ｙｅｓ）、戻りアドレス候補を戻りアドレスであると判定し、ステップＳ８に処理を進める。
【００５５】
ステップＳ８の処理では、図４と同様に、ポインタ更新部１３が、スタックポインタＲＳＰを、戻りアドレスと判定された戻りアドレス候補が存在する位置の直後のスタック領域の位置に更新し、命令ポインタＲＩＰを戻りアドレスと判定されたアドレスの値に更新する。また、ポインタ更新部１３は、更新されたスタックポインタがコールスタックの底に到達したか否かを確認し（ステップＳ９）、到達していない場合に（ステップＳ９，Ｎｏ）、ステップＳ２に処理を戻し、到達した場合に（ステップＳ９，Ｙｅｓ）、一連のコールスタック取得処理を終了する。
【００５６】
以上、説明したように、本実施形態のコールスタック取得装置１０において、スタックスキャン部１１は、アプリケーションプロセスのメモリ空間内の、コールスタックの取得対象となるスレッドが持つスタック領域から、関数呼び出し命令の直後の命令を示すメモリ空間内の実行可能領域内のアドレスである戻りアドレス候補を抽出する。また、プログラム解析部１２が、戻りアドレス候補のそれぞれが示す命令の直前の関数呼び出し命令によって呼び出される関数の内部における分岐命令で構築される制御の流れを示す制御フローを解析し、該制御フローにおいて、現在実行中の命令に到達する経路が存在する場合に、該戻りアドレス候補を戻りアドレスと判定し、該経路が存在しない場合に戻りアドレスではないと判定する。
【００５７】
これにより、コールスタック取得装置１０は、他の戻りアドレスが示す関数と呼び出し元と呼び出し先との関係が成立しない関数ポインタ等を、戻りアドレスとして誤検出することを回避できる。また、過去に戻りアドレスとして使用された値が上書きされずに残っていた場合にも、戻りアドレスとして誤検出することを回避できる。従って、高精度にコールスタックを再現することが可能となる。
【００５８】
また、コールスタック取得処理の対象は、デバッグシンボルを取得可能なプログラムや、監視用プログラムを導入している環境下の監視対象プログラム等に限定する必要はない。このように、本実施形態のコールスタック取得装置１０によれば、適用範囲を限定することなく、高精度にコールスタックを再現することが可能となる。
【００５９】
なお、本実施形態のコールスタック取得装置１０は、スタックポインタや命令ポインタを用いる手法に限定されず、スキャンするスタック領域の範囲と、コールスタック取得処理前に最後に実行されていた関数とが特定できればよい。例えば、スタック領域や実行コンテキストを示すデータ構造を用いてもよい。
【００６０】
［実施例］
図６は、コールスタック取得装置１０の実施例を例示する図である。例えば、図６（ａ）に示すように、インシデントレスポンスにコールスタック取得装置１０を用いてもよい。この場合、コールスタック取得装置１０は、被害ＰＣのメモリダンプを解析し、コールスタックを取得する。そして、フォレンジックアナリスト等が、作成されたコールスタックの内容を見ることで、被害ＰＣの被害状況や対策を検討し、インシデントレスポンスを速やかに行うことができる。
【００６１】
また、図６（ｂ），（ｃ）に示すように、脅威監視サーバによる監視対象ＰＣ（エンドポイント）の脅威監視にコールスタック取得装置１０を用いてもよい。この場合、図６（ｂ）に示すように、コールスタック取得装置１０は、ＰＣのメモリを解析し、コールスタックを取得する。そして、ＰＣの監視ソフトウェアが取得されたコールスタックを分析することで、ＰＣの動作状態を監視することができる。
【００６２】
また、図６（ｃ）に示すように、コールスタック取得装置１０は、脅威監視サーバに装備してリモート監視を行う場合にも用いることができる。この場合に、脅威監視サーバは、監視Ａｇｅｎｔにより監視された監視対象ＰＣのメモリの監視データ（メモリダンプ）を取得すると、コールスタック取得装置１０により、メモリダンプを解析し、監視対象ＰＣで動作するアプリケーションのコールスタックを取得する。脅威監視サーバは、取得されたコールスタックを分析することで、監視対象ＰＣの動作状態を監視することができる。
【００６３】
また、図６（ｄ）に示すように、仮想化基盤による仮想計算機（ＶＭ）の監視にコールスタック取得装置１０を用いてもよい。この場合、コールスタック取得装置１０は、仮想化基盤となるコンピュータに装備される。そして、仮想化基盤となるコンピュータは、自身の内部に構築された各ＶＭのメモリを監視し、必要に応じて各ＶＭで動作するアプリケーションのコールスタックを取得する。そして、仮想化基盤となるコンピュータは、各ＶＭのコールスタックを分析することで、各ＶＭの動作状態を監視することができる。
【００６４】
さらに、図６（ｅ）に示すように、アプリケーションプログラムのデバッグ作業にコールスタック取得装置１０を用いてもよい。この場合、コールスタック取得装置１０は、デバッグ対象のプログラムのメモリやメモリダンプを解析し、コールスタックを取得する。そして、デバッガが取得されたコールスタックを分析することで、デバッグシンボルを持たないプログラムに対しても、詳細な実行監視を必要とせずに効率よくデバッグ作業を行うことができる。
【００６５】
［プログラム］
上記実施形態に係るコールスタック取得装置１０が実行する処理をコンピュータが実行可能な言語で記述したプログラムを作成することもできる。一実施形態として、コールスタック取得装置１０は、パッケージソフトウェアやオンラインソフトウェアとして上記のコールスタック取得処理を実行するコールスタック取得プログラムを所望のコンピュータにインストールさせることによって実装できる。例えば、上記のコールスタック取得プログラムを情報処理装置に実行させることにより、情報処理装置をコールスタック取得装置１０として機能させることができる。ここで言う情報処理装置には、デスクトップ型またはノート型のパーソナルコンピュータが含まれる。また、その他にも、情報処理装置にはスマートフォン、携帯電話機やＰＨＳ（Personal  Handyphone  System）などの移動体通信端末、さらには、ＰＤＡ（Personal  Digital  Assistants）などのスレート端末などがその範疇に含まれる。
【００６６】
また、コールスタック取得装置１０は、ユーザが使用する端末装置をクライアントとし、当該クライアントに上記のコールスタック取得処理に関するサービスを提供するサーバ装置として実装することもできる。例えば、コールスタック取得装置１０は、仮想メモリ空間、スタックポインタおよび命令ポインタを入力とし、コールスタックを出力するコールスタック取得処理サービスを提供するサーバ装置として実装される。この場合、コールスタック取得装置１０は、Ｗｅｂサーバとして実装することとしてもよいし、アウトソーシングによって上記のコールスタック取得処理に関するサービスを提供するクラウドとして実装することとしてもかまわない。以下に、コールスタック取得装置１０と同様の機能を実現するコールスタック取得プログラムを実行するコンピュータの一例を説明する。
【００６７】
図７は、コールスタック取得プログラムを実行するコンピュータを例示する図である。コンピュータ１０００は、例えば、メモリ１０１０と、ＣＰＵ１０２０と、ハードディスクドライブインタフェース１０３０と、ディスクドライブインタフェース１０４０と、シリアルポートインタフェース１０５０と、ビデオアダプタ１０６０と、ネットワークインタフェース１０７０とを有する。これらの各部は、バス１０８０によって接続される。
【００６８】
メモリ１０１０は、ＲＯＭ（Read  Only  Memory）１０１１およびＲＡＭ１０１２を含む。ＲＯＭ１０１１は、例えば、ＢＩＯＳ（Basic  Input  Output  System）等のブートプログラムを記憶する。ハードディスクドライブインタフェース１０３０は、ハードディスクドライブ１０３１に接続される。ディスクドライブインタフェース１０４０は、ディスクドライブ１０４１に接続される。ディスクドライブ１０４１には、例えば、磁気ディスクや光ディスク等の着脱可能な記憶媒体が挿入される。シリアルポートインタフェース１０５０には、例えば、マウス１０５１およびキーボード１０５２が接続される。ビデオアダプタ１０６０には、例えば、ディスプレイ１０６１が接続される。
【００６９】
ここで、ハードディスクドライブ１０３１は、例えば、ＯＳ１０９１、アプリケーションプログラム１０９２、プログラムモジュール１０９３およびプログラムデータ１０９４を記憶する。
【００７０】
また、コールスタック取得プログラムは、例えば、コンピュータ１０００によって実行される指令が記述されたプログラムモジュール１０９３として、ハードディスクドライブ１０３１に記憶される。具体的には、上記実施形態で説明したコールスタック取得装置１０が実行する各処理が記述されたプログラムモジュール１０９３が、ハードディスクドライブ１０３１に記憶される。
【００７１】
また、コールスタック取得プログラムによる情報処理に用いられるデータは、プログラムデータ１０９４として、例えば、ハードディスクドライブ１０３１に記憶される。そして、ＣＰＵ１０２０が、ハードディスクドライブ１０３１に記憶されたプログラムモジュール１０９３やプログラムデータ１０９４を必要に応じてＲＡＭ１０１２に読み出して、上述した各手順を実行する。
【００７２】
なお、コールスタック取得プログラムに係るプログラムモジュール１０９３やプログラムデータ１０９４は、ハードディスクドライブ１０３１に記憶される場合に限られず、例えば、着脱可能な記憶媒体に記憶されて、ディスクドライブ１０４１等を介してＣＰＵ１０２０によって読み出されてもよい。あるいは、コールスタック取得プログラムに係るプログラムモジュール１０９３やプログラムデータ１０９４は、ＬＡＮ（Local  Area  Network）やＷＡＮ（Wide  Area  Network）等のネットワークを介して接続された他のコンピュータに記憶され、ネットワークインタフェース１０７０を介してＣＰＵ１０２０によって読み出されてもよい。
【００７３】
以上、本発明者によってなされた発明を適用した実施形態について説明したが、本実施形態による本発明の開示の一部をなす記述および図面により本発明は限定されることはない。すなわち、本実施形態に基づいて当業者等によりなされる他の実施形態、実施例および運用技術等は全て本発明の範疇に含まれる。
【符号の説明】
【００７４】
１０  コールスタック取得装置
１１  スタックスキャン部（抽出部）
１２  プログラム解析部（解析部）
１３  ポインタ更新部（更新部）
【図１】
2019049478.tif 000003
【図２】
2019049478.tif 000004
【図３】
2019049478.tif 000005
【図４】
2019049478.tif 000006
【図５】
2019049478.tif 000007
【図６】
2019049478.tif 000008
【図７】
2019049478.tif 000009
【国際調査報告】
2019049478.tif 000010
2019049478.tif 000011
2019049478.tif 000012
2019049478.tif 000013