(57)【要約】  リターン指向プログラミングのエクスプロイトを防ぐように調整された中間コードファイルを生成するための方法およびシステムであって、複数のルーチンを備えるコンパイル済み中間コードファイルを受信することと、プロセッサで実行可能な実行ファイルを生成する前にそれらを調整することとを備える。調整は、中間コードファイルのシンボルテーブルを分析してそれぞれのルーチンの先頭アドレスを特定することと、それぞれのルーチンを分析してルーチン内の間接分岐命令を特定することと、検出された各間接分岐命令を、それぞれの間接分岐命令がルーチンの先頭アドレスを指していることを検証するように構成された検証コードセグメントの呼び出しで置き換えることを備える。実行時に、検証コードセグメントは、間接分岐命令が複数のルーチンの１つの先頭アドレスを指していない場合に、プロセッサに１つ以上の事前定義された動作を開始させる。
2022502723.tif 000002
【特許請求の範囲】
【請求項１】
コンピュータに実装された方法で、リターンアドレス保護を適用するように調整されたコンパイル済み中間コードファイルを生成する、コンピュータ実装される方法であって、
コンパイラによって生成された少なくとも１つの中間コードファイルであって、複数のルーチンを備える少なくとも１つの中間コードファイルを受信することと、
少なくとも１つのプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、前記少なくとも１つの中間コードファイルを調整することであって、前記調整は、
前記少なくとも１つの中間コードファイルのシンボルテーブルを分析して、前記複数のルーチンのそれぞれを特定することと、
前記複数のルーチンの少なくとも１つのルーチンを調整して、前記少なくとも１つのルーチンで検出された、リターンアドレスのスタックへのプッシュ命令をそれぞれのプロローグコードセグメントに置き換えるとともに、前記少なくとも１つのルーチンで検出されたそれぞれのリターンアドレスの前記スタックからのポップ命令をそれぞれのエピローグコードセグメントに置き換えることであって、それぞれの前記プロローグコードセグメントは、前記リターンアドレスが前記スタックにプッシュされた後に前記スタックを変更するように構成され、それぞれの前記エピローグコードセグメントは、前記スタックから取得されたリターンアドレスに分岐する前に、それぞれの前記プロローグコードセグメントによってなされた前記スタックの変更を検証するように構成されている、置き換えることと、
を備える、調整することと、
調整された少なくとも１つの前記中間コードファイルを出力することと、
を備え、
実行時に前記スタックの変更が検証できない場合に、それぞれの前記エピローグコードセグメントは、少なくとも１つのプロセッサに少なくとも１つの事前定義された動作を開始させる、方法。
【請求項２】
少なくとも１つの中間コードファイルは、オブジェクトファイル、アーカイブファイル、およびバイナリファイルを備えるグループの１つである、請求項１に記載の方法。
【請求項３】
前記複数のルーチンのそれぞれは、ルーチン、サブルーチン、および関数を備えるグループの１つである、請求項１に記載の方法。
【請求項４】
アドレスの前記スタックへのプッシュ命令が、前記スタックへの少なくとも１つのデータ項目のプッシュに関連付けられている場合、それぞれの前記プロローグコードセグメントは、前記少なくとも１つのデータ項目を前記スタックにプッシュするように構成され、それぞれの前記エピローグコードセグメントは、前記スタックから前記少なくとも１つのデータ項目をポップするように構成されている、請求項１に記載の方法。
【請求項５】
前記スタックの変更は、可逆的な方法で前記リターンアドレスを変更することに基づき、
前記スタックにプッシュされた前記リターンアドレスを読み取り、可逆的な方法で前記リターンアドレスを変更し、変更された前記リターンアドレスを前記スタックにプッシュして戻すように、それぞれの前記プロローグコードセグメントを構成することと、
スタックアドレスから変更されたリターンアドレスを読み取り、それぞれの前記プロローグコードセグメントが行った操作を逆にして、変更された前記リターンアドレスから前記リターンアドレスを復元し、復元した前記リターンアドレスを前記スタックにプッシュして戻すように、それぞれの前記エピローグコードセグメントを構成することと、
を備える、請求項１に記載の方法。
【請求項６】
前記リターンアドレスの変更は、それぞれの前記プロローグコードセグメントが前記リターンアドレスをランダムに選択された値でＸＯＲするように構成されるとともに、それぞれの前記エピローグコードセグメントが変更された前記リターンアドレスを同一の前記ランダムに選択された値でＸＯＲするように構成されるように、前記リターンアドレスの前記ランダムに選択された値によるＸＯＲ操作に基づく、請求項５に記載の方法。
【請求項７】
前記スタックの変更は、
前記スタック内の、プッシュされた前記リターンアドレスの位置に隣接する位置に定数値マーカを挿入するようにそれぞれの前記プロローグコードセグメントを構成することと、
前記定数値マーカを検証し、前記定数値マーカを前記スタックから削除するように、それぞれの前記エピローグコードセグメントを構成することと、
により、前記スタック内の前記隣接する位置にマーカをプッシュすることに基づいて行われる、請求項１の方法。
【請求項８】
前記定数値マーカは、前記少なくとも１つのプロセッサのすべての起動イベントの間にランダムに選択される、請求項７に記載の方法。
【請求項９】
前記少なくとも１つの事前定義された動作は、前記少なくとも１つのプロセッサの実行をクラッシュさせることと、前記少なくとも１つのプロセッサの実行を停止することと、前記少なくとも１つのプロセッサに事前定義されたアドレスに分岐させることと、前記少なくとも１つのプロセッサに少なくとも１つの潜在的に悪意のあるコード命令を実行することを阻止させることと、無効なスタック変更の指示を生成することと、を備えるグループの１つである、請求項１に記載の方法。
【請求項１０】
それぞれの前記プロローグコードセグメントおよびそれぞれの前記エピローグコードセグメントは、アドレスの前記スタックへのプッシュ命令およびアドレスの前記スタックからのポップ命令のそれぞれを、前記アドレスのプッシュ操作およびポップ操作の間に追加された前記コードセグメントを呼び出すように構成されたトランポリン分岐関数に置き換えることによって、前記少なくとも１つのルーチンに追加されることを特徴とする、請求項１に記載の方法。
【請求項１１】
前記少なくとも１つの中間コードファイルは、追加された前記コードセグメントの追加によって影響を受けた命令およびデータエレメントの少なくとも１つを修正するように調整される、請求項１に記載の方法。
【請求項１２】
前記少なくとも１つの中間コードファイルは、追加されたコードセグメントおよび調整された前記ルーチンのサイズの増加を反映するように、その前記シンボルテーブルを更新するように修正される、請求項１１に記載の方法。
【請求項１３】
リターンアドレス保護を適用するように調整されたコンパイル済み中間コードファイルを生成するためのシステムであって、
コードを格納するプログラムストアと、
前記プログラムストアに結合され、格納された前記コードを実行する少なくとも１つのプロセッサであって、前記コードは、
コンパイラによって生成された、複数のルーチンを備える少なくとも１つの中間コードファイルを受信するためのコード命令と、
前記少なくとも１つのプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、少なくとも１つの中間コードファイルを調整するためのコード命令であって、前記調整は、
前記少なくとも１つの中間コードファイルのシンボルテーブルを分析して、前記複数のルーチンのそれぞれを特定することと、
少なくとも１つの前記ルーチンで検出された、アドレスのスタックへのプッシュ命令をそれぞれのプロローグコードセグメントに置き換えるとともに、少なくとも１つの前記ルーチンで検出されたそれぞれのアドレスのスタックからのポップ命令をそれぞれのエピローグコードセグメントに置き換えるように、前記複数のルーチンの少なくとも１つを調整することであって、それぞれの前記プロローグコードセグメントは、リターンアドレスが前記スタックにプッシュされた後にスタックを変更するように構成され、それぞれの前記エピローグコードセグメントは、前記スタックから取得された前記リターンアドレスに分岐する前に、それぞれの前記プロローグコードセグメントによってなされたスタック変更を検証するように構成されている、調整することと、
を備える、コード命令と、
調整された前記少なくとも１つの中間コードファイルを出力するためのコード命令と。
を備え、実行時に、前記スタックの変更が検証できない場合、それぞれの前記エピローグコードセグメントは、前記少なくとも１つのプロセッサに少なくとも１つの事前定義された動作を開始させる、システム。
【請求項１４】
リターンアドレス保護を適用するように調整された少なくとも１つの中間コードファイルから生成されたコンピュータプログラムの実行可能ファイルであって、
非一過性のコンピュータ可読な記憶媒体と、
前記少なくとも１つの中間コードファイルから少なくとも１つのプロセッサによる実行のために生成され、リターンアドレス保護をサポートするように調整された、実行可能ファイルの少なくとも１つの調整されたルーチンの複数のプログラム命令であって、前記少なくとも１つの調整されたルーチンにおいて、アドレスのスタックへのプッシュ命令がそれぞれのプロローグコードセグメントに置き換えられ、それぞれのアドレスのスタックからのポップ命令がそれぞれのエピローグコードセグメントに置き換えられ、それぞれの前記プロローグコードセグメントは、リターンアドレスが前記スタックにプッシュされた後に前記スタックを変更するように構成され、それぞれの前記エピローグコードセグメントは、前記スタックから取得された前記リターンアドレスに分岐する前に、それぞれの前記プロローグコードセグメントによってなされたスタック変更を検証するように構成され、前記スタック変更が検証できない場合、それぞれの前記エピローグコードセグメントは、前記少なくとも１つのプロセッサに、少なくとも１つの所定の動作を開始させる、複数のプログラム命令と、
を備え、前記非一過性のコンピュータ可読な記憶媒体からの前記複数のプログラム命令が、前記少なくとも１つのプロセッサによって実行される、コンピュータプログラムの実行可能ファイル。
【請求項１５】
リターン指向プログラミングのエクスプロイトを防ぐように調整されたコンパイル済み中間コードファイルを生成するためのコンピュータ実装される方法であって、
コンパイラによって生成された少なくとも１つの中間コードファイルであって、複数のルーチンを備える少なくとも１つの中間コードファイルを受信することと、
少なくとも１つのプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、前記少なくとも１つの中間コードファイルを調整することであって、
前記少なくとも１つの中間コードファイルのシンボルテーブルを分析して、前記複数のルーチンのそれぞれの先頭アドレスを特定することと、
前記複数のルーチンのそれぞれを分析して、前記複数のルーチンの少なくとも１つの中の少なくとも１つの間接分岐命令を特定することと、
前記複数のルーチンの少なくとも１つで検出された前記間接分岐命令のそれぞれが前記複数のルーチンの１つの前記先頭アドレスを指していることを間接分岐動作のそれぞれを実行する前に検証するように構成されたそれぞれの検証コードセグメントの呼び出しで、それぞれの前記間接分岐命令を置き換えることと、
を備える、調整することと、
調整された前記少なくとも１つの中間コードファイルを出力することと、
を備え、実行時に、前記間接分岐命令が前記複数のルーチンの１つの前記先頭アドレスを指していない場合、前記それぞれの検証コードセグメントは、前記少なくとも１つのプロセッサに少なくとも１つの所定の動作を開始させる、
方法。
【請求項１６】
少なくとも１つの前記ルーチンを調整することは、前記間接分岐命令を、それぞれの検証コードセグメントを指す直接分岐命令に置き換えることを備える、請求項１５の方法。
【請求項１７】
少なくとも１つの前記ルーチンを調整することは、前記間接分岐命令によって指されるアドレスをスタックにプッシュするための直接分岐命令の前に前記スタックへのプッシュ命令を挿入することをさらに含み、前記スタックからポップされた後にプッシュされた前記アドレスは、前記検証コードセグメントによって検証のために使用される、請求項１６に記載の方法。
【請求項１８】
少なくとも１つの前記ルーチンを調整することは、前記間接分岐命令によって指されるアドレスを事前に決定されたレジスタに書き込むための書き込み命令を前記直接分岐命令の前に挿入することをさらに備え、書き込まれた前記アドレスは、前記事前に決定されたレジスタから取得された後に検証コードセグメントによって検証のために使用される、請求項１６の方法。
【請求項１９】
少なくとも１つの前記ルーチンを調整することは、前記間接分岐命令によって指されるアドレスを事前定義された変数に書き込むための書き込み命令を前記直接分岐命令の前に挿入することをさらに備え、書き込まれた前記アドレスは、前記事前定義された変数から取得された後に前記検証コードセグメントによって検証のために使用される、請求項１６に記載の方法。
【請求項２０】
前記複数のルーチンの１つの前記先頭アドレスを指す前記間接分岐命令の検証は、前記少なくとも１つの中間コードファイル内の前記複数のルーチンのそれぞれに先行する一意的なコードの検証に基づき、前記一意的なコードの検証は、
前記複数のルーチンのそれぞれの前記先頭アドレスに先行するアドレスの前記少なくとも１つの中間コードファイルに前記一意的なコードを追加することと、
間接分岐関数が指すアドレスの前に前記一意的なコードがあることを検証するように、それぞれの前記検証コードセグメントを構成することと、
によって適用される、請求項１５に記載の方法。
【請求項２１】
前記複数のルーチンの１つの先頭アドレスを指す前記間接分岐命令の検証は、前記複数のルーチンのそれぞれの先頭アドレスをマッピングしたデータセットに基づいて行われ、前記データセットのマッピングの検証は、
複数のルーチンのそれぞれの前記先頭アドレスをマッピングするための前記データセットを構築することと、
間接分岐関数によって指されるアドレスが、前記データセットにマッピングされた前記複数のルーチンの１つの前記先頭アドレスと一致することを検証するように、それぞれの前記検証コードセグメントを構成することと、
によって適用される、請求項１５に記載の方法。
【請求項２２】
前記少なくとも１つの所定の動作は、前記少なくとも１つのプロセッサの実行をクラッシュさせることと、前記少なくとも１つのプロセッサの実行を停止することと、前記少なくとも１つの中間コードファイル内の事前定義されたアドレスに前記少なくとも１つのプロセッサを分岐させることと、前記少なくとも１つのプロセッサが前記少なくとも１つの潜在的に悪意のあるコード命令を実行することを防止することと、前記少なくとも１つの間接分岐命令が前記複数のルーチンの１つの前記先頭アドレスを指していないことの指示を生成することと、を備えるグループの１つである、請求項１５に記載の方法。
【請求項２３】
前記少なくとも１つの中間コードファイルは、前記少なくとも１つの間接分岐をそれぞれの検証コードセグメントの呼び出しで置き換えることによって影響を受ける命令およびデータ要素の少なくとも１つを修正するように調整される、請求項１５に記載の方法。
【請求項２４】
前記少なくとも１つの中間コードファイルは、前記少なくとも１つの間接分岐の前記それぞれの検証コードセグメントの呼び出しでの置き換えを反映するように、そのシンボルテーブルを更新するように修正される、請求項１５に記載の方法。
【請求項２５】
リターン指向プログラミングのエクスプロイトを防ぐように調整されたコンパイル済み中間コードファイルを生成するためのシステムであって、
コードを格納するプログラムストアと、
プログラムストアに結合され、格納された前記コードを実行する少なくとも１つのプロセッサであって、前記コードは、
コンパイラによって生成された少なくとも１つの中間コードファイルであって、複数のルーチンを備える少なくとも１つの中間コードファイルを受信するコード命令と、
少なくとも１つのプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、前記少なくとも１つの中間コードファイルを調整するコード命令であって、前記調整は、
前記少なくとも１つの中間コードファイルのシンボルテーブルを分析して、前記複数のルーチンのそれぞれの先頭アドレスを特定することと、
前記複数のルーチンのそれぞれを分析して、前記複数のルーチンの少なくとも１つの中の少なくとも１つの間接分岐命令を特定することと、
前記複数のルーチンの少なくとも１つで検出されたそれぞれの間接分岐命令が前記複数のルーチンの１つの前記先頭アドレスを指していることをそれぞれの間接分岐動作を実行する前に検証するように構成されたそれぞれの検証コードセグメントの呼び出しで、それぞれの前記間接分岐命令を置き換えることと、
を備える、調整するコード命令と、
調整された前記少なくとも１つの中間コードファイルを出力するコード命令と、
を備え、実行時に、前記間接分岐命令が前記複数のルーチンの１つの前記先頭アドレスを指していない場合、前記それぞれの検証コードセグメントは、前記少なくとも１つのプロセッサに少なくとも１つの所定の動作を開始させる、
システム。
【請求項２６】
リターン指向プログラミングのエクスプロイトを防ぐように調整された、少なくとも１つの中間コードファイルから生成されたコンピュータプログラムの実行可能ファイルであって、
非一過性のコンピュータ可読な記憶媒体と、
リターンアドレス保護をサポートするように調整された、少なくとも１つの中間コードファイルから少なくとも１つのプロセッサによる実行のために生成された実行可能ファイルの複数のルーチンの少なくとも１つの調整されたルーチンの複数のプログラム命令であって、前記少なくとも１つの調整されたルーチンにおいて、それぞれの間接分岐命令は、前記それぞれの間接分岐命令が前記複数のルーチンの１つの先頭アドレスを指していることを検証するように構成されたそれぞれの検証コードセグメントの呼び出しに置き換えられ、前記間接分岐命令が前記複数のルーチンの１つの前記先頭アドレスを指していない場合、前記それぞれの検証コードセグメントは、前記少なくとも１つのプロセッサに少なくとも１つの事前定義された動作を開始させる、複数のプログラム命令と、
を備え、前記非一過性のコンピュータ可読な記憶媒体からの前記複数のプログラム命令は、前記少なくとも１つのプロセッサによって実行される、コンピュータプログラムの実行可能ファイル。
【発明の詳細な説明】
【技術分野】
【０００１】
［関連出願］
本出願は、２０１８年１０月１８日に出願された米国仮特許出願第６２／７４７，１５０号からの優先権の利益を主張し、その内容は参照によりその全体が本明細書に組み込まれる。
【背景技術】
【０００２】
本発明は、そのいくつかの実施形態において、スタック破損のエクスプロイトに対する保護を適用すること、より具体的には、スタック破損のエクスプロイトに対する保護を適用するために中間コードファイルを調整することに関するものであるが、これに限定されない。
【０００３】
コンピュータ化された現代環境が常に進化し続ける中で、サイバーの脅威は大きな関心事となっている。悪意のある者は、無害なハッキングから金銭的な利益を得るためのエクスプロイト、重要なシステムへの悪意のある干渉まで、様々な目標や目的のために、複数のプラットフォーム、アプリケーション、サービスに対してサイバー攻撃を仕掛けて、それらを支配しようとすることがある。
【０００４】
これらの懸念は、多数の分野、分野、市場、例えば、自律走行車、スマートシティ、農業、医療、医療処置などの自動化をサポートするために使用される小型のローエンドの組み込み機器の膨大な数の機器が急速に展開されることにより、劇的に強まる可能性がある。このようなローエンドの組み込み機器は、通常、限られたリソースしか持っておらず、このようなサイバー脅威に対抗するための高度な緩和手段を適用するには不十分であるかもしれない。
【０００５】
しかし、これらの限られたリソースの組み込み機器は、重要なアプリケーション、サービス、および／またはそれらに類するものに関与している可能性があり、また、オプションとして、より高水準のプラットフォームやシステムへのアクセスポイントとして機能している可能性がある。したがって、組み込み機器は、悪意のある者によってエクスプロイトされる可能性のある重大なセキュリティ侵害をもたらす可能性がある。
【発明の概要】
【課題を解決するための手段】
【０００６】
本発明の第１の態様によれば、リターンアドレス保護を適用するように調整されたコンパイル済み中間コードファイルを生成するコンピュータ実装される方法であって、
−  コンパイラによって生成された１つ以上の中間コードファイルであって、複数のルーチンで構成される中間コードファイルを受信することと、
−  １つ以上のプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、１つ以上の中間コードファイルを調整することであって、
＊  １つ以上の中間コードファイルのシンボルテーブルを分析して、複数のルーチンのそれぞれを特定することと、
＊  複数のルーチンの１つ以上を調整して、それぞれのルーチンで検出されたリターンアドレスのスタックへのプッシュ命令をそれぞれのプロローグコードセグメントに置き換え、それぞれのルーチンで検出された各リターンアドレスのスタックからのポップ命令をそれぞれのエピローグコードセグメントに置き換えることであって、それぞれのプロローグコードセグメントは、リターンアドレスがスタックにプッシュされた後にスタックを変更するように構成され、それぞれのエピローグコードセグメントは、スタックから取得されたリターンアドレスに分岐する前に、それぞれのプロローグコードセグメントによってなされたスタック変更を検証するように構成されている、置き換えることと、
を備える、調整することと、
−  １つ以上の調整された中間コードファイルを出力することと、
を備え、実行時にスタックの変更が検証できない場合、それぞれのエピローグコードセグメントは、１つ以上のプロセッサの１つ以上の事前定義された動作を開始するようにする、方法が提供される。
【０００７】
本発明の第２の態様によれば、リターンアドレス保護を適用するように調整されたコンパイル済み中間コードファイルを生成するシステムであって、コードを格納するプログラムストアと、格納されたコードを実行するためにプログラムストアに結合された１つ以上のプロセッサを備え、コードは、
−  コンパイラによって生成された１つ以上の中間コードファイルを受信するためのコード命令であって、中間コードファイルは複数のルーチンを備える、コード命令と、
−  １つ以上のプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、１つ以上の中間コードファイルを調整するためのコード命令であって、調整は、
＊  １つ以上の中間コードファイルのシンボルテーブルを分析して、複数のルーチンのそれぞれを特定することと、
＊  複数のルーチンの１つ以上を調整して、それぞれのルーチンで検出されたリターンアドレスのスタックへのプッシュ命令をそれぞれのプロローグコードセグメントに置き換え、それぞれのルーチンで検出されたそれぞれのリターンアドレスのスタックからのポップ命令をそれぞれのエピローグコードセグメントに置き換えることであって、それぞれのプロローグコードセグメントは、リターンアドレスがスタックにプッシュされた後にスタックを変更するように構成され、それぞれのエピローグコードセグメントは、スタックから取得されたリターンアドレスに分岐する前に、それぞれのプロローグコードセグメントによってなされたスタック変更を検証するように構成されている、置き換えることと、
を備える、コード命令と、
−  １つ以上の調整された中間コードファイルを出力するためのコード命令と、
を備え、実行時に、スタックの変更が検証できない場合には、それぞれのエピローグコードセグメントは、１つ以上のプロセッサに１つ以上の事前定義された動作を開始させる、システムが提供される。
【０００８】
本発明の第３の態様によれば、リターンアドレス保護を適用するように調整された中間コードファイルから生成されたコンピュータプログラムの実行可能ファイルであって、非一過性のコンピュータ可読な記憶媒体と、リターンアドレス保護をサポートするように調整された１つ以上の中間コードファイルから１つ以上のプロセッサによって実行されるように生成された実行可能ファイルの１つ以上の調整されたルーチンの複数のプログラム命令と、を備える、実行可能ファイルが提供される。調整されたルーチンのそれぞれにおいて、スタックへのアドレスプッシュ命令はそれぞれのプロローグコードセグメントに置き換えられ、スタックからのアドレスポップ命令はそれぞれのエピローグコードセグメントに置き換えられる。それぞれのプロローグコードセグメントは、リターンアドレスがスタックにプッシュされた後にスタックを変更するように構成され、それぞれのエピローグコードセグメントは、スタックから取得されたリターンアドレスに分岐する前に、それぞれのプロローグコードセグメントによって行われたスタック変更を検証するように構成される。スタックの変更が検証できない場合、それぞれのエピローグコードセグメントは、プロセッサの１つまたは複数に、事前定義された動作を開始させる。ここで、複数のプログラム命令は、非一過性のコンピュータ可読な記憶媒体からプロセッサの１つ以上によって実行される。
【０００９】
本発明の第４の態様によれば、リターン指向プログラミングのエクスプロイトを防ぐように調整されたコンパイル済み中間コードファイルを生成するコンピュータ実装される方法であって、
−  コンパイラによって生成され、複数のルーチンを備える１つ以上の中間コードファイルを受信することと、
−  １つ以上のプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、１つ以上の中間コードファイルを調整することであって、調整は、
＊  複数のルーチンのそれぞれの先頭アドレスを特定するために、１つ以上の中間コードファイルのシンボルテーブルを分析することと、
＊  複数のルーチンのそれぞれを分析して、それぞれのルーチン内の１つ以上の間接分岐命令を特定することと、
＊  複数のルーチンの１つ以上で検出されたそれぞれの間接分岐命令を、それぞれの間接分岐命令が複数のルーチンの１つの先頭を指していることを、それぞれの間接分岐動作を実行する前に検証するように構成されたそれぞれの検証コードセグメントの呼び出しに置き換えることと、
を備える、調整することと、
−  １つ以上の調整された中間コードファイルを出力することと、
を備え、実行時に、間接分岐命令が複数のルーチンの１つの先頭を指していない場合、それぞれの検証コードセグメントは、１つ以上のプロセッサに１つ以上の事前定義された動作を開始させる、コンピュータ実装される方法が提供される。
【００１０】
本発明の第５の態様によれば、リターン指向プログラミングのエクスプロイトを防ぐように調整されたコンパイル済みの中間コードファイルを生成するシステムであって、コードを格納するプログラムストアと、プログラムストアに結合され、格納されたコードを実行する１つ以上のプロセッサと、を備えるシステムが提供され、コードは、
−  コンパイラによって生成され、複数のルーチンを備える１つ以上の中間コードファイルを受信するためのコード命令と、
−  １つ以上のプロセッサによって実行されるそれぞれの実行可能ファイルを生成する前に、１つ以上の中間コードファイルを調整するためのコード命令で、調整は、
＊  複数のルーチンのそれぞれの先頭アドレスを特定するために、１つ以上の中間コードファイルのシンボルテーブルを分析することと、
＊  複数のルーチンのそれぞれを分析して、それぞれのルーチン内の１つ以上の間接分岐命令を特定することと、
＊  複数のルーチンのそれぞれで検出されたそれぞれの間接分岐命令を、それぞれの間接分岐動作を実行する前に、それぞれの間接分岐命令が複数のルーチンの１つの先頭を指していることを検証するように構成されたそれぞれの検証コードセグメントの呼び出しに置き換えることと、
を備える、コード命令と、
−  調整された中間コードファイルを出力するためのコード命令と、
を備え、実行時に、間接分岐命令が複数のルーチンの１つの先頭を指していない場合、それぞれの検証コードセグメントは、１つ以上のプロセッサに１つ以上の事前定義された動作を開始させる、システムが提供される。
【００１１】
本発明の第６の態様によれば、リターン指向プログラミングのエクスプロイトを防止するように調整された中間コードファイルから生成されたコンピュータプログラムの実行可能ファイルが提供され、非一過性のコンピュータ可読な記憶媒体と、リターンアドレス保護をサポートするように調整された１つ以上の中間コードファイルから１つ以上のプロセッサによって実行されるように生成された実行可能ファイルの１つ以上の調整されたルーチンの複数のプログラム命令とから構成される。調整されたルーチンのそれぞれにおいて、それぞれの間接分岐命令は、それぞれの間接分岐命令が複数のルーチンの１つの先頭を指していることを検証するように構成されたそれぞれの検証コードセグメントの呼び出しで置き換えられる。間接分岐命令が複数のルーチンの１つの先頭を指していない場合、それぞれの検証コードセグメントは、１つ以上のプロセッサに１つ以上の事前定義された動作を開始させる。ここで、複数のプログラム命令は、非一過性のコンピュータ可読な記憶媒体からプロセッサの１つ以上によって実行される。
【００１２】
第１、第２、第３、第４、第５および／または第６の態様のさらなる実施形態では、それぞれの中間コードファイルは、オブジェクトファイル、アーカイブファイル、およびバイナリファイルを備えるグループの１つである。
【００１３】
第１、第２、第３、第４、第５および／または第６の態様のさらなる実施形態では、複数のルーチンのそれぞれは、ルーチン、サブルーチン、および関数を備えるグループの１つである。
【００１４】
第１、第２、第３、第４、第５および／または第６の態様のさらなる実施形態では、事前定義された動作は、１つ以上のプロセッサの実行をクラッシュさせることと、１つ以上のプロセッサの実行を停止させることと、１つ以上のプロセッサに所定のアドレスに分岐させることと、１つ以上のプロセッサが１つ以上の潜在的に悪意のあるコード命令を実行することを防止することと、無効なスタック変更の指示を発生させることと、を備えるグループの１つである。
【００１５】
第１、第２、第３、第４、第５および／または第６の態様のさらなる実施形態では、１つ以上の中間コードファイルの１つまたは複数が、追加されたコードセグメントの追加によって影響を受ける命令およびデータ要素の１つまたは複数を修正するように調整される。
【００１６】
第１、第２、第３、第４、第５および／または第６の態様のさらなる実施形態では、１つ以上の中間コードファイルの１つ以上は、追加されたコードセグメントを反映してシンボルテーブルを更新し、調整されたルーチンのサイズを増加させるように修正される。
【００１７】
第１、第２および／または第３の態様のさらなる実施形態において、スタックへのアドレスプッシュ命令が、１つ以上のデータ項目をスタックにプッシュすることに関連付けられている場合、それぞれのプロローグコードセグメントは、データ項目をスタックにプッシュするように構成され、それぞれのエピローグコードセグメントは、データ項目をスタックからポップするように構成されている。
【００１８】
第１、第２および／または第３の態様のさらなる実施形態では、スタックの変更は、
−  スタックにプッシュされたリターンアドレスを読み出し、可逆的な仕方でリターンアドレスを変更し、変更されたリターンアドレスをスタックにプッシュして戻すように、それぞれのプロローグコードセグメントを設定することと、
−  スタックアドレスから変更されたリターンアドレスを読み出し、それぞれのプロローグコードセグメントが行った操作を反転させて、変更されたリターンアドレスからリターンアドレスを復元し、復元したリターンアドレスをスタックにプッシュして戻すように、それぞれのエピローグコードセグメントを構成することと、
によって、可逆的な仕方でリターンアドレスを変更することに基づいている。
【００１９】
第１、第２および／または第３の態様のさらなる実施形態では、リターンアドレスの変更は、それぞれのプロローグコードセグメントがランダムに選択された値でリターンアドレスをＸＯＲするように構成され、それぞれのエピローグコードセグメントが同一のランダムに選択された値で変更されたリターンアドレスをＸＯＲするように構成されるように、ランダムに選択された値でリターンアドレスをＸＯＲする操作に基づいて行われる。
【００２０】
第１、第２および／または第３の態様のさらなる実施形態では、スタックの変更は、
−  スタック内の隣接する位置に定数値マーカを挿入するように、それぞれのプロローグコードセグメントを設定することと、
−  定数値マーカを検証し、スタックから定数値マーカを除去するように、それぞれのエピローグコードセグメントを設定することと、
によって、プッシュされたリターンアドレスの位置に隣接する位置において、マーカをスタックにプッシュすることに基づいて行われる。
【００２１】
第１、第２および／または第３の態様のさらなる実施形態では、定数値マーカは、１つ以上のプロセッサの起動イベントごとにランダムに選択される。
【００２２】
第１、第２および／または第３の態様のさらなる実施形態では、スタックの変更は、リターンアドレスの位置に隣接する位置において、マーカをスタックにプッシュすることに基づいて行われる。
【００２３】
第１、第２および／または第３の態様のさらなる実施形態では、それぞれのプロローグコードセグメント、それぞれのエピローグコードセグメント、および／または検証コードセグメントは、スタックへのアドレスプッシュ命令およびそれぞれのスタックからのアドレスポップ命令を、アドレスのプッシュ操作およびアドレスのポップ操作の間にそれぞれの追加されたコードセグメントを呼び出すように構成されたトランポリン分岐関数に置き換えることによって、１つまたは複数のルーチンに追加される。
【００２４】
第４、第５および／または第６の態様のさらなる実施形態では、複数のルーチンの１つの先頭を指す間接分岐命令の検証は、１つ以上の中間コードファイル内の複数のルーチンのそれぞれに先行する一意的なコードの検証に基づいて行われ、一意的なコードの検証は、
−  複数のルーチンのそれぞれの先頭のアドレスに先行するアドレスで１つ以上の中間コードファイルに一意的なコードを追加することと、
−  間接分岐関数が指すアドレスの前に一意的なコードがあることを検証するように、それぞれの検証コードセグメントを設定することと、
によって適用される。
【００２５】
第４、第５および／または第６の態様のさらなる実施形態では、複数のルーチンの１つの先頭を指す間接分岐命令の検証は、複数のルーチンのそれぞれの先頭をマッピングするデータセットに基づいて行われ、データセットマッピングの検証は、
−  複数のルーチンのそれぞれの先頭アドレスをマッピングするためのデータセットを構築することと、
−  間接分岐関数によって指されるアドレスが、データセット内にマッピングされた複数のルーチンの１つの先頭アドレスと一致することを検証するように、それぞれの検証コードセグメントを構成することと、
によって適用される。
【００２６】
第４、第５および／または第６の態様のさらなる実施形態では、間接分岐命令をそれぞれの検証コードセグメントを指す直接分岐命令に置き換えるように１つ以上のルーチンが調整される。
【００２７】
第４、第５および／または第６の態様の任意選択の実施形態では、１つ以上のルーチンは、間接分岐命令によって指されたアドレスをスタックにプッシュするための直接分岐命令の前にスタックへのプッシュ命令を含むように調整される。プッシュされたアドレスは、検証コードセグメントによって検証のために使用される。
【００２８】
第４、第５および／または第６の態様のさらなる実施形態において、検証コードセグメントは、間接分岐命令を実行する前に、間接分岐命令をそれぞれの追加された検証コードセグメントを呼び出すように構成されたトランポリン分岐関数に置き換えることによって１つ以上のルーチンに追加される。
【００２９】
本開示の他のシステム、方法、特徴、および利点は、以下の図面および詳細な説明を検討すると、当技術分野の当業者であれば明らかであるか、または明らかになるであろう。そのような追加のシステム、方法、特徴、および利点はすべて、本明細書中に含まれ、本開示の範囲内にあり、添付の特許請求の範囲によって保護されることが意図されている。
【００３０】
別段の定義がない限り、本明細書で使用されるすべての技術用語および／または科学用語は、本発明が適用される当技術分野の通常の当業者が一般的に理解するのと同じ意味を有する。本明細書に記載されたものと類似または同等の方法および材料が、本発明の実施形態の実施または試験において使用され得るが、例示的な方法および／または材料が以下に記載されている。矛盾する場合は、定義を含む特許明細書が支配する。さらに、材料、方法、および例示は例示的なものに過ぎず、必ずしも限定的であることを意図していない。
【００３１】
本発明の実施形態の方法および／またはシステムの実施は、選択されたタスクを手動で、自動的に、またはそれらの組み合わせで実行または完了することを含み得る。さらに、本発明の方法および／またはシステムの実施形態の実際の計装および装置によれば、いくつかの選択されたタスクは、オペレーティングシステムを使用して、ハードウェアによって、ソフトウェアによって、またはファームウェアによって、またはそれらの組み合わせによって実施され得る。
【００３２】
例えば、本発明の実施形態に従って選択されたタスクを実行するためのハードウェアは、チップまたは回路として実装され得る。ソフトウェアとして、本発明の例示的な実施形態に従った選択されたタスクは、任意の適切なオペレーティングシステムを使用してコンピュータによって実行される複数のソフトウェア命令として実装され得る。本発明の例示的な実施形態では、本明細書に記載の方法および／またはシステムの例示的な実施形態に従った１つ以上のタスクは、複数の命令を実行するためのコンピューティングプラットフォームなどのデータプロセッサによって実行される。任意選択で、データプロセッサは、命令および／またはデータを格納するための揮発性メモリ、および／または命令および／またはデータを格納するための不揮発性ストレージ、例えば磁気ハードディスクおよび／またはリムーバブルメディアを含む。任意選択で、ネットワーク接続も提供される。ディスプレイおよび／またはキーボードまたはマウスなどのユーザ入力装置も任意選択で提供される。
【００３３】
本発明のいくつかの実施形態を、例示のためだけに、添付の図面を参照して本明細書に記載する。今、図面を詳細に参照して、示された特定の実施形態は、例示のためのものであり、本発明の実施形態の例示的な議論のためのものであることが強調されている。この点で、図面と一緒に取られた説明は、本発明の実施形態がどのように実施され得るかを、当業者には明らかにする。
【図面の簡単な説明】
【００３４】
【図１】図１は、本発明のいくつかの実施形態に従った、リターンアドレス保護を適用するように中間コードファイルを調整する例示的な工程のフローチャートである。
【図２】図２は、本発明のいくつかの実施形態に従った、メモリ破損のエクスプロイトに対する保護を適用するように中間コードファイルを調整するための例示的なシステムの概略図である。
【図３】図３は、本発明のいくつかの実施形態に従った、リターン指向プログラミングエクスプロイトに対する保護を適用するように中間コードファイルを調整する例示的な工程のフローチャートである。
【発明を実施するための形態】
【００３５】
本発明は、そのいくつかの実施形態において、スタック破損のエクスプロイトに対する保護を適用すること、より具体的には、スタック破損のエクスプロイトに対する保護を適用するように中間コードファイルを調整することに関するものであるが、これに限定されない。
【００３６】
本発明のいくつかの実施形態によれば、１つ以上の中間コードファイル、例えば、１つ以上のコンパイラによって１つ以上のソースコードファイルから生成されたオブジェクトファイル、バイナリファイル、ライブラリファイル、アーカイブファイルおよび／またはそれらに類するものを、１つ以上の中間コードファイルにリターンアドレス保護（ＲＡＰ）を適用するように構成された追加のコードを含めるように調整するための方法、システム、およびコンピュータプログラム製品が提供される。以降でルーチンと総称される、複数のルーチン、サブルーチン、関数および／またはそれらに類するものを備える中間コードファイルは、１つ以上の実行可能ファイルの生成、例えば、ビルド、リンクおよび／またはそれらに類するものに使用される前に調整される。１つ以上の実行可能ファイルは、以降で装置と総称される、１つ以上の装置、システムおよび／またはプラットフォームによっての１つ以上のプロセッサによって実行されてもよい。
【００３７】
マルウェア（悪意のあるコード）、例えば、コンピュータウイルス、ワーム、トロイの木馬、ランサムウェア、スパイウェア、アドウェア、スケアウェア、および／またはそれらに類するものは、プロセッサの制御（実行）フローの制御を獲得するために、潜在的に悪意のある者によって使用される可能性がある。このマルウェアは、例えば、バッファオーバーフロー、バッファオーバーラン、および／またはそのようなセキュリティ上のエクスプロイトを適用して、プロセッサによって実行される１つ以上のルーチンからの戻り時のリターンアドレスを使用して、プロセッサのスタック（揮発性メモリリソースに実装されている）を操作して、プロセッサに対する制御を獲得しようとすることができる。バッファオーバーフローを引き起こすことで、マルウェアは実行コードを保持することが知られている領域に悪意のあるコードを配置する、プログラムの状態に関連するデータを選択的に上書きするといった、元のプログラマが意図していない動作を引き起こす可能性がある。
【００３８】
現在実行中のルーチンが呼び出された元の（呼び出し元の）ルーチンに戻るのを容易にするようにスタックへのプッシュ命令／スタックからのポップ命令がアドレスの格納動作と取得動作のために使用されている分岐動作のためにコード内に存在するスタックへのプッシュ命令／スタックからのポップ命令を、実行時にスタックを操作するためにマルウェアが利用することがある。したがって、スタックへのプッシュ命令／スタックからのポップ命令は、マルウェアによってエクスプロイトされやすい。別の例では、マルウェアは、データ要素、特にグローバルデータ要素、例えば、変数、構造体、配列、および／またはそれらに類するものへのポインタのためにコードに存在するスタックへのプッシュ命令／スタックからのポップ命令を利用する可能性がある。このような場合、マルウェアは、プロセッサの制御フローの制御を獲得する、および／またはプロセッサに意図しない動作を行わせるために、ポインタによって指されたデータ要素の１つ以上を悪意のあるコードで置き換える、および／またはオーバーランさせることを試みることがある。
【００３９】
１つ以上の中間コードファイル内のＲＡＰを適用するために、１つ以上の中間コードファイル内の１つ以上のルーチンは、実行時にスタックの操作を特定し、スタックを操作することによってマルウェアが１つ以上のプロセッサの制御フローを制御することを防止するように適合されたＲＡＰロジック（コード）を含むように調整されてもよい。それぞれの中間コードファイルは、最初に、複数のルーチンを特定するために分析されてもよい。それぞれのルーチンは、リターンアドレスのスタックへのプッシュ命令と、対応するリターンアドレスのスタックからのポップ命令を特定するために、さらに分析されてもよい。特定されたターンアドレスのスタックへのプッシュ命令と、対応するリターンアドレスのスタックからのポップ命令は、マルウェアによってスタックに対して行われた操作を特定するように構成されたコードセグメントに置き換えられてもよい。
【００４０】
それぞれの、リターンアドレスをスタックにプッシュする命令は、リターンアドレスがスタックにプッシュされた後、特定の方法でスタックを変更するように構成されたプロローグコードセグメントで置き換えられてもよい。補完的に、それぞれの、リターンアドレスのスタックからのポップ命令は、スタックから取り出されたリターンアドレスに分岐する前に、対応するプロローグコードセグメントによってなされたスタックの変更を検証するように構成されたエピローグコードセグメントで置き換えられてもよい。
【００４１】
実行時に、エピローグコードセグメントが対応するプロローグコードセグメントによって行われたスタック変更を確認できない場合、エピローグコードセグメントは、マルウェアが制御を獲得するのを防ぐために、１つ以上の事前定義された動作を開始することができる。事前定義された動作は、例えば、プロセッサの実行をクラッシュさせること、プロセッサの実行を停止すること、プロセッサを事前定義されたアドレスに分岐させること、破損したスタックを対象とした少なくとも１つの潜在的に悪意のあるコード命令をプロセッサが実行することを防止すること、無効なスタック変更の１つ以上の表示および／または警告を発生させること、および／またはそれらに類するものを含んでもよい。事前定義された動作は、制御（実行）フローの１つ以上のパラメータ、例えば、プロセッサアーキテクチャ、各ルーチンの重大度および／または重要度、ユーザ定義パラメータおよび／またはそれらに類するものに応じて選択されてもよい。
【００４２】
追加されたコードセグメントは、通常、限られた数の命令によって実装された非常にシンプルなロジックを備えるため、ストレージリソースやコンピューティングリソースを必要とするフットプリントが非常に小さくなっている。
【００４３】
本発明のいくつかの実施形態によれば、リターン指向プログラミング（ＲＯＰ）を防止するように構成された追加コードを含むように中間コードファイルの１つ以上を調整するための方法、システム、およびコンピュータプログラム製品が提供される。
【００４４】
多くのコンピューティング装置、システム、プラットフォーム、および／または環境において、悪意のある者は、プロセッサのヒープおよび／またはスタックからコードを実行することができず、実行可能なコード環境にマルウェアを注入（追加、挿入など）することができないことがある。そのような場合、悪意のある者は、実行可能ファイル内で既に利用可能な、例えば、関数、コードセグメント、コード断片、および／またはそれらに類するものなどの１つ以上のコード要素（ガジェットとも呼ばれる）を利用することができる。悪意のある者は、そのようなガジェットを操作して、実行可能ファイルを実行するプロセッサを通常の実行パスから、１つ以上の潜在的なサイバー脅威をもたらす可能性のある代替の実行パスに流用することができる。
【００４５】
このようなコンピューティング装置、システム、プラットフォーム、および／または環境では、実行フローは常にルーチンの先頭アドレスであるアドレスの場所に分岐することがある。しかし、ガジェットを起動、実行、および／または開始するために、悪意のある者は、有効なルーチンの代わりにガジェットを呼び出すために分岐操作によって使用されるコールスタックを操作することによって、１つ以上のルーチンの分岐操作をエクスプロイトするためにＲＯＰを適用しうる。特に、悪意のある者は、分岐アドレスが揮発性メモリリソース（スタック、ヒープ、レジスタなど）から取得される間接分岐動作をエクスプロイトすることができる。分岐アドレスがハードコードされている直接分岐操作は、分岐アドレスが揮発性メモリリソースから取得されないため、ＲＯＰエクスプロイトにさらされない可能性がある。したがって、本明細書に記載されているＲＯＰエクスプロイト防止ロジックおよび手段は、直接分岐というより間接分岐に向けられている。
【００４６】
中間コードファイル内のＲＯＰエクスプロイト防止を適用するために、中間コードファイル内の１つ以上のルーチンは、有効なルーチンの先頭ではないアドレス位置への分岐を防止するように構成されたＲＯＰエクスプロイト防止ロジックを含むように調整されてもよく、これにより、悪意のある者がプロセッサの実行フローを制御するために典型的にはルーチン内に配置されたガジェットを使用することを防止することができる。
【００４７】
それぞれの中間コードファイルは、複数のルーチンを特定するために分析されてもよい。それぞれのルーチンは、間接分岐命令を特定するためにさらに分析される。特定されたそれぞれの間接分岐命令は、それぞれの間接分岐命令によって指された分岐アドレスが複数のルーチンの１つの先頭アドレスであることを検証するように構成された検証コードセグメントを呼び出すように調整されてもよい。
【００４８】
実行時に、検証コードセグメントが、１つ以上の間接分岐命令が指す分岐アドレスが、複数のルーチンの１つの先頭アドレスを指していないと判断した場合、検証コードセグメントは、間接分岐命令を操作して、ガジェットのアドレスであってもよい代替アドレスを指すように操作することにより、悪意のある者がプロセッサの実行フローを制御することを防ぐための１つ以上の事前定義された動作を開始することができる。
【００４９】
ポストコンパイル段階で中間コードファイルを調整することにより、ＲＡＰおよびＲＯＰエクスプロイトセキュリティ緩和を適用することは、ＲＡＰおよびＲＯＰエクスプロイト手段をコードに組み込むための既存の方法およびシステムと比較して、大きな利点と利益を提示することができる。
【００５０】
第一に、ＲＡＰおよびＲＯＰエクスプロイト緩和策は、ソースコードファイルにそのような緩和策を適用することができる既存の方法と比較して、中間コードファイルに適用される。したがって、既存の方法とは対照的に、ＲＡＰおよびＲＯＰエクスプロイト緩和手段は、ソースコードが利用できない中間コードファイル、例えば、サードパーティの中間コードファイル、ライブラリファイル、および／またはそれらに類するものに適用されてもよい。
【００５１】
さらに、既存の方法の中には、ＲＡＰおよび／またはＲＯＰエクスプロイト緩和を適用するために、特定のプラットフォーム、ハードウェアおよび／またはソフトウェアの機能性、例えば、ヒープ分離、タスク呼び出し、カーネルユーザ分離および／またはそれらに類するものを必要としたり、依存したりするものがある。対照的に、中間コードファイル内のルーチンの調整を介したＲＡＰおよびＲＯＰエクスプロイト緩和手段の適用は、そのような要件および／または前提条件から独立しており、したがって、オペレーティングシステム、ハードウェア機能、アーキテクチャの仕様および／またはそれらに類するものに不可知および非依存である。このように、ＲＡＰおよびＲＯＰエクスプロイト緩和手段は、実質的にあらゆるプラットフォーム、アーキテクチャ、実行環境、オペレーティングシステムおよび／またはそれらに類するものに適用することができる。
【００５２】
さらに、既存の方法のいくつかは、ＲＡＰおよびＲＯＰエクスプロイト緩和手段を適用するために、例えば、動的にロード可能なコードモジュール、システムコール、割り込みハンドラおよび／またはそれらに類するものなどのオペレーティングシステムリソースを必要とする場合がある。そのような動的にロード可能なコードモジュールは、複数のコンピューティング装置、システムおよび／またはプラットフォーム、特にローエンドおよび／または限られたリソースの装置、例えば、組み込み装置、ＩｏＴ装置、医療装置および／またはそのような装置では利用できないかもしれない。対照的に、１つ以上の中間コードファイル内の１つ以上のルーチンの調整を介してＲＡＰおよびＲＯＰエクスプロイト緩和手段を適用することは、単純な単一バイナリファイルのファームウェアから複雑なオペレーティングシステムまで、実行可能ファイルを生成するために使用される実質的に任意のタイプの中間コードファイルに緩和手段を適用することを可能にしうる。
【００５３】
さらに、ＲＡＰおよびＲＯＰエクスプロイト緩和手段、すなわち、追加されたコードセグメントは、非常に単純なロジックおよび限られた少ない数の命令で構成され、したがって、それらの実行および／または記憶のために、非常に限られた、および典型的には取るに足らない処理および／または記憶リソースしか必要としない。このように、適用されたＲＡＰおよびＲＯＰ利用緩和手段は、ローエンドおよび／または典型的に限られたリソースの装置に非常に適しうる。
【００５４】
また、中間コードファイルにＲＡＰおよびＲＯＰエクスプロイト緩和策を適用することで、既存の方法で必要とされるような開発環境の変更、修正、改変および／または適応を必要としない場合がある。ツールチェイン、コンパイラ、リンカ、ビルダ、および／またはそれらのような１つ以上のツールを備える開発環境は非常に複雑であるため、それらの調整には多大なリソースおよび／または時間を必要とし、その結果、既存の方法はコストがかかり、非効率的であり、および／または制限されたものとなる。対照的に、調整された中間コードファイルに適用されたＲＡＰおよびＲＯＰエクスプロイト緩和手段は、開発者の環境に影響を与えることなく、既存の開発環境やソフトウェアパッケージのビルドに容易に統合することができる。例えば、追加されたコードセグメントを生成して追加するために必要なツールおよび／または手続きは、１つまたは複数のビルドおよび／またはリンク設定ファイル、例えばメークファイルおよび／またはそれらに類するものに１つまたは複数のエントリ（行）を追加することによって起動することができる。さらに、ＲＡＰおよびＲＯＰエクスプロイト緩和手段は中間コードファイルに適用され、開発者のツールチェインに影響を与えないので、開発者は、既存の方法で必要とされるかもしれない修正されたツールチェインを使用するために訓練されることを要さない。
【００５５】
本発明の少なくとも１つの実施形態を詳細に説明する前に、本発明は、以下の説明および／または図面および／または実施例に示された構成要素および／または方法の詳細な構成および／または配置に必ずしも限定されるものではないことが理解されるであろう。本発明は、他の実施形態が可能であり、または様々な方法で実施または実施されることが可能である。
【００５６】
当業者には理解されるであろうが、本発明の側面は、システム、方法、またはコンピュータプログラム製品として具現化されてもよい。したがって、本発明の側面は、完全にハードウェアの実施形態、完全にソフトウェアの実施形態（ファームウェア、常駐ソフトウェア、マイクロコードなどを含む）、またはソフトウェアとハードウェアの態様を組み合わせた実施形態の形をとってもよく、これらはすべて本明細書では一般的に「回路」、「モジュール」、または「システム」と呼ばれることがある。さらに、本発明の側面は、そこに具現化されたコンピュータ可読プログラムコードを有する１つ以上のコンピュータ可読媒体に具現化されたコンピュータプログラム製品の形態をとってもよい。
【００５７】
１つ以上のコンピュータ可読媒体の任意の組み合わせを利用することができる。コンピュータ可読記憶媒体は、命令実行装置によって使用するための命令を保持し、記憶することができる有形の装置であってもよい。コンピュータ可読媒体は、コンピュータ可読信号媒体であってもよいし、コンピュータ可読記憶媒体であってもよい。コンピュータ可読記憶媒体は、例えば、電子式、磁気式、光学式、電磁式、赤外線式、または半導体式のシステム、機器、装置、またはそれらの任意の適切な組み合わせであってもよいが、これらに限定されない。コンピュータ可読な記憶媒体のより具体的な例（非網羅的なリスト）としては、１本以上のワイヤを有する電気的接続部、ポータブルコンピュータディスケット、ハードディスク、ランダムアクセスメモリ（ＲＡＭ）、読み取り専用メモリ（ＲＯＭ）、消去可能なプログラム可能な読み取り専用メモリ（ＥＰＲＯＭまたはフラッシュメモリ）、光ファイバ、ポータブルコンパクトディスク読み取り専用メモリ（ＣＤ−ＲＯＭ）、光記憶装置、磁気記憶装置、または前記の任意の適切な組み合わせが挙げられる。本明細書の文脈において、コンピュータ可読な記憶媒体は、命令実行システム、機器、または装置によって、またはそれに関連して使用するためのプログラムを含むことができ、または格納することができる任意の有形媒体であってもよい。
【００５８】
コンピュータ可読信号媒体は、例えば、ベースバンドで、または搬送波の一部として、そこに具現化されたコンピュータ可読プログラムコードを有する伝搬データ信号を含んでもよい。このような伝搬信号は、電磁気、光学、またはそれらの任意の適切な組み合わせを含むがこれらに限定されない、様々な形態の任意の形態をとってもよい。コンピュータ可読信号媒体は、コンピュータ可読記憶媒体ではない任意のコンピュータ可読媒体であってもよく、命令実行システム、機器、または装置によって、またはそれに関連して使用するためのプログラムを通信、伝搬、または搬送することができる。
【００５９】
コンピュータ可読媒体上に具現化されたコンピュータ可読プログラム命令を構成するコンピュータプログラムコードは、無線、有線、光ファイバケーブル、ＲＦなどを含むがこれらに限定されない、任意の適切な媒体、またはこれらの任意の適切な組み合わせを使用して送信することができる。
【００６０】
本発明の態様に係る動作を実行するためのプログラムコードは、Ｊａｖａ、Ｓｍａｌｌｔａｌｋ、Ｃ＋＋などのオブジェクト指向プログラミング言語と、「Ｃ」プログラミング言語または類似のプログラミング言語などの従来の手続き型プログラミング言語を含む、１つ以上のプログラミング言語の任意の組み合わせで記述することができる。
【００６１】
プログラムコードは、全体がユーザのコンピュータ上で実行されてもよいし、一部がスタンドアロンのソフトウェアパッケージとしてユーザのコンピュータ上で実行されてもよいし、一部がユーザのコンピュータ上で、一部がリモートコンピュータ上で実行されてもよいし、全体がリモートコンピュータまたはサーバ上で実行されてもよい。後者のシナリオでは、リモートコンピュータは、ローカルエリアネットワーク（ＬＡＮ）またはワイドエリアネットワーク（ＷＡＮ）を含む任意のタイプのネットワークを介してユーザのコンピュータに接続されてもよく、または接続は、外部コンピュータ（例えば、インターネットサービスプロバイダを使用してインターネットを介して）に行われてもよい。プログラムコードは、コンピュータ可読記憶媒体からそれぞれのコンピューティング／処理装置に、またはネットワーク、例えば、インターネット、ローカルエリアネットワーク、ワイドエリアネットワークおよび／または無線ネットワークを介して外部コンピュータまたは外部記憶装置にダウンロードすることができる。
【００６２】
本発明の態様は、本発明の実施形態に従った方法、装置（システム）、およびコンピュータプログラム製品のフローチャート図および／またはブロック図を参照して本明細書に記載されている。フローチャート図示および／またはブロック図の各ブロック、ならびにフローチャート図示および／またはブロック図のブロックの組み合わせは、コンピュータ可読なプログラム命令によって実施され得ることが理解されるであろう。
【００６３】
図面のフローチャートおよびブロック図は、本発明の様々な実施形態に従ったシステム、方法、およびコンピュータプログラム製品の可能な実施形態のアーキテクチャ、機能、および動作を例示している。これに関して、フローチャートまたはブロック図の各ブロックは、モジュール、セグメント、または命令の一部を表してもよく、これは、指定された論理機能を実装するための１つ以上の実行可能な命令を構成する。いくつかの代替的な実施形態では、ブロックに記載されている機能は、図面に記載されている順序から外れて発生してもよい。例えば、連続して示された２つのブロックは、実際には実質的に同時に実行されてもよく、あるいは、ブロックは、関与する機能に応じて、時には逆の順序で実行されてもよい。また、ブロック図の各ブロックおよび／またはフローチャートの図示、ならびにブロック図の各ブロックおよび／またはフローチャートの図示の組み合わせは、所定の機能または動作を実行するか、または特定目的ハードウェアとコンピュータ命令の組み合わせを実行する特定目的ハードウェアベースのシステムによって実装され得ることにも留意されたい。
【００６４】
次に図面を参照すると、図１は、本発明のいくつかの実施形態に従って、リターンアドレス保護を適用するために中間コードファイルを調整する例示的な工程のフローチャートを示す。例示的な工程１００は、１つ以上の中間コードファイル、例えば、１つ以上のコンパイラによって１つ以上のソースコードファイルから生成されたオブジェクトファイル、バイナリファイル、ライブラリファイル、アーカイブファイル、および／またはそれらに類するものを調整するために実行され、１つ以上の中間コードファイルにＲＡＰを適用するように構成されたコードを含むようにすることができる。複数のルーチン、サブルーチン、関数および／または本明細書で総称されるルーチンを備える１つ以上の中間コードファイルは、１つ以上の装置の１つ以上のプロセッサによって実行するために作成された１つ以上の実行可能ファイルの生成、例えばビルド、リンクおよび／またはそれらに類するものに使用される前に調整される。
【００６５】
前に本明細書で説明したように、ランタイムにおいて、マルウェアは、悪意のあるコードを呼び出すために、プロセッサによって実行されるルーチンの１つ以上のルーチンからのリターン時のリターンアドレスを使用してプロセッサの制御の獲得をする試みにおいてプロセッサのスタックを操作するための１つ以上のセキュリティエクスプロイトを適用しうる。ＲＡＰを適用するために、中間コードファイルは、実行時にスタックの操作を特定し、マルウェアがプロセッサの制御（実行）フローを制御することを防止するように適合されたＲＡＰロジックを含むように調整されてもよい。
【００６６】
本発明のいくつかの実施形態に従った、メモリ破損エクスプロイトに対する保護を適用するために中間コードファイルを調整するための例示的なシステムの概略図である図２を参照されたい。例示的な構築システム２００、例えば、コンピュータ、サーバ、コンピューティングノード、コンピューティングノードのクラスタ、および／またはそれらに類するものは、入出力（Ｉ／Ｏ）インターフェース２０２、工程１００のような工程を実行するための１つ以上のプロセッサ２０４、およびコードおよび／またはデータを格納するためのストレージ２０６を含んでもよい。
【００６７】
Ｉ／Ｏインターフェース２０２は、１つ以上の有線および／または無線ネットワーク、例えば、ローカルエリアネットワーク（ＬＡＮ）、ワイドエリアネットワーク（ＷＡＮ）、市町村エリアネットワーク（ＭＡＮ）、セルラーネットワーク、インターネットおよび／またはそれらに類するものに接続するための１つ以上のネットワークインターフェースを含んでもよい。Ｉ／Ｏインターフェース２０２は、１つ以上のローカルリソース、例えば、外付けディスクドライブ、別のコンピューティング装置、および／またはそれらに類するものに接続するための、１つ以上のインターフェース、例えば、ユニバーサルシリアルバス（ＵＳＢ）、取り付け可能なストレージインターフェース、および／またはそれらに類するものをさらに含んでもよい。
【００６８】
同種または異種のプロセッサ２０４は、並列処理のために配置された１つ以上の処理ノードを、クラスタとして、および／または１つ以上のマルチコアプロセッサとして含んでもよい。データおよび／またはプログラムコードを格納するために使用されるストレージ２０６は、永続的不揮発性装置、例えば、ハードドライブ、ソリッドステートドライブ（ＳＳＤ）、磁気ディスク、フラッシュアレイおよび／またはそれらに類するもの、および／または揮発性装置、例えば、ランダムアクセスメモリ（ＲＡＭ）装置、キャッシュメモリおよび／またはそれらに類するもののいずれかである、１つ以上の非一過性メモリ装置を含んでもよい。ストレージ２０６は、さらに、Ｉ／Ｏインターフェース２０２を介して１つ以上のネットワークを介してアクセス可能な、１つ以上のローカルおよび／またはリモートのネットワークストレージリソース、例えば、ストレージサーバ、ネットワークアタッチドストレージ（ＮＡＳ）、ネットワークドライブ、および／またはそれらに類するものを備えてもよい。
【００６９】
Ｉ／Ｏインターフェース２０２を介して、構築システム２００は、例えば、１つ以上のソースコードファイルから、１つ以上のコンパイラによって生成された１つ以上の中間コードファイルを、受信、フェッチおよび／または取得してもよい。構築システム２００は、１つ以上のリモートネットワークリソース、例えば、サーバ、処理ノード、ストレージサーバ、ＮＡＳ、クラウドサービス、クラウドストレージおよび／またはそれらに類するものから中間コードファイルを取得してもよい。追加的に、および／または代替的に、構築システム２００は、Ｉ／Ｏインターフェース２０２を介して、ローカルに取り付けられたストレージリソース、例えば、取り付け可能な記憶媒体、別のコンピューティングノード、および／またはそれらに類するものから、１つ以上の中間コードファイルを取得してもよい。構築システム２００は、任意選択で、取得した中間コードファイルをストレージ２０６にローカルに格納してもよい。
【００７０】
１つ以上のプロセッサ２０４は、例えば、プロセス、スクリプト、アプリケーション、エージェント、ユーティリティ、ツール、および／またはそれらに類するものであって、それぞれが、ストレージ２０６のような非一過性の媒体に記憶され、１つ以上のプロセッサ２０４のような１つ以上のプロセッサによって実行される複数のプログラム命令を備える、１つ以上のソフトウェアモジュールを実行してもよい。例えば、１つ以上のプロセッサ２０４は、ＲＡＰを適用するために１つ以上の中間コードファイルを調整するための分析および構築アプリケーション（コンストラクタ）２１０を実行してもよい。任意選択で、コンストラクタ２１０は、１つ以上のツール、例えば、ツールチェイン、コンパイラ、リンカ、ビルダおよび／またはそれらに類するものを備える１つ以上の開発環境に統合されてもよいし、および／または呼び出されてもよい。例えば、コンストラクタ２１０は、１つ以上のビルドおよび／またはリンク構成ファイル、例えばメークファイルおよび／またはそれらに類するものに１つ以上のエントリ（行）を追加することによって呼び出されてもよい。
【００７１】
任意選択で、構築システム２００および／またはコンストラクタ２１０は、例えば、Ａｍａｚｏｎ  Ｗｅｂ  Ｓｅｒｖｉｃｅ（ＡＷＳ）、Ｇｏｏｇｌｅ  Ｃｌｏｕｄ、Ｍｉｃｒｏｓｏｆｔ  Ａｚｕｒｅおよび／またはそれらに類するものなどの１つ以上のクラウドインフラストラクチャおよび／またはサービスによって提供される１つ以上のクラウドコンピューティングサービス、例えば、Ｉｎｆｒａｓｔｒｕｃｔｕｒｅ  ａｓ  ａ  Ｓｅｒｖｉｃｅ（ＩａａＳ）、Ｐｌａｔｆｏｒｍ  ａｓ  ａ  Ｓｅｒｖｉｃｅ（ＰａａＳ）、Ｓｏｆｔｗａｒｅ  ａｓ  ａ  Ｓｅｒｖｉｃｅ（ＳａａＳ）および／またはそれらに類するものによって提供される。
【００７２】
１０２に示されるように、工程１００は、コンストラクタ２１０が、１つ以上のコンパイラによって１つ以上のソースコードファイルから生成されてもよい、１つ以上の中間コードファイル、例えば、オブジェクトファイル、バイナリファイル、ライブラリファイル、アーカイブファイルおよび／またはそれらに類するものを取得することから開始される。中間コードファイルは、１つ以上のファイル形式、例えば、ＥＬＦ（Ｅｘｅｃｕｔａｂｌｅ  ａｎｄ  Ｌｉｎｋａｂｌｅ  Ｆｏｒｍａｔ）および／またはそのような形式で取得されてもよい。１つ以上の中間コードファイルは、典型的には、１つ以上のプロセッサによって実行され得る１つ以上の実行可能ファイルを生成、ビルド、および／またはリンクするために使用されてもよい。コンストラクタ２１０は、１つ以上の中間コードファイルを、１つ以上のソース、例えば、１つ以上の中リモートネットワークリソース、取り付け可能なストレージ装置、および／またはストレージ２０６から取得してもよい。
【００７３】
１０４に示されるように、コンストラクタ２１０は、中間コードファイルのすべてのルーチンを特定するために、１つ以上の中間コードファイルのそれぞれを分析するために、１つ以上の中間コードファイル分析ツールを適用してもよい。例えば、コンストラクタ２１０は、ＥＬＦファイルを分析およびパースするためのｐｙｔｈｏｎのツール（ライブラリ）である「ｐｙｅｌｆｔｏｏｌｓ」を利用してもよい。「ｐｙｅｌｆｔｏｏｌｓ」ツールを使用して、コンストラクタ２１０は、ルーチンのシンボルを特定するためにＥＬＦ形式の１つ以上の中間ファイルのシンボルテーブルをスキャンし、ルーチンのアドレスをそれぞれのコードセクションで検出してもよい。コンストラクタ２１０は、１つ以上の中間コードファイルが準拠する１つ以上の対象のプロセッサのアーキテクチャおよび命令セット、例えば、ＡＲＭ、ＡＲＭ−Ｔｈｕｍｂ、ｘ８６、ｘ８６−６４、Ｐｏｗｅｒ  ＩＳＡおよび／またはそれらに類するものに従って、１つ以上の中間コードファイルを分析するように適合されていてもよい。
【００７４】
例えば、コンストラクタ２１０は中間コードファイル内のルーチンのそれぞれに対して、コンパイラによって生成されたシンボルを特定しマッピングすることを、中間コードファイルのシンボルテーブルに亘って反復することによって、ルーチンを特定してもよい。例えば、ＡＲＭ−Ｔｈｕｍｂアーキテクチャでは、それぞれの「．ｏ」オブジェクト（中間）ファイルは、ＥＬＦファイル形式で実装される。コンストラクタ２１０は、ＥＬＦ標準の拡張子「．ｓｙｍｔａｂ」で割り当てられた「シンボルテーブル」セクション内のエントリを反復処理することによって、ルーチンのシンボル名を特定してもよい。シンボルテーブルは、プログラムのシンボル定義および参照を検索し、再配置するために必要な情報から構成される。シンボルテーブル内のルーチンの１つに関連付けられたそれぞれのシンボルエントリは、非ゼロサイズのフィールド、型「ＦＵＮＣ」フィールド、および「．ｏ」オブジェクト（中間）ファイル内の「コード」セクションの１つを参照するインデックスフィールドを有することを特徴とする。シンボルテーブルエントリの１つ以上は、バインド「ＧＬＯＢＡＬ」フィールドおよび／またはバインド「ＬＯＣＡＬ」フィールドをさらに含んでもよい。
【００７５】
コンストラクタ２１０は、１つ以上の中間コードファイルのそれぞれをさらに分析して、中間コードファイル内のルーチンのそれぞれの先頭アドレスを特定してもよい。例えば、ＡＲＭ−Ｔｈｕｍｂアーキテクチャでは、シンボルテーブルの「Ｆｕｎｃｔｉｏｎ」（ルーチン）シンボルの値は、関数がＴｈｕｍｂコードを含むことを特定するために、「関数（ルーチン）の開始＋１」である。このような場合、および任意に他のプロセッサアーキテクチャのための同様のケースでは、コンストラクタ２１０は、「．ｏ」オブジェクト（中間）ファイルのシンボルテーブルからルーチンの「値」を抽出し、ルーチンの実際の先頭アドレス、すなわち「値−１」を抽出するための反対の数学的操作を実行してもよい。
【００７６】
１０６に示されるように、コンストラクタ２１０は、リターンアドレスのスタックへのプッシュ命令および対応する１つ以上のリターンアドレスのスタックからのポップ命令を特定するために、１つ以上の中間コードファイルのそれぞれに含まれる複数のルーチンの１つ以上のルーチンを分析する。コンストラクタ２１０は、まず、それらのバイナリ（機械）コードを抽出し、マシンコードを逆アセンブルして、ルーチンのアセンブラコードを提供することにより、ルーチンを分析してもよい。コンストラクタ２１０は、ルーチンをさらに分析して、データ要素、例えば、変数、構造体、配列および／またはそれらに類するものへのポインタの、１つ以上のスタックへのプッシュ命令およびそれぞれの対応するスタックからのポップ命令を特定してもよい。
【００７７】
コンストラクタ２１０は、それぞれのルーチンに対応するシンボルテーブルエントリの情報を使用して、中間コードファイルから１つ以上のルーチンのバイナリコードを抽出してもよい。次に、コンストラクタ２１０は、ルーチンのバイナリコードをアセンブラ命令に分解し、アセンブラ命令を分析するために、１つ以上の中間コードファイルの逆アセンブル方法、技術、および／またはツールを適用してもよい。例えば、コンストラクタ２１０は、「ｐｙｅｌｆｔｏｏｌｓ」ツールを利用して、それぞれのルーチンのコードを機械コードとして抽出してもよい。コンストラクタ２１０は、抽出された機械コードを逆アセンブルするために、１つ以上のツール、例えば「Ｃａｐｓｔｏｎｅ  Ｄｉｓａｓｓｅｍｂｌｅｒ」および／またはそれらに類するものを適用してもよい。
【００７８】
リターンアドレスのスタックへのプッシュ命令およびリターンアドレスのスタックからのポップ命令の構文および／またはオペコードは、プロセッサアーキテクチャおよび／または命令セットの間で異なりうる。したがって、コンストラクタ２１０は、１つ以上の中間コードファイルを生成するために選択されたプロセッサアーキテクチャおよび命令セットの構文に従って、リターンアドレスのスタックへのプッシュ命令およびリターンアドレスのスタックからのポップ命令を特定するためにルーチンを分析するように適合されてもよい。例えば、プロセッサアーキテクチャがＡＲＭ−Ｔｈｕｍｂアーキテクチャであると仮定すると、コンストラクタ２１０は、例えば、ＰＵＳＨ  ｛ＲｅｇｉｓｔｅｒＮａｍｅ１，．．．，ＲｅｇｉｓｔｅｒＮａｍｅＮ｝、ＳＴＭＦＤ  ＳＰ！、｛ＲｅｇｉｓｔｅｒＮａｍｅ１，．．．，ＲｅｇｉｓｔｅｒＮａｍｅＮ｝、ＳＴＭＩＡ  ＳＰ！、｛ＲｅｇｉｓｔｅｒＮａｍｅ１，．．．，ＲｅｇｉｓｔｅｒＮａｍｅＮ｝などの１つ以上のＡＲＭ−Ｔｈｕｍｂオペコードによって実装されたスタックへのプッシュ命令を特定するために、逆アセンブルされたそれぞれのルーチンを検索してもよい。プロセッサアーキテクチャのいくつか、例えば、ｘ８６アーキテクチャでは、リターンアドレスは、コード中に特定のスタックへのプッシュ命令が存在しない状態で、自動的にスタックにプッシュされてもよい。そのような場合、コンストラクタ２１０は、ベースポインタをスタックにプッシュする命令を特定してもよい。
【００７９】
さらに、コンストラクタ２１０は、リターンアドレスのスタックへのプッシュ命令を検出するために、１つ以上のルーチンの開始時に所定の数の命令を反復処理するように適合されてもよい。コンストラクタ２１０が、あるルーチンの先頭でリターンアドレスのスタックへのプッシュ命令を検出しない場合、コンストラクタ２１０は、あるルーチンが、他のルーチンへの呼び出し（分岐）を行わない「葉」のルーチンであり、したがって、スタックへのプッシュ命令および対応するスタックからのポップ命令を含まないと決定してもよい。このように、特定のルーチンは、スタックオーバーランエクスプロイトの影響を受けない可能性があり、コンストラクタ２１０は、それに応じて特定のルーチンをマークしてもよく、すなわち、特定のルーチンにＲＡＰ手段（ロジック）を適用する必要がないと判断してもよい。
【００８０】
複数のルーチンの１つ以上は、単一のエントリポイントを有する一方で、ルーチンのエントリポイントでスタックからのプッシュ命令によってスタックにプッシュされたリターンアドレスに分岐することにより、ルーチンが呼び出し元のルーチンに戻ることができる複数のエンドポイントを含みうる。したがって、コンストラクタ２１０は、ルーチンのすべてのエンドポイントでリターンアドレスのスタックからのポップ命令を特定するように、１つ以上のルーチンのアセンブラコードを分析してもよい。
【００８１】
コンストラクタ２１０は、まず、特定されたリターンアドレスのスタックへのプッシュ命令を分析して、リターンアドレスが占有するスタック内の場所を特定してもよい。次に、コンストラクタ２１０は、ルーチンのアセンブラ命令に亘って反復して、スタックからリターンアドレスを使用するように構成された命令を特定してもよい。コンストラクタ２１０は、現在のスタックポインタの値とリターンアドレスの位置からの距離を保持し、スタックポインタに影響を与えるそれぞれの命令により現在のスタックポインタの値を更新することによってこれを達成してもよい。したがって、コンストラクタ２１０は、プッシュされたリターンアドレスを使用するそれぞれの命令を検出し、この命令をリターンアドレスのスタックからのポップ命令として特定してもよい。
【００８２】
ルーチンの１つ以上は、プロセッサが同じルーチン内の別の場所に分岐するように指示されうる内部分岐を含んでもよい。したがって、コンストラクタ２１０は、潜在的なリターンアドレスのスタックからのポップ命令をチェックするために、内部分岐の分岐対象位置をさらに分析するように適合されてもよい。
【００８３】
当然のことながら、コンストラクタ２１０は、既に分析されたコードセクションの再分析を避けるために、分析されたルーチンおよび／またはその一部の記録を保持する。
【００８４】
コンストラクタ２１０は、１つ以上の中間コードファイルの１つ以上の関連ルーチン、すなわちそのような命令が存在する１つ以上のルーチンにおいて特定された、リターンアドレスのスタックへのプッシュ命令およびリターンアドレスのスタックからのポップ命令が特定された位置をマークしてもよい。
【００８５】
１０８に示されるように、コンストラクタ２１０は、リターンアドレスのスタックへのプッシュ命令／スタックからのポップ命令が特定され、ＲＡＰ手段（ロジック）を含むようにマークされた複数のルーチンの１つまたは複数を調整することによって、１つ以上の中間コードファイルを調整してもよい。具体的には、コンストラクタ２１０は、特定されたリターンアドレスのスタックへのプッシュ命令をプロローグコードセグメントに置き換えるとともに、それぞれの特定されたリターンアドレスのスタックからのポップ命令を対応するエピローグコードセグメントに置き換えることによって、それぞれのそのようなルーチンを調整する。
【００８６】
コンストラクタ２１０は、１つ以上のコーディング方法、技術、および／または実装を使用して、リターンアドレスのスタックへのプッシュ命令および／または１つ以上のリターンアドレスのスタックからポップ命令をそれぞれ置き換えるために、１つ以上のプロローグコードセグメントおよび／またはエピローグコードセグメントを追加してもよい。例えば、コンストラクタ２１０は、リターンアドレスのスタックへのプッシュ命令および／または１つ以上のリターンアドレスのスタックからのポップ命令のそれぞれを、プッシュおよびポップアドレス動作の間にそれぞれの追加のコードセグメントを呼び出すように構成されたトランポリン分岐関数で置き換えてもよい。追加されたコードセグメントを１つ以上の調整された中間コードファイルに挿入する前に、コンストラクタ２１０は、追加された１つ以上のコードセグメントをホストするための十分な利用可能なリソース、例えば、ストレージ空間および／またはそれらに類するものがあることを確認してもよい。しかしながら、追加されたコードセグメントは、典型的には非常に単純なロジックで構成されるので、追加されたコードセグメントのフットプリントは著しく小さくなりうるので、調整された１つ以上の中間コードファイルに統合することにおける制限をなくしうる。
【００８７】
リターンアドレスのスタックへのプッシュ命令を置き換えるプロローグコードセグメントは、リターンアドレスがスタックにプッシュされた後にスタックを変更するように構成されており、したがって、スタックからのリターンアドレスのポップ命令を置き換えるそれぞれのプロローグコードセグメントによって後で検証されうる一意的なシグネチャを作成する。実行時の間、１つ以上のプロセッサが調整された中間コードファイルを使用して生成された実行可能ファイルを実行するとき、エピローグコードセグメントは、それぞれのプロローグコードセグメントによってスタックにプッシュされたリターンアドレスを取得するためにスタックにアクセスし、それぞれのプロローグコードセグメントによってなされたスタック変更を検証してもよい。エピローグコードセグメントがスタック変更を検証することができる場合、エピローグコードセグメントは、プロセッサに対して、取得されたリターンアドレスに分岐することを許可してもよい。しかしながら、エピローグコードセグメントがスタック変更を検証できない場合、エピローグコードセグメントは、プロセッサに１つ以上の事前定義された動作を開始させてもよい。事前定義された動作は、例えば、プロセッサの実行をクラッシュさせること、プロセッサの実行を停止させること、プロセッサを事前定義されたアドレスに分岐させること、破損したスタックを対象とした少なくとも１つの潜在的に悪意のあるコード命令をプロセッサが実行することを防止すること、無効なスタック変更の１つ以上の表示および／または警告を発生させること、および／またはそれらに類するものを含んでもよい。事前定義された動作は、実行フローの１つ以上のパラメータ、例えば、プロセッサアーキテクチャ、それぞれのルーチンの重大度および／または重要度、ユーザ定義パラメータおよび／またはそれらに類するものに応じて選択されてもよい。
【００８８】
コンストラクタ２１０は、プロローグコードセグメントおよびエピローグコードセグメントを構成するための１つ以上の方法、技術および／または実装を適用して、スタック変更を適用し、スタック変更を復元するように、１つ以上の方法、技術および／または実装をそれぞれ適用してもよい。
【００８９】
第１の例示的な実施形態では、プロローグコードセグメントは、それぞれのエピローグコードセグメントが、変更されたリターンアドレスから元々プッシュされたリターンアドレスを復元しうるような可逆的な方法でスタックにプッシュされたリターンアドレスを修正することによってスタックを変更するように構成されてもよい。プロローグコードセグメントは、スタックにプッシュされたリターンアドレスを読み取り、可逆的な方法でリターンアドレスを変更する、例えば、リターンアドレスを暗号化し、変更されたリターンアドレスをスタックにプッシュして戻すように構成されてもよい。プロローグコードセグメントは、１つ以上の数学演算子、論理演算子、および／またはそれらに類するものを元々プッシュされたリターンアドレスに適用することにより、リターンアドレスを変更してもよい。例えば、プロローグコードセグメントは、リターンアドレスにランダムに選択される定数値とのＸＯＲ演算を適用することによってリターンアドレスを変更するように構成されてもよい。ランダムに選択される定数値は、例えば、乱数発生器を使用して生成されてもよい。別の例では、ランダムに選択される定数値は、非常に多数のランダム値を備えるデータセットからランダムに選択されてもよい。
【００９０】
それぞれのエピローグコードセグメントは、それぞれのプロローグコードセグメントによってなされた操作を逆にすることによって、最初にプッシュされたリターンアドレスを、変更されたリターンアドレスから復元および／または復号するように構成されてもよい。例えば、プロローグコードセグメントが、ランダムに選択された定数値でリターンアドレスをＸＯＲするように構成されていると仮定すると、エピローグコードセグメントは、元々プッシュされたリターンアドレスを復元するために、（プロローグコードセグメントによって使用された）同じ定数値で変更されたリターンアドレスをＸＯＲするように構成されてもよい。それぞれのエピローグコードセグメントは、スタックから取得された（ポップされた）リターンアドレスに分岐する前に、復元されたリターンアドレスを検証するようにさらに構成されてもよい。例えば、それぞれのエピローグコードセグメントの１つ以上は、取得されたリターンアドレスが、中間コードファイルにコード化されたプログラムコードの有効なアドレス範囲内にあることを検証してもよい。
【００９１】
実行時の間、変更されたスタックの一意的なシグネチャとして機能するランダムに選択された定数値は、スタックから取得されたリターンアドレスに分岐する前に、エピローグコードセグメントによって検証されてもよい。追加されたプロローグおよびエピローグコードセグメントが、調整された中間コードファイルを使用して作成された実行ファイルを実行するプロセッサのアーキテクチャ、命令セットおよび／またはオペレーティングシステムに不可知であるようにするために、ＸＯＲ操作に使用されるランダムに選択された定数値は、スレッドの安全性を確保するために、グローバル定数として定義されてもよい。しかしながら、セキュリティを高めるために、ランダムに選択された定数値は、例えば、実行可能ファイルを実行しているプロセッサのすべての起動シーケンス（ブート）の間、プロローグコードセグメントの最初の呼び出しの間、および／またはそれらに類するものの間にランダムに選択されるような、一過性のものであってもよく、頻繁に置き換えられてもよい。
【００９２】
第２の例示的な実施形態では、プロローグコードセグメントは、スタックカナリアを使用してスタックを変更するように構成されてもよく、すなわち、それぞれのエピローグコードセグメントがスタックにプッシュされたマーカの値を検証するように、プッシュされたリターンアドレスの位置に隣接する位置にあるスタックにマーカ（カナリア）をプッシュするように構成されてもよい。マーカが押されるスタック内の隣接する位置は、スタック内のプッシュされたリターンアドレスの位置に先行するか、またはプッシュされたリターンアドレスの位置に後続してもよい。例えば、スタックが、プッシュ命令ごとにスタックアドレスがデクリメントされる完全な降順スタック実装を採用している場合、マーカは、プッシュされたリターンアドレスのアドレスに先行するアドレス位置にプッシュされてもよい。別の例では、スタックが、プッシュ命令ごとにスタックアドレスがインクリメントする完全な昇順スタック実装を採用している場合、マーカは、プッシュされたリターンアドレスのアドレスに続くアドレス位置にプッシュされてもよい。具体的には、プロローグコードセグメントは、定数値マーカをスタック内の隣接する位置に挿入するように構成されてもよく、一方、それぞれのエピローグコードセグメントは、プロローグコードセグメントによってスタックにプッシュされたマーカの値を検証するように構成されてもよい。定数値マーカは、乱数発生器、例えば、ハードウェア真乱数発生器（ＴＲＮＧ）、ソフトウェア擬似乱数発生器（ＰＲＮＧ）および／またはそれらに類するものを使用して生成されてもよい。別の例では、定数値マーカは、非常に多数の乱数値を備えるデータセットからランダムに選択されてもよい。
【００９３】
前の例示的なスタック変更の実施形態でＸＯＲ演算に使用されるランダムに選択された定数値について説明したように、追加されたプロローグコードセグメントおよびエピローグコードセグメントをプロセッサのアーキテクチャ、命令セットおよび／またはオペレーティングシステムに不可知であるようにするために、プロローグコードセグメントによって挿入され、エピローグコードセグメントによって検証される定数値マーカは、スレッドの安全性を確保するために、グローバル定数として定義されてもよい。同様に、安全性を高めるために、定数値マーカは、例えば、実行可能ファイルを実行しているプロセッサのすべての起動シーケンス（ブート）の間、プロローグコードセグメントの最初の呼び出しの間、および／またはそれらに類するものの間にランダムに選択されるような、一過性のものであってもよく、頻繁に交換されてもよい。
【００９４】
実行時に、変更されたスタックの一意的なシグネチャとして機能するプッシュされた定数値マーカは、スタックから取得されたリターンアドレスに分岐する前に、エピローグコードセグメントによって検証されてもよい。マーカはスタックにプッシュされるので、スタックポインタからの調整されたルーチンのいくつかのパラメータの距離が変更されてもよいので、コンパイルフェーズの間に設定されたスタックレイアウトが変更されうる。したがって、コンストラクタ２１０は、調整されたルーチンの逆アセンブルされたコードを分析して、スタック内のこれらのパラメータにアクセスする命令を検索し、スタック内の正しいオフセットにアクセスするようにこれらの命令を修正してもよい。例えば、中間コードファイルがＡＲＭアーキテクチャおよび命令セット用にコンパイルされていると仮定すると、コンストラクタ２１０は、「ｌｄｒ  Ｒｎ，  ［ｓｐ  ＃ｏｆｆｓｅｔ］」命令を検索してもよく、ここで「ｓｐ」はスタックポインタである。次に、コンストラクタ２１０は、スタックの新しいレイアウトに従って、すなわち、スタックポインタからのそれぞれのパラメータの新しい距離に従って、「＃ｏｆｆｓｅｔ」の値を修正してもよい。
【００９５】
中間コードファイル内の１つ以上のルーチンで特定され、およびマークされたリターンアドレスのスタックへの１つ以上のプッシュ命令は、１つ以上のデータ項目をスタックにプッシュすることに関連付けられてもよい。したがって、コンストラクタ２１０は、追加されたプロローグコードセグメントが、データ項目をスタックにプッシュすることに応じて、そのようなリターンアドレスのスタックへのプッシュ命令を置き換えるように構成してもよい。例えば、トランポリン分岐関数が、１つ以上のデータのスタックへのプッシュ命令を備える特定のルーチンに特定のプロローグコードセグメントを挿入するために適用されると仮定する。コンストラクタ２１０は、特定のプロローグコードセグメントの実行の完了後にデータのスタックへのプッシュ命令が行われるように、リターンアドレスのスタックへのプッシュ命令をデータのスタックへのプッシュ命令から分離するように、特定のプロローグコードセグメントを構成してもよい。補完的に、そのようなリターンアドレスのスタックへのプッシュ命令に対応するリターンアドレスのスタックへのプッシュ命令は、スタックからリターンアドレスを取得しながら、プッシュされたデータ項目を取得してもよい。したがって、コンストラクタ２１０は、対応するプロローグコードセグメントによってスタックにプッシュされたデータ項目を取得するために、リターンアドレスのスタックからのポップ命令を適宜置き換えるように、追加されたそれぞれのエピローグコードセグメントを構成してもよい。提示された例を続けると、トランポリン分岐関数が、１つ以上のデータのスタックへのプッシュ命令を備える特定のルーチンで挿入された特定のプロローグコードセグメントに対応する特定のエピローグコードセグメントを挿入するように適用されていると仮定する。コンストラクタ２１０は、特定のエピローグコードセグメントの実行に先立ってデータのスタックからポップが行われるように、データのスタックからのポップ命令からリターンアドレスのスタックからのポップ命令を分離するように、特定のエピローグコードセグメントを構成してもよい。
【００９６】
１１０で示されるように、コンストラクタ２１０は、１つ以上のプロローグコードセグメント、１つ以上のエピローグコードセグメント、および／またはマーカを含むように行われた１つ以上の中間コードファイルの調整によって影響を受ける１つ以上の中間コードファイルのデータ、１つ以上の命令、１つ以上のシンボルテーブル、および／または１つ以上の属性を修正する。
【００９７】
例えば、１つ以上の中間コードファイルのコンパイル中に定義された１つ以上の中間コードファイル内の調整されたルーチンの１つ以上のレイアウトは、追加されたコードセグメントおよび／またはマーカの挿入により変更されてもよく、それにより、１つ以上の調整されたルーチン内の１つ以上の命令および／またはデータ項目の相対的な位置が変更されてもよい。したがって、コンストラクタ２１０は、１つ以上の他の命令および／または１つ以上の他のデータ項目への１つ以上の参照および／または１つ以上のポインタを備える命令および／またはデータ項目を検索するために、１つ以上のルーチンの逆アセンブルされたコードを分析してもよい。コンストラクタ２１０は、１つ以上の検出された参照および／または１つ以上のポインタを調整し、追加されたコードセグメントおよび／またはマーカの挿入後の１つ以上のルーチンの新しいレイアウトに従って更新してもよい。例えば、１つ以上の中間コードファイルがＡＲＭアーキテクチャおよび命令セット用にコンパイルされていると仮定すると、コンストラクタ２１０は、ルーチンのレイアウトの変更によって影響を受ける可能性のある「ＬＤＲ  Ｒｎ，  ［ｐｃ  ＃ｏｆｆｓｅｔ］」を検索してもよい。次に、調整器は、プログラムカウンタである「ｐｃ」に関して正しい位置を指すように、調整されたルーチンの新しいレイアウトに従って「＃ｏｆｆｓｅｔ」を修正（更新）してもよい。
【００９８】
別の例では、コンストラクタ２１０は、追加されたコードセグメントおよび／またはマーカの挿入によって調整された１つ以上のルーチンに適用された変更を反映するように、１つ以上の調整されたルーチンのシンボルテーブルを修正してもよい。例えば、コンストラクタ２１０は、追加されたコードセグメントのシンボルを含むようにシンボルテーブルを更新してもよい。コンストラクタ２１０は、追加されたコードセグメントおよび／またはマーカの挿入によって変更されたかもしれない１つ以上の調整されたルーチンのアドレス位置を反映するように、シンボルテーブルをさらに修正してもよい。
【００９９】
さらに、追加されたコードセグメントの挿入およびマーカの挿入は、それぞれの中間コードファイルのサイズを膨らませるかもしれない。したがって、コンストラクタ２１０は、１つ以上の調整された中間コードファイルの１つ以上の属性、例えば、ファイルサイズおよび／またはそれらに類するものを修正するように、１つ以上の調整された中間コードファイルを調整してもよい。例えば、１つ以上の中間コードファイルがＥＬＦ形式であると仮定して、コンストラクタ２１０は、追加されたコードセグメントおよび／またはマーカの挿入後の１つ以上の中間コードファイルの１つ以上のルーチンにおける新しいオフセットおよびアライメントを反映するように、１つ以上のＥＬＦファイルのヘッダを調整してもよい。
【０１００】
コンストラクタ２１０は、追加されたコードおよび／または１つ以上のマーカを、１つ以上の調整された中間ファイル自体に含ませてもよい。さらに、および／または代替的に、コンストラクタ２１０は、追加されたコードおよび／または１つ以上のマーカを、１つ以上の追加の中間コードファイルに含ませてもよい。１つ以上の追加の中間コードファイルは、１つ以上の実行可能ファイルの生成、ビルドおよび／またはリンクのために、１つ以上の調整された中間コードファイルとともに提供されてもよい。
【０１０１】
コンストラクタ２１０はまた、例えばトランポリン分岐関数を使用して実装された追加コードセグメントへの分岐が、追加コードセグメントおよび／またはマーカの挿入によって必然的に伴われる変更を反映するように１つ以上の中間コードファイルが調整された後に、ビルドおよび／またはリンクに対して有効であることを検証してもよい。例えば、コンストラクタ２１０は、それぞれの分岐に対して、再配置エントリが事前定義された名前を備える追加されたコードセグメントの１つに再配置エントリを追加してもよい。再配置エントリは、１つ以上の分岐関数を含む１つ以上のコードセクションのための再配置を記述する再配置セクションに追加されてもよい。そのようなコードセクションが存在しない場合、再配置エントリを作成し、中間ファイル内の既存のセクションに追加してもよい。追加されたコードセグメントは、追加されたコードセグメントを含むように作成された追加の中間コードファイルの１つ以上において、同じ事前定義された名前でコンパイルされてもよい。
【０１０２】
１１２で示されるように、コンストラクタ２１０は、１つ以上のプロセッサによって実行されうる１つ以上の実行可能ファイルを生成、ビルドおよび／またはリンクするために使用されうる１つ以上の調整された中間コードファイルを出力してもよい。例えば、コンストラクタ２１０は、１つ以上の実行可能ファイルを生成するために、１つ以上の調整された中間コードファイルから１つ以上の実行可能ファイルを生成するように、１つ以上のアプリケーション、ツール、および／またはそれらに類するもの、例えばリンカ、コードビルダ、および／またはそれらに類するものを使用しうるリモートネットワークリソースの１つまたは複数に、１つ以上の中間コードファイルを送信してもよい。別の例では、コンストラクタ２１０は、１つ以上の中間コードファイルをストレージ２０６に格納してもよく、そこから、１つ以上の中間コードファイルが、実行可能ファイルを作成するための１つ以上のアプリケーション、ツール、および／または、例えば、リンカ、コードビルダ、および／または、１つ以上の実行可能ファイルを作成するためのそれらに類するものによって取得されてもよい。別の例では、コンストラクタ２１０は、１つ以上の中間コードファイルが、１つ以上の実行可能ファイルを作成するための１つ以上のアプリケーション、ツールおよび／またはそれに類するもの、例えば、リンカ、コードビルダおよび／または１つ以上の実行可能ファイルを作成するためのそれらに類するものによって取得されうる別のシステムに接続されてもよい取り付け可能な記憶装置の１つ以上に、１つ以上の中間コードファイルを格納してもよい。
【０１０３】
本発明のいくつかの実施形態によれば、ＲＯＰエクスプロイトを防止するために中間コードファイルの１つ以上を調整するための方法、システム、およびコンピュータプログラム製品が提供される。本明細書に上述されているように、実行時において、悪意のある者は、プロセッサの制御を獲得する試みにおいて、中間ファイル内のルーチン内に埋め込まれた１つ以上のガジェットを呼び出すようにプロセッサに迂回させるようにＲＯＰをエクスプロイトしうる。ＲＯＰのエクスプロイトの防止を適用するために、中間コードファイルは、ガジェットを呼び出す可能性のある無効な分岐操作を特定するためのＲＯＰエクスプロイト防止ロジックを含むように調整されてもよい。実行時に悪意のある者が揮発性メモリリソースのみを操作する可能性があるため、ＲＯＰエクスプロイト防止ロジックは通常、揮発性メモリリソース（スタック、ヒープ、レジスタなど）から分岐アドレスを取得する間接分岐動作に適用されてもよい。分岐アドレスがハードコードされている直接分岐動作は、分岐アドレスが揮発性メモリリソースから取得されないため、ＲＯＰエクスプロイトの影響を受けない場合がある。したがって、ＲＯＰエクスプロイト防止ロジックは必要とされないこともあり、直接分岐動作には適用されないこともある。
【０１０４】
本発明のいくつかの実施形態に従った、リターン指向プログラミングエクスプロイトに対する保護を適用するように中間コードファイルを調整する例示的なプロセスのフローチャートである図３を参照されたい。例示的な工程３００は、ＲＯＰを防止するように構成されたコードを含むように中間コードファイルの１つ以上を調整するために、構築システム２００のような構築システムによって実行されるコンストラクタ２１０のような調整器によって実行されてもよい。
【０１０５】
３０２に示されるように、工程３００は、工程１００のステップ１０２で説明したように、コンストラクタ２１０が１つ以上の中間コードファイルを取得することから始まる。
【０１０６】
３０４に示されるように、コンストラクタ２１０は、工程１００のステップ１０４に記載されるように、中間コードファイルのすべてのルーチンを特定するために、中間コードファイルのそれぞれを分析する。
【０１０７】
３０６で示されるように、コンストラクタ２１０は、工程１００のステップ１０６に記載されているように、１つ以上の中間コードファイルのそれぞれのルーチンの複数のルーチンの１つ以上を分析して、ルーチン内の間接的な分岐を特定する。
【０１０８】
３０８で示されるように、コンストラクタ２１０は、間接分岐が特定され、ＲＯＰエクスプロイト防止手段（ロジック）を含むようにマークされたルーチンの１つ以上を調整することによって、１つ以上の中間コードファイルを調整してもよい。具体的には、コンストラクタ２１０は、特定された間接分岐を、それぞれの検証コードセグメントの呼び出しに置き換えることによって、そのようなルーチンをそれぞれ調整する。コンストラクタ２１０は、間接分岐を検証コードセグメントの呼び出しに置き換えるための１つ以上の符号化方法、技術および／または実装を適用してもよい。例えば、コンストラクタ２１０は、実行時に、間接分岐を実行する代わりに検証コードセグメントが呼び出されて実行されるように、追加された１つ以上の検証コードセグメントのアドレス位置を指すそれぞれの直接分岐に１つ以上の間接分岐命令を置き換えてもよい。検証コードセグメントは、例えば、トランポリン関数を使用して実装されてもよい。ステップ１０８で説明したように、追加された１つ以上の検証コードセグメントを１つ以上の調整された中間コードファイルに挿入する前に、コンストラクタ２１０は、追加されたコードセグメントをホスティングするための十分な利用可能なリソース、例えばストレージ空間および／またはそれらに類するものがあるかどうかを検証してもよい。しかしながら、追加されたコードセグメントは、典型的には非常に単純なロジックで構成されるので、追加されたコードセグメントのフットプリントは著しく小さくてもよく、したがって、追加されたコードセグメントを調整された中間コードファイルに統合することにおける制限をなくしうる。
【０１０９】
コンストラクタ２１０は、それぞれの検証コードセグメントが、それぞれの間接分岐命令によって指されたルーチンシンボルおよび／またはアドレスを取得するように構成してもよい。コンストラクタ２１０は、それぞれの間接分岐命令によって指摘されたルーチンシンボルおよび／またはアドレスが、有効なルーチンの始まりであるアドレス位置、すなわち1つ以上の中間コードファイルの複数のルーチンの１つを指していることを検証するように、検証コードセグメントをさらに構成してもよい。
【０１１０】
１つ以上の実施形態および／または技術は、分岐アドレス、すなわち、１つ以上の間接分岐命令によって指されるルーチンのシンボルおよび／またはアドレスを、検証コードセグメントに適用または転用してもよい。例えば、分岐アドレスは、呼び出されたときに検証コードセグメントがスタックから分岐アドレスを取得（読み出し、ポップなど）できるように、スタックにプッシュされてもよい。このために、コンストラクタ２１０は、それぞれの間接分岐命令に含まれる分岐アドレスをプッシュするためのスタックへのプッシュ命令を追加してもよく、追加されたスタックへのプッシュ命令を、それぞれの間接分岐命令を置き換えるために挿入された直接分岐命令の前に配置してもよい。別の例では、分岐アドレスは、コードを実行するプロセッサの事前に決定されたレジスタに書き込まれてもよく、そのようにして、呼び出されたときに、検証コードセグメントは、分岐アドレスを取得するために事前に決定されたレジスタにアクセスしてもよい。この目的のために、コンストラクタ２１０は、事前に決定されたレジスタにそれぞれの間接分岐命令に含まれる分岐アドレスを書き込むための書き込み命令を追加してもよく、追加された書き込み命令を、それぞれの間接分岐命令を置き換えるために挿入された直接分岐命令の前に配置してもよい。別の例では、分岐アドレスは、呼び出されたときに検証コードセグメントが事前定義された変数にアクセスして分岐アドレスを取得することができるように、コードを実行するプロセッサのメモリに格納されている事前定義された変数（および／または構造体）に書き込まれてもよい。この目的のために、コンストラクタ２１０は、事前定義された変数を初期化し、それぞれの間接分岐命令に含まれる分岐アドレスを事前定義された変数に書き込むための書き込み命令を追加し、追加された書き込み命令を、それぞれの間接分岐命令を置き換えるために挿入された直接分岐命令の前に配置してもよい。
【０１１１】
実行時の間、１つ以上のプロセッサが、調整された中間コードファイルを使用して生成された実行可能ファイルを実行するとき、検証コードセグメントは、まず、それぞれの間接分岐によって指されたルーチンシンボルおよび／またはアドレス（分岐アドレス）を取得し、それが有効なルーチンの先頭（アドレス）を指していることを検証してもよい。検証コードセグメントは、分岐が有効なルーチンの先頭に導かれていることを検証することができる場合、検証コードセグメントは、１つ以上のプロセッサが分岐アドレスに分岐することを許可してもよい。しかし、検証コードセグメントは、分岐が有効なルーチンの先頭に導かれていることを検証できない場合、検証コードセグメントは、間接分岐が無効であると判断し、プロセッサに１つ以上の事前定義された動作を開始させることができる。事前定義された動作には、例えば、プロセッサの実行をクラッシュさせること、プロセッサの実行を停止させること、プロセッサが事前定義されたアドレスに分岐させること、プロセッサにガジェットの実行を阻止させること、プロセッサが無効な分岐の１つ以上の指示を生成すること、および／またはそれらに類するものが含まれてもよい。事前定義された動作は、実行フローの１つ以上のパラメータ、例えば、プロセッサアーキテクチャ、それぞれのルーチンの重大度および／または重要度、ユーザ定義パラメータおよび／またはそれらに類するものに応じて選択されてもよい。
【０１１２】
コンストラクタ２１０は、それぞれの間接分岐によって指されたルーチンシンボルおよび／またはアドレスが有効なルーチンの先頭であることを検証するように、検証コードセグメントを構成するための１つ以上の方法、技術、および／または実装を適用してもよい。
【０１１３】
第１の例示的な実施形態では、コンストラクタ２１０は、１つ以上の中間コードファイルのそれぞれの複数のルーチンのそれぞれを、それぞれのルーチンの先頭のアドレス位置に先行するアドレス位置に挿入（追加）された一意的なコードと関連付けることができる。具体的には、コンストラクタ２１０は、ステップ３０６のアセンブラコード分析中に間接分岐が特定されるそれぞれのルーチンに一意的なコードを関連付ける。任意選択で、コンストラクタ２１０は、複数のルーチンを共通の、すなわち類似した一意的なコードに関連付けてもよい。例えば、コンストラクタ２１０は、１つ以上の有効なルーチンの先頭アドレスの直前のアドレスに一意的なコードを挿入してもよい。コンストラクタ２１０は、選択されたプロセッサのアーキテクチャおよび／または命令セットに応じて、一意的なコードを挿入するための正確なアドレスを選択してもよい。例えば、プロセッサのアーキテクチャが４バイトのネイティブ「ワード」粒度を有する３２ビット命令セットを実装する３２ビットであると仮定すると、コンストラクタ２１０は、一意的なコードをアドレス「先頭アドレス−４」に挿入してもよい。さらに、コンストラクタ２１０によって使用される一意的なコードは、１つ以上のプロセッサがそれを有効な命令として解釈することを防止し、それによって１つ以上のプロセッサの実行フローを変更することを防止するために、選択された１つ以上のプロセッサの命令セットの一部ではなくてもよい。さらに、コンストラクタ２１０によって挿入されるのではなく、１つ以上の中間コードファイルを生成したコンパイラによって挿入される一意的なコードの無関係な出現を防止するために、一意的なコードは、選択された１つ以上のプロセッサの命令セットの一部ではないように選択される。
【０１１４】
コンストラクタ２１０は、検証コードセグメントが、指定されたアドレス、例えば、間接分岐命令によって示された分岐アドレスに先行するアドレスから一意的なコードを最初に取得するように構成してもよい。前述の例に続いて、一意的なコードが「アドレス−先頭アドレス−４」に挿入される場合、コンストラクタ２１０は、一意的なコードを取得するために最初に「先頭アドレス−４」にアクセスするように検証コードセグメントを構成してもよい。コンストラクタ２１０は、一意的なコードの値を検証し、分岐アドレスが有効なルーチンの１つの先頭アドレスを指しているかどうかを適宜決定するように、検証コードセグメントをさらに構成してもよい。
【０１１５】
実行時の間、検証コードセグメントが一意的なコードの値を肯定的に検証した場合、検証コードセグメントは、間接分岐が有効なルーチンの先頭を指していると判断してもよい。しかし、検証コードセグメントが一意的なコードの値を正しく検証できなかった場合、検証コードセグメントは、間接分岐が有効なルーチンの先頭を指していないため、間接分岐が無効であると判断してもよい。
【０１１６】
第２の例示的な実施形態では、コンストラクタ２１０は、複数のルーチンのそれぞれの先頭アドレス、具体的には、ステップ３０６のアセンブラコード分析の間に間接分岐が特定されたそれぞれのルーチンの先頭アドレスをマッピングするためのデータセット、例えば、テーブル、リスト、および／またはそれらに類するものを構築してもよい。このように、データセットは、マッピングされたルーチンの１つにそれぞれ関連付けられ、それぞれのルーチンの先頭アドレスを格納する１つ以上のエントリを含むことができる。ルーチンの絶対アドレス、特にルーチンの先頭アドレスは、典型的には実行可能ファイルの生成段階の間、すなわちビルドおよび／またはリンクの後に設定される可能性があるので、中間コードファイルでは利用できないかもしれない。この制限を克服するために、コンストラクタ２１０は、データセット内にマッピングされたそれぞれのルーチンの再配置エントリを含むようにデータセットを構築してもよい。実行ファイルの生成、ビルドおよび／またはリンクの間、再配置エントリは、マッピングされたルーチンの実際の（絶対）先頭アドレスに置き換えられる。
【０１１７】
任意選択で、コンストラクタ２１０は、例えば、マッピングされたルーチンの絶対先頭アドレスに応じて、１つ以上の順序のソートスキームでエントリをソートすることにより、ルーチンエントリデータセットの配列を最適化する。並べ替えられたエントリは、並べ替えられたデータセットをトラバースする効率を大幅に向上させ、それ故に、データセットエントリ内にマッピングされたアドレスの１つとの一致を検索する処理時間を短縮することができる。ルーチンの絶対先頭アドレスは、１つ以上の実行可能ファイルの生成段階の前には利用できないかもしれないので、コンストラクタ２１０は、それぞれのデータセットエントリに、１つ以上のターゲットプロセッサの命令セットの一部ではない一意的なコード値を含ませてもよい。実行可能ファイルの生成、ビルドおよび／またはリンクの後、コンストラクタ２１０は、マッピングされたルーチンの絶対先頭アドレスを決定するために、実行可能ファイル、例えばＥＬＦ実行ファイル内の１つ以上の一意的なコードを検索してもよい。コンストラクタ２１０は、次に、データセットを更新し、マッピングされたルーチンの実際の先頭アドレスに従って、そのエントリを、例えば、昇順、降順、および／またはそれらに類する順序で並べ替えてもよい。
【０１１８】
コンストラクタ２１０は、ルーチンの先頭アドレスをマッピングするデータセットを含めるように、１つ以上の調整された中間コードファイルをさらに調整してもよい。追加的および／または代替的に、コンストラクタ２１０は、ルーチンの先頭アドレスをマッピングするデータセットを格納するための１つ以上の追加の中間コードファイルを生成する。１つ以上の追加の中間コードファイルは、最終的なビルドにデータセットを正しく含めるように、実行ファイルの生成、ビルドおよび／またはリンクの間に使用されてもよい。データセットの正確な実装と実行時の使用のための保存は，調整された中間コードファイルを用いて生成された実行ファイルが対象とするコンピューティングシステムの１つ以上のパラメータに従って選択されてもよい。
【０１１９】
コンストラクタ２１０は、検証コードセグメントが、まず、間接分岐命令によって示された分岐アドレスを、データセットに記載されたアドレスと比較して一致を検索し、分岐アドレスがマッピングされたルーチンの１つの先頭アドレスであるかどうかを、それに応じて決定するように構成されてもよい。
【０１２０】
実行時の間、検証コードセグメントは、分岐アドレスをデータセットのエントリに記載されているアドレスと比較する。分岐アドレスがデータセットに列挙されているアドレスのいずれかと一致する場合、検証コードセグメントは、間接分岐が有効なルーチンの先頭を指していると判断してもよい。しかし、分岐アドレスがデータセットに記載されているアドレスのいずれにも一致しない場合、検証コードセグメントは、間接分岐が有効なルーチンの先頭を指していないので、間接分岐は無効であると判断してもよい。前述したように、データセットは、そのエントリがソートされた状態で最適化されてもよい。したがって、検証コードセグメントは、一致するものを検索するために、実行時にソートされたデータセットをトラバースするための１つ以上の検索スキームを適用してもよい。これにより、検証コードセグメントのアクセス性能が大幅に改善され、その結果、検証コードセグメントが一致を検索するために必要とされる処理時間が大幅に短縮されてもよい。
【０１２１】
３１０で示されるように、コンストラクタ２１０は、工程１００のステップ１１０で説明されるように、検証コードセグメントを含めるために行われた１つ以上の中間コードファイルの調整によって影響を受ける１つ以上の中間コードファイルのデータ、１つ以上の命令、１つ以上のシンボルテーブル、および／または１つ以上の属性を修正する。
【０１２２】
３１２で示されるように、コンストラクタ２１０は、工程１００のステップ１１２で説明されるように、１つ以上のプロセッサによって実行されうる１つ以上の実行可能ファイルを生成、ビルドおよび／またはリンクするために使用されうる１つ以上の調整された中間コードファイルを出力してもよい。
【０１２３】
本出願から開始した特許の存続期間中に、多くの関連システム、方法、およびコンピュータプログラムが開発されることが予想され、中間コードファイル形式、中間コードファイル分析ツールという用語の範囲は、先験的にそのような新しい技術をすべて含むことを意図している。
【０１２４】
本明細書で使用されるように、用語「約」は、±１０％を指す。
【０１２５】
用語「備える」、「備えている」、「含む」、「含んでいる」、「有する」およびそれらの活用語は、「含むが、それに限定されない」ことを意味する。
【０１２６】
用語「からなる」は、「それを含み、かつ、それに限定されない」ことを意味する。
【０１２７】
本明細書で使用されるように、単数形の「ａ」、「ａｎ」および「ｔｈｅ」は、文脈が明確に指示しない限り、複数の参照を含む。例えば、用語「化合物」または「少なくとも１つの化合物」は、それらの混合物を含む複数の化合物を含むことができる。
【０１２８】
本出願を通して、本発明の様々な実施形態が範囲形式で示されてもよい。範囲形式での記述は、単に利便性と簡潔さのためのものであり、本発明の範囲に対する柔軟性のない制限として解釈されるべきではないことが理解されるべきである。したがって、範囲の記述は、その範囲内の個々の数値だけでなく、可能なすべての部分的範囲を具体的に開示したものとみなされるべきである。例えば、１から６までのような範囲の記述は、１から３まで、１から４まで、１から５まで、２から４まで、２から６まで、３から６までなどのような部分的範囲と、その範囲内の個々の数値、例えば、１、２、３、４、５、６などが具体的に開示されていると考えるべきである。これは範囲の広さに関係なく適用される。
【０１２９】
本明細書で数値範囲が示されている場合はいつでも、それは示された範囲内で引用される任意の数値（小数または整数）を含むことを意味している。本明細書では、第１の指示値と第２の指示値との「間の範囲に亘る／間の範囲」、および第１の指示値「から」第２の指示値「までの範囲に亘る／までの範囲」という表現が互換的に使用されており、第１および第２の指示値、ならびにその間の全ての小数および整数を含むことを意味している。
【０１３０】
明快さのために、別個の実施形態の文脈で説明されている本発明の特定の特徴は、単一の実施形態において組み合わせて提供されてもよいことが理解される。逆に、簡潔さのために、単一の実施形態の文脈で説明されている本発明の様々な特徴は、別個に、または任意の適切な部分的な組み合わせで、または本発明の他の説明された実施形態において適切なように提供されてもよい。様々な実施形態の文脈で説明されている特定の特徴は、それらの要素なしでは実施形態が動作しない場合を除き、それらの実施形態の本質的な特徴とはみなされない。さらに、本出願の任意の優先権書類は、その／それらの全体が参照により本明細書に組み込まれる。
【図１】
2022502723.tif 000003
【図２】
2022502723.tif 000004
【図３】
2022502723.tif 000005
【国際調査報告】
2022502723.tif 000006
2022502723.tif 000007
2022502723.tif 000008