(57)【要約】【課題】ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止すること。【解決手段】本発明は、遅延リンクを採用した実行ファイルからリンクされるプログラム内の関数が呼び出されるコンピュータでの処理において、関数が呼び出された際に指示されたアドレスが間接参照するグローバルオフセットテーブル中の前記関数のスロットが呼び出された関数を正しく指し示しているかを判定し、指し示していなければ実行を停止するようにプログラムを変換することで、不正なプログラムの実行を未然に防止する。【選択図】図１
2019121203.tif 000002
【特許請求の範囲】
【請求項１】
攻撃を検知して停止するようにプログラムを変換する変換装置であって、
変換対象プログラムの実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、ロードアドレス算出命令生成挿入部と、
前記共有ライブラリ内の関数を呼び出す際に前記変換対象プログラムに存在する前記関数のプロシージャリンケージテーブルから特定されるグローバルオフセットテーブル中の前記関数のスロット（以下、ＧＯＴスロット）を、前記変換対象プログラムに問い合わせ、取得して、保持するＧＯＴスロット取得部と、
前記変換対象プログラムに存在するグローバルオフセットテーブルが書き込み可能かどうかを判定するＧＯＴ書き込み可否判定部と、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムに存在するプロシージャリンケージテーブルに記述されている遅延リンクの際に前記関数のアドレスを解決するための命令群の先頭アドレス（以下、ＰＬＴ解決アドレス）を、前記変換対象プログラムに問い合わせ、取得して、保持するＰＬＴ解決アドレス取得部と、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムから呼び出される前記関数本体の先頭アドレス（以下、関数アドレス）を、前記共有ライブラリに問い合わせ、取得して、保持する関数アドレス取得部と、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記ＰＬＴ解決アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入部が生成した命令に引き渡す命令を、値が一致していなければ関数アドレスチェック命令生成挿入部に引き渡す命令を、生成して、前記変換対象プログラムに挿入する、ＰＬＴチェック命令生成挿入部と、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入部が生成した命令に引き渡す命令を、値が一致しなければ前記変換対象プログラムを終了させる命令を、生成して、前記変換対象プログラムに挿入する、関数アドレスチェック命令生成挿入部と、
グローバルオフセットテーブルが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、ＧＯＴスロットが参照する値に分岐する分岐命令を、それ以外の場合には、プロシージャリンケージテーブル経由で関数をコールする命令を、生成して、前記変換対象プログラムに挿入する、関数別ジャンプ命令生成挿入部と、
前記変換対象プログラムから前記共有ライブラリ内の関数を呼び出す命令を検出し、検出した前記関数を呼び出す命令を、リターンアドレスを計算して保持した後に、グローバルオフセットテーブルが書き込み可能な場合にはＰＬＴチェック命令生成挿入部が挿入した命令に、グローバルオフセットテーブルが書き込み禁止の場合には関数別ジャンプ命令生成挿入部が挿入した命令に分岐する命令に書き換えるコール命令書き換え部と、
前記変換対象プログラムからリターン命令を検出し、検出した前記リターン命令を前記計算して保持しているアドレスに分岐する命令に書き換えるリターン命令書き換え部と、
を備えることを特徴とする変換装置
【請求項２】
前記ロードアドレス算出命令生成挿入部は、変換対象プログラムが実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、その算出結果を１つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、
請求項１に記載の変換装置
【請求項３】
コンピュータに、
攻撃を検知して停止するようにプログラムの変換を実行させる変換プログラムであって、
変換対象プログラムの実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、ロードアドレス算出命令生成挿入処理ステップと、
前記ＧＯＴスロットを、前記変換対象プログラムに問い合わせ、取得して、保持するＧＯＴスロット取得処理ステップと、
前記変換対象プログラムに存在するグローバルオフセットテーブルが書き込み可能かどうかを判定するＧＯＴ書き込み可否判定処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記ＰＬＴ解決アドレスを、前記変換対象プログラムに問い合わせ、取得して、保持するＰＬＴ解決アドレス取得処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記関数アドレスを、前記共有ライブラリに問い合わせ、取得して、保持する関数アドレス取得処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記ＰＬＴ解決アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば、関数別ジャンプ命令生成挿入処理ステップが生成した命令に引き渡す命令を、値が一致していなければ関数アドレスチェック命令生成挿入部に引き渡す命令を、生成して、前記変換対象プログラムに挿入する、ＰＬＴチェック命令生成挿入処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入処理ステップが生成した命令に引き渡す命令を、値が一致しなければ前記変換対象プログラムを終了させる命令を、生成して、前記変換対象プログラムに挿入する、関数アドレスチェック命令生成挿入処理ステップと、
グローバルオフセットテーブルが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、ＧＯＴスロットが参照する値に分岐する分岐命令を、それ以外の場合には、プロシージャリンケージテーブル経由で関数をコールする命令を、生成して、前記変換対象プログラムに挿入する、関数別ジャンプ命令生成挿入ステップと、
前記変換対象プログラムから前記共有ライブラリ内の関数を呼び出す命令を検出し、検出した前記関数を呼び出す命令を、リターンアドレスを計算して保持したした後に、グローバルオフセットテーブルが書き込み可能な場合にはＰＬＴチェック命令生成挿入処理ステップが挿入した命令に、グローバルオフセットテーブルが書き込み禁止の場合には関数別ジャンプ命令生成挿入処理ステップが挿入した命令に分岐させる命令に書き換えるコール命令書き換え処理ステップと、
前記変換対象プログラムからリターン命令を検出し、検出した前記リターン命令を前記計算して保持しているアドレスに分岐する命令に書き換えるリターン命令書き換え処理ステップと、
を実行させる変換プログラム
【請求項４】
コンピュータを用いた、攻撃を検知して停止するようにプログラムの変換を実行させるプログラム変換方法であって、
変換対象プログラムの実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、ロードアドレス算出命令生成挿入手段と、
前記ＧＯＴスロットを、前記変換対象プログラムに問い合わせ、取得して、保持するＧＯＴスロット取得手段と、
前記変換対象プログラムに存在するグローバルオフセットテーブルが書き込み可能かどうかを判定するＧＯＴ書き込み可否判定手段と、
グローバルオフセットテーブルが書き込み可能な場合に、前記ＰＬＴ解決アドレスを、前記変換対象プログラムに問い合わせ、取得して、保持するＰＬＴ解決アドレス取得手段と、
グローバルオフセットテーブルが書き込み可能な場合に、前記関数アドレスを、前記共有ライブラリに問い合わせ、取得して、保持する関数アドレス取得手段と、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記ＰＬＴ解決アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入手段で生成した命令に引き渡す命令を、値が一致していなければ関数アドレスチェック命令生成挿入部に引き渡す命令を、生成して、前記変換対象プログラムに挿入する、ＰＬＴチェック命令生成挿入手段と、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入手段で生成した命令に引き渡す命令を、値が一致しなければ前記変換対象プログラムを終了させる命令を、生成して、前記変換対象プログラムに挿入する、関数アドレスチェック命令生成挿入手段と、
グローバルオフセットテーブルが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、ＧＯＴスロットが参照する値に分岐する分岐命令を、それ以外の場合には、プロシージャリンケージテーブル経由で関数をコールする命令を、生成して、前記変換対象プログラムに挿入する、関数別ジャンプ命令生成挿入手段と、
前記変換対象プログラムから前記共有ライブラリ内の関数を呼び出す命令を検出し、検出した前記関数を呼び出す命令を、リターンアドレスを計算して保持した後に、グローバルオフセットテーブルが書き込み可能な場合にはＰＬＴチェック命令生成挿入手段が挿入した命令に、グローバルオフセットテーブルが書き込み禁止の場合には関数別ジャンプ命令生成挿入処理ステップが挿入した命令に分岐させる命令に書き換えるコール命令書き換え手段と、
前記変換対象プログラムからリターン命令を検出し、検出した前記リターン命令を前記計算して保持しているアドレスに分岐する命令に書き換えるリターン命令書き換え手段と、
を備えることを特徴とするプログラム変換方法
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止する技術に関するものである。
【背景技術】
【０００２】
不正なプログラムをコンピュータにおいて実行することによる情報流出が問題となっている。これらの不正なプログラムは、ソフトウェアの脆弱性を利用するものが多い。
【０００３】
代表的な例としてバッファオーバーフロー攻撃がある。コンピュータでのプログラムの動作において関数が呼び出される際には、当該関数の呼び出し元へ戻ることを可能とするために、戻り先のアドレスがレジスタまたはメモリ上のスタック領域に格納されるが、関数の脆弱性を利用してスタック領域上の戻り先のアドレスを不正なアドレスに上書きする攻撃がよく知られている。
【０００４】
特許文献１には、バッファオーバーフローの発生を防ぐようにプログラムを変換する変換装置が記載されている。
【０００５】
特許文献２には、バッファオーバーフローによる不正なプログラムの実行を防止する手段を備えるプロセッサが記載されている。
【先行技術文献】
【特許文献】
【０００６】
【特許文献１】特許第５８２０７５４号公報
【特許文献２】特許第５７７７８４３号公報
【発明の概要】
【発明が解決しようとする課題】
【０００７】
しかしながら、バッファオーバーフロー攻撃以外にもソフトウェアの脆弱性を利用して、本来意図しないアドレスに書き換える攻撃が存在する。例えば、位置独立コード化された共有ライブラリ内の関数を実行可能ファイルから呼び出す場合、Ｌｉｎｕｘ（登録商標）でよく利用される実行ファイル形式であるＥｘｅｃｕｔａｂｌｅ  ａｎｄ  Ｌｉｎｋａｂｌｅ  Ｆｏｒｍａｔ（以下、ＥＬＦ）では、関数のアドレスを再配置可能とするために、プロシージャリンケージテーブル（以下、ＰＬＴ）を経由してグローバルオフセットテーブル（以下、ＧＯＴ）というアドレス管理テーブルを利用する。共有ライブラリがロードされれば、共有ライブラリの絶対アドレスが決定されるため、当該関数の絶対アドレスも必然的に解決できることになるが、解決のためにはアドレスの再計算が必要となる。よって、実行可能ファイルの起動を優先するために、アドレス解決のタイミングを個々の関数が実際に呼び出される時に行う方式があり、遅延リンクと呼ばれている。この場合は、アドレス解決のタイミングが関数の呼び出し時となるため、ＧＯＴは読み書き可能とせざるを得ない。ところが、この特徴を利用したＧＯＴ上書き攻撃というものが存在する。攻撃時に、本来のアドレスの代わりに、不正なアドレスに書き換えておき、実際の関数呼び出しの際に、不正な処理を実行させる攻撃である。このように、共有ライブラリが位置独立コード化されていると、実行可能ファイルの実行時に動的リンクによってその絶対アドレスが解決されるために、特許文献１及び特許文献２に記載された発明では、いずれも主処理で呼び出されるプログラムを指し示す絶対アドレスが主処理の実行前にすべて判明していることを前提としているために対応ができない。
【０００８】
また、遅延リンクを採用せずＧＯＴを書き込み禁止とする対策も考えられるが、前述のように起動に時間がかかるという課題がある。
【０００９】
本発明は、このような事情を鑑みてなされたものであり、前述の課題を解決しつつ、ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止する変換装置、変換プログラム、プログラム変換方法を提供することを目的とする。
【課題を解決するための手段】
【００１０】
本発明である変換装置、変換プログラム及びコンピュータを用いたプログラム変換方法は、共有ライブラリ内の関数を呼び出す際に、変換対象プログラムに存在する前記関数のＰＬＴから、ＧＯＴ中の前記関数のスロット（以下、ＧＯＴスロット）を特定し、さらに、このＧＯＴスロットが参照する値が適正か否かを判定し、不正なアドレスに書き換えられていると判定した場合には実行を中断するように、変換対象プログラムを変換することで、前述の課題を解決する。
【００１１】
前述の課題を解決するために、本発明は、ＧＯＴスロットが参照する値と変換対象プログラムに存在するＰＬＴに記述されている遅延リンクの際に関数のアドレスを解決するための命令群の先頭アドレス（以下、ＰＬＴ解決アドレス）と対比し、次に、変換対象プログラムから呼び出される関数本体の先頭アドレス（以下、関数アドレス）と対比することで、値がいずれも一致しない場合に不正なアドレスに書き換えられていると判定する命令を、いずれかに値が一致する場合は直接的または間接的に関数を呼び出す命令を生成して、変換対象プログラムに挿入することを特徴とする。また、前記命令は、変換対象プログラム及び共有ライブラリの各々が位置独立コード化されているか否かの場合分けによって、対比すべきアドレスを算出することを特徴とする。
【００１２】
前述の課題を解決するために、本発明は、判定に必要なＧＯＴスロットとＰＬＴ解決アドレスを変換対象プログラムに問い合わせることで、さらに、関数アドレスを共有ライブラリに問い合わせることで、それぞれ取得し、保持することを特徴とする。
【００１３】
前述の課題を解決するために、本発明は、対比すべきアドレスの算出に必要な変換対象プログラムの開始アドレス及び共有ライブラリの開始アドレスを、変換対象プログラムの実行開始直後に算出して静的変数に格納するプログラムを生成して、変換対象プログラムに挿入することを特徴とする。
【００１４】
前述の課題を解決するために、本発明は、変換対象プログラムから共有ライブラリ内の関数を呼び出す命令を検出して、命令を追加することを考慮してリターンアドレスを再計算して保持した後に、前述のＧＯＴスロットが参照する値が適正か否かを判定する命令にジャンプし、さらに保持したリターンアドレスに復帰させる命令に書き換えることを特徴とする。
【００１５】
前述の課題を解決するために、本発明は、変換対象プログラムから変換対象プログラム内の関数を呼び出す命令を検出して、検出した命令の前に、さらに命令を追加することを考慮してリターンアドレスを再計算して保持する命令を挿入し、検出した命令の後に、保持したリターンアドレスに復帰させる命令を挿入する。さらに、変換対象プログラム内の関数のリターン命令を検出して、検出した命令を保持したリターンアドレスにジャンプする命令に書き換えることを特徴とする。
【発明の効果】
【００１６】
以上のように本発明によれば、前述の課題を解決して、ソフトウェアの脆弱性を利用した攻撃による不正なプログラムの実行を防止することができる。
【図面の簡単な説明】
【００１７】
【図１】変換装置の構成例を示すブロック図である。
【図２】変換装置のハードウェア構成である。
【図３】変換装置の動作を示すフローチャートである。
【図４】メモリマップの例である。
【図５】第１実施形態において、変換済みプログラム実行時のロードアドレス算出命令の動作を示すフローチャートである。
【図６】ＰＬＴ経由のＧＯＴの間接参照のしくみを説明する概念図である。
【図７】ＧＯＴ書き込み可の場合に、ＧＯＴスロットが参照する値が適正か否かを判定するアルゴリズムを示した図である。
【図８】変換装置の動作のうちチェック命令生成挿入処理を示すフローチャートである。
【図９】変換済みプログラム実行時のＰＬＴチェック命令Ａの動作を示すフローチャートである。
【図１０】変換済みプログラム実行時のＰＬＴチェック命令Ｂの動作を示すフローチャートである。
【図１１】チェック命令生成挿入処理のうち関数アドレスチェック命令生成挿入処理を示すフローチャートである。
【図１２】変換済みプログラム実行時の関数アドレスチェック命令Ａの動作を示すフローチャートである。
【図１３】変換済みプログラム実行時の関数アドレスチェック命令Ｂの動作を示すフローチャートである。
【図１４】変換済みプログラム実行時の関数アドレスチェック命令Ｃの動作を示すフローチャートである。
【図１５】変換済みプログラム実行時の関数アドレスチェック命令Ｄの動作を示すフローチャートである。
【図１６】第２実施形態において、変換済みプログラム実行時のロードアドレス算出命令の動作を示すフローチャートである。
【図１７】各オブジェクトの開始アドレスを結合した文字列をひとつの静的変数に、格納した状態を模式的に例示した図である。
【発明を実施するための形態】
【００１８】
本発明の実施の形態について図面を参照して説明する。なお、各図において同一又は相当部分には同一の符号を付し、重複する説明を省略する。
【００１９】
（第１実施形態）
本実施形態に係る変換装置は、攻撃を検知して停止するようにプログラムを変換する変換装置である。この変換装置は、ＧＯＴを書き換えることで不正なプログラムを実行するＧＯＴ上書き攻撃からの防御のためにプログラムを変換する装置として好適に採用されるものである。
【００２０】
図１は、本実施形態による変換装置１０の構成を示すブロック図である。変換装置１０は、アセンブリプログラムをセキュアなアセンブリプログラムに変換するものである。本明細書において、セキュアとは、プログラムへの攻撃から防御するための処理を施された状態を指し、プログラムをセキュアなプログラムに変換することがセキュア化である。図１で示すように、ソースプログラムをコンパイラによってアセンブリプログラムに変換した後に、変換装置１０でセキュア化する。変換装置１０によってセキュア化されたアセンブリプログラムは、アセンブラによってオブジェクトプログラムに変換する。コンパイラに代えて逆アセンブルすることでオブジェクトプログラムをアセンブリプログラムに変換した後に、変換装置１０でセキュアなアセンブリプログラムに変換してもよい。
【００２１】
図１に示すように、変換装置１０は、ロードアドレス算出命令生成挿入部１００、ＧＯＴスロット取得部１１０、ＧＯＴ書き込み可否判定部１２０、ＰＬＴ解決アドレス取得部１３０、関数アドレス取得部１４０、ＰＬＴチェック命令生成挿入部１５０、関数アドレスチェック命令生成挿入部１６０、関数別ジャンプ命令生成挿入部１７０、コール命令書き換え部１８０、及び、リターン命令書き換え部１９０を備えている。
【００２２】
また、ＧＯＴスロット取得部１１０、ＧＯＴ書き込み可否判定部１２０、ＰＬＴ解決アドレス取得部１３０、及び、関数アドレス取得部１４０を情報取得ブロックＢ１０と、ＰＬＴチェック命令生成挿入部１５０、関数アドレスチェック命令生成挿入部１６０、及び、関数別ジャンプ命令生成挿入部１７０を命令生成挿入ブロックＢ２０と、コール命令書き換え部１８０、及び、リターン命令書き換え部１９０を命令書き換えブロックＢ３０として説明する。
【００２３】
ロードアドレス算出命令生成挿入部１００は、変換対象プログラムの実行開始直後に変換対象プログラムの開始アドレス及び共有ライブラリの開始アドレスを算出して静的変数に格納するプログラムを生成し、変換対象プログラムから呼び出すことができるように前記変換対象プログラムに挿入する機能を有している。
【００２４】
ＧＯＴスロット取得部１１０は、変換対象プログラムにリンクされる共有ライブラリ内の関数についてのＧＯＴスロットを、変換対象プログラムに問い合わせ、取得して、保持する機能を有している。
【００２５】
ＧＯＴ書き込み可否判定部１２０は、変換対象プログラムに存在するＧＯＴが書き込み可能かどうかを判定する機能を有している。
【００２６】
ＰＬＴ解決アドレス取得部１３０は、ＧＯＴが書き込み可能な場合に、変換対象プログラムにリンクされる共有ライブラリ内の関数についてのＰＬＴ解決アドレスを、変換対象プログラムに問い合わせ、取得して、保持する機能を有している。
【００２７】
関数アドレス取得部１４０は、ＧＯＴが書き込み可能な場合に、変換対象プログラムから呼び出される関数についての関数アドレスを、共有ライブラリに問い合わせ、取得して、保持する機能を有している。
【００２８】
ＰＬＴチェック命令生成挿入部１５０は、ＰＬＴチェック命令を、生成して、変換対象プログラムに挿入する機能を有している。本実施形態では、判定処理中にＧＯＴスロットが他のスレッドによって改ざんされることを回避するためにＧＯＴスロットが参照する値をレジスタに転送する例で説明する。なお、レジスタに限定するものではなく、他のスレッドからアクセスできないような他の記憶媒体であってもよい。ここで、ＰＬＴチェック命令とは、ＧＯＴが書き込み可能な場合に、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、ＰＬＴ解決アドレスと、ＧＯＴスロットが参照する値を対比して、変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、変換対象プログラムの開始位置を示す絶対アドレスとＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば、関数別ジャンプ命令生成挿入部１７０が生成した命令に引き渡す命令をいう。以下において同様である。ここで引き渡す命令とは、目的の命令にジャンプする命令であっても、後続の命令として続けて実行させる命令でもよい。以下において同様の意味で使用する。
【００２９】
関数アドレスチェック命令生成挿入部１６０は、関数アドレスチェック命令を、生成して、変換対象プログラムに挿入する機能を有している。本実施形態では、判定処理中にＧＯＴスロットが参照先するアドレスが他のスレッドによって改ざんされることを回避するために、ＧＯＴスロットが参照する値をレジスタに転送する例で説明する。なお、レジスタに限定するものではなく他のスレッドからアクセスできないような他の記憶媒体であってもよい。ここで、関数アドレスチェック命令とは、ＧＯＴが書き込み可能な場合に、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、関数アドレスと、ＧＯＴスロットが参照する値とを対比して、共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、ＧＯＴスロットが参照する値とを対比して、変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる関数の開始位置を示す絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば、関数別ジャンプ命令生成挿入部１７０が生成した命令に引き渡す命令を、値が一致しなければ変換対象プログラムを終了させる命令をいう。以下において同様である。
【００３０】
関数別ジャンプ命令生成挿入部１７０は、関数別ジャンプ命令を、生成して、変換対象プログラムに挿入する機能を有している。ここで、関数別ジャンプ命令とは、ＧＯＴが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、関数アドレスチェック命令生成挿入部１６０で、ＧＯＴスロットが参照する値を格納したレジスタの値に分岐する命令を、それ以外の場合には、本来のＰＬＴ経由で関数をコールする命令をいう。なお、ここでＧＯＴスロットが参照する値を格納したレジスタの値に分岐する命令は、ジャンプ命令であってもよいし、ＧＯＴスロットが参照する値を格納したレジスタの値を関数アドレスとしてコールする命令であってもよい。以下において同様である。
【００３１】
コール命令書き換え部１８０は、変換対象プログラムから共有ライブラリ内の関数を呼び出す命令を検出し、命令が追加される分を考慮し、リターンアドレスを再計算してレジスタに格納し、検出した関数を呼び出す命令を、ＧＯＴが書き込み可能な場合にはＰＬＴチェック命令に、ＧＯＴが書き込み禁止の場合には関数別ジャンプ命令に、ジャンプする命令に書き換える機能を有している。なお、本実施形態では、再計算したリターンアドレスをレジスタに転送する例で説明するが、レジスタに限定するものではなく他のスレッドからアクセスできないような他の記憶媒体であってもよい。
【００３２】
リターン命令書き換え部１９０は、変換対象プログラムからリターン命令を検出し、検出したリターン命令を、コール命令書き換え部１８０でレジスタに格納されたアドレスにジャンプする命令に書き換える機能を有している。
【００３３】
図１に示す変換装置１０は、図２に示すハードウェア構成２０を有する。図２に示すように、変換装置１０は、物理的には、中央演算装置（ＣＰＵ）２１０、入力装置２２０、出力装置２３０、主記憶装置（ＲＡＭ／ＲＯＭ）２４０、補助記憶装置２５０等を含むコンピュータシステムとして構成される。また、一時的な記憶回路としてＣＰＵ内に複数のレジスタ２６０を有する。
【００３４】
変換装置１０の各機能は、図２に示す中央演算装置（ＣＰＵ）２１０、主記憶装置（ＲＡＭ／ＲＯＭ）２４０等に所定のコンピュータソフトウェアを読み込ませることにより、中央演算装置（ＣＰＵ）２１０の制御により入力装置２２０、出力装置２３０を動作させるとともに、主記憶装置（ＲＡＭ／ＲＯＭ）２４０、補助記憶装置２５０とデータの読み書きを行うことで実現される。
【００３５】
次に、本実施形態に係る変換装置１０の動作について説明する。図３は、本実施形態に係る変換装置１０の動作を示すフローチャートである。なお、説明理解の容易性を考慮して、以下では、オペレーションシステムとしてＬｉｎｕｘ（登録商標）、プログラミング言語としてＣ言語、コンパイラとしてＧＮＵコンパイラコレクション（以下、ＧＣＣ）、及び、コンパイラが生成するファイル形式としてＥＬＦを使用するものとして説明するが、コンピュータが同様の挙動をとる環境であれば同じである。
【００３６】
変換装置１０は、例えば、変換対象プログラム及び変換対象プログラムにリンクされるプログラムをプロセス空間にロードした後に明示的に動作の開始を指示するなどによって、図３に示す動作を開始する。
【００３７】
変換装置１０の動作の開始にあたっては、変換装置１０に対して変換対象プログラムを指定する。例えば、変換装置１０で起動する変換プログラムに引数として、変換対象プログラムの実行可能ファイルのプロセスＩＤ、変換対象プログラムのオブジェクトファイルのディレクトリパス、変換対象プログラムのオブジェクトファイルのソースファイルのディレクトリパスを与えるなどによって指定する。
【００３８】
図３に示すフローチャートに従って、本実施形態に係る変換装置１０の動作について説明する。
【００３９】
ロードアドレス算出命令生成挿入部１００が、ロードアドレス算出命令生成挿入処理（Ｓ３０１）を行う。ロードアドレス算出命令生成挿入処理（Ｓ３０１）では、まず、変換対象プログラム及び変換対象プログラムにリンクされるプログラムの開始アドレスを格納する静的変数を定義する処理を行う。次に、変換対象プログラムの実行開始直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされるプログラムの開始アドレスを算出し、定義した静的変数に格納することで保持するプログラムを生成する処理を行う。最後に、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する処理を行う。以下、ロードアドレス算出命令生成挿入処理（Ｓ３０１）の内容を説明する。
【００４０】
まず、ロードアドレス算出命令生成挿入部１００は、変換対象プログラム及び変換対象プログラムにリンクされるプログラムの開始アドレスを格納する静的変数を定義する処理を行う。
【００４１】
ロードアドレス算出命令生成挿入部１００は、メモリマップを取得する。メモリマップとは、オペレーティングシステムのカーネルにおいてプロセスの状態を示すデータ構造の情報をマッピングしたファイルである。メモリマップによってプロセス空間の各領域の正確な開始アドレスを得ることができる。例えば、Ｌｉｎｕｘ（登録商標）では、／ｐｒｏｃディレクトリ配下にプロセスＩＤごとに存在する。自プロセスＩＤは、Ｃ言語ではｇｅｔｐｉｄ関数によって取得できる。
【００４２】
図４に、メモリマップの例を示す。符号ａに開始アドレスが、符号ｂに終了アドレスが、符号ｃにアクセス権限が、符号ｄにフルパスが示される。実行可能ファイル（符号ｅ）と共有ライブラリ（符号ｆ）は、いずれもアクセス権限（符号ｃ）がｒ−ｘｐ（読み込み可、書き込み不可、実行可）であることから識別ができる。
【００４３】
ロードアドレス算出命令生成挿入部１００は、取得したメモリマップからアクセス権限（符号ｃ）がｒ−ｘｐであるオブジェクトファイルについて、フルパス（符号ｄ）と開始アドレス（符号ａ）を抽出する。なお、アクセス権限（符号ｃ）がｒ−ｘｐであってもローダなどチェックの必要がないオブジェクトファイルについて、処理の効率化を図るために抽出対象から除外してもよい。
【００４４】
ロードアドレス算出命令生成挿入部１００は、抽出した実行可能ファイル及び共有ライブラリについて、開始アドレスを格納するための静的変数として開始アドレス格納変数を定義する。ここでは、開始アドレス格納変数名に連番を付与して定義して、開始アドレスの降順に格納するとして説明する。
【００４５】
表１は、例として、ロードアドレス算出命令生成挿入部１００が、図４に示すメモリマップから実行可能ファイル及び共有ライブラリについて、フルパス及び対応する定義した開始アドレス格納変数を示したものである。
【表１】
2019121203.tif 000003
【００４６】
次に、ロードアドレス算出命令生成挿入部１００は、変換対象プログラムの実行開始直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされる共用ライブラリの開始アドレスを算出し、定義した静的変数に格納することで保持するプログラムを生成する処理を行う。
【００４７】
ロードアドレス算出命令生成挿入部１００が生成するプログラムの詳細と変換済みの変換対象プログラム実行時の動作については後述する。
【００４８】
最後に、ロードアドレス算出命令生成挿入部１００は、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する処理を行う。定義した静的変数（開始アドレス格納変数）をヘッダファイルとして、変換対象プログラムのソースコードにインクルードし、さらに生成したプログラムの呼び出しを変換対象プログラムのソースコード中のｍａｉｎ関数の冒頭に記述することで、変換対象プログラムの起動直後に生成したプログラムを呼び出すことができるようにする。したがって、ロードアドレス算出命令生成挿入処理（Ｓ３０１）は、変換対象プログラム及び生成したプログラムのコンパイルとリンクを行う。ロードアドレス算出命令生成挿入処理（Ｓ３０１）が終了すると、ＧＯＴスロット取得処理（Ｓ３０３）に移行する。
【００４９】
ここで、実行時におけるロードアドレス算出命令生成挿入部１００が生成し、挿入したプログラムの動作を説明する。
【００５０】
プログラムが実行されると実行可能ファイルのヘッダファイルに記述された開始アドレス格納変数の領域がプロセス空間に確保される。アドレス格納変数は静的変数であるからアドレス（変数のアドレス）は絶対アドレスとなる。表２は、実行可能ファイル及び共有ライブラリについてのフルパス、開始アドレス格納変数及び定義した開始アドレス格納変数のアドレスを示した例である。
【表２】
2019121203.tif 000004
【００５１】
図５は、変換済みのプログラム実行時におけるロードアドレス算出命令生成挿入部１００が生成し、挿入したプログラムの動作を示すフローチャートである。
【００５２】
変換済みのプログラムの実行ファイルからロードアドレス算出命令生成挿入部１００が生成し、挿入したプログラムが呼び出されると自プロセスＩＤを取得する処理（Ｓ５０１）が実行される。ｇｅｔｐｉｄ関数でプロセスＩＤを取得する。Ｓ５０１の処理が終了するとＳ５０３の処理に移行する。
【００５３】
Ｓ５０３の処理では、取得したプロセスＩＤのメモリマップを取得する。メモリマップは／ｐｒｏｃディレクトリ配下にプロセスＩＤごとに存在する。Ｓ５０３の処理が終了するとＳ５０５の処理に移行する。
【００５４】
Ｓ５０５の処理では、取得したプロセスＩＤのメモリマップを１行ずつ取得する。アクセス権限がｒ−ｘｐである場合（Ｓ５０７）に、開始アドレスを対応する開始アドレス格納変数に入力（Ｓ５０９）する。メモリマップの最終行までＳ５０５の処理が終了するとロードアドレス算出命令生成挿入部１００が生成するプログラムによる処理が終了する。
【００５５】
表３は、図４に示すメモリマップについて、図５に示す処理終了後の状態を例として示した表である。例えば、表３の１行目は、ｍａｉｎの先頭を示す絶対アドレスは０ｘ００４０００００であって、この値は定義された静的変数ｓｔａｒｔ＿ｌｏａｄ＿ａｄｄｒ０に格納されており、この静的変数のアドレスが０ｘ００００００００００６０１８ｄ０であることを示している。
【表３】
2019121203.tif 000005
【００５６】
図３に戻り、ロードアドレス算出命令生成挿入処理（Ｓ３０１）が終了すると、ＧＯＴスロット取得処理（Ｓ３０３）から始まる情報取得ブロックＢ１０で行う処理に移行する。
【００５７】
情報取得ブロックＢ１０で行う処理の説明の前に、以降の説明理解のために、共有ライブラリ内の関数呼出におけるＧＯＴとＰＬＴの役割について概説する。
【００５８】
共有ライブラリ内の関数を呼び出す手段としてＧＯＴを利用する。ＧＯＴは、外部関数及び外部変数のアドレスを格納しているテーブルである。これにより、共有ライブラリが位置独立コードであっても目的の関数や変数にアクセス可能となる。
【００５９】
一般に外部関数や外部変数の数が多くなるとアドレス解決に要する時間が無視できなくなり、実行可能ファイルの起動が遅延することがある。このため、関数が初めて呼び出された時にアドレス解決を行う方法があり、遅延リンクという。ＰＬＴは遅延リンクの際に利用される。
【００６０】
遅延リンクは、ＰＬＴを経由してＧＯＴを間接参照することで実現する。共有ライブラリ内の関数を指し示すアドレスは、共有ライブラリがロードされた際に、共有ライブラリの開始アドレスと関数のオフセットを用いて決定される。演算を必要とするため直接的にアドレスを指定することができないので、ＰＬＴを経由してＧＯＴを間接参照する。ＰＬＴにはアドレス解決のための小さなコードが含まれている。
【００６１】
図６は、共有ライブラリ内のｐｕｔｓ関数を例としてＰＬＴ経由のＧＯＴの間接参照のしくみを説明する概念図である。
【００６２】
図６に示すように、共有ライブラリ内の関数の呼び出しは、アセンブリプログラムにおいて、「ｃａｌｌ  ＰＬＴの当該関数のアドレス解決のための命令群の先頭アドレス  ＜（当該関数名）＠ｐｌｔ＞」（図６では、ｃａｌｌ  ８０４８２ａ８  ＜ｐｕｔｓ＠ｐｌｔ＞）と記述される。この命令の参照先には、ｊｍｐ命令があり、ジャンプ先として当該関数のＧＯＴスロットが参照する値にさらにジャンプする。図６の例では、「アドレス０ｘ８０４９５５ｃ（ＧＯＴスロット：ＧＯＴの０ｘ８０４９５５ｃを指示）で参照するアドレス（ＰＬＴ解決アドレス：ＰＬＴの８０４８２ａｅ）にジャンプせよ」との命令となっている。
【００６３】
当該関数のＧＯＴスロットの初期値は、ＰＬＴの当該関数について記述された領域の２行目の命令（ＰＬＴ解決アドレス：図６では、ＰＬＴの８０４８２ａｅ）となっている。このＰＬＴ解決アドレスはアドレス解決のための小さなコードの先頭である。当該関数が初めて呼び出されると、当該関数のアドレスを解決する処理に移る。この処理は、当該関数のアドレスを取得した後、ＧＯＴスロットの値（図６では、ＰＬＴの８０４８２ａｅ）を取得した当該関数の絶対アドレス（関数アドレス：図６では、ｐｕｔｓのアドレス）に書き換える。これにより、当該関数の２回目の呼び出し以降は、ＰＬＴ経由でＧＯＴスロットに設定された当該関数の絶対アドレスを直接参照することで当該関数（図６では、ｐｕｔｓ）を呼び出すことができる。以上が遅延リンクの仕組みである。
【００６４】
上述の通り、遅延リンクの正常な動作において、ＧＯＴスロットが参照する値は、ＰＬＴ解決アドレスもしくは関数アドレスのいずれかを取る。
【００６５】
図３に戻り、情報取得ブロックＢ１０で行う処理を説明する。ＧＯＴスロット取得処理（Ｓ３０３）から関数アドレス取得処理（Ｓ３０９）までは、情報取得ブロックＢ１０で行う処理である。これらの処理によって攻撃によってＧＯＴが書き換えられたかどうかチェックするために必要な情報を取得する。
【００６６】
表４及び表５は、以降の説明理解を容易とするために、情報取得ブロックＢ１０で行う処理によって取得される情報の例を模式的に表に示したものである。
【表４】
2019121203.tif 000006
【表５】
2019121203.tif 000007
【００６７】
表４は、変換対象プログラムのＥＬＦヘッダのエントリポイントに記述された値が絶対アドレスの場合の例である。エントリポイントアドレス≧０ｘ０４０００００の場合が相当する。表４は、変換対象プログラムが実行可能ファイルの場合で、標準関数ｐｒｉｎｔｆ、自作関数ｍｙａｄｄ、及び、自作関数ｍｙｃａｌｃを呼び出す例である。表４の関数名の欄には呼び出される関数の名前が、共有ライブラリフルパスの欄には関数が格納されている共有ライブラリのフルパスが、関数アドレスの欄には関数の開始位置を示すアドレス（関数アドレス）が、ＧＯＴスロットの欄には当該関数のＧＯＴスロットが、ＰＬＴ解決用絶対アドレスの欄にはＰＬＴに記述されている遅延リンクの際に関数の開始位置を示すアドレスを解決するための命令群の先頭アドレス（ＰＬＴ解決アドレス）が、それぞれ記述されている。また、網掛けの部分は相対アドレスであり、その他の部分は絶対アドレスが記述されている。変換対象プログラムが絶対アドレスでロードされるので、当該ＰＬＴとＧＯＴも絶対アドレスとなる。
【００６８】
表５は、変換対象プログラムのＥＬＦヘッダのエントリポイントに記述された値が相対アドレスの場合の例である。エントリポイントアドレス＜０ｘ０４０００００の場合が相当する。表５は、変換対象プログラム自体が自作の共有ライブラリｍｙｌｉｂ１．ｓｏ．１．０の場合であり、標準関数ｐｒｉｎｔｆ、及び、自作関数ｍｙｃａｌｃを呼び出す例である。表５の関数名の欄には呼び出される関数の名前が、共有ライブラリフルパスの欄には関数が格納されている共有ライブラリのフルパスが、関数アドレスの欄には関数アドレスが、ＧＯＴスロットが、ＰＬＴアドレス解決用オフセットの欄にはＰＬＴ解決アドレスが、それぞれ記述されている。また、網掛けの部分は相対アドレスであり、その他の部分は絶対アドレスが記述されている。
【００６９】
図３に示すフローチャートで、ＧＯＴスロット取得処理（Ｓ３０３）から説明する。
【００７０】
ＧＯＴスロット取得部１１０が、ＧＯＴスロット取得処理（Ｓ３０３）を行う。ＧＯＴスロット取得処理（Ｓ３０３）では、ＧＯＴスロットを変換対象プログラムに問い合わせ、取得して、保持する。ＧＯＴ上書き攻撃を受けた場合にはＧＯＴスロットが参照する値が変わることから、ＧＯＴ上書き攻撃有無の判定対象とするためにＧＯＴスロットを取得する。
【００７１】
ＧＯＴスロット取得部１１０が、ｏｂｊｄｕｍｐ命令により変換対象プログラムに問い合わせて、ＧＯＴスロットを取得して、保持する。表４及び表５のＧＯＴスロットの欄に記述された値である。変換対象プログラムのＥＬＦヘッダのエントリポイントに記述された値が絶対アドレスの場合（表４）には絶対アドレスと、変換対象プログラムのＥＬＦヘッダのエントリポイントに記述された値が相対アドレスの場合（表５）には相対アドレスとなる。すべての変換対象プログラムについてＳ３０３の処理が終了すると、ＧＯＴ書き込み可否判定処理（Ｓ３０５）に移行する。
【００７２】
ＧＯＴ書き込み可否判定部１２０が、ＧＯＴ書き込み可否判定処理（Ｓ３０５）を行う。ＧＯＴ書き込み可否判定処理（Ｓ３０５）では、変換対象プログラムに存在するＧＯＴが書き込み可能かどうかを判定する。ＧＯＴが書き込み可能な場合に、ＧＯＴ上書き攻撃を受ける可能性があるためである。
【００７３】
ＧＯＴ書き込み可否の判定は、例えば、コンパイラでＧＣＣを利用する場合であれば、調査対象プログラムのＥＬＦヘッダにＧＮＵ＿ＲＥＬＲＯ及びＢＩＮＤ＿ＮＯＷの文字列が含まれている場合にはＧＯＴは書き込み不可であると判定する。
【００７４】
Ｓ３０５の処理が終了すると、ＧＯＴ書き込み可と判定された場合にはＰＬＴ解決アドレス取得処理（Ｓ３０７）に、ＧＯＴ書き込み不可と判定された場合には情報取得ブロック（Ｂ１０）での処理を終えてＳ３１７の処理に移行する。
【００７５】
ＧＯＴ書き込み可否判定処理（Ｓ３０５）でＧＯＴ書き込み可と判定された場合に、ＰＬＴ解決アドレス取得処理（Ｓ３０７）では、ＰＬＴ解決アドレスを変換対象プログラムに問い合わせ、取得して、保持する。
【００７６】
ＰＬＴ解決アドレス取得部１３０が、ｏｂｊｄｕｍｐ命令により変換対象プログラムに問い合わせて、ＰＬＴ解決アドレスを取得して、保持する。表４のＰＬＴアドレス解決用絶対アドレス、並びに、表５のＰＬＴアドレス解決用オフセットの欄に記述された値である。変換対象プログラムのＥＬＦヘッダのエントリポイントに記述された値が絶対アドレスの場合（表４）には絶対アドレスと、変換対象プログラムのＥＬＦヘッダのエントリポイントに記述された値が相対アドレスの場合（表５）には相対アドレスとなる。すべての変換対象プログラムについてＳ３０７の処理が終了すると、関数アドレス取得処理（Ｓ３０９）に移行する。
【００７７】
ＧＯＴ書き込み可否判定処理（Ｓ３０５）でＧＯＴ書き込み可と判定された場合に、関数アドレス取得処理（Ｓ３０９）では、関数アドレスを共有ライブラリに問い合わせ、取得して、保持する。
【００７８】
関数アドレス取得部１４０が、ｎｍ命令により共有ライブラリに問い合わせて、関数アドレスを取得して、保持する。表４及び表５の関数アドレスの欄に記述された値である。共有ライブラリのＥＬＦヘッダのエントリポイントに記述された値が相対アドレスの場合は位置独立コード化された共有ライブラリであって、この共有ライブラリ内の関数（例えば、ｍｙａｄｄやｍｙｃａｌｃ）では関数アドレスは相対アドレスをとる。共有ライブラリのＥＬＦヘッダのエントリポイントに記述された値が絶対アドレスの場合は、標準関数（例えば、ｐｒｉｎｔｆ）などであって関数アドレスは絶対アドレスをとる。すべての共有ライブラリについてＳ３０９の処理が終了すると命令生成処理ブロック（Ｂ２０）に移行する。
【００７９】
情報取得処理ブロック（Ｂ１０）が終了すると、変換対象プログラムで呼び出される関数について、表４または表５に記述された情報が保持された状態となる。情報は、記憶装置に記憶するなどして保持する。
【００８０】
命令生成挿入ブロック（Ｂ２０）は、ＧＯＴ書き込み可否判定処理（Ｓ３０５）でＧＯＴ書き込み可と判定された場合に機能するＰＬＴチェック命令生成挿入部１５０と関数アドレス命令生成挿入部１６０、関数別ジャンプ命令生成挿入部１７０及び、ＧＯＴ書き込み不可と判定された場合に機能する関数別ジャンプ命令生成挿入部１７０からなる。まず、ＧＯＴ書き込み可と判定された場合について説明をすすめ、次にＧＯＴ書き込み不可と判定された場合についての説明を行う。
【００８１】
図７は、ＧＯＴ書き込み可の場合に、ＧＯＴスロットが参照する値が適正か否かを判定するアルゴリズムを示した図である。Ｆ７１で示す部分をＰＬＴチェック命令生成挿入部１５０が生成した命令が実施する。Ｆ７３で示す部分を関数アドレス命令生成挿入部１６０が生成した命令が実施する。図７で、判定結果がＯＫの場合は処理を継続し、ＮＧの場合はＧＯＴが不正に書き換えられたと判定してプログラムの実行を停止する。図７で示すアルゴリズムの各判定ステップは次の通りである。
Ｓ７０１  変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスか相対アドレスか判定する。
Ｓ７０３  Ｓ７０１の処理で絶対アドレスと判定された場合に、ＰＬＴ解決アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致するか判定する。
Ｓ７０５  Ｓ７０１の処理で相対アドレスと判定された場合に、変換対象プログラムの開始位置を示す絶対アドレスとＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致するか判定する。
Ｓ７０７  Ｓ７０３の処理で値が一致しないと判定された場合に、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスか相対アドレスか判定する。
Ｓ７０９  Ｓ７０７の処理で絶対アドレスと判定された場合に、関数アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致するか判定する。
Ｓ７１１  Ｓ７０７の処理で相対アドレスと判定された場合に、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致するか判定する。
Ｓ７１３  Ｓ７０５の処理で値が一致しないと判定された場合に、共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスか相対アドレスか判定する。
Ｓ７１５  Ｓ７１３の処理で絶対アドレスと判定された場合に、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致するか判定する。
Ｓ７１７  Ｓ７１３の処理で相対アドレスと判定された場合に、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致するか判定する。
【００８２】
次に、ＰＬＴチェック命令生成挿入部１５０と関数アドレス命令生成挿入部１６０の動作を説明する。ＰＬＴチェック命令生成挿入部１５０と関数アドレス命令生成挿入部１６０は、前述の図７に示すアルゴリズムを実行するプログラムを生成し、変換対象プログラムに挿入する。
【００８３】
ＧＯＴ書き込み可否判定処理（Ｓ３０５）でＧＯＴ書き込み可と判定された場合、図３のＳ３１１の処理で示すように変換対象プログラムのすべてのソースファイルについてチェック命令生成挿入処理（Ｓ３１５）を行う。チェック命令生成挿入処理（Ｓ３１５）はアセンブリで行うため、ソースコードは事前にアセンブリに変換（Ｓ３１３）する。
【００８４】
チェック命令生成挿入処理（Ｓ３１５）は、ＰＬＴチェック命令生成挿入部１５０が行うＰＬＴチェック命令生成挿入処理（Ｓ８０５Ａ及びＳ８０５Ｂ）と関数チェック命令生成挿入部１６０が行う関数チェック命令生成挿入処理（Ｓ１１０７Ａ、Ｓ１１０７Ｂ、Ｓ１１０７Ｃ及びＳ１１０７Ｄ）で構成される。
【００８５】
図８は、チェック命令生成挿入処理（Ｓ３１５）について示すフローチャートである。Ｓ８０１の処理は、変換対象プログラムで呼び出されるすべての関数について順次処理を行う。
【００８６】
Ｓ８０３の処理は、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスの場合と相対アドレスの場合で場合分けする。それぞれの場合によって次に行うＰＬＴチェック命令生成挿入処理が異なるためである。変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合にはＰＬＴチェック命令生成挿入処理Ａ（Ｓ８０５Ａ）に、相対アドレスと判定された場合にはチェック命令生成挿入処理Ｂ（Ｓ８０５Ｂ）に移行する。
【００８７】
Ｓ８０３の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合、ＰＬＴチェック命令生成挿入部１５０がＰＬＴチェック命令生成挿入処理Ａ（Ｓ８０５Ａ）を行う。ＰＬＴチェック命令生成挿入処理Ａ（Ｓ８０５Ａ）では、ＰＬＴ解決アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致しなければ関数アドレスチェック命令生成挿入部１６０が生成した命令（関数アドレスチェック命令）に引き渡してチェック処理を継続し、値が一致したならば関数別ジャンプ命令生成挿入部１７０が生成した命令（関数別ジャンプ命令）に引き渡して処理を継続する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。
【００８８】
Ｓ８０３の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合とは、表４に示される場合である。関数が含まれる共有ライブラリが位置独立コード化されているかどうかによらず、ＰＬＴ解決アドレス及びＧＯＴスロットのいずれも絶対アドレスである。このことから、ＰＬＴ解決アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致しなければＧＯＴが攻撃によって書き換えられた可能性があると判定する。
【００８９】
図９は、変換対象プログラムの実行時に、ＰＬＴチェック命令生成挿入処理Ａ（Ｓ８０５Ａ）で生成された命令（ＰＬＴチェック命令Ａ）が実行された際の動作を示すフローチャートである。
【００９０】
Ｓ９０１の処理では、レジスタＡにＧＯＴスロットが参照する値を転送する。Ｓ９０１の処理が終了するとＳ９０３の処理に移行する。
【００９１】
Ｓ９０３の処理では、レジスタＢにＰＬＴ解決アドレスを転送する。Ｓ９０３の処理が終了するとＳ９０５の処理に移行する。
【００９２】
Ｓ９０５の処理では、レジスタＡとレジスタＢの値を対比する。値が一致しなければＳ９０７の処理に、値が一致すればＳ９０９の処理に移行する。
【００９３】
Ｓ９０７の処理では、関数アドレスチェック命令に引き渡してチェック処理を継続する。また、Ｓ９０９の処理では、関数別ジャンプ命令に引き渡して処理を継続する。
【００９４】
図８に戻り、Ｓ８０３の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合、ＰＬＴチェック命令生成挿入部１５０がＰＬＴチェック命令生成挿入処理Ｂ（Ｓ８０５Ｂ）を行う。ＰＬＴチェック命令生成挿入処理Ｂ（Ｓ８０５Ｂ）では、変換対象プログラムの開始位置を示す絶対アドレスとＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して値が一致しなければ関数アドレスチェック命令生成挿入部１６０が生成した命令（関数アドレスチェック命令）に引き渡してチェック処理を継続し、値が一致したならば関数別ジャンプ命令生成挿入部１７０が生成した命令（関数別ジャンプ命令）に引き渡して処理を継続する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。共有ライブラリの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理（Ｓ３０１）が生成した命令が実行されることで取得する。（表３を参照）
【００９５】
Ｓ８０３の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合とは、表５に示される場合である。この場合は、ＰＬＴ解決アドレス及びＧＯＴスロットのいずれも相対アドレスであってオフセットとなる。このことから、変換対象プログラムの開始位置を示す絶対アドレスとＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければＧＯＴが攻撃によって書き換えられた可能性があると判定する。
【００９６】
図１０は、変換対象プログラムの実行時に、ＰＬＴチェック命令生成処理Ｂ（Ｓ８０５Ｂ）で生成された命令（ＰＬＴチェック命令Ｂ）が実行された際の動作を示すフローチャートである。
【００９７】
Ｓ１００１の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部（Ｓ３０１）で生成した命令が実行されることで算出された変換対象プログラムの開始アドレスを格納した静的変数アドレスを取得する。Ｓ１００１の処理が終了するとＳ１００３の処理に移行する。
【００９８】
Ｓ１００３の処理では、レジスタＡにＳ１００１の処理で取得したアドレスで間接参照されるアドレスを転送する。Ｓ１００３の処理が終了するとＳ１００５の処理に移行する。
【００９９】
Ｓ１００５の処理では、レジスタＢにＧＯＴスロットを転送する。Ｓ１００５の処理が終了するとＳ１００７の処理に移行する。
【０１００】
Ｓ１００７の処理では、レジスタＡの値とレジスタＢの値を加算してレジスタＢに転送する。Ｓ１００７の処理が終了するとＳ１００９の処理に移行する。
【０１０１】
Ｓ１００９の処理では、レジスタＣにＰＬＴ解決アドレスを転送する。Ｓ１００９の処理が終了するとＳ１０１１の処理に移行する。
【０１０２】
Ｓ１０１１の処理では、レジスタＡの値とレジスタＣの値を加算してレジスタＣに転送する。Ｓ１０１１の処理が終了するとＳ１０１３の処理に移行する。
【０１０３】
Ｓ１０１３の処理では、レジスタＢの参照する値とレジスタＣの値を対比する。値が一致しなければＳ１０１５の処理に、値が一致すればＳ１０１７の処理に移行する。
【０１０４】
Ｓ１０１５の処理では、関数アドレスチェック命令に引き渡してチェック処理を継続する。また、Ｓ１０１７の処理では、関数別ジャンプ命令に引き渡して処理を継続する。
【０１０５】
図８に戻り、関数アドレスチェック命令生成挿入処理（Ｓ８０７）について説明する。図１１は、関数アドレスチェック命令生成挿入処理（Ｓ８０７）について示したフローチャートである。
【０１０６】
Ｓ１１０１、Ｓ１１０３及びＳ１１０５の処理は、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスの場合と相対アドレスの場合、変換対象プログラムに呼び出される関数が含まれる共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスの場合と相対アドレスの場合、それぞれの組合せでその後の処理を４つに場合分けする。それぞれの場合によって次に行う関数アドレスチェック命令生成挿入処理が異なるためである。
【０１０７】
Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、Ｓ１１０３の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合、関数アドレスチェック命令生成挿入部１６０は関数アドレスチェック命令生成挿入処理Ａ（Ｓ１１０７Ａ）を行う。関数アドレスチェック命令生成挿入処理Ａ（Ｓ１１０７Ａ）では、関数アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部１７０が生成した命令（関数別ジャンプ命令）に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。
【０１０８】
Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、Ｓ１１０３の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合とは、例えば表４に示されるｐｒｉｎｔｆ関数の場合である。ＧＯＴスロットも絶対アドレスである。また、関数が含まれる共有ライブラリが位置独立コード化されておらず関数アドレスも絶対アドレスである。このことから、関数アドレスと、ＧＯＴスロットが参照する値とを直接に対比して、値が一致しなければＧＯＴが攻撃によって書き換えられた可能性があると判定する。
【０１０９】
図１２は、変換対象プログラムの実行時に、関数アドレスチェック命令生成挿入処理Ａ（Ｓ１１０７Ａ）で生成された命令（関数アドレスチェック命令Ａ）が実行された際の動作を示すフローチャートである。
【０１１０】
Ｓ１２０１の処理では、レジスタＡにＧＯＴスロットが参照する値を転送する。Ｓ１２０１の処理が終了するとＳ１２０３の処理に移行する。
【０１１１】
Ｓ１２０３の処理では、レジスタＢに関数アドレスを転送する。Ｓ１２０３の処理が終了するとＳ１２０５の処理に移行する。
【０１１２】
Ｓ１２０５の処理では、レジスタＡの値とレジスタＢの値を対比する。値が一致しなければＳ１２０７の処理に、値が一致すればＳ１２０９の処理に移行する。
【０１１３】
Ｓ１２０７の処理では、当該関数の呼出命令を中止する命令を出力する。また、Ｓ１２０９の処理では、関数別ジャンプ命令に分岐して処理を継続する。
【０１１４】
図１１に戻り、Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、Ｓ１１０３の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合、関数アドレスチェック命令生成挿入部１６０は関数アドレスチェック命令生成挿入処理Ｂ（Ｓ１１０７Ｂ）を行う。関数アドレスチェック命令生成挿入処理Ｂ（Ｓ１１０７Ｂ）では、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部１７０が生成した命令（関数別ジャンプ命令）に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。共有ライブラリの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理（Ｓ３０１）が生成した命令が実行されることで取得する。（表３を参照）
【０１１５】
Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定され、Ｓ１１０３の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合とは、例えば表４に示されるｍｙａｄｄ関数やｍｙｃａｌｃ関数の場合である。ＧＯＴスロットは絶対アドレスである。また、関数が含まれる共有ライブラリが位置独立コード化されており関数アドレスは相対アドレスであってオフセットである。このことから、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、ＧＯＴスロットが参照する値とを対比して、値が一致しなければＧＯＴが攻撃によって書き換えられた可能性があると判定する。
【０１１６】
図１３は、変換対象プログラムの実行時に、関数アドレスチェック命令生成処理Ｂ（Ｓ１１０７Ｂ）で生成された命令（関数アドレスチェック命令Ｂ）が実行された際の動作を示すフローチャートである。
【０１１７】
Ｓ１３０１の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部（Ｓ３０１）で生成した命令が実行されることで算出された共有ライブラリの開始アドレスを格納した静的変数アドレスを取得する。Ｓ１３０１の処理が終了するとＳ１３０３の処理に移行する。
【０１１８】
Ｓ１３０３の処理では、レジスタＡにＳ１３０１の処理で取得したアドレスで間接参照されるアドレスを転送する。Ｓ１３０３の処理が終了するとＳ１３０５の処理に移行する。
【０１１９】
Ｓ１３０５の処理では、レジスタＢにＧＯＴスロットが参照する値を転送する。Ｓ１３０５の処理が終了するとＳ１３０７の処理に移行する。
【０１２０】
Ｓ１３０７の処理では、レジスタＣに関数アドレスを転送する。Ｓ１３０７の処理が終了するとＳ１３０９の処理に移行する。
【０１２１】
Ｓ１３０９の処理では、レジスタＡの値とレジスタＣの値を加算してレジスタＣに転送する。Ｓ１３０９の処理が終了するとＳ１３１１の処理に移行する。
【０１２２】
Ｓ１３１１の処理では、レジスタＢの値とレジスタＣの値を対比する。値が一致しなければＳ１３１３の処理に、値が一致すればＳ１３１５の処理に移行する。
【０１２３】
Ｓ１３１３の処理では、当該関数の呼出命令を中止する命令を出力する。また、Ｓ１３１５の処理では、関数別ジャンプ命令に分岐して処理を継続する。
【０１２４】
図１１に戻り、Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、Ｓ１１０５の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合、関数アドレスチェック命令生成挿入部１６０は関数アドレスチェック命令生成挿入処理Ｃ（Ｓ１１０７Ｃ）を行う。関数アドレスチェック命令生成挿入処理Ｃ（Ｓ１１０７Ｃ）では、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部１７０が生成した命令（関数別ジャンプ命令）に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。変換対象プログラムの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理（Ｓ３０１）が生成した命令が実行されることで取得する。（表３を参照）
【０１２５】
Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、Ｓ１１０５の処理で共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定された場合とは、例えば表５に示されるｐｒｉｎｔｆ関数の場合である。ＧＯＴスロットは相対アドレスであってオフセットである。一方、関数が含まれる共有ライブラリが位置独立コード化されておらず関数アドレスは絶対アドレスである。このことから、関数アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければＧＯＴが攻撃によって書き換えられた可能性があると判定する。
【０１２６】
図１４は、変換対象プログラムの実行時に、関数アドレスチェック命令生成処理Ｃ（Ｓ１１０７Ｃ）で生成された命令（関数アドレスチェック命令Ｃ）が実行された際の動作を示すフローチャートである。
【０１２７】
Ｓ１４０１の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部（Ｓ３０１）で生成した命令が実行されることで算出された変換対象プログラムの開始アドレスを格納した静的変数アドレスを取得する。Ｓ１４０１の処理が終了するとＳ１４０３の処理に移行する。
【０１２８】
Ｓ１４０３の処理では、レジスタＡにＳ１４０１の処理で取得したアドレスで間接参照されるアドレスを転送する。Ｓ１４０３の処理が終了するとＳ１４０５の処理に移行する。
【０１２９】
Ｓ１４０５の処理では、レジスタＢにＧＯＴスロットを転送する。Ｓ１４０５の処理が終了するとＳ１４０７の処理に移行する。
【０１３０】
Ｓ１４０７の処理では、レジスタＡの値とレジスタＢの値を加算してレジスタＢに転送する。Ｓ１４０７の処理が終了するとＳ１４０９の処理に移行する。
【０１３１】
Ｓ１４０９の処理では、レジスタＣに関数アドレスを転送する。Ｓ１４０９の処理が終了するとＳ１４１１の処理に移行する。
【０１３２】
Ｓ１４１１の処理では、レジスタＢの参照する値とレジスタＣの値を対比する。値が一致しなければＳ１４１３の処理に、値が一致すればＳ１４１５の処理に移行する。
【０１３３】
Ｓ１４１５の処理では、当該関数の呼出命令を中止する命令を出力する。また、Ｓ１４１７の処理では、関数別ジャンプ命令に分岐して処理を継続する。
【０１３４】
図１１に戻り、Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、Ｓ１１０５の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合、関数アドレスチェック命令生成挿入部１６０は関数アドレスチェック命令生成挿入処理Ｄ（Ｓ１１０７Ｄ）を行う。関数アドレスチェック命令生成挿入処理Ｄ（Ｓ１１０７Ｄ）では、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければ変換対象プログラムを終了させ、値が一致したならば関数別ジャンプ命令生成挿入部１７０が生成した命令（関数別ジャンプ命令）に分岐する命令を、生成して、変換対象プログラムに挿入する。変換対象プログラムへの挿入は、生成した命令を、アセンブラに変換された変換対象プログラムのソースコードの冒頭に記述し、ラベルを付与することで分岐元から分岐できるようにする。変換対象プログラムと共有ライブラリの開始位置を示す絶対アドレスは、変換対象プログラムの実行開始直後に、ロードアドレス算出命令生成挿入処理（Ｓ３０１）が生成した命令が実行されることで取得する。（表３を参照）
【０１３５】
Ｓ１１０１の処理で変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスと判定され、Ｓ１１０５の処理で共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスと判定された場合とは、例えば表５に示されるｍｙｃａｌｃ関数の場合である。ＧＯＴスロットは相対アドレスであってオフセットである。また、関数が含まれる共有ライブラリが位置独立コード化されており関数アドレスも相対アドレスであってオフセットである。このことから、共有ライブラリの開始位置を示す絶対アドレスと関数アドレスとを加算して得られる絶対アドレスと、変換対象プログラムの開始位置を示す絶対アドレスとＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致しなければＧＯＴが攻撃によって書き換えられた可能性があると判定する。
【０１３６】
図１５は、変換対象プログラムの実行時に、関数アドレスチェック命令生成処理Ｄ（Ｓ１１０７Ｄ）で生成された命令（関数アドレスチェック命令Ｄ）が実行された際の動作を示すフローチャートである。
【０１３７】
Ｓ１５０１の処理では、ロードアドレス格納変数に格納されているロードアドレス算出命令生成挿入部（Ｓ３０１）で生成した命令が実行されることで算出された変換対象プログラムと共有ライブラリの開始アドレスを格納した静的変数アドレスを取得する。Ｓ１５０１の処理が終了するとＳ１５０３の処理に移行する。
【０１３８】
Ｓ１５０３の処理では、レジスタＡにＳ１５０１の処理で取得したアドレスで間接参照される変換対象プログラムの開始アドレスを、レジスタＢにＳ１５０１の処理で取得したアドレスで間接参照される共有ライブラリの開始アドレスを転送する。Ｓ１５０３の処理が終了するとＳ１５０５の処理に移行する。
【０１３９】
Ｓ１５０５の処理では、レジスタＣにＧＯＴスロットを転送する。Ｓ１５０５の処理が終了するとＳ１５０７の処理に移行する。
【０１４０】
Ｓ１５０７の処理では、レジスタＡの値とレジスタＣの値を加算してレジスタＣに転送する。Ｓ１５０７の処理が終了するとＳ１５０９の処理に移行する。
【０１４１】
Ｓ１５０９の処理では、レジスタＤに関数アドレスを転送する。Ｓ１５０９の処理が終了するとＳ１５１１の処理に移行する。
【０１４２】
Ｓ１５１１の処理では、レジスタＢの値とレジスタＤの値を加算してレジスタＤに転送する。Ｓ１５１１の処理が終了するとＳ１５１３の処理に移行する。
【０１４３】
Ｓ１５１３の処理では、レジスタＣの参照する値とレジスタＤの値を対比する。値が一致しなければＳ１５１５の処理に、値が一致すればＳ１５１７の処理に移行する。
【０１４４】
Ｓ１５１５の処理では、当該関数の呼出命令を中止する命令を出力する。また、Ｓ１５１７の処理では、関数別ジャンプ命令に分岐して処理を継続する。
【０１４５】
図３に戻り、ＧＯＴ書き込み可否判定処理（Ｓ３０５）でＧＯＴ書き込み不可と判定された場合、ＧＯＴに不正な書き込みが行われたかどうかのチェックを行う必要はない。Ｓ３１７の処理で示すように変換対象プログラムのすべてのソースファイルについて関数別ジャンプ命令生成挿入処理（Ｓ３１９）を行う。関数別ジャンプ命令生成挿入処理（Ｓ３１９）はアセンブリで行うため、ソースコードは事前にアセンブリに変換（Ｓ３２１）する。
【０１４６】
関数別ジャンプ命令生成挿入部１７０が、関数別ジャンプ命令生成挿入処理（Ｓ３１９）を行う。関数別ジャンプ命令生成挿入処理（Ｓ３１９）では、関数別ジャンプ命令を、生成して、変換対象プログラムに挿入する。
【０１４７】
関数別ジャンプ命令は、ＧＯＴ書き込み可否判定処理（Ｓ３０５）でＧＯＴが書き込み可能と判定され、関数アドレスチェック命令生成挿入処理で変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスと判定（Ｓ１１０１）され、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスと判定（Ｓ１１０３）された場合には、関数アドレスチェック命令生成挿入部１６０で、ＧＯＴスロットが参照する値を格納したレジスタの値に分岐する命令、それ以外の場合には、本来のＰＬＴ経由で当該関数をコールする命令である。なお、ここでＧＯＴスロットが参照する値を格納したレジスタの値に分岐する命令は、ジャンプ命令であってもよいし、ＧＯＴスロットが参照する値を格納したレジスタの値を関数アドレスとしてコールする命令であってもよい。
【０１４８】
命令生成挿入ブロック（Ｂ２０）での処理を終えた関数について、アセンブラに変換されたソースコードの冒頭に、ＰＬＴチェック命令と関数アドレスチェック命令、及び、関数別ジャンプ命令が挿入された状態となる。
【０１４９】
命令書き換えブロック（Ｂ３０）は、コール命令書き換え処理（Ｓ３２３）を行うコール命令書き換え部１８０とリターン命令書き換え処理（Ｓ３２５）を行うリターン命令書き換え部１９０からなる。
【０１５０】
本実施形態の環境においてはコール命令によって関数が呼び出される。コール命令は関数を呼び出す際に、この関数呼び出しの次の命令をリターンアドレスとしてスタックに格納する。その後、関数の処理完了時にリターン命令によって、スタックに格納したリターンアドレスに戻る処理を行う。しかしながら、関数の処理中にスタックに格納したリターンアドレスがバッファオーバーフロー攻撃などによって書き換えられる恐れがある。そこで、本実施形態では、命令書き換えブロック（Ｂ３０）で、リターンアドレスを計算してレジスタに格納し、ＧＯＴが書き込み可能な場合には当該関数に対応するＰＬＴチェック命令に、ＧＯＴが書き込み禁止の場合には当該関数に対応する関数別ジャンプ命令に、ジャンプする命令に関数のコール命令を書き換え、ジャンプ先の関数の処理完了後にレジスタに格納してある値にジャンプし、適正なリターンアドレスに戻るようにすることでバッファオーバーフロー攻撃などから回避する。
【０１５１】
コール命令書き換え部１８０が、コール命令書き換え処理（Ｓ３２３）を行う。コール命令書き換え処理（Ｓ３２３）では、変換対象であるアセンブリプログラムを一行ずつ読み込んで「ｃａｌｌ」の文字列を発見することで関数を呼び出すためのコール命令を検出して、検出したコール命令を次に示す一連の処理を行う命令に書き換える。書き換えられた命令は、まず、レジスタをスタックに退避した後にリターンアドレスを再計算してレジスタに格納し、次に、ＧＯＴが書き込み可能な場合には当該関数に対応するＰＬＴチェック命令へ、ＧＯＴが書き込み禁止の場合には当該関数に対応する関数別ジャンプ命令へ分岐し、関数の処理完了後に前記レジスタにスタックから復帰させる処理を行う。これにより、変換対象プログラムが共有ライブラリの関数を呼び出した際に命令生成ブロック（Ｂ２０）で生成したチェック命令が動作する。また、チェック命令によりアドレスが適性であると判定された場合は前記レジスタに格納されたリターンアドレスに復帰する。
【０１５２】
リターン命令書き換え部１９０が、リターン命令書き換え処理（Ｓ３２５）を行う。リターン命令書き換え処理（Ｓ３２５）では、まず、変換対象であるアセンブリプログラムを一行ずつ読み込んで「ｒｅｔ」の文字列を発見することでリターン命令を検出する。検出したリターン命令をコール命令書き換え部１８０でレジスタに格納しているアドレスに分岐する命令に書き換える。リターン命令書き換え処理（Ｓ３２５）により、リターンアドレスを書き換える攻撃を回避する。
【０１５３】
命令生成ブロック（Ｂ２０）及び命令書き換えブロック（Ｂ３０）の処理が変換対象プログラムにロジックを追加することによる取得するアドレスの変更に対応するため、変換装置１０は変換対象プログラムのリコンパイルを行い、アドレス更新のために再度、命令生成ブロック（Ｂ２０）及び命令書き換えブロック（Ｂ３０）の処理を行う。
【０１５４】
次に、コンピュータシステムを変換装置１０として機能させるための変換プログラムについて説明する。コンピュータシステムの構成は、図２に示す通りである。
【０１５５】
変換プログラムは、メインモジュール、入力モジュール、出力モジュール及び演算処理モジュールを備える。メインモジュールは変換処理を統括的に制御する部分である。入力モジュールは変換対象のプログラムの入力を、出力モジュールは変換後のプログラムの出力をするようにコンピュータシステムを動作させる。演算処理モジュールは、ロードアドレス算出命令生成挿入モジュール、ＧＯＴスロット取得モジュール、ＧＯＴ書き込み可否判定モジュール、ＰＬＴ解決アドレス取得モジュール、関数アドレス取得モジュール、ＰＬＴチェック命令生成挿入モジュール、関数アドレスチェック命令生成挿入モジュール、関数別ジャンプ命令生成挿入モジュール、コール命令書き換えモジュール及びリターン命令書き換えモジュールを備える。メインモジュール、入力モジュール、出力モジュール及び演算処理モジュールを実行させることにより実現される機能は、変換装置１０のロードアドレス算出命令生成挿入部１００、ＧＯＴスロット取得部１１０、ＧＯＴ書き込み可否判定部１２０、ＰＬＴ解決アドレス取得部１３０、関数アドレス取得部１４０、ＰＬＴチェック命令生成挿入部１５０、関数アドレスチェック命令生成挿入部１６０、関数別ジャンプ命令生成挿入部１７０、コール命令書き換え部１８０及びリターン命令書き換え部１９０の機能とそれぞれ同様である。
【０１５６】
（第２実施形態）
本実施形態に係る変換装置は、攻撃を検知して停止するようにプログラムを変換する変換装置である。第１実施形態が、ロードアドレス算出命令生成挿入部１００は変換対象プログラム及び共有ライブラリの開始アドレスを静的変数に格納することで保持するプログラムを生成するのに対して、本実施形態は、ロードアドレス算出命令生成挿入部１００は、変換対象プログラム及び共有ライブラリの開始アドレスを低い順に１つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成して、変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する点が相違する。読み取り専用でメモリに書き込むため、第１実施形態よりもセキュアなプログラムへの変換が実現できる。
【０１５７】
本実施形態に係る変換装置の構成を示すブロック図及びハードウェア構成は、図１に示すブロック図及び図２に示すハードウェア構成と同様である。第１実施形態と大きく相違するのはロードアドレス算出命令生成挿入部１００の動作であるので、この点を中心に説明する。
【０１５８】
本実施形態に係る変換装置のロードアドレス算出命令生成挿入部１００は、変換対象プログラム及び変換対象プログラムにリンクされるプログラムが実施された直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされるプログラムの開始アドレスを算出し、アドレスの低い順に１つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成する機能を有している。また、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する機能を有している。
【０１５９】
本実施形態に係る変換装置１０が、図３に示す動作を開始すると、ロードアドレス算出命令生成挿入部１００が、ロードアドレス算出命令生成挿入処理（Ｓ３０１）を行う。ロードアドレス算出命令生成挿入処理（Ｓ３０１）では、変換対象プログラム及び変換対象プログラムにリンクされるプログラムが実施された直後に、変換対象プログラムの開始アドレス及び変換対象プログラムにリンクされるプログラムの開始アドレスを算出し、アドレスの低い順に１つの文字列に連結してファイルに出力し、このファイルに記載された文字列を読み込み可能、書き込み不可としてプロセス空間に新たなメモリ領域として保存し、このメモリ領域の開始アドレスを静的変数に格納するプログラムを生成する処理を行う。次に、生成したプログラムを変換対象プログラムから呼び出すことができるように変換対象プログラムに挿入する処理を行う。
【０１６０】
ロードアドレス算出命令生成挿入部１００が生成するプログラムの詳細と変換済みのプログラム実行時の動作について説明する。図１６は、ロードアドレス算出命令生成挿入部１００が生成するプログラムの詳細と変換済みのプログラム実行時の動作を示すフローチャートである。
【０１６１】
変換済みのプログラムの実行ファイルからロードアドレス算出命令生成挿入部１００が生成するプログラムが呼び出されると現在のプロセスＩＤを取得する処理（Ｓ１６０１）が実行される。ｇｅｔｐｉｄ命令でプロセスＩＤを取得する。Ｓ１６０１の処理が終了するとＳ１６０３の処理に移行する。
【０１６２】
Ｓ１６０３の処理では、取得したプロセスＩＤのメモリマップを取得する。メモリマップは／ｐｒｏｃディレクトリ配下にプロセスＩＤごとに存在する。Ｓ１６０３の処理が終了するとＳ１６０５の処理に移行する。
【０１６３】
Ｓ１６０５の処理では、取得したメモリマップからロードされているオブジェクトファイルの開始アドレスの数を取得する。例えば、図４に示すメモリマップの場合４つとなる。Ｓ１６０５の処理が終了すると１５０７の処理に移行する。
【０１６４】
Ｓ１６０７の処理では、ロードされているオブジェクトファイルの開始アドレスを書き込むのに必要なページサイズを計算する。まず、必要メモリ量を求める。ＯＳが６４ビットの場合は、（ロードされているオブジェクトファイルの開始アドレスの数）に１６を乗じることで求められる。ＯＳが３２ビットの場合は、（ロードされているオブジェクトファイルの開始アドレスの数）に８を乗じることで求められる。次に、ページサイズを取得する。システムでのメモリ管理におけるページサイズは、ｇｅｔｐａｇｅｓｉｚｅ命令で取得できる。通常、４０９６（４ｋＢ）である。必要ページサイズは、（必要メモリ量）／（ページサイズ）で余りを繰り上げることで求められる。Ｓ１６０７の処理が終了するとＳ１６０９の処理に移行する。
【０１６５】
Ｓ１６０９は、ｒ−ｘｐ行の開始アドレスを連結した文字列を生成する。後の処理で開始アドレスが復元できるように各開始アドレスのバイト数を統一する。例えば、バイト数については、０を埋めることで１６バイトにアドレスを修正する。また、バイト順（エンディアン）はプロセッサやプラットフォームによって異なるため環境にあわせて文字列を生成するようにする。エンディアンの種別についてはＥＬＦヘッダに情報が記載されている。Ｓ１６１７の処理が終了するとＳ１６１１の処理に移行する。
【０１６６】
Ｓ１６１１の処理では、メモリの書き込み開始アドレスから開始アドレスを結合した文字列をｍｍａｐ関数を使用して読み取り専用で書き込む。
【０１６７】
Ｓ１６１３の処理では、静的変数をひとつ定義して、その静的変数にＳ１６１１の処理で読み取り専用で文字列を書き込んだメモリ領域の先頭のアドレスを格納する。
【０１６８】
図１７は、図４に示すメモリマップの場合で例示した図である。各オブジェクトの開始アドレスを１６バイトに編集した後にリトルエンディアンで結合した文字列を示している。この文字列を読み取り専用で書き込んだメモリ領域の先頭アドレスが７ｆ０７８５２ｅ１０００であり、このアドレスが、ひとつの静的変数（開始アドレス格納変数）ｓｔａｒｔ＿ｌｏａｄ＿ａｄｄｒに格納されている。
【０１６９】
第１実施形態では、図１０に示すＳ１００１の処理、図１３に示すＳ１３０１の処理、図１４に示すＳ１４０１の処理及び図１５に示すＳ１５０１の処理で各オブジェクトの開始アドレスを取得するためには各々のオブジェクトごとに定義された開始アドレス格納変数を参照したが、本実施形態では、ひとつの静的変数（開始アドレス格納変数）を参照する点が相違する。開始アドレス格納変数で指示されるメモリ領域に読み込み専用で書き込まれた文字列の先頭から１６バイトごとに各々のオブジェクトの開始アドレスが記述されているので、目的の位置から文字列を読み込むことで目的とするオブジェクトの開始アドレスを取得することができる。
【０１７０】
第１実施形態では、開始アドレス格納変数がオブジェクトの数だけ定義されるのに対して、本実施形態で定義する静的変数はひとつであることから、よりセキュアなプログラムへの変換を実現できる。また、静的変数によって指示されるメモリ領域に書き込まれた開始アドレスを連結した文字列は読み取り専用であるために書き換えられることがないことから、第１実施形態と比べて本実施形態は、よりセキュアなプログラムへの変換を実現できる。
【０１７１】
変換対象のプログラムが起動時に、静的変数に格納された開始アドレスを連結した文字列を書き込んだメモリ領域の開始アドレスをレジスタに格納するように、更にプログラムを変換するようにしてもよい。これにより変換対象のプログラムが起動後に当該静的変数の値が攻撃によって書き換えられた場合などにもリスクを回避することができ、よりセキュアなプログラムへの変換を実現できる。
【符号の説明】
【０１７２】
１０      変換装置
１００    ロードアドレス算出命令生成挿入部
１１０    ＧＯＴスロット取得部
１２０    ＧＯＴ書き込み可否判定部
１３０    ＰＬＴ解決アドレス取得部生成部
１４０    関数アドレス取得部
１５０    ＰＬＴチェック命令生成挿入部
１６０    関数アドレスチェック命令生成挿入部
１７０    関数別ジャンプ命令生成挿入部
１８０    コール命令書き換え部
１９０    リターン命令書き換え部
Ｂ１０    情報取得ブロック
Ｂ２０    命令生成挿入ブロック
Ｂ３０    命令書き換えブロック
２０      ハードウェア構成
２１０    中央演算装置（ＣＰＵ）
２２０    入力装置
２３０    出力装置
２４０    主記憶装置（ＲＡＭ／ＲＯＭ）
２５０    補助記憶装置
２６０    複数のレジスタ
【図１】
2019121203.tif 000008
【図２】
2019121203.tif 000009
【図３】
2019121203.tif 000010
【図４】
2019121203.tif 000011
【図５】
2019121203.tif 000012
【図６】
2019121203.tif 000013
【図７】
2019121203.tif 000014
【図８】
2019121203.tif 000015
【図９】
2019121203.tif 000016
【図１０】
2019121203.tif 000017
【図１１】
2019121203.tif 000018
【図１２】
2019121203.tif 000019
【図１３】
2019121203.tif 000020
【図１４】
2019121203.tif 000021
【図１５】
2019121203.tif 000022
【図１６】
2019121203.tif 000023
【図１７】
2019121203.tif 000024
【手続補正書】
【提出日】平成30年3月27日(2018.3.27)
【手続補正１】
【補正対象書類名】特許請求の範囲
【補正対象項目名】請求項４
【補正方法】変更
【補正の内容】
【請求項４】
攻撃を検知して停止するようにプログラムを変換するプログラム変換方法であって、コンピュータが、
変換対象プログラムの実行開始直後に、前記変換対象プログラムの開始アドレス及び前記変換対象プログラムにリンクされる共有ライブラリの開始アドレスを算出し、静的変数に格納するプログラムを生成して、前記変換対象プログラムから、このプログラムを呼び出すことができるように前記変換対象プログラムに挿入する、ロードアドレス算出命令生成挿入処理ステップと、
前記ＧＯＴスロットを、前記変換対象プログラムに問い合わせ、取得して、保持するＧＯＴスロット取得処理ステップと、
前記変換対象プログラムに存在するグローバルオフセットテーブルが書き込み可能かどうかを判定するＧＯＴ書き込み可否判定処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記ＰＬＴ解決アドレスを、前記変換対象プログラムに問い合わせ、取得して、保持するＰＬＴ解決アドレス取得処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記関数アドレスを、前記共有ライブラリに問い合わせ、取得して、保持する関数アドレス取得処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記ＰＬＴ解決アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＰＬＴ解決アドレスとを加算して得られる絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入手段で生成した命令に引き渡す命令を、値が一致していなければ関数アドレスチェック命令生成挿入部に引き渡す命令を、生成して、前記変換対象プログラムに挿入する、ＰＬＴチェック命令生成挿入処理ステップと、
グローバルオフセットテーブルが書き込み可能な場合に、前記変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記ＧＯＴスロットが参照する値とを対比して、前記変換対象プログラムのヘッダのエントリポイントに記述された値が相対アドレスである場合であって、前記共有ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、前記関数アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、前記共有ライブラリのヘッダのエントリポイントに記述された値が相対アドレスである場合には、前記共有ライブラリの開始位置を示す絶対アドレスと前記関数アドレスとを加算して得られる前記関数の開始位置を示す絶対アドレスと、前記変換対象プログラムの開始位置を示す絶対アドレスと前記ＧＯＴスロットとを加算した結果であるアドレスが参照する値とを対比して、値が一致していれば関数別ジャンプ命令生成挿入手段で生成した命令に引き渡す命令を、値が一致しなければ前記変換対象プログラムを終了させる命令を、生成して、前記変換対象プログラムに挿入する、関数アドレスチェック命令生成挿入処理ステップと、
グローバルオフセットテーブルが書き込み可能であり、変換対象プログラムのヘッダのエントリポイントに記述された値が絶対アドレスであり、共用ライブラリのヘッダのエントリポイントに記述された値が絶対アドレスである場合には、ＧＯＴスロットが参照する値に分岐する分岐命令を、それ以外の場合には、プロシージャリンケージテーブル経由で関数をコールする命令を、生成して、前記変換対象プログラムに挿入する、関数別ジャンプ命令生成挿入処理ステップと、
前記変換対象プログラムから前記共有ライブラリ内の関数を呼び出す命令を検出し、検出した前記関数を呼び出す命令を、リターンアドレスを計算して保持した後に、グローバルオフセットテーブルが書き込み可能な場合にはＰＬＴチェック命令生成挿入手段が挿入した命令に、グローバルオフセットテーブルが書き込み禁止の場合には関数別ジャンプ命令生成挿入処理ステップが挿入した命令に分岐させる命令に書き換えるコール命令書き換え処理ステップと、
前記変換対象プログラムからリターン命令を検出し、検出した前記リターン命令を前記計算して保持しているアドレスに分岐する命令に書き換えるリターン命令書き換え処理ステップと、
を実行するプログラム変換方法