4

デバッガー (olly、IDA、gdb などの一般的な x86 ring3 デバッガー) がソフトウェア ブレークポイントを仮想アドレス 0x1234 に設定するとします。

これは、0x1234 の任意のオペコードを「0xCC」に置き換えることで実現されます。ここで、デバッグ対象プロセスがこの 0xCC 命令を実行し、ソフトウェア例外を発生させ、デバッガーがこれをキャッチすると仮定しましょう。

デバッガーはメモリの内容を検査し、登録し、いくつかのことを行います..そして今、デバッグ対象プロセスを再開したいと考えています。

これは私の知る限りです。今から、それは私の仮定です。

デバッガーは、実行を再開するために、debugee の元のオペコード (0xCC に置き換えられた) を回復します。

デバッガーは、デバッグ対象の CONTEXT の EIP を操作して、回復された命令をポイントします。

デバッガーが例外を処理し、debugee がブレークポイントから再開します。

しかし、デバッガーはブレークポイントを維持したいと考えています。デバッガーはこれをどのように管理できますか?

4

2 に答える 2

0

短くて一般的な人々の言葉で:

デバッグ状態に入るのはアトミック操作であるため、プロセッサはアーキテクチャ内の他の命令と同じように、プロセッサに入り、デバッグ状態を終了しますX86gdbのドキュメントARMを参照して、それがどのように機能し、使用できるかについて説明します。

ARM および X86 仕様のハイライトを次に示します。

アームで:

SW (ソフトウェア) ブレークポイントは、コードをステップ実行または実行する直前に、ブレークポイント位置の命令オペコードを特別な「ブレークポイント」命令に一時的に置き換えることによって実装されます。コアがブレークポイント命令を実行すると、強制的にデバッグ状態になります。SW ブレークポイントは、ターゲット メモリの変更に依存しているため、RAM にのみ配置できます。

HW (ハードウェア) ブレークポイントは、ウォッチポイント ユニットをプログラミングして、特定のメモリ位置からの命令フェッチのコア バスを監視することによって設定されます。HW ブレークポイントは、RAM または ROM の任意の場所に設定できます。命令がコピーされるコード (スキャッターローディング)、変更されるコード、またはプロセッサ MMU がメモリ領域を再マップするコードをデバッグする場合は、HW ブレークポイントを使用する必要があります。これらのシナリオでは、SW ブレークポイントは失われたり上書きされたりする可能性があるため、信頼できません。

X86では:

ソフトウェア ブレークポイントの仕組みは非常に単純です。特に x86 について言えば、ソフトウェア ブレークポイントを設定するために、デバッガーはターゲット命令の最初のバイトに int 3 命令 (オペコード 0xCC) を書き込むだけです。これにより、ブレークポイントを設定したアドレスに実行が転送されるたびに、割り込み 3 が発生します。これが発生すると、デバッガーは「ブレークイン」し、ブレークポイントを設定したときに 0xCC オペコード バイトを命令の元の最初のバイトと交換するため、同じブレークポイントにすぐに到達することなく実行を続行できます。実際には、ブレークポイントから実行を継続し、すぐにヒットするのではなく、将来の使用のためにブレークポイントをアクティブに保つことができる、もう少し魔法が関係しています。これについては、今後の投稿で説明します。

ハードウェア ブレークポイントは、その名前から想像できるように、特別なハードウェア サポートによって設定されます。特に x86 の場合、これには「Dr」レジスター (デバッグ レジスター用) として知られている、あまり知られていないレジスターの特別なセットが含まれます。これらのレジスタを使用すると、最大 4 つのアドレス (x86 の場合、これは非常にプラットフォームに固有です) を設定できます。これらのアドレスは、読み取り、読み取り/書き込み、または実行のいずれかのときに、実行を停止して制御する特別な例外をプロセッサにスローさせます。デバッガに転送される

于 2013-04-18T20:12:44.683 に答える