(57)【要約】  本発明は、複数の基本ブロックに編成されたコンピュータコード命令を備えたコンパイル済みのソフトウェアコード（ＳＣ）をセキュアにする方法に関し、前記方法は、セキュアなソフトウェアコード（ＳＳＣ）を生成し、・保護されるべきソフトウェアコードの部分を、プロセッサによって決定するステップ（Ｓ１）と、・命令の第１のシーケンスを、ソフトウェアコードの選択された基本ブロックに、プロセッサによって挿入するステップ（Ｓ２）であって、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、保護されるべきソフトウェアコードの前記部分における完全性チェック値を計算し、前記計算された完全性チェック値に基づいてインデクス値を計算する、ステップと、・メモリアドレスのインデクス付けされた配列を、ソフトウェアコードの選択された基本ブロックに、プロセッサによって挿入するステップ（Ｓ３）であって、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスが、前記インデクス値によってインデクス付けされる、ステップと、・ランタイムにおいて計算された前記インデクス値によって配列中でインデクス付けされたアドレスへのジャンプ命令を、ソフトウェアコードの選択された基本ブロックの最後に、プロセッサによって挿入するステップ（Ｓ４）とを備える。
2020505709.tif 000002
【特許請求の範囲】
【請求項１】
複数の基本ブロックに編成されたコンピュータコード命令を備えたコンパイル済みのソフトウェアコード（ＳＣ）をセキュアにする方法であって、セキュアなソフトウェアコード（ＳＳＣ）を生成し、
保護されるべきソフトウェアコードの部分を、プロセッサ（２１）によって決定するステップ（Ｓ１）と、
命令の第１のシーケンスを、ソフトウェアコードの選択された基本ブロックに、プロセッサによって挿入するステップ（Ｓ２）であって、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、
保護されるべきソフトウェアコードの前記部分における完全性チェック値を計算し（Ｅ１）、
前記計算された完全性チェック値に基づいてインデクス値を計算する（Ｅ２）、ステップと、
メモリアドレスのインデクス付けされた配列を、ソフトウェアコードの選択された基本ブロックに、プロセッサによって挿入するステップ（Ｓ３）であって、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスが、前記インデクス値によってインデクス付けされる、ステップと、
ランタイムにおいて計算された前記インデクス値によって、配列中でインデクス付けされたアドレスへのジャンプ命令を、ソフトウェアコードの選択された基本ブロックの最後に、プロセッサによって挿入するステップ（Ｓ４）と
を備えた、方法。
【請求項２】
保護されるべきソフトウェアコードの部分が、ランダムに決定される、請求項１に記載の方法。
【請求項３】
完全性チェック値が、保護されるべきソフトウェアコードの前記部分、および選択された基本ブロックの少なくとも部分において計算される、請求項１に記載の方法。
【請求項４】
命令の第１のシーケンスが、ランタイムにおいて実行されたとき、チェックサム、マスク、ハッシュ関数、バイナリシフト、および算術演算のうちの1つ以上の演算を実施することによって、前記完全性チェック値を計算する命令の第２のシーケンスを備えた、請求項１に記載の方法。
【請求項５】
前記命令の第２のシーケンスが、完全性チェック関数を計算する命令の所定のシーケンスのセットにおいてランダムに選択される、請求項１に記載の方法。
【請求項６】
命令の第１のシーケンスが、ランタイムにおいて実行されたとき、前記インデクス値を計算するために、変換関数を、前記計算された完全性チェック値に適用する命令の第３のシーケンスを備え、前記変換関数は、チェックサム、マスク、ハッシュ関数、バイナリシフト、および算術演算のうちの1つ以上の演算を備えた、請求項１に記載の方法。
【請求項７】
変換関数が、所定の変換関数のセットにおいてランダムに選択される、請求項６に記載の方法。
【請求項８】
配列におけるアドレスが、セキュアなソフトウェアコードが実行されたときにおけるセキュアなソフトウェアコードの基本ブロックのアドレスである、請求項１に記載の方法。
【請求項９】
前記完全性チェック値が、開始アドレスと停止アドレスとの間のセキュアなソフトウェアコードの命令において計算され、
セキュアなソフトウェアコードをコンパイルおよびリンクしたときに、またはその後に実施される、第５のセキュアにするステップ（Ｓ５）であって、
完全性チェック値が計算されるべきソフトウェアコードの部分の開始および終了のソフトウェアコードにおける開始アドレスおよび終了アドレスを決定することと、
前記完全性チェック値、および、前記計算された完全性チェック値に基づいて前記インデクス値を計算することとを備えた、ステップと、
セキュアなソフトウェアコードをコンパイルおよびリンクしたときに、またはその後に実施される、第６のセキュアにするステップ（Ｓ６）であって、
前記開始アドレスおよび停止アドレスを、第５のセキュアにするステップにおいて決定された前記開始アドレスおよび終了アドレスに設定することと、
第５のセキュアにするステップにおいて計算された前記インデクス値で、後続する基本ブロックのアドレスを、配列中に設定することとを備えた、ステップと
を備えた、請求項１に記載の方法。
【請求項１０】
配列および命令の第１のシーケンスが、ソフトウェアコードの選択された基本ブロック内のランダムな位置に挿入される、請求項１に記載の方法。
【請求項１１】
命令の第１のシーケンスが、挿入されたジャンプ命令の前で、選択された基本ブロックの最後に挿入される、請求項１に記載の方法。
【請求項１２】
プロセッサによる実行のためのセキュアなソフトウェアコードの命令でエンコードされた非一時的機械可読記憶媒体であって、
前記セキュアなソフトウェアコードは、複数の基本ブロックに編成されたコンピュータコード命令を備えたソフトウェアコードの変更バージョンであり、
セキュアなソフトウェアコードの選択された基本ブロックは、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスを備えた、メモリアドレスのインデクス付けされた配列を備え、
前記非一時的機械可読記憶媒体は、セキュアなソフトウェアコードの選択された基本ブロックに挿入された、命令の第１のシーケンスを用いてエンコードもされ、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、
保護されるべきソフトウェアコードの部分における完全性チェック値を計算し（Ｅ１）、
前記計算された完全性チェック値に基づいて、後続する基本ブロックのアドレスを配列中でインデクス付けするインデクス値を計算し（Ｅ２）、
セキュアなソフトウェアコードの選択された基本ブロックは、その最後に、ランタイムにおいて計算された前記インデクス値によってインデクス付けされた配列のアドレスへのジャンプ命令も備えた、非一時的機械可読記憶媒体。
【請求項１３】
完全性チェック値が、保護されるべきソフトウェアコードの部分と、選択された基本ブロックの少なくとも部分とにおいて計算される、請求項１２に記載の非一時的機械可読記憶媒体。
【請求項１４】
セキュアなソフトウェアコードの選択された基本ブロックの命令をプロセッサ（３１）によって実行する方法であって、
前記セキュアなソフトウェアコードは、複数の基本ブロックに編成されたコンピュータコード命令を備えたソフトウェアコードの変更されたバージョンであり、
セキュアなソフトウェアコードの選択された基本ブロックは、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスを備えた、メモリアドレスのインデクス付けされた配列を備え、
前記方法は、
保護されるべきソフトウェアコードの部分における完全性チェック値を計算するステップ（Ｅ１）と、
前記計算された完全性チェック値に基づいて、後続する基本ブロックのアドレスを配列中でインデクス付けするインデクス値を計算するステップ（Ｅ２）と、
前記計算されたインデクス値によって配列中でインデクス付けされたアドレスへのジャンプ命令を、選択された基本ブロックの最後に実行するステップ（Ｅ３）と
を備えた、方法。
【請求項１５】
完全性チェック値が、保護されるべきソフトウェアコードの部分と、選択された基本ブロックの少なくとも部分とにおいて計算される、請求項１４に記載の方法。
【発明の詳細な説明】
【技術分野】
【０００１】
本発明は、ソフトウェア保護の分野に関し、より詳細には、改ざん防止技術の分野に関する。本発明は、完全性チェックに基づく、コンパイル済みのコードの静的解析に耐性がある改ざん防止方法を開示する。
【背景技術】
【０００２】
現在、ソフトウェアアプリケーションを作動させることにより、多くのサービスがユーザに提供される。このようなアプリケーションは、デスクトップコンピュータ、ラップトップ、店頭（ｐｏｉｎｔ  ｏｆ  ｓａｌｅ）端末、スマートフォンなど、モバイルまたはモバイル以外の様々なデバイスで作動する。このようなアプリケーションは、ローカルで作動することも、ＬＡＮやインターネットなどのネットワークを介して実装されることもできる。スマートカードや銀行のクレジットカードなどのいくつかのデバイスは、１つまたはいくつかのアプリケーションの作動専用になっている場合もある。このようなアプリケーションは通常、セキュアにされていない環境で作動させられ、そこでは、攻撃者は、アプリケーションを作動させているシステムの動作のいくつかを制御するか、または完全に制御することさえできる。この結果、これらのアプリケーションのほとんどは、アプリケーションによって取り扱われるデータが、このような攻撃者によって読み取られる、または変更されることを防ぐために、いくつかのセキュリティメカニズムを実装する必要がある。
【０００３】
攻撃者は、システムによって実行される、コンパイル済みのコードをリバースエンジニアリングすることによって、ソフトウェアの動作を理解しようとする場合がある。攻撃者は、その後、悪意のある動作を実施するために、ソフトウェアによって取り扱われるセキュアな情報にアクセスしたり、および／または、ソフトウェアを変更する可能性がある。たとえば、攻撃者は、悪意のある金融取引を実施するために、銀行業務ソフトウェアを変更したり、ライセンスを購入せずに無料で、ライセンスで保護されたソフトウェアを作動させるために、それを変更したりできる。このようなリバースエンジニアリングは通常、コードアナライザやデバッガなどのツールを使用して実施され、これらのツールは、コード内の命令の実行の順序を示す制御フローグラフなど、コードの動作に関する情報をコンパイル済みのコードから抽出する。
【０００４】
ソフトウェアコードのあらゆる変更を阻止するために、改ざん防止技術が開発された。改ざん防止技術は、たとえば、ソフトウェアコードの特定の領域でチェックサム値を計算し、次いで、取得した値を知られている参照値と比較することによって、コードのある部分において完全性チェックを実施することにしばしば依存する。値が一致しない場合、コードは改ざんされており、ソフトウェアの通常の実行を拒否するか、ふりをするかのいずれかにより、ソフトウェアの実行を阻止する必要がある。それにも関わらず、このような保護も、攻撃者によってリバースエンジニアリングされ、破壊される可能性がある。デバッガまたはコードアナライザにとって、変数の定数値への初期化と、改ざん防止プロセスによって実施される比較におけるこのような定数値の使用とを突き止めることは特に簡単である。この種の情報は、コードにおいて実装されている保護の種類を識別するために攻撃者によって使用される可能性があり、それで、これにより保護を破ることができる。たとえば、攻撃者は、完全性チェックが実施されるソフトウェアの領域の開始と終了を識別し、コードが変更されていないときに完全性チェックルーチンによってこの領域で計算されるチェックサム値を推定し、次いで、チェックサム値が計算されるソフトウェアの領域内であっても、ソフトウェアコードの他の変更に関係なく、常に有効なチェックサム値を提供するために、完全性チェックルーチンにパッチを当てることができる。
【発明の概要】
【発明が解決しようとする課題】
【０００５】
その結果、ソフトウェアコードのある部分で完全性チェックを実施し、保護されたコードの静的解析によって、このような方法がどのように機能するかを攻撃者が理解することを困難にし、このような攻撃者が、保護されたソフトウェアコードを成功裏に変更することを阻止する方法に対するニーズがある。
【課題を解決するための手段】
【０００６】
したがって、この目的のために、第１の態様によれば、本発明は、複数の基本ブロックに編成されたコンピュータコード命令を備えたコンパイル済みのソフトウェアコードをセキュアにする方法に関し、前記方法は、セキュアなソフトウェアコードを生成し：
・保護されるべきソフトウェアコードの部分を、プロセッサによって決定するステップと、
・命令の第１のシーケンスを、ソフトウェアコードの選択された基本ブロックに、プロセッサによって挿入するステップであって、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、保護されるべきソフトウェアコードの前記部分における完全性チェック値を計算し、前記計算された完全性チェック値に基づいてインデクス値を計算する、ステップと、
・メモリアドレスのインデクス付けされた配列を、ソフトウェアコードの選択された基本ブロックに、プロセッサによって挿入するステップであって、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスが、前記インデクス値によってインデクス付けされる、ステップと、
・ランタイムにおいて計算された前記インデクス値によって、配列中でインデクス付けされたアドレスへのジャンプ命令を、ソフトウェアコードの選択された基本ブロックの最後に、プロセッサによって挿入するステップと
を備えている。
【０００７】
保護されるべきソフトウェアコードの部分が改ざんされている場合、セキュアなソフトウェアコードの実行を中断させることにより、攻撃者による改ざんからソフトウェアコードを保護し、インデクス付けされた配列の他の候補ターゲットアドレスの中に、ジャンプ命令のターゲットを隠すことを可能にする。
【０００８】
実施形態では、保護されるべきソフトウェアコードの部分は、ランダムに決定される。保護されるべきコードのすべての部分を１つずつマニュアルで選択する必要なく、この方法を複数回適用することにより、コードの大部分を保護することができる。
【０００９】
実施形態では、完全性チェック値は、保護されるべきソフトウェアコードの前記部分、および選択された基本ブロックの少なくとも部分において計算される。これは、攻撃者が、完全性チェックが計算される選択された基本ブロックの部分に実行ブレークポイントを挿入することを阻止する。このような停止ポイントが、完全性チェックによって出力される値、または実行されるべき後続する基本ブロックのインデクスの値についての知識を獲得することを可能にする。
【００１０】
実施形態では、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、チェックサム、マスク、ハッシュ関数、バイナリシフト、および算術演算のうちの1つ以上の演算を実施することによって、前記完全性チェック値を計算する命令の第２のシーケンスを備えている。
【００１１】
実施形態において、前記命令の第２のシーケンスは、完全性チェック関数を計算する命令の所定のシーケンスのセットにおいてランダムに選択される。
【００１２】
これは、ランタイムにおいて完全性チェック値がどのように計算されるかを攻撃者が理解することを困難にする。これは、攻撃者が、コードのさらなる解析なしで、後続する正しい基本ブロックの配列におけるインデクスが計算される完全性チェック値を計算するために、使用すべき完全性関数を予測することを不可能にする。
【００１３】
実施形態では、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、前記インデクス値を計算するために、変換関数を、前記計算された完全性チェック値に適用する命令の第３のシーケンスを備え、前記変換関数は、チェックサム、マスク、ハッシュ関数、バイナリシフト、および算術演算のうちの1つ以上の演算を備えている。
【００１４】
変換関数は、所定の変換関数のセットにおいてランダムに選択され得る。
【００１５】
これは、ランタイムにおいて、後続する正しい基本ブロックのインデクスがどのようにして検索されるのかを攻撃者が理解することをより困難にする。これは、前記完全性チェック値から、後続する正しい基本ブロックの配列におけるインデクスを計算するために使用すべき変換関数を、コードのさらなる解析なしで、攻撃者が予測することを不可能にする。
【００１６】
配列におけるアドレスは、セキュアなソフトウェアコードが実行されたときにおけるセキュアなソフトウェアコードの基本ブロックのアドレスである場合がある。
【００１７】
これは、配列において、セキュアなソフトウェアコードの基本ブロックをやはり指している他のすべてのアドレスから、後続する基本ブロックのアドレスを、攻撃者が区別することをよりさらに困難にする。
【００１８】
前記完全性チェック値は、開始アドレスと停止アドレスとの間のセキュアなソフトウェアコードの命令において計算されてもよく、第１の態様による方法は：
−  セキュアなソフトウェアコードをコンパイルおよびリンクしたときに、またはその後に実施される、第５のセキュアにするステップであって、
・完全性チェック値が計算されるべきソフトウェアコードの部分の開始および終了のソフトウェアコードにおける開始アドレスおよび終了アドレスを決定することと、
・前記完全性チェック値、および、前記計算された完全性チェック値に基づいて前記インデクス値を計算することとを備えた、ステップと、
−  セキュアなソフトウェアコードをコンパイルおよびリンクしたときに、またはその後に実施される、第６のセキュアにするステップであって、
・前記開始アドレスおよび停止アドレスを、第５のセキュアにするステップにおいて決定された前記開始アドレスおよび終了アドレスに設定することと、
・第５のセキュアにするステップにおいて計算された前記インデクス値で、後続する基本ブロックのアドレスを、配列中に設定することとを備えた、ステップと
を備え得る。
【００１９】
実施形態では、配列および命令の第１のシーケンスは、ソフトウェアコードの選択された基本ブロック内のランダムな位置に挿入される。これは、潜在的な攻撃者にとって、セキュアなソフトウェアコードをさらにわかりにくくする。
【００２０】
命令の第１のシーケンスは、挿入されたジャンプ命令の前で、選択された基本ブロックの最後に挿入され得る。完全性チェック値および後続する基本ブロックのインデクス値は、それで、ジャンプに対する後続する基本ブロックのアドレスを検索するために、それらが必要とされる直前に計算されるので、したがって、攻撃者がコードの動的解析によって検索するタイムウィンドウを制限する。
【００２１】
第２の態様によれば、本発明は、プロセッサによる実行のためのセキュアなソフトウェアコードの命令でエンコードされた非一時的機械可読記憶媒体に関し：
・前記セキュアなソフトウェアコードは、複数の基本ブロックに編成されたコンピュータコード命令を備えたソフトウェアコードの変更バージョンであり、
・セキュアなソフトウェアコードの選択された基本ブロックは、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスを備えた、メモリアドレスのインデクス付けされた配列を備え、前記非一時的機械可読記憶媒体は、セキュアなソフトウェアコードの選択された基本ブロックに挿入された、命令の第１のシーケンスを用いてエンコードもされ、命令の第１のシーケンスは、ランタイムにおいて実行されたとき：
・保護されるべきソフトウェアコードの部分における完全性チェック値を計算し、
・前記計算された完全性チェック値に基づいて、後続する基本ブロックのアドレスを配列中でインデクス付けするインデクス値を計算し、セキュアなソフトウェアコードの選択された基本ブロックは、その最後に、ランタイムにおいて計算された前記インデクス値によってインデクス付けされた配列のアドレスへのジャンプ命令も備えている。
【００２２】
実施形態では、完全性チェック値は、保護されるべきソフトウェアコードの部分と、選択された基本ブロックの少なくとも部分とにおいて計算される。
【００２３】
第３の態様によれば、本発明は、セキュアなソフトウェアコードの選択された基本ブロックの命令をプロセッサによって実行する方法に関し：
・前記セキュアなソフトウェアコードは、複数の基本ブロックに編成されたコンピュータコード命令を備えたソフトウェアコードの変更されたバージョンであり、
・セキュアなソフトウェアコードの選択された基本ブロックは、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスを備えた、メモリアドレスのインデクス付けされた配列を備え、前記方法は：
・保護されるべきソフトウェアコードの部分における完全性チェック値を計算するステップと、
・前記計算された完全性チェック値に基づいて、後続する基本ブロックのアドレスを配列中でインデクス付けするインデクス値を計算するステップと、
・前記計算されたインデクス値によって配列中でインデクス付けされたアドレスへのジャンプ命令を、選択された基本ブロックの最後に実行するステップと
を備えている。
【００２４】
完全性チェック値は、保護されるべきソフトウェアコードの部分と、選択された基本ブロックの少なくとも部分とにおいて計算され得る。
【００２５】
第２の態様によるこのような非一時的機械可読記憶媒体、および第３の態様による方法は、第１の態様による方法のものと同じ利点を示す。
【００２６】
前述の目的および関連する目的を達成するために、1つ以上の実施形態は、以下で十分に説明され、特に特許請求の範囲で指摘される特徴を備えている。
【００２７】
以下の説明および添付の図面は、特定の例示的な態様を詳細に説明し、実施形態の原理が採用され得る様々な方法のほんのわずかを示している。他の利点および新規の特徴は、図面と併せて考慮されるとき、後続する詳細な説明から明らかになり、開示される実施形態は、このようなすべての態様およびそれらの均等物を含むことが意図される。
【図面の簡単な説明】
【００２８】
【図１】ソフトウェアをコンパイルするプロセスを示す図である。
【図２】本発明の実施形態によるセキュアにするデバイスを概略的に示す図である。
【図３】本発明の実施形態による実行デバイスを概略的に示す図である。
【図４】本発明の実施形態によるコンパイル済みのソフトウェアコードをセキュアにする方法を概略的に示す図である。
【図５】本発明の実施形態によるインデクス付けされた配列を示す図である。
【図６】本発明の実施形態によるセキュアなソフトウェアコードの選択された基本ブロックの命令を実行する方法を概略的に示す図である。
【発明を実施するための形態】
【００２９】
以下に詳述する説明では、本発明が実践され得る特定の実施形態を例示として示す添付図面に対する参照がなされる。これらの実施形態は、当業者が本発明を実践できるように十分詳細に説明されている。本発明の様々な実施形態は、異なるが、必ずしも相互に排他的ではないことを理解されたい。たとえば、１つの実施形態に関連して本明細書で説明される特定の特徴、構造、または特性は、本発明の精神および範囲から逸脱することなく、他の実施形態内で実装され得る。それに加えて、開示された各実施形態内の個々の要素の位置または配置は、本発明の精神および範囲から逸脱することなく変更され得ることを理解されたい。したがって、以下に詳述する説明は限定的な意味で解釈されるべきではなく、本発明の範囲は添付の特許請求の範囲によってのみ定義され、請求項が権利を与えられる均等物の全範囲とともに、適切に解釈される。
【００３０】
本発明は、コンパイル済みのソフトウェアコードＳＣに、保護されるべきソフトウェアコードの部分に対する少なくとも１つの完全性チェックを含めることにより、および、コードの後続する命令へのジャンプ命令を、ジャンプ命令ターゲットが完全性チェックの結果に依存するような様式で、コードに挿入することにより、このソフトウェアコードをセキュアにすることを目的とする。これは、コンパイル済みのセキュアなソフトウェアコードＳＳＣを作り出し、これによって、攻撃者が、コードの実行を中断させることなく、コードアナライザまたはデバッガを用いて、コンパイル済みのセキュアなソフトウェアコードを解析して、完全性チェックおよびジャンプ命令ターゲットに関する十分な知識を得て、保護されるべきソフトウェアコードの部分を変更することを困難にする。
【００３１】
コンパイルは、ＣやＦｏｒｔｒａｎなどの高級プログラミング言語で記述されたソースコード１１を、図１に示すように、コードが実行されることになっているシステムのハードウェア実装を考慮に入れたマシンコード１５などの低級言語で記述されたオブジェクトコードに変換する。コンパイルは、シンタックス解析１２、制御フローグラフ生成１３、およびアセンブリコード生成１４などの中間ステップを実施することがよくある。コンパイル済みのコードの実行可能ファイルをビルドするために、通常、コンパイルは、オブジェクトコードを含む多数のファイルを単一の実行可能ファイルにともにリンクするリンクステップによって後続される。
【００３２】
コンパイル済みのコードは、命令の基本ブロックに集められた命令を備えている。このような基本ブロックは、最小限の命令シーケンスと見なすことができる。基本ブロックは、開始に１つのエントリポイントを、終了に１つのエグジットポイントを有する。基本ブロックの第１の命令が実行されるたびに、基本ブロック内の命令の出現順に、残りの命令が必ず１回実行される。基本ブロックは、ランタイムにおいて実行される次の基本ブロックのエントリポイントへのジャンプ命令を最後に備え得る。
【００３３】
本発明の第１の態様は、実行前にコンパイル済みのソフトウェアコードＳＣをセキュアにするための改ざん防止方法である。このようなセキュアにする方法は、複数の基本ブロックに編成されたコンピュータコード命令を備えたコンパイル済みのソフトウェアコードＳＣを処理し、セキュアなソフトウェアコードＳＳＣを作り出すセキュアにするデバイス２０によって実施される。その後、取得されたセキュアなソフトウェアコードＳＳＣは、実行デバイス３０によって、セキュアに実行され得る。
【００３４】
このようなセキュアにするデバイス２０は、プロセッサを含む任意の電子デバイスであり得る。たとえば、これは、開発環境がインストールされたパーソナルコンピュータＰＣであり得る。図２は、第１のプロセッサ２１、第１のＲＡＭメモリ２２、イーサネットまたはＷｉｆｉネットワークアダプタのような第１の通信ユニット２３、第１のディスプレイ２４、ハードドライブのような第１の大容量記憶手段２５、および第１のユーザ入力手段２６を備えた、このようなセキュアにするデバイスの例示的な実施形態を説明する。セキュアにされるべきソフトウェアコードＳＣは、セキュアにするデバイスの第１の大容量記憶手段２５に記憶され得る。セキュアにするデバイス２０が、第１の態様による方法をソフトウェアコードＳＣに適用した後に得られるセキュアなソフトウェアコードＳＳＣは、第１の大容量記憶装置２５に記憶されることもできる。
【００３５】
図３は、実行デバイス３０の例示的な実施形態を説明する。たとえば、実行デバイス３０は、パーソナルコンピュータＰＣ、スマートフォンやタブレットのようなモバイルデバイス、または、銀行や店頭における公共端末であり得る。これは、スマートカードまたはクレジットカードに含まれる単純なチップでもよい。これは、第２のプロセッサ３１、第２のＲＡＭメモリ３２、イーサネットまたはＷｉｆｉネットワークアダプタのような第２の通信ユニット３３、第２のディスプレイ３４、ハードドライブのような第２の大容量記憶手段３５、および第２のユーザ入力手段３６を備え得る。実行デバイス３０の第２のプロセッサ３１によって実行されるべきセキュアなソフトウェアコードＳＳＣは、実行デバイスの第２の大容量記憶手段３５に記憶されてもよい。電子デバイス３０は、実行デバイスのものと類似または異なる任意のタイプのものであり得る。両デバイスは、ｘ８６、ＡＲＭ、ＰｏｗｅｒＰＣのような同じハードウェアアーキテクチャを共有することも、または異なるアーキテクチャを有することもある。
【００３６】
セキュアにする方法の主なステップ
以下の段落では、図４に示すように、ソフトウェアコードＳＣをセキュアにし、セキュアなソフトウェアコードＳＳＣを作り出す、本発明の第１の態様による方法のステップを説明する。これらのセキュアにするステップは、セキュアにするデバイス２０の第１のプロセッサ２１によって実施され、ステップ番号が後続する文字「Ｓ」ですべてラベル付けされている。
【００３７】
必要なとき、第１の態様による方法が完了した後、セキュアなソフトウェアコードＳＳＣを実行したときに実行デバイス３０によって実施されるステップが参照される。このような実行ステップには、ステップ番号が後続する文字「Ｅ」でラベル付けされている。
【００３８】
セキュアにする方法の主なステップ：第１のセキュアにするステップ
第１のセキュアにするステップＳ１では、保護されるべきソフトウェアコードの部分が、ソフトウェアコードＳＣにおいて決定される。これは、攻撃者によるあらゆる変更を阻止するために、完全性チェックが実施されるコードの部分である。保護されるべきソフトウェアコードのこのような部分は、人間のオペレータによって第１のプロセッサ２１に指定され得る。あるいは、これは、第１のプロセッサ２１自体によってランダムに決定されるか、第１のプロセッサ２１によって実行される第１の解析プログラムによって計算され得る。ソフトウェアコードのこのような部分は、命令の1つ以上の基本ブロックを備え得る。
【００３９】
以下のステップにおいて、目的は、命令をソフトウェアコードに挿入することであり、それらの命令は、攻撃者による静的解析に抵抗できるように、実行されたとき、保護されるべきソフトウェアコードの決定された部分において完全性チェックを実施する。このような完全性チェックが、保護されるべきソフトウェアコードの部分においてチェックサム値を計算し、次いで、それを参照値と比較することのみである場合、攻撃者がこのような比較を見つけ、参照値についての知識を獲得して、保護されるべきソフトウェアコードの部分において攻撃者が何を変更しようと、常に比較の結果を成功させるために、この比較の結果を検証する命令のシーケンスを変更することは非常に簡単であろう。
【００４０】
代わりに、完全性チェックによって計算された値に基づいて、ソフトウェアコードの既存の基本ブロックのリストの中から、別の基本ブロックをターゲットとし、そのターゲットがオンザフライで選択されるジャンプ命令を、ソフトウェアコードの基本ブロックの最後に挿入することが提案される。セキュアにするデバイス２０によって実行されるセキュアにする方法は、実行デバイス３０の第２のプロセッサ３１によって実施されたとき、セキュアなソフトウェアコードの実行フローを、保護されるべきコードの部分が、攻撃者によって変更されていないにのみ、次の正しい基本ブロックにジャンプさせ；保護されるべきコードの部分が改ざんされている場合、別の不適切な基本ブロックにジャンプさせ、したがって、コードの実行の予測不能な振舞に導く命令を、ソフトウェアコードに挿入するように設計されている。このようなセキュアなソフトウェアコードは、取得されるべき値がセキュアなソフトウェアコードに格納されていないため、保護されるべきソフトウェアコードの部分において完全性チェックを実施したとき取得されるべき予想されるチェックサム値を、攻撃者が推測することを非常に困難にする。また、基本ブロックのリストのうち、セキュアなソフトウェアコードのどの基本ブロックが、ジャンプ命令で終わる現在のブロックの後に実行されるべき後続する正しいブロックであるかを、攻撃者が静的解析によって決定することも困難にする。したがって、攻撃者は、完全性チェックの結果とは無関係に、ジャンプのターゲットとして後続する正しい基本ブロックをマニュアルで強制することにより、改ざん防止保護をバイパスすることができない。
【００４１】
セキュアにする方法の主なステップ：第２のセキュアにするステップ
より正確には、第２のセキュアにするステップＳ２において、セキュアにするデバイス２０の第１のプロセッサ２１は、ソフトウェアコードの選択された基本ブロックに、命令の第１のシーケンスを挿入し得る。この命令の第１のシーケンスは、セキュアなソフトウェアコードの選択された基本ブロックの命令を実行したとき、実行デバイス３０が、選択された基本ブロックの直後に実行されるべき後続する適切な基本ブロックのアドレスを検索することを可能にすることを目的とする。
【００４２】
この命令の第１のシーケンスは、この命令の第１のシーケンスを備えたセキュアなソフトウェアコードＳＳＣが、実行デバイス３０の第２のプロセッサ３１によって実行されたとき、実行ステップＥ１、Ｅ２、およびＥ３で説明されるアクションが実施されるようになっており、これら実行ステップは、以下および図６で説明される。
【００４３】
このような選択された基本ブロックは、人間のオペレータによって第１のプロセッサ２１に指定され得る。あるいは、セキュアなソフトウェアコードＳＳＣを実行するときの計算時間を最小化するために、第１のプロセッサ２１自体によりランダムに決定されるか、または第１のプロセッサ２１により実行される第２の解析プログラムによって決定され得る。
【００４４】
命令の第１のシーケンスは、ＳＳＣランタイムにおいて、実行デバイス３０によって実行されたとき、
・保護されるべきソフトウェアコードの前記部分における完全性チェック値を計算し、
・前記計算された完全性チェック値に基づいてインデクス値を計算する。
【００４５】
セキュアにする方法の主なステップ：第３のセキュアにするステップ
第３のセキュアにするステップＳ３では、セキュアにするデバイス２０の第１のプロセッサ２１は、ソフトウェアコードの選択された基本ブロックに、図５に説明されたメモリアドレスのインデクス付けされた配列を挿入し得、ここでは、セキュアなソフトウェアコードを実行するとき、選択された基本ブロックの後に実行されるべき実際の後続する基本ブロックのアドレスが、命令の第１のシーケンスによって計算された前記インデクス値によってインデクス付けされる。
【００４６】
命令の第１のシーケンスおよびインデクス付けされた配列は、命令の第１のシーケンスによって計算されたインデクス値が、保護されるべきソフトウェアコードの部分が改ざんされていない場合にのみ、後続する基本ブロックのアドレスをインデクス付けする配列のインデクス値と等しくなるような様式で設計される。
【００４７】
配列の使用は非限定的な実施形態であり、テーブルやマトリクスのような、値のインデクス付けされたストレージ、つまり、インデクス値と、対応する格納された値との間のマッチング、を可能にする他の任意のデータ構造が、配列を使用する代わりに使用され得る。
【００４８】
セキュアにする方法の主なステップ：第４のセキュアにするステップ
第４のセキュアにするステップＳ４では、セキュアにするデバイス２０の第１のプロセッサ２１は、ソフトウェアコードの選択された基本ブロックの最後に、ランタイムにおいて計算された前記インデクス値によってインデクス付けされた配列のアドレスへのジャンプ命令を挿入する。
【００４９】
セキュアにする方法の例示的な実施形態
以下の段落では、セキュアにするデバイス２０によって実施される本発明の第１の態様によるセキュアにする方法の例示的かつ非限定的な実施形態について説明する。
【００５０】
上記で説明したように、第１のセキュアにするステップＳ１では、ソフトウェアコードＳＣ内で保護されるべきソフトウェアコードの部分が決定される。
【００５１】
次に、第２のセキュアにするステップＳ２において、命令の第１のシーケンスが、選択された基本ブロックに挿入される。上記で説明したように、この命令の第１のシーケンスは、ランタイムにおいて実行されたとき、完全性チェック値を計算する命令を含んでいる。命令の第１のシーケンスは、ランタイムにおいて実行されたとき、チェックサム、マスク、ハッシュ関数、バイナリシフト、および算術演算のうちの1つ以上の演算を実施することにより、前記完全性チェック値を計算する命令の第２のシーケンスを備え得る。この完全性チェック値は、セキュアなソフトウェアコードの開始アドレスと停止アドレスとの間のソフトウェアコードの命令において計算され得る。このような開始アドレスおよび停止アドレスは、第１のセキュアにするステップにおいて決定された、保護されるべきソフトウェアコードの少なくとも部分を含む、ソフトウェアコードの部分を定義するように設計される。
【００５２】
完全性チェック値は、たとえば、ＭＤ５またはＳＨＡ−１を使用して計算されたチェックサムまたはダイジェストであり得る。
【００５３】
実施形態において、前記命令の第２のシーケンスは、完全性チェック関数を計算する命令の所定のシーケンスのセットにおいて、ランダムに選択される。その結果、このような完全性チェックが実施される手法は多様化する。それは、難読化することもできるので、攻撃者がセキュアなソフトウェアコードにおいて簡単に識別し、開始アドレスと停止アドレスとの間で同じ完全性チェック値を自分で計算することを阻止する。
【００５４】
代替実施形態では、完全性チェック値は、保護されるべきソフトウェアコードの前記部分と、選択された基本ブロックの少なくとも部分とにおいて計算される。完全性チェックは、命令の第１のシーケンス、および／またはインデクス付けされた配列、および／またはブロックの最後におけるジャンプ命令を備えた、選択された基本ブロックの部分において計算され得る。これは、ソフトウェアコードの保護を無効にするために、選択された基本ブロックのこのような部分を、攻撃者が変更することを阻止する。完全性チェック値は、ジャンプ命令の直前にある命令においても計算され得る。こうすることが、攻撃者が、完全性チェックによって出力される値について、次いで、選択された基本ブロックの後に実行される後続する基本ブロックのアドレスについて知識を獲得できる、実行ブレークポイントを、攻撃者がジャンプの前に挿入することを阻止する。
【００５５】
命令の第１のシーケンスは、計算された完全性チェック値に基づいてインデクス値を計算する命令も含む。
【００５６】
そのために、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、前記インデクス値を計算するために、前記計算された完全性チェック値に変換関数を適用する、命令の第３のシーケンスを備え得る。変換関数は、たとえば、完全性チェック値のチェックサムまたはハッシュ、またはインデクス値を出力するために完全性チェック値のほんの少数の所定のビットを選択するマスクであり得る。変換関数はまた、完全性チェック値のビットのバイナリシフト、または完全性チェック値に対する算術演算の実施も含み得る。
【００５７】
変換関数は、所定の変換関数のセットにおいて、セキュアにするデバイスの第１のプロセッサによってランダムに選択され得る。
【００５８】
その後、第３のセキュアにするステップＳ３の一部として、選択された基本ブロックに、インデクス付けされた配列が挿入される。
【００５９】
配列のすべてのインデクス値が、変換関数のターゲットセットに含まれるように、配列のインデクス値が選択され得る。そうすることによって、配列のすべてのインデクス値は、変換関数の適用の結果となる。
【００６０】
インデクス付けされた配列の目的は、選択された基本ブロックの後に実行されるべき実際の後続する基本ブロックのアドレスを、特定のインデクスに格納することであり、これにより、実行デバイスが、選択された基本ブロックの命令において第１のシーケンスを実行したとき、保護されるべきソフトウェアコードの部分が改ざんされていない場合、配列の後続する基本ブロックのアドレスのインデクスに等しいインデクス値を計算する（以下に説明されるステップＥ２）。
【００６１】
ただし、第３のセキュアにするステップＳ３を実施するセキュアにするデバイスによって選択された基本ブロックに、インデクス付けされた配列が挿入されたとき、命令の第１のシーケンスの実行から生じる完全性チェック値、および前記完全性チェック値に基づいて計算されたインデクス値は、まだ知られていない。
【００６２】
結果として、方法のこのステップにおいて、セキュアにするデバイスの第１のプロセッサは、選択された基本ブロックに、配列における所定のインデクス、たとえば配列の第１の位置に、後続する基本ブロックのアドレスを備えたインデクス付けされた配列を挿入し得る。
【００６３】
その後、第４のセキュアにするステップＳ４において、セキュアにするデバイスの第１のプロセッサは、選択された基本ブロックの最後に、命令の第１のシーケンスの実行から生じるインデクス値によって配列中でインデクス付けされたアドレスへのジャンプ命令を挿入する。
【００６４】
選択された基本ブロックの最後の命令が既にジャンプ命令であった場合、この既存のジャンプ命令は削除されてよく、第４のセキュアにするステップＳ４において選択された基本ブロックの最後に挿入されたジャンプ命令がそれに置き換わる。
【００６５】
プロセスのこのステップにおいては、命令の第１のシーケンスを実行するときに取得されるインデクス値は知られておらず、ほぼ確実に、後続する基本ブロックのアドレスの配列におけるインデクスではない可能性がある。さらに確実には、別の基本ブロックのアドレスの配列におけるインデクスである。それで、プロセスのこのステップから生じるソフトウェアコードを実行すると、通常の実行制御フローで選択された基本ブロックの直後に実行されるはずのない基本ブロックへ実行フローをジャンプさせ、予測不能な実行の振舞に導く。
【００６６】
この問題を解決するために、この方法は、セキュアなソフトウェアコードをコンパイルおよびリンクしたときに、またはその後に実施される、第５のセキュアにするステップＳ５を備え得、この間、セキュアにするデバイス２０の第１のプロセッサ２１は、ソフトウェアコードが実行可能ファイルになるためにアセンブルされた後、その解析を実施し、最終的なセキュアなソフトウェアコードに非常に近い状態で、このソフトウェアコードを解析することを可能にする。第５のセキュアにするステップＳ５は：
・保護されるべきソフトウェアコードの少なくとも部分を含む、完全性チェック値が計算されるべきソフトウェアコードの部分の開始および終了の、ソフトウェアコードにおける実際の開始アドレスおよび終了アドレスを決定することと、
・選択された基本ブロックに挿入された命令の第１のシーケンスによって計算されるように、完全性チェック値を計算することと、
・選択された基本ブロックに挿入された命令の第１のシーケンスによって計算されるように、変換関数を完全性チェック値に適用することによってインデクス値を計算することとを備え得る。
【００６７】
このようなステップにおいて、特にこの命令の第２のシーケンスが、命令の所定のシーケンスのセットにおいてランダムに選択されたとき、完全性チェック値は、命令の第２のシーケンスにしたがって計算されるものとする。同様に、インデクス値は、所定の変換関数のセットにおいて、変換関数がランダムに選択されたとき、選択された変換関数を適用することによって計算されるものとする。
【００６８】
この方法は、セキュアなソフトウェアコードをコンパイルおよびリンクしたときに、またはその後に実施される、第６のセキュアにするステップＳ６も備え得、この間、セキュアにするデバイス２０の第１のプロセッサ２１は、セキュアなソフトウェアコードを配信するために、ソフトウェアコードに最終的な変更を実施する。
【００６９】
第６のセキュアにするステップＳ６は：
・完全性チェック値が計算されるソフトウェアコードの部分を定義する開始アドレスおよび停止アドレスを、第５のセキュアにするステップＳ５において決定された開始アドレスおよび終了アドレスに設定すること。このようなアドレスは、第１の実行ステップＥ１の間に完全性チェック値を計算するために使用される。
・配列の、実際の後続する基本ブロックのアドレスを、第５のセキュアにするステップＳ５において計算されたインデクス値に設定すること。これは、実行ステップＥ２の間に計算されるのと同じインデクス値である、
を備え得る
【００７０】
この配列は、セキュアなソフトウェアコードの基本ブロックの他の多くのアドレスを、それが実行されたときに、他のインデクスにおいて備え得る。このようなアドレスは、セキュアなソフトウェアコードの他の基本ブロックの中からランダムに選択された、後続する可能性のある基本ブロックのアドレスであり得る。このような場合、第６のセキュアにするステップＳ６の間、実際の後続する基本ブロックのアドレスを、第５のセキュアにするステップにおいて計算されたインデクス値に設定したとき、実際の後続する基本ブロックのアドレスが、配列において、第５のセキュアにするステップにおいて計算されたインデクス値によって配列で既にインデクス付けされている別の基本ブロックのアドレスとスワップされ得る。
【００７１】
そうすることによって、攻撃者は、配列のアドレスが、後続する基本ブロックのアドレスになりえないことを決定することができない（これは、このようなアドレスが、基本ブロックのアドレスではない場合、または、配列における関連付けられたインデクスが、変換関数の可能な結果ではなかった場合に、可能であり得る）。攻撃者が、セキュアなソフトウェアコードに対して静的解析を実施した場合、彼は、選択された基本ブロックの最後において、単にジャンプ命令を突き止めることができるだけであり、セキュアなソフトウェアコードを正しく実行させ続けるために、配列に格納された複数のアドレスの中から、どのアドレスが、ジャンプのターゲットとして指定されるべきかを決定できないだろう。
【００７２】
実施形態では、配列および命令の第１のシーケンスは、挿入されたジャンプ命令の前で、ソフトウェアコードの選択された基本ブロック内のランダムな位置に挿入され得る。あるいは、挿入されたジャンプ命令の前で、選択された基本ブロックの最後に挿入され得る。命令の第１のシーケンスは、選択された基本ブロックの既存の命令と干渉しないような様式で、この既存の命令とインターレースされ得る。
【００７３】
セキュアにされたソフトウェアコード実行
上記のステップが、セキュアなソフトウェアコードを作り出すセキュアにするデバイスによって実施された後、このようなセキュアなソフトウェアコードは、実行デバイス３０の第２のプロセッサ３１によって、セキュアに実行され得る。選択された基本ブロックを実行したとき、実行デバイスは、命令の第１のシーケンス：
・第１の実行ステップＥ１の間、第２のプロセッサ３１は、保護されるべきソフトウェアコードの少なくとも前記部分において完全性チェック値を計算する。
・第２の実行ステップＥ２の間、第２のプロセッサ２１は、前記計算された完全性チェック値に基づいてインデクス値を計算する、
を実行する。
【００７４】
保護されるべきソフトウェアコードの部分が改ざんされていない場合：
・計算された完全性チェック値は、計算されたインデクス値が、選択された基本ブロックの実行直後に実行されるべき後続する正しい基本ブロックのアドレスの配列におけるインデクスであるようになり、
・選択された基本ブロックの最後におけるジャンプ命令が、実行フローを、この後続する正しい基本ブロックの先頭にジャンプさせる。
【００７５】
そうではなくて、保護されるべきソフトウェアコードの部分が改ざんされている場合：
・計算された完全性チェック値は、計算されたインデクス値が、選択された基本ブロックの実行直後に実行されるべき後続する正しい基本ブロックのアドレスとほぼ確実に異なるアドレスの配列におけるインデクスであるようになり、
・選択された基本ブロックの最後におけるジャンプ命令は、実行フローをこのアドレスへジャンプさせ、実行の予測不能な振舞に導く。
【００７６】
第１の態様による方法の複数回適用
本発明の第１の態様による方法は、ソフトウェアコードの、場合によっては互いに重複するいくつかの部分を保護するために、複数回適用され得る。この場合、第１のセキュアにするステップＳ１の間、方法の各適用に対する保護されるべきコードの部分は、すべてのソフトウェアコードまたはソフトウェアコードのすべての機密部分が保護されるように、第１の解析プログラムによって決定され得る。変換関数が、所定の変換関数のセットの中からランダムに毎回選択される場合、保護されるべきソフトウェアコードの各部分に対して、異なる変換関数が選択され得る。
【００７７】
他の態様
第２の態様では、本発明は、セキュアにするデバイス２０の第１のプロセッサ２１が、上述した第１の態様による方法の少なくともステップＳ１からＳ４を実施した後に取得されるセキュアにするソフトウェアコードの命令でエンコードされた非一時的機械可読記憶媒体にも関する。前記セキュアなソフトウェアコードは、それで、第１の態様による前記方法が適用される非セキュアなソフトウェアコードの変更されたバージョンであり、複数の基本ブロックに編成されたコンピュータコード命令を備えている。前記記憶媒体にエンコードされた命令では、セキュアなソフトウェアコードの選択された基本ブロックは、セキュアなソフトウェアコードを実行したとき選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスを備えた、メモリアドレスのインデクス付けされた配列を備えている。
【００７８】
非一時的機械可読記憶媒体は、セキュアなソフトウェアコードの選択された基本ブロックに挿入された、命令の第１のシーケンスでもエンコードされ、命令の第１のシーケンスは、ランタイムにおいて実行されたとき、上記で説明された実行ステップＥ１からＥ２：
・保護されるべきソフトウェアコードの部分における完全性チェック値を計算することと、
・前記計算された完全性チェック値に基づいて、後続する基本ブロックのアドレスを配列中でインデクス付けするインデクス値を計算することを実施し、セキュアなソフトウェアコードの選択された基本ブロックは、ランタイムにおいて計算された前記インデクス値によって配列中でインデクス付けされたアドレスへのジャンプ命令も備えている。
【００７９】
第３の態様では、本発明はまた、実行デバイス３０の第２のプロセッサ３１によって実行されるような、セキュアなソフトウェアコードの命令を実行する方法にも関する。前記セキュアなソフトウェアコードは、それで、上記の第１の態様による方法が適用された複数の基本ブロックに編成されたコンピュータコード命令を備えた非セキュアなソフトウェアコードの変更されたバージョンである。前記セキュアなソフトウェアコードの選択された基本ブロックは、セキュアなソフトウェアコードを実行したとき、選択された基本ブロックの後に実行されるべき後続する基本ブロックのアドレスを備えた、メモリアドレスのインデクス付けされた配列も備えている。セキュアなソフトウェアコードの命令を実行する方法は、上記で説明された実行ステップＥ１からＥ２：
・第１の実行ステップＥ１の間、第２のプロセッサ３１は、保護されるべきソフトウェアコードの部分における完全性チェック値を計算し；
・第２の実行ステップＥ２の間、第２のプロセッサ３１は、前記計算された完全性チェック値に基づいて、後続する基本ブロックのアドレスを配列中でインデクス付けするインデクス値を計算する；
を備えている。
【００８０】
この方法は、第３の実行ステップＥ３を備え、この間、第２のプロセッサ３１は、選択された基本ブロックの最後に、前記計算されたインデクス値によってインデクス付けされた配列のアドレスへのジャンプ命令を実行する。
【００８１】
結果として、提案された方法は、保護されるべきソフトウェアコードの部分において完全性チェックを実施し、保護された部分が改ざんされているのであれば、セキュアなソフトウェアコードの実行をインタラプトするジャンプによって、この完全性チェックを保護することを可能にする。さらなる保護のために、提案された方法は、ジャンプ命令のターゲットである実行されるべき後続する基本ブロックをソフトウェアコードに隠すので、したがって、攻撃者が、保護されたコードの静的解析によって、このような方法がどのように機能するかを理解し、保護されたコードを変更することを阻止する。
【図１】
2020505709.tif 000003
【図２】
2020505709.tif 000004
【図３】
2020505709.tif 000005
【図４】
2020505709.tif 000006
【図５】
2020505709.tif 000007
【図６】
2020505709.tif 000008
【国際調査報告】
2020505709.tif 000009
2020505709.tif 000010
2020505709.tif 000011