5

GDB のようなデバッグ機能は、eflags レジスタの TF フラグを設定することで機能します。これにより、プロセッサによる命令の実行ごとに例外が発生し、gdb のようなツールがデバッグを制御できるようになります。 MONITOR TRAP FLAG (現在のインテル ソフトウェア マニュアル 3c の 15 ページ) と呼ばれるフラグを設定する必要があるのと同じことです。これにより、すべての命令がハイパーバイザーにデバッグを与えるたびに、仮想マシンが終了 (VMEXIT) されます。

ハイパーバイザーは、VM (ゲスト) のほぼすべてのビット/レジスタを設定できます。そのようなフラグがアーキテクチャ (EFLAG) に既に存在するのに、VMCS (仮想マシン制御構造) に別のフラグが必要なのはなぜですか??

EFLAGS が使用されている場合、ゲストが VMM (ハイパーバイザー) の意図を単一ステップにオーバーライドできるためです。

A:制御できない場合、ハードウェアをエミュレートする意味は何ですか??

B: BTF (ブランチ トラップ フラグ) を設定する必要がある問題に直面しています (PG 689 ボリューム 3a INTEL ソフトウェア マニュアル)。通常のシナリオでは、これによりすべての分岐命令で DEBUG EXCEPTION が発生しますが、VM でこれを行いたいため、VMCS でどのビットを設定するかを判断できません。シングルステッピングの場合のように、これを行う直接的な方法はないようです。他の手段を使用して同じことを行う方法があれば、誰でも教えてもらえますか?

ありがとう

4

1 に答える 1

4

いいえ、Branch Monitor Trap Flag はありません。

インテルはおそらくそれを作ることができましたが、そうではありませんでした.

詳細

まず、用語を確認して定義しましょう。

[これはすべて Intel x86 にのみ関連することに注意してください]

トラップフラグ (TF)

質問で説明されているように、命令の実行後に #DBG を引き起こします (例外 0x1 を介してトラップします)。RFLAGS のビット 8 を使用して制御されます。

分岐トラップ フラグ (BTF)

TLDR: BTF は TF の動作を変更して、ブランチでのみ例外をトリガーします。

Intel SDM の 2016 年 4 月版から:

ソフトウェアが IA32_DEBUGCTL MSR の BTF フラグ (ビット 1) と EFLAGS レジスタの TF フラグの両方を設定すると、プロセッサは分岐を引き起こす命令の後でのみシングルステップ デバッグ例外を生成します。[1] このメカニズムにより、デバッガーは、分岐によって引き起こされた制御転送をシングルステップで実行できます。この「分岐シングル ステッピング」は、命令シングル ステッピングが検索をさらに絞り込む前に、バグを特定のコード ブロックに分離するのに役立ちます。プロセッサは、デバッグ例外を生成すると BTF フラグをクリアします。デバッガーは、プログラムの実行を再開する前に BTF フラグを設定して、分岐でシングル ステップを続行する必要があります。

[1] タスク スイッチを引き起こす CALL、IRET、および JMP の実行は、(BTF フラグの値に関係なく) シングルステップ デバッグ例外を引き起こしません。タスクへの切り替え時にデバッグ例外を必要とするデバッガは、そのタスクの TSS で T フラグ (デバッグ トラップ フラグ) を設定する必要があります。セクション 7.2.1「タスク状態セグメント (TSS)」を参照してください。</p>

監視トラップフラグ (MTF)

MTF は VMCS 内のビットで、ゲスト中に特定の命令境界でモニター トラップ フラグ VMEXIT をトリガーします。

一般的に言えば、ゲストが前進するたびに終了が発生し、MTF VMEXIT よりも優先度の高いホスト側は何も発生しません。REP MOV (割り込み可能な命令) や SMI (ホスト OS からは見えない割り込み) などの奇妙なエッジ ケースがあります。詳細については、SDM の Monitor Trap Flag セクションを参照してください (2016 年 4 月の 25.5.2)。

反応

そのようなフラグがアーキテクチャ (EFLAG) に既に存在するのに、VMCS (仮想マシン制御構造) に別のフラグが必要なのはなぜですか?

ホストとゲストの状態は分離する必要があります。GDB を実行しているゲストをデバッグする場合、ゲスト内の例外ではなく、ホストが VMEXIT をトリガーできる必要があります。トラップ フラグが設定されている場合、デフォルトでは、現在のコンテキスト内で例外が発生することに注意してください (ゲストで実行している場合はゲストの、ホストで実行している場合はホストの)。

ホストは、ゲストの TF を強制的に設定し、VMCS の例外ビットマップを使用してデバッグ例外で VMEXIT を構成することにより、MTF を使用せずにデバッグを試みることができました。残念ながら、ゲストがデバッグ例外も有効にしている場合、ホストがデバッグ例外の所有者を明確に知る方法はありません (私の記憶が正しければ、RFLAGS への書き込みで終了する方法はありません)。MTF の存在により、デバッガーを実行している VM をデバッグできます。

...他の手段を使用して同じことを行う方法があれば、誰か教えてもらえますか?

分岐監視トラップフラグはありません。ゲストの RIP (VMCS にあるはず) でデコードされた命令を調べることで同等のものを実装できますが、それには余分な VMEXITS が必要になります。明らかに、それは理想的ではありません。

ゲストに入る前に BTF を設定すると、事態はすぐに混乱します。ホストに関連する BTF ではなく、ゲストの BTF として認識されます。VMCS で MTF も設定した場合、BTF は MTF VMEXIT を遅らせません。一方で、ゲストの次のデバッグ トラップを遅らせます。

ゲスト VMEXIT が次に実行されるたびに、BTF がデバッグ例外によってまだクリアされていない場合は、BTF が上書きされます (IA32_DEBUGCTL は終了時にクリアされます)。MSR LOAD/STORE リストを使用して値を保存することはできますが、それではあまり効果がありません。

于 2016-06-01T02:02:41.780 に答える