web-dev-qa-db-ja.com

gdbを使用して、指定された実行可能ファイルの外部のアセンブリコードをシングルステップ実行すると、「現在の関数の境界が見つかりません」というエラーが発生します。

私はgdbのターゲット実行可能ファイルの外にいて、そのターゲットに対応するスタックさえ持っていません。とにかくシングルステップにしたいので、x86アセンブリの専門家ではないので、アセンブリコードで何が行われているかを確認できます。残念ながら、gdbはこの単純なアセンブリレベルのデバッグを拒否しています。適切なブレークポイントで設定および停止できますが、1ステップ先に進むとすぐに、gdbは「現在の関数の境界が見つかりません」というエラーを報告し、EIPは変わりません。

さらなる詳細:

マシンコードはgcc asmステートメントによって生成され、objdump -dの出力から、実行するカーネルメモリの場所にコピーしました。ローダーを使用してオブジェクトコードを再配置アドレスにロードする簡単な方法は気にしませんが、カーネルモジュールでロードする必要があることに注意してください。

別の代替手段は、gdbに提供する偽のカーネルモジュールまたはデバッグ情報ファイルを作成し、この領域がプログラムコード内にあると信じさせることです。 gdbは、カーネル実行可能ファイル自体で正常に機能します。

(本当に知りたい人のために、実行時にVMware VM内のLinuxカーネルデータスペースにコードを挿入し、VMware Workstationの組み込みgdbを介してカーネルをデバッグするgdbリモートからデバッグします注:私はカーネルのエクスプロイトを書いているのではなく、プロトタイプを書いているセキュリティの大学院生です。)

(アセンブリ内の各命令にブレークポイントを設定できます。これは動作しますが、x86アセンブリ命令のサイズが異なり、再起動するたびにアセンブリの場所が変わるため、しばらくするとかなり面倒になります。)

79
Paul

stepiまたはnextisiまたはniと省略可能)を使用して、マシンコードをステップ実行できます。

103

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)
142
ephemient

ここでできる最も便利なことはdisplay/i $pc、R Samuel Klatchkoの回答で既に示唆されているようにstepiを使用する前。これは、毎回プロンプトを出力する直前に現在の命令を逆アセンブルするようgdbに指示します。 Enterキーを押し続けると、stepiコマンドを繰り返すことができます。

(詳細については 別の質問に対する私の答え を参照してください-その質問のコンテキストは異なりますが、原則は同じです。)

23