(19)【発行国】日本国特許庁(JP)
(12)【公報種別】特許公報(B2)
(11)【特許番号】
(24)【登録日】2022-03-16
(45)【発行日】2022-03-25
(54)【発明の名称】セルフデバッギング
(51)【国際特許分類】
G06F 21/14 20130101AFI20220317BHJP
G06F 11/36 20060101ALI20220317BHJP
【FI】
G06F21/14
G06F11/36 120
(21)【出願番号】P 2019527551
(86)(22)【出願日】2017-12-05
(86)【国際出願番号】 EP2017081587
(87)【国際公開番号】W WO2018104344
(87)【国際公開日】2018-06-14
【審査請求日】2020-11-18
(32)【優先日】2016-12-05
(33)【優先権主張国・地域又は機関】EP
(73)【特許権者】
【識別番号】504344495
【氏名又は名称】ナグラビジョン エス アー
(74)【代理人】
【識別番号】100085372
【氏名又は名称】須田 正義
(74)【代理人】
【識別番号】100129229
【氏名又は名称】村澤 彰
(72)【発明者】
【氏名】スタイン,ヴォルカールト
(72)【発明者】
【氏名】ビョルン,デ ステル
(72)【発明者】
【氏名】ベルト,アブラス
【審査官】岸野 徹
(56)【参考文献】
【文献】特開2012-008825(JP,A)
【文献】特開2005-011342(JP,A)
【文献】特開2008-059404(JP,A)
【文献】特表2016-528635(JP,A)
【文献】米国特許第07647589(US,B1)
(58)【調査した分野】(Int.Cl.,DB名)
G06F 21/14
G06F 11/36
(57)【特許請求の範囲】
【請求項1】
ソフトウェアを保護する方法
を処理装置に実行させるコンピュータプログラムであって、
ソフトウェアプロセスを開始するステップと、
デバッガプロセスを前記ソフトウェアプロセスにアタッチするステップと、
前記デバッガプロセスが少なくとも1回呼び出されるように、前記ソフトウェアプロセスを実行するステップと、
前記デバッガプロセスの起動に応答して前記デバッガプロセス中に1つ以上の機能を実行するステップであって、前記1つ以上の機能は前記ソフトウェアプロセスと関連したデータに依存する出力を有するステップと、
を含む
コンピュータプログラム。
【請求項2】
前記出力は、前記ソフトウェアプロセス用のデータ出力を含む請求項1に記載の
コンピュータプログラム。
【請求項3】
所与の機能の前記出力は、継続的な実行のために前記ソフトウェアプロセス中に複数の戻り点を示すことができる請求項1又は2に記載の
コンピュータプログラム。
【請求項4】
前記デバッガプロセスは、前記1つ以上の機能がデータを前記ソフトウェアプロセスのアドレス空間の中のメモリから検索することを可能にするためにメモリサポート機能を提供する請求項1~3のいずれか1項に記載の
コンピュータプログラム。
【請求項5】
前記ソフトウェアプロセス中のブレークポイントに達すると、前記デバッガプロセスは呼び出される請求項1~4のいずれか1項に記載の
コンピュータプログラム。
【請求項6】
前記ソフトウェアプロセスが終了すると、前記デバッガプロセスを前記ソフトウェアプロセスから分離することを更に含む請求項1~5のいずれか1項に記載の
コンピュータプログラム。
【請求項7】
前記ソフトウェアプロセスは、
コンピュータプログラムとして実行可能なファイル、例えばアプリケーションを実施する請求項1~6のいずれか1項に記載の
コンピュータプログラム。
【請求項8】
前記ソフトウェアプロセスは、ライブラリを実施する請求項1~6のいずれか1項に記載の
コンピュータプログラム。
【請求項9】
請求項1~8のいずれか1項に記載の
コンピュータプログラムを実行するためのコンピュータ実行可能なコードを含むコンピュータ実行可能な
コンピュータプログラ
ム。
【請求項10】
請求項1~8のいずれか1項に記載の
コンピュータプログラムを実行するように構成される
処理装置。
【発明の詳細な説明】
【技術分野】
【0001】
本開示につながる研究は、承認契約n°609734の下で[欧州連合][欧州原子力共同体]第7フレームワークプログラム([FP7/2007-2013][FP7/2007-2011])から資金提供を受けたものである。
【0002】
本開示は、ソフトウェアセキュリティ、詳細には、デバッギング技術を用いる攻撃からのアプリケーション又はライブラリのようなソフトウェアの保護に関する。
【背景技術】
【0003】
デバッギングは、コードのエラーを識別できるプロセスである。このための1つのツールは、デバッガ、多くのオペレーティングシステムによってデバッグされるコードと対になることができる一種のユーティリティである。例外または他のエラーが発生すると、これは、その場合はコードを検査して、この問題の起点を識別することが可能であるデバッガに報告される。
【発明の概要】
【発明が解決しようとする課題】
【0004】
デバッガをコードと対にする能力は、そのコードのセキュリティを危うくするために悪意の人々により利用された。特に、デバッガがコードの動作を識別することが可能であるので、それは脆弱性のソースであり得る。
【課題を解決するための手段】
【0005】
技術は、コードをこの種の攻撃から保護しようとするために開発された。これらの技術は、コードが作動中のデバッガがいつコードに不正に連結したかについて識別することを可能にする試みを含む。別の方法は、実行されるときにそれ自体デバッガを開始するようにコードを設計することである(このデバッガは「セルフデバッガ」と称される場合がある)。大部分のオペレーティングシステムは、単一のデバッガが所与のプロセスと対にされることを可能にするだけであり、セルフデバッガが、悪意のあるデバッガがさもなければ使用することを望むことができる空間を占有することを意味する。
【図面の簡単な説明】
【0006】
【
図1】従来のコードプロセス、並びに本開示のカップル・コード・プロセス及びデバッガプロセスの主要な機能の略図である。
【
図2】実施形態による実行時ステップを示すフローチャートである。
【
図3】本開示によるバイナリの生成の主要な態様を示す。
【
図4】好ましい実施形態を実施するためのハードウェア基盤を示す。
【発明を実施するための形態】
【0007】
大まかに言うと、コードの動作を保護する方法が提供される。本開示に従って、方法は、コードプロセスを開始すること、及びコードプロセスにアタッチされたデバッガプロセスを初期化することを含むことができる。コードプロセスの実行中に、コードプロセスの機能に極めて関連する動作は、デバッガプロセスの中で実行できる。その結果、デバッガプロセスは、コードプロセスの機能に影響を与えずに置き換えられるか又は損なわれることがありえない。コードプロセスは、従って、変更されたか悪意のあるデバッギング技術による検査から保護できる。
【0008】
この文脈において、「極めて」は、デバッガプロセスで行われるそれらの動作によって生ずる出力がコードプロセスの残りの部分のための入力として役立つこと、及びその入力がそのコードプロセスの他の入力と仮定するとコードプロセスがその正しい出力を生成することを可能にするのに必要であることを意味すると理解できる。
【0009】
本開示のいくつかの態様において、ソフトウェアを保護する方法を処理装置に実行させるコンピュータプログラムが提供される。この方法は、ソフトウェアプロセスを開始すること、及びデバッガプロセスをソフトウェアプロセスにアタッチすることを含むことができる。デバッガプロセスが少なくとも一回呼び出されるように、コードプロセスは、その場合は実行できる。起動に応じて、1つ以上の機能は、デバッガプロセス中に実行することができて、これらの機能は、ソフトウェアプロセスと関連したデータに依存する出力を有する。出力が、ソフトウェアプロセスと関連したデータに依存して変化することがあり得る(即ちそれは予定されていない)ので、ソフトウェアプロセス及びデバッガプロセスの両方とも正しく作動するときに、全体の機能は達成されるだけである。これは、コードを分析するためにデバッガプロセスに対する干渉の余地を残さない。
【0010】
この態様のソフトウェアプロセスが、デバッガによってデバッグされているプロセスに代わるので、それは、「デバッギ(debuggee)」プロセスと考えることができる。デバッガプロセスは、ソフトウェアプロセスが開始されるときか又は後の時間に初期化できる。例えば、特定の機能(例えばライブラリ)がソフトウェアプロセスにロードされるときに、デバッガプロセスは初期化できる。いくつかの実施例において、ソフトウェアプロセスは、デバッガプロセスを初期化するためにフォーク(fork)する。他の実施例において、デバッガプロセスは、最初に初期化されて、次に、ソフトウェアプロセスを生成するためにフォークすることができる。
【0011】
いくつかの実施形態では、出力は、ソフトウェアプロセス用のデータ出力を含む。このように、デバッガプロセス内の機能の出力は、ソフトウェアプロセスの後の動作に直接影響することがありえて、それによって、ブレークするのが容易でない方法で2つのプロセスをきつく連結する。デバッガプロセスの機能の出力は、ソフトウェアプロセスのためのデータ入力を含み、前記データ入力は、ソフトウェアプロセスの実行のために重要である。
【0012】
いくつかの実施形態では、所与の機能の出力は、継続的な実行のためにソフトウェアプロセス内で複数の戻り点を示すことができる。このように、少なくとも1つの機能のための戻り点は、(固定されるよりはむしろ)可変的である。制御フローは、従って、デバッガプロセスの動作に従って可変的であり、そして容易に推定されるかまたは再作成されることができない。
【0013】
いくつかの実施形態では、デバッガプロセス・デバッガプロセスは、1つ以上の機能がソフトウェアプロセスのアドレス空間の中のメモリからデータを検索することを可能にするメモリサポート機能を提供する。このように、プログラム関連の機能が、あたかもソフトウェアプロセスの中で実行されるかのように、それらは、データを処理する能力を有することができる。
【0014】
コードプロセス中のブレークポイントに達すると、デバッガプロセスを呼び出すことができる。ソフトウェアプロセスが終了すると、デバッガプロセスは、ソフトウェアプロセスから切り離すことができる。ソフトウェアプロセスが完了したか又はその他の理由(例えば強制終了されるとき)で、それは終了できる。或いは、ソフトウェアプロセス中の機能が、プロセスが全体として終了するのを待つよりはむしろ終了すると、デバッガプロセスは、ソフトウェアプロセスから切り離すことができる。
【0015】
いくつかの実施形態では、ソフトウェアプロセスは、プログラムとして実行可能なファイル、例えばアプリケーションを実施する。他の実施形態では、コードプロセスはライブラリを実施する。
【0021】
いくつかの特定の実施形態は、ここで同じ参照符号が同じ特徴を指す添付図面を参照して実例によって説明される。
【0022】
バイナリ書換え技術によって、本開示は、機能の全部のチャンクを最初のソフトウェアからセルフデバッガへ移行できる。これは、いくつかの利点を提供する。第一に、セルフデバッガの入出力動作は、もはや予め決められず、セルフデバッガが介入するたびに、それは予め決められないが、保護プログラムの機能が変化できるほどその代わりに変化できる異なる機能を実行する。これは、保護をオートメーション化した分析、難読化の解除、及びデコンストラクションに対してずっと強じんにする。第二に、攻撃者が、最初のプログラムに相当する制御フロー及びデータフローを見つけ出すことができる場合であっても、攻撃者が保護を取り消して、その最初のプログラムを再構成することは、非常により難しくなる。組み合わせて、これらの2つの長所は、追跡されるか又はライブでデバッグされる機能プログラムを維持すると共に、攻撃者がセルフデバッガを切り離すことを非常により難しくする。
【0023】
全体のセルフデバッガ設計
図1は、本開示によるセルフデバッギング方式の基本的概念を示す。この実施形態は、Linux(登録商標)(及びアンドロイド(登録商標)のような派生品)を目標とし、原理は、他の環境、例えばWindows(登録商標)及びOS Xに適用することもできる。
【0024】
図1の左側に、小さい制御フロー・グラフ・フラグメントを含む、最初の保護されないアプリケーションが示される。示されたアセンブリコードは、(疑似)ARMv7コードである。この保護されないアプリケーションは、2つの部分、即ち、図の中央に示すように大部分は最初のアプリケーションに対応するデバッギ、及び右側に示すようにデバッガから成る保護されたアプリケーションに変換される。デバッギ及びデバッガに注入されるいくつかの新しい構成要素は別として、最初のアプリケーションとの主要な差は、制御フロー・グラフ・フラグメントがアプリケーションからデバッガに移行されたことである。この特定の実施形態は、機能呼び出しのような手順間制御フローを含まない全ての単一エントリ、複数の終了コードフラグメントをサポートする。
【0025】
この種のフラグメントの移行は、単純な複写を超えたものであり、保護されたアプリケーションにおいては、デバッガアドレス空間で実行する移行されたコードが、デバッギアドレス空間にまだあるデータに好ましくはアクセスできるので、LDR命令のようなメモリ参照は、変形しなければならない。全ての関連した構成要素および変形は、後の節において更に詳細に述べられる。
【0026】
移行されたフラグメントは、アプリケーションの動作にとって好ましくは重要である。即ち、デバッガプロセスに移行されるそれらの動作により生成される出力は、コードプロセスの残りの部分のための入力として役に立ち、そしてその入力は、コードプロセスがそのコードプロセスの他の入力ならばその正しい出力を生成することを可能にするために必要である。この要件は、実際には見落としやすい。例えば、典型的プログラマーは、デバッガの前後関係においてコードプロセスの変数の初期化を実行することを考えるかもしれない。しかしながら、一般に、デバッガプロセスにおいてコードプロセスから変数の初期化を実行することは十分でない。その理由は、次のことにある。実際には、プロセスにおいて、(例えば、機能への入力時の局所変数の)変数初期化が、プロセスの正しい機能のために、そして正しい出力を生成するために実際に必要されずに、良好なプログラム実行の結果として、そしてソースプログラミング言語定義要件を満たすために実行されることがたいへん頻繁に起こる。これは、変数がコードプロセスの実行された経路において、単に使われないという理由か、又はそれらがコードプロセスの実行又は出力に影響を与えることができる前に、初期値が重ね書きされるという理由であり得る。
【0027】
実行時に、この保護されたアプリケーションの動作は、以下の通りである。最初に、あたかもデバッギが原アプリケーションであるかのように、それは、ステップs21で開始する。新しく注入された初期化子は、次に、デバッガのための新しいプロセスからフォークし、そこにおいて、デバッガの初期化子は、デバッギプロセスに直ちにアタッチする。このように、デバッガプロセスは開始されて、ステップs22でデバッギプロセスにアタッチされる。
【0028】
後でプログラムの実行の間に、移行されたコードフラグメントのエントリポイントに達すると、アプリケーションの1つの可能な制御フローは、
図1の矢印をたどる。アプリケーション/デバッギにおいて、命令を誘導する例外が実行されて、ステップs23で例外が生じる(
図1に1と表示されている)。デバッガは、この例外を通知されて、ステップs24でそのデバッガループでそれを処理する(
図1に2と表示されている)。特に、このループのコードは、デバッギからプロセス状態を取り出して対応する移行されたコードフラグメントを調べて、ステップs25で制御をそのフラグメントのエントリポイントへ移す役割を果たす(
図1に3と表示されている)。前述のように、そのフラグメントにおいて、メモリアクセスはそのままで実行することができない。それで、それらは、ステップs26でデバッギのアドレス空間のメモリにアクセスするメモリサポート機能5の起動4と置き換えられる。移行されたコードフラグメントにおいて、出口点6に最終的に達すると、制御は、ステップs27でデバッガループ7の対応点へ移されて、それは、ステップs28でデバッガで計算されるデータによってデバッギの状態を更新し、8制御は、ステップs29でデバッギへ戻される。複数の出口を有するコードフラグメント、例えば図の実施例の場合は、制御は、デバッギの複数の継続点へ戻すことができる。この点に関しては、本開示のデバッガは、既存のセルフデバッガより複雑な方法で機能し、それは、デバッギとデバッガの間で前後の制御フロー転送の間に1対1のマッピングを実施する。
【0029】
最終的に、アプリケーションが終了すると、埋込み型終了化子は必要な分離動作を実行する。
【0030】
この方式が、プログラムとして実行可能なファイル(即ち、主要な機能及びエントリポイントを有するバイナリ)を保護するためだけでなく、共有ライブラリを保護するためにも展開できる点に留意することは重要である。プログラムとして実行可能形なファイルのように、ライブラリは、それらがOSローダーによってロードされるか又はアンロードされるときに実行される初期化子及び終了化子を含むことができる。その時、必要なフォーキング、アタッチング、及び分離は、同様に実行できる。
【0031】
以下の説明が、アプリケーションを保護することに主に関連するが、暗に、教示はアプリケーション及びライブラリを等しく適用する。ライブラリに特に関連する1つの態様は、デバッガの適当な初期化及び終了化の必要である。ライブラリが、プログラムの単一の実行中に複数回ロードされるか又はアンロードされることがまれでないので、これは必要である。例えば、反復してロードしてアンロードすることは、メディアプレーヤ及びブラウザのプラグインにとってしばしば起こる。更に、主プログラムが、それらがそれ自体開始されるときに1つのスレッドだけから成るのに対して、それらは、ライブラリがロードされてアンロードされるときは複数のスレッドから成ることができる。
【0032】
ツールサポート
図3は、1つの可能な概念上のツールフローを示す。
【0033】
ソースコード注釈
デバッガに移行されるコードフラグメントを決定するために、多くのオプションが存在する。図に示す1つ、そして又我々が我々の実施態様で用いるものは、プラグマ、コメント、又はデバッガプロセスに移行されるコード領域の始め及び終了をマークするその他の形態の注釈によって、ステップs31でソースコードに注釈をつけることである。単純なグレップ(grep)は、注釈及びそれらの行番号を抽出して、ステップs32でその情報を注釈ファイルに格納するのに十分である。
【0034】
代わりのオプションは、保護される手順又はソース・コード・ファイルをリストすることか、或いは興味のあるフラグメントを半自動式に選択するためにトレース又はプロフィールを集めることである。
【0035】
その点で、デバッガに移行されるフラグメントが、必ずしもまったくのホットフラグメントでなければならないというわけではない点に留意することは、重要である。デバッギとデバッガの間に強いアタッチメントを達成するために、比較的高い頻度で例外を提起することが十分であるが、これは最もホットなコードパスにある必要はない。フラグメントの選択のための更なる考慮点は、以下に詳述される。あらゆる提起された例外が、大きな量のオーバーヘッド(コンテキストスイッチ、多くのptraceコール、...)を導入するので、保護のレベルを損なわずにそれらの数を最小化することが重要である。
【0036】
標準コンパイラ及びツール
開示されたセルフデバッギング方法を展開するために、いかなる「標準」コンパイラも、ステップs33で用いることができる。技術は、いかなる規制もコンパイラによって生成するコードに課さない。実験評価において、GCC及びLLVMの両方が使われ、そこにおいてコード生成に適応するか又は調整する必要がなかった。
【0037】
1つの必要条件は、しかしながら、コンパイラ及びバイナリのユーティリティ(アセンブラ及びリンカー)がリンクタイムリライタに十分に正確なシンボル及び再配置情報を提供するということである。これは、信頼性が高い保守的なリンクタイムコード分析及び変換が、選択されたコードフラグメントの移行及び変換を含む全部のセルフデバッギング方式を実施することを可能にするために必要とされる。十分に正確な情報を提供することは、一般的に用いられるツールのために確実に手の届く範囲内にある。ARM所有のコンパイラは、例えば、デフォルトによって長期間そうした。そしてGNU binutilis、GCC、及びLLVMの場合は、非常に単純なパッチは、それらのツールがあまりに積極的シンボル緩和及び再配置簡略化を実行するのを防止して、マッピングシンボルを挿入してコードでデータをマークすることをそれらに強いるために十分である。これらの要件は、以前に文書化されて、それらは、手動で書込みされたアセンブリコードで満ちている、Linux(登録商標)カーネル及びCライブラリのCISC(x86)及びRISC(ARMv7)版の両方と同程度の複雑且つ非慣習的なコードの信頼性が高い保守的なリンクタイム書換えを実行するために十分であることが示された。
【0038】
デバッガの大きい共通部分「ミニデバッガ」は、標準コンパイラとプレコンパイルして、次に、保護されるアプリケーションに簡単にリンクした。他の部分、例えば、移行されたフラグメントの各々のためのデバッグループのプロローグ及びエピローグは、それらが特定のフラグメントのためにカスタマイズされるときに、リンクタイムリライタによって生成される。
【0039】
リンクタイムリライタが、ソースコードにおいて注釈付きフラグメントを識別することを可能にするために、それは、それにソースコードファイルから抽出された行番号情報を渡して、コンパイラに、デバック情報付きのオブジェクトファイルを生成させるのに十分である。そのデバック情報は、次に、バイナリコードのすべてのアドレスを、リライターが注釈から行番号にリンクすることができるソース行番号にマップする。
【0040】
バイナリ、ライブラリ、及びプロセス
リンクタイムリライタは、ステップs35で保護されたアプリケーションを生成するために2つのオプションを有する。第1のオプションは、2つのバイナリ、即ち、アプリケーション/デバッギのための1つ、及びデバッガのための1つを生成することである。セキュリティの観点から、これは好ましいかもしれない。その理由は、アプリケーション意味論及びその実施が、次に、複数のバイナリを通じて分散されて、それは、攻撃者が保護を取り消す、即ち、デバッギを最初のアプリケーションに戻すことをおそらく更により難しくするからである。しかしながら、デバッガの開始が、次に、第2のバイナリをロードすることも必要とするので、このオプションは、追加の実行時オーバーヘッドを導入する。
【0041】
以下の更なる実施例において使用される代わりのオプションは、全てのデバッギコード及び全てのデバッガコードを1つのバイナリに埋め込むことである。その場合には、単純なフォーキングは、デバッガを開始するのに十分である。これがセルフデバッギングにより提供される保護に対する攻撃を容易にするか否か、及びその程度は、未解決な研究課題である。
【0042】
実施態様
初期化及び終了処理
追加の初期化ルーチンを、保護されたバイナリに加えることができる。このルーチンは、バイナリがロードされるとすぐに呼び出される(それが高い優先権を割り当てたので)。その後に、バイナリのinitセクションにリストした全ての他のルーチンは実行される。
【0043】
この初期化ルーチンはフォーク()を呼び出し、それで親(parent)および子供(child)と呼ばれる2つのプロセスを生成する。一旦初期化ルーチンが終了すると、親プロセスは、通常は次の初期化ルーチンを呼び出すことによって実行を続ける。
【0044】
2つのオプションは、デバッガ及びデバッギの役割を割り当てるために存在する。フォークの後に、子プロセスは親プロセスにアタッチするか、或いは逆も又同じである。前者の場合、子供はデバッガになり、そして親はデバッギになり、後者の場合、役割は明らかに逆転する。
【0045】
前のオプションが好ましい。親プロセス(即ち、デバッギ)は、主要なアプリケーションプロセスのままであり、そしてそれは同じプロセスID(PID)を保つ。これは、最初のPIDに依存する全ての外部アプリケーション及びプロセス間通信路の継続実行または利用を容易にする。その理由は、例えば、それらは保護されたライブラリのローディング及びフォーキングの前に準備されたことである。
【0046】
しかしながら、この方式はそれ自体の課題を伴う。すでに述べたように、共有ライブラリは、プログラムの実行中はいつでも、(dlopen()およびdlclose()を使用して)ロードしたり、アンロードしたりすることができる。それ故、最初にロードされてフォークされたデバッガが、その初期化をまだ完了しない間に、保護された共有ライブラリがアンロードされて再びロードされることができるという潜在的課題がある。これは、両方ともデバッギにアタッチすることを試みる(そして1つは失敗する)、2つのデバッガプロセスの同時の存在に結果としてなることがあり得る。この状況を回避するために、我々は、dlopen()を呼び出したスレッドの実行をブロックする。それで、その時間までは、そのスレッドは、それがdlopen()によって得たハンドルを用いてdlclose()を呼び出すことができず、そしてそれは、ハンドルを別のスレッドにも渡すことができない。デバッギの初期化ルーチンの無限ループは、デバッガがその進行を許可する前に、ローディングスレッドが初期化ルーチンを出るのを防止する。
【0047】
初期化ルーチンはまた、終了化子をデバッギにインストールする。この終了化子は多くのことをしない。プログラム出口で(又は共有ライブラリがアンロードされるときに)、それは、SIGUSR1信号を上げることによって、この事実をミニデバッガに単に知らせ、ミニデバッガを全てのデバッギのスレッドから分離させて、デバッガプロセスをシャットダウンさせる。
【0048】
マルチスレッディングサポート
デバッガをアタッチすることは、特に保護された共有ライブラリの場合、簡単ではない。ライブラリがロードされるときに、アプリケーションは、いくつかのスレッドから成るかもしれない。それらのうちの1つだけは、dlopenへのその呼び出しの間にデバッギ初期化ルーチンを実行する。1つのフォークだけが実行されるので、これは良好であるが、それは、1つのスレッドだけが前節に記載の無限ループに入るという不利な面をもたらす。デバッギプロセスの他のスレッドは、動作し続けて、デバッギ初期化ルーチン又はデバッガ初期化ルーチンの実行中のいかなる時点でも新規なスレッドを生成するかもしれない。適当な保護を確実にするために、デバッガは、その初期化の一部としてデバッギプロセスのあらゆるスレッドにアタッチしなければならない。デバッガがその間にデバッギにおいて生成されるいかなるスレッドも見逃さないことを確実にするために、我々は、プロセスのスレッドごとにエントリを含む、/proc/[pid]/タスクディレクトリを使用する。デバッガプロセスは、このディレクトリのエントリを繰り返すことによって、そして新しいエントリが見つからないまで繰り返し続けることによって、全てのスレッドにアタッチする。PTRACE_ATTACH要求によって生じるスレッドにアタッチすると、スレッドも止められる(そしてデバッガは、OSによってこのイベントを通知される)。そして、それがその時以来新規なスレッドをもはや生じることができないことを意味する。それで、有限数のスレッドを生じるいかなるプログラムに対しても、全てのスレッドにアタッチする反復手順は、終了すると保証される。一旦全てのスレッドがアタッチされると、デバッギの無限ループは終わり、そしてその止められたスレッドは続くことができる。追加スレッドが、プログラム実行中に後で生成されると、デバッガは、OSによってそれらに自動的にアタッチされて、全ての必要なブックキーピングが実行されることができるように、それは信号を得る。
【0049】
制御フロー
制御フローを移行されたコードフラグメントに変形することは、いくつかの部分から成る。我々は、デバッガに通知するために例外を提起することを検討し、IDの転送は、デバッガにどんなフラグメントが実行されることになっているか、及びコードフラグメントごとに加えられるカスタマイズされたプロエピローグとエピローグを通知する。
【0050】
例外の提起
デバッガの実際の通知は、例外を提起させるいかなる命令によっても起こることがあり得る。我々の実施態様において、我々は、簡単にするためにソフトウェアブレークポイント(即ち、ARMv7に関するBKPT命令)を使用する。他のより顕著でない例外、例えば、違法であるか未確定の命令によって生じるそれらは、もちろん使用できる。この種の命令が、直接的な制御フロー(直接的な分岐又はフォールスルーパス)を経て届くとき、それらは、もちろん、静的に容易に検出できる。しかし、間接的な制御フロー転送がコードセクションのデータへジャンプするために用いられて、データビットが違法であるか未確定の命令に対応するとき、静的検出は非常により難しくなることがあり得る。同様に、それらのオペランドが「無効な」場合にだけ例外を投げる法的命令は、命令の目的を隠すために用いることができる。この種の命令は、ゼロ除算、無効なメモリアクセス(即ち、セグメンテーションフォールト)、又は無効なポインタ(バスエラーに結果としてなる)のデリファレンスを含む。
【0051】
IDの転送
それがあるコードフラグメントを実行することをデバッガに基本的に求めているので、我々は、例外を提起するデバッギのスレッドを要求スレッドと称する。
【0052】
デバッガは、OSによって要求について通知された後に、どのフラグメントを実行するべきか理解する必要がある。これを可能にするために、デバッギは、フラグメントのIDを多くの方法で渡すことができる。1つのオプションは、IDとして命令を誘導する例外のアドレスを単に使用することである。別のオプションは、例外を提起する直前に固定レジスタに、又は固定記憶場所にそれを配置することによってIDを渡すことである。我々の実施態様において、我々は後のオプションを使用した。デバッギの複数のスレッドが、異なるフラグメントを並行して要求できるので、記憶場所は汎用位置ではありえない。その代わりに、それはスレッドローカルであることを必要とする。各スレッドがそれ自体のスタックを有するので、我々は、要求スレッドのスタックのトップを介してフラグメントのIDを渡すことを選択した。
【0053】
例外を提起するために用いる命令のタイプに応じて、他の方法を同様に構想できる。例えば、除算(ゼロによる)命令の除数オペランドは、同様にIDを渡すために用いることができる。
【0054】
プロローグ及びエピローグ
ミニデバッガのデバッガループは、フラグメントが実行される前にデバッギのプログラム状態を取り出し、そしてその実行の後にそれをもとに戻す。標準ptrace機能は、こうするために用いる。
【0055】
移行されたコードフラグメントごとに、デバッグループは、コードフラグメントの前後それぞれで実行されるカスタムのプロローグ及びエピローグも含む。プロローグは、必要な値を構造体からレジスタにロードし、エピローグは、必要な値を書込んで構造体に戻す。プロローグは、それがフラグメント(いわゆるライブインレジスタ)において実際に用いられるレジスタにロードするだけであるという点でカスタマイズされる。エピローグは、ライブアウトであり(即ち、デバッギにおいて消費される)、そしてコードフラグメントに上書きされた値を格納するだけである。
【0056】
メモリアクセス
移行されたコードフラグメントのロード又は格納動作ごとに、デバッギのメモリへのアクセスが必要である。この種のアクセスを実行する複数のオプションが存在する。第1は、ptrace機能を単に使用することであり、デバッガは、デバッギのアドレス空間において読込み及び書込みを行うために、PTRACE_PEEKDATA及びPTRACE_POKEDATA要求を実施できる。この場合に、読込み又は書込みが行われる語当たり、ptraceシステムコールが必要であり、それは著しいオーバーヘッドに結果としてなる。いくつかの最近のLinux(登録商標)版は、より広いアクセスをサポートするが、それらは、Android(登録商標)のように、まだ至る所で利用できるわけではない。
【0057】
第2のオプションは、デバッガにおいてデバッギの/proc/[pid]/memファイルを開き、次に、このファイルに単に読込み又は書込みを行うことである。これは実施するのがより容易であり、そしてより広いデータは、単一のシステムコールによって読込み又は書込みを行うことができるので、しばしば、この方法はより急速である。別のプロセスの/proc/[pid]/memへの書込みは、Linux(登録商標)/Android(登録商標)カーネルの全ての版でサポートされているわけではなく、しかしながら、それで我々のプロトタイプでは、書込み要求は依然として第1のオプションによって実施される。
【0058】
第3のオプションは、第2のものに基づいている。バイナリリライターが、どのメモリページが移行されたコードフラグメントでアクセスするかについて決定できる場合、デバッグループは、オプション2を使用してそれらのページをデバッガアドレス空間に実際に複製できる。デバッガのフラグメントは、次に、複製されたページにアクセスするために、正規のロード及び格納動作を単に実行し、そしてフラグメントが実行した後に、更新されたページは、複製されてデバッギへ戻される。例えば、コードフラグメントが、スタックのバッファにアクセスするためにループを含む場合、このオプションはより急速であり得る。我々が第3のオプションを前の2つのオプションと比較するために行った実験で、この技術がわずか8つのメモリアクセスのために価値があるかもしれないことが分かった。しかしながら、我々は、我々のプロトタイプにおいてそれに対する確実なサポートを実施しなかった。どのページがコードフラグメントによってアクセスされるか決定するための保守的なリンクタイム分析は、この点で将来の仕事のままである。
【0059】
全ての割当られたメモリ(又は少なくともヒープ)が、デバッギとデバッガプロセス間の共有メモリとして割り当てられるように、第4の潜在的オプションは、例えば、カスタムヒープメモリ管理ライブラリ(malloc,free,…)を提供することによって、デバッギに適応することである。次に、デバッガのコードフラグメントは、データに直接アクセスすることができる。勿論、フラグメントは、2つのアドレス空間の間でのアドレスの変換を含むために、依然として書き換えることを必要とするが、おそらく、このオプションのオーバーヘッドは、他のオプションのオーバーヘッドより非常に小さいことがあり得る。このオプションを実施してそれを評価することは、この点で将来の仕事のままである。
【0060】
セキュリティの点で、いろいろなオプションは、それらが、攻撃者がプログラムの最初のセマンテイクスをリバースエンジニアリングして、セルフデバッギング版を最初のプログラム相当品に分解することが難しくなるように影響を与えるという点で、おそらく異なる影響も有する。
【0061】
セルフデバッギングの他の保護との組み合わせ
MATE攻撃に対する強力なソフトウェア保護を提供するために、追加の保護技術を使用できる。例えば、セルフデバッギングに加えて、静的解析を防止する難読化は、あらゆる種類の攻撃を防止するために不正加工防止技術と共に使用できる。
【0062】
例えば、セルフデバッギング方法を実施するバイナリリライターは、また、多くの他の保護、例えば、以下の1つ以上を適用できる。
制御フロー難読化:不明確な述部の周知の難読化、制御フローフラット化、及び 分岐機能、
コード・レイアウト・ランダム化:コードレイアウトの間、全ての機能からのコ ードは混ぜられて、レイアウトはランダム化される、
コード可動性:コードフラグメントが静的バイナリから取外されて、いわゆるモ バイルコードとして、実行時のアプリケーションにダウンロードされるだけで ある技術、
コードガード:ハッシュがプロセスのコードにわたって計算される技術のオンラ イン及びオフラインの実施は、コードが変えられなかったことを検査するため に空間をアドレス指定する、
制御フロー完全性:復帰アドレスが内部機能が外部コードから呼び出されること を防止するために検査される軽量技術、
命令セット仮想化:固有コードがネイティブに実行される代わりに埋め込みバー チャルマシンにより解釈されるバイトコードに翻訳される技術。
【0063】
セルフデバッギング技術をそれらの保護の全てと組み合わせることは、実際にはいかなる課題も提起しない。リンク時間リライターにおいて、保護の全てに対して全ての変換を実行するために、そしてそれらの技術が実際に構成しないときに複数の技術が同じコードフラグメントに適用されることを防止するために良好な命令を決定することは困難ではない。例えば、モバイルコードは、ランダム化された位置へ再配置される。全ての保護を処理することは、なんらかのブックキーピングを間違いなく必要とするが、複雑なことは何もない。
【0064】
実行時動作に関しては、技術は同様に構成する。複数の技術は、初期化子及び終了化子を必要とするが、デバッガプロセスにおいて、そのデバッガプロセスがデバッガであり、そしてコード可動性又はその他の技術のための別のクライアントであってはならないだけであるので、我々は他の保護の初期化子を実行することを望まない。他の初期化子が実行するのを防止するために、セルフデバッガ初期化子は、最高優先度を与えられる。バイナリ又はライブラリがロードされるときに、それらは最初に実行され、そしてデバッガ初期化ルーチンは、実初期化子並びにデバッグループの両方とも実際に実施する。ルーチンは、従って、決して終わらない(即ち、終了化子が呼び出されない限り)、そして、それ故、制御は、バイナリに存在するかもしれない他の初期化子へ決して転送されない。
【0065】
評価
評価プラットフォーム
セルフデバッガの1つの実施態様は、ARMv7プラットフォームを目標とする。具体的に、この実施態様は、Linux(登録商標)3.15及び(ルート化を解除された)Android(登録商標)4.3+4.4の実施を目標として、広範囲に評価した。技術がLinux(登録商標)(4.7)及びAndroid(登録商標)(7.0)の最新版でまだ機能し、そしてそれは実際このケースであることが更に確認された。
【0066】
テストハードウェアは、いくつかのデベロッパーボードから構成された。Linux(登録商標)の場合は、シングルコアのテキサスインスツルメンツOMAP4プロセッサを特徴とするPanda Board、ダブルコアのSamsung Exynosプロセッサを特徴とするArndale Board、及びシングルコアのFreescale i.MX6qプロセッサを特徴とするBoundary Devices Nitrogen6X/SABRE Lite Boardが使われた。後のボードは、Android(登録商標)版にも用いられた。
【0067】
ツールチェーンにおいて、GCC 4.8、LLVM 3.4及びGNU binutils 2.23が用いられた。コードは、以下のフラグによってコンパイルされた:-Os-march=armv7-a-marm-mfloat-abi=softfp-mfpu=neon-msoft-float。
【0068】
使用事例
セルフデバッギング方式は、複数の使用事例において機能することを示した。例えば、デジタル権利管理シナリオにおいて、以下の実際的な考慮点がみられた。
【0069】
この使用事例は、Android(登録商標)メディアフレームワーク及びAndroid(登録商標)DRMフレームワークのために、C及びC++で書かれる、2つのプラグインから構成された。これらのライブラリは、暗号化された動画にアクセスして、それらを解読するために必要である。Java(登録商標)でプログラムされるビデオアプリは、ビデオにアクセスするGUIとして用いられる。このアプリは、Android(登録商標)のメディアサーバー及びDRMフレームワークと通信して、フレームワークにそれがプラグインを必要とするベンダーを知らせる。要求に応じて、これらのフレームワークは、次に、プラグインをロードする。具体的に、これらのサーバーは、Android(登録商標)で動作するメディアサーバー及びdrmserverプロセスである。
【0070】
実験および開発の間に、この使用事例をこの技術のための完全なストレステストにするいくつかの特徴が観察された。第1に、メディアサーバーは、マルチスレッド化されて、常に新規なスレッドを生成して、キルする。第2に、プラグインライブラリは、ロードされて、しばしばアンロードされる。時々、ライブラリの初期化が終わる前でも、アンローディングは開始される。第3に、プロセスがクラッシュするとすぐに、新規な例は開始する。時々、これによって、Java(登録商標)ビデオプレーヤが中断されない機能を続けることができて、時々、それはそうしない。これは、我々の技術の実施をデバッグすることをそれがすでに単純なアプリケーション用であるより更に複雑にする。第4に、メディアサーバー及びdrmserverは、頻繁なプロセス間通信に関係している。にもかかわらず、成功した実施態様は、上記の原則に基づいて達成された。
【0071】
技術は、多くの他の使用事例シナリオに適用できる。例えば、セキュリティが望ましいその他のシナリオのモバイルバンキングにおいても。
図4は、コンピュータに本願明細書で述べる技法のいかなる1つ以上も実行させるために、一組の命令を実行できるコンピュータ400の1つの実施態様のブロック図を示す。代替の実施態様において、コンピュータは、ローカル・エリア・ネットワーク(LAN)、イントラネット、エクストラネット、又はインターネットにおいて、他の機械に接続する(例えば、ネットワーク化する)ことができる。コンピュータは、クライアント・サーバー・ネットワーク環境のサーバー又はクライアントマシンの能力で、或いはピア・ツー・ピア(又は分散される)ネットワーク環境のピアマシンとして作動できる。コンピュータは、パーソナルコンピュータ(PC)、タブレット型コンピュータ、セットトップボックス(STB)、パーソナル携帯情報機器(PDA)、移動電話、ウェブ機器、サーバー、ネットワークルーター、スイッチ又はブリッジ、或いはその機械によって、とられる措置を特定する一組の命令(経時的又はその他)を実行できるいかなる機械でもあり得る。更に、単一のコンピュータだけが例示されるが、用語「コンピュータ」は、本願明細書において述べる技法のいかなる1つ以上も実行するために一組(又は複数の組)の命令を個々に、又は共同で実行する機械(例えば、コンピュータ)のいかなるコレクションも含むとも受け取られる。
【0072】
例示のコンピュータ400は、処理装置402、主メモリ404(例えば、読出し専用メモリ(ROM)、フラッシュメモリ、ダイナミック・ランダム・アクセス・メモリ(DRAM)、例えば、同期型DRAM(SDRAM)又はラムバスDRAM(RDRAM等))、スタティックメモリ406(例えば、フラッシュメモリ、スタティック・ランダム・アクセス・メモリ(SRAM)等)、及び二次メモリ(例えば、データ記憶装置418)を含み、それらはバス430を介して互いに通信する。
【0073】
処理装置402は、1つ以上の汎用プロセッサ、例えば、マイクロプロセッサ、中央演算処理装置等を表す。より詳しくは、処理装置402は、複合命令セット演算(CISC)マイクロプロセッサ、減少した命令セツト演算(RISC)マイクロプロセッサ、非常に長い命令ワード(VLIW)マイクロプロセッサ、他の命令セットを実施するプロセッサ、又は命令セットの組合せを実施するプロセッサであり得る。処理装置402は、1つ以上の特殊目的の処理装置、例えば、特定用途向け集積回路(ASIC)、フィールド・プログラマブル・ゲート・アレイ(FPGA)、デジタル信号プロセッサ(DSP)、ネットワークプロセッサ等でもあり得る。処理装置402は、本願明細書に述べる動作及びステップを実行するための処理ロジック(命令422)を実行するように構成される。
【0074】
コンピュータ400は、ネットワークインタフェース装置408を更に含むことができる。コンピュータ400は、ビデオ・ディスプレイ・ユニット410(例えば、液晶ディスプレイ、LCD)又は陰極線管、CRT、英数字入力装置412(例えば、キーボード又はタッチスクリーン)、カーソル制御装置414(例えば、マウス又はタッチスクリーン)、及び音声装置416(例えば、スピーカ)も含むことができる。
【0075】
データ記憶装置418は、本願明細書に記載の技法又は機能のいかなる1つ以上も実施する1つ以上の組の命令422が格納される1つ以上の機械可読記憶媒体(又はより詳しくは1つ以上の非一時的コンピュータ可読記憶媒体)428を含むことができる。命令422は、コンピュータシステム400、主メモリ404、及びコンピュータ可読記憶媒体も構成する処理装置402によるその実行の間に主メモリ404内に、及び/又は処理装置402内に完全に又は少なくとも部分的にあることもできる。
【0076】
上記の各種の方法は、コンピュータプログラムによって実施できる。コンピュータプログラムは、コンピュータに上記の各種の方法の1つ以上の機能を実行するように命令するように調整されるコンピュータコードを含むことができる。この種の方法を実行するためのコンピュータプログラム及び/又はコードは、1つ以上のコンピュータ可読媒体又は、更に一般的にいえば、コンピュータプログラム製品に関して、装置、例えばコンピュータに提供されることができる。コンピュータ可読媒体は、一過性又は非一過性であり得る。1つ以上のコンピュータ可読媒体は、例えば、データ伝送のための、例えばインターネットを通じてコードをダウンロードするための電子的、磁気的、光学的、電磁気的、赤外線、又は半導体のシステム、或いは伝播媒体であり得る。或いは、1つ以上のコンピュータ可読媒体は、1つ以上の物理的なコンピュータ可読媒体、例えば、半導体又は固体メモリ、磁気テープ、着脱可能なコンピュータディスケット、ランダム・アクセス・メモリ(RAM)、読出し専用メモリ(ROM)、固定磁気ディスク、及び光ディスク、例えばCD-ROM、CD-R/W又はDVDという形をとることができる。
【0077】
実施態様において、本願明細書に記載のモジュール、構成要素、及び他の特徴(例えば、
図4に関する制御ユニット410)は、個別の構成要素として実施されるか、或いは、ハードウェア構成要素、例えばASICS、FPGA、DSP、又は個別化サーバーの一部としての同様の装置の機能において集積化される。
【0078】
「ハードウェア構成要素」は、特定の動作を実行できる有形の(例えば、非一過性の)物理的な構成要素(例えば、一組の1つ以上のプロセッサ)であり、そして特定の物理的な方法で構成するか又は配置することができる。ハードウェア構成要素は、特定の動作を実行するように永続的に構成される専用の回路又はロジックを含むことができる。ハードウェア構成要素は、特殊目的のプロセッサ、例えば、フィールド・プログラマブル・ゲート・アレイ(FPGA)又はASICであるか、或いはそれを含むことができる。ハードウェア構成要素は、特定の動作を実行するためにソフトウェアによって一時的に構成されるプログラム可能なロジック又は回路を含むこともできる。
【0079】
従って、「ハードウェア構成要素」というフレーズは、特定の方法で動作するために、又は本願明細書に記載の特定の動作を実行するために、物理的に構成されるか、永続的に構成される(例えば、物理的に組み込まれる)か、又は一時的に構成される(例えば、プログラムされる)ことができる有形の実体を含むと理解しなければならない。
【0080】
加えて、モジュール及び構成要素は、ハードウェア装置内でファームウェア又は機能回路として実施できる。更に、モジュール及び構成要素は、ハードウェア装置とソフトウェア構成要素のいかなる組合せでも、又は、ソフトウェア(例えば、機械可読媒体又は伝送媒体に格納されるかさもなければ組み入れられるコード)だけで実施できる。
【0081】
特に述べられない限り、以下の説明から明らかな様に、説明の全体にわたって、「受け取る」、「決定する」、「比較する」、「可能にする」、「維持する」、「識別する」、「置き換える」等のような用語を用いる説明は、コンピュータシステムのレジスタ及びメモリの中の物理的(電子的)量として表わされるデータを操作して、コンピュータシステムのメモリ又はレジスタ、或いは他のこの種の情報記憶、伝送、又は表示装置の中の物理的量として同様に表わされる他のデータに変換するコンピュータシステム又は類似の電子コンピュータの動作及びプロセスに関連すると認められる。
【0082】
前記説明が例証を示すものであり、限定的ではないことを目的とすることを理解すべきである。多くの他の実施態様は、前記説明を読んで理解すると、即座に当業者にとって明らかである。本開示が特定の実施態様に関して説明されたけれども、本開示は、記載された実施態様に限定されなくて、添付の請求項の精神及び範囲内の変更態様及び改変で実践可能であると認識される。従って、本明細書及び図面は、限定的な意味よりもむしろ例示的な意味で考えるべきである。本開示の範囲は、従って、この種の請求項が有する等価物の完全な範囲とともに、添付の請求の範囲に関して決定しなければならない。