私はgdbのターゲット実行可能ファイルの外にいて、そのターゲットに対応するスタックさえ持っていません。とにかくシングルステップにしたいので、x86アセンブリの専門家ではないので、アセンブリコードで何が行われているかを確認できます。残念ながら、gdbはこの単純なアセンブリレベルのデバッグを拒否しています。適切なブレークポイントで設定および停止できますが、1ステップ先に進むとすぐに、gdbは「現在の関数の境界が見つかりません」というエラーを報告し、EIPは変わりません。
さらなる詳細:
マシンコードはgcc asmステートメントによって生成され、objdump -dの出力から、実行するカーネルメモリの場所にコピーしました。ローダーを使用してオブジェクトコードを再配置アドレスにロードする簡単な方法は気にしませんが、カーネルモジュールでロードする必要があることに注意してください。
別の代替手段は、gdbに提供する偽のカーネルモジュールまたはデバッグ情報ファイルを作成し、この領域がプログラムコード内にあると信じさせることです。 gdbは、カーネル実行可能ファイル自体で正常に機能します。
(本当に知りたい人のために、実行時にVMware VM内のLinuxカーネルデータスペースにコードを挿入し、VMware Workstationの組み込みgdbを介してカーネルをデバッグするgdbリモートからデバッグします注:私はカーネルのエクスプロイトを書いているのではなく、プロトタイプを書いているセキュリティの大学院生です。)
(アセンブリ内の各命令にブレークポイントを設定できます。これは動作しますが、x86アセンブリ命令のサイズが異なり、再起動するたびにアセンブリの場所が変わるため、しばらくするとかなり面倒になります。)
stepi
またはnexti
(si
またはni
と省略可能)を使用して、マシンコードをステップ実行できます。
gdb
の代わりに、gdbtui
を実行します。または、-tui
スイッチを使用してgdb
を実行します。または押す C-x C-a gdb
を入力した後。これでGDBの [〜#〜] tui [〜#〜] モードになりました。
layout asm
を入力して、上部ウィンドウにアセンブリを表示します。これは自動的に命令ポインターに従いますが、デバッグ中にフレームを変更したりスクロールしたりすることもできます。押す C-x s run continue up down finish
などが単一のキーに短縮され、プログラムを非常に迅速に進めることができるSingleKeyモードに入ります。
+ -------------------------------------------- ------------------------------- + B +> | 0x402670 <main> Push%r15 | | 0x402672 <main + 2> mov%edi、%r15d | | 0x402675 <main + 5> Push%r14 | | 0x402677 <main + 7> Push%r13 | | 0x402679 <main + 9> mov%rsi、%r13 | | 0x40267c <main + 12> Push%r12 | | 0x40267e <main + 14> Push%rbp | | 0x40267f <main + 15> Push%rbx | | 0x402680 <main + 16> sub $ 0x438、%rsp | | 0x402687 <main + 23> mov(% rsi)、%rdi | | 0x40268a <main + 26> movq $ 0x402a10,0x400(%rsp)| | 0x402696 <main + 38> movq $ 0x0,0x408(%rsp)| | 0x4026a2 <main + 50> movq $ 0x402510,0x410( %rsp)| + ---------------------------------------- ----------------------------------- + 子プロセス21518 In:main Line:?? PC:0x402670 (gdb)ファイル/opt/j64-602/bin/jconsole /opt/j64-602/bin/jconsole...done. からのシンボルの読み取り(デバッグなしシンボルが見つかりました)... done。 (gdb)layout asm (gdb)start (gdb)
ここでできる最も便利なことはdisplay/i $pc
、R Samuel Klatchkoの回答で既に示唆されているようにstepi
を使用する前。これは、毎回プロンプトを出力する直前に現在の命令を逆アセンブルするようgdbに指示します。 Enterキーを押し続けると、stepi
コマンドを繰り返すことができます。
(詳細については 別の質問に対する私の答え を参照してください-その質問のコンテキストは異なりますが、原則は同じです。)