9

プログラムのある時点で実行されるコードのアセンブリ コードがあります。メモリ内のコードのアドレスがわかりません。

現在の命令が入力された命令と一致する場合、gdb を中断させることはできますか?

たとえば、gdb が次の命令に達するたびに gdb を中断させたいとします。

leaq        0x000008eb(%rip),%rax
4

3 に答える 3

3

メモリ内のコードのアドレスがわかりません。

そのアドレスを見つけるのを妨げているのは何ですか? を実行objdump -dし、目的の命令を見つけ、そのアドレスを書き留めます。問題が解決しました?(これは、共有ライブラリにも簡単に拡張されます。)

于 2012-12-25T16:04:15.973 に答える
2

いいえ、これは不可能であり、実装するのも非常に非効率的です。

デバッガーは通常、次の 2 種類のブレークポイントをサポートしています。

  • ハードウェア ブレークポイント: デバッガーは、メモリ内の場所が変更されるなど、何らかのイベントが発生したときに特別な例外割り込みを発生させるように CPU に要求します。
  • ソフトウェア ブレークポイント: デバッガーは、ブレークポイントのアドレスにあるオペコードを特別な "トラップ" 命令 ( x86 アーキテクチャではint 3/ ) に置き換えます。0xcc

現在の命令のオペコードを一致させるには、CPU サポートがハードウェア ブレークポイントを挿入する必要があるか、デバッガがソフトウェア ブレークポイントを使用するためのアドレスを知る必要があります。

理論的には、デバッガーはメモリ全体で命令のバイト シーケンスを検索できますが、バイト シーケンスは命令の途中またはデータ内でも発生する可能性があるため、誤検知が発生する可能性があります。

アセンブリ命令は可変長であるため、制御が任意のアドレスにジャンプしたり、コード自体が変更されたりする可能性があります。特定の命令を見つけるためにメモリ領域全体を逆アセンブルすることも簡単ではありません。

したがって、基本的に、任意のアセンブリ コードで命令を確実に見つける唯一の方法は、命令レベルでシングル ステップを実行することです。そして、これは非常にコストがかかります。今日のハードウェアでは、すべての命令を 1 ステップ実行すると、わずかなライブラリ呼び出しでもprintf()数分かかる可能性があります。

于 2012-12-25T15:49:32.633 に答える