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


88

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

追加の詳細:

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

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

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

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


賢いksplice.comの人々は、「偽の」カーネルモジュールを組み立ててロードすることにより、データとコードをカーネルに挿入します。そして、彼らがそれを行うことができるのなら、なぜあなたはできないのですか?;-)
ephemient 2010年

回答:


118

あなたは使用することができますstepinexti(略称することができsiたりni、あなたのマシンコードをステップ実行)。


1
ワオ。振り返ってみると、私はステップを忘れていません。gdbにはソースコードがなかったので、そのステップはアセンブリ命令に戻ると思いました。
ポール

1
注:アセンブリプログラムに対して「breakmain」、「run」と入力できないことがよくあります。代わりに「layoutasm」、「start」と入力してください。私は以下のメッセージを読んでこれを得ましたが、この投稿を読んでいる他の誰かはそれほど辛抱強くないかもしれません。
ドミトリー

1
@Dmitrystartは、tbreak mainその後に続くrun(注:のtbreak代わりにbreak)と同等です
Ruslan

154

の代わりにgdb、を実行しgdbtuiます。またはgdb-tuiスイッチを使用して実行します。またはC-x C-a、を入力してからを押しgdbます。これで、GDBのTUIモードになります。

Enterキーlayout asmを押して、上部ウィンドウの表示アセンブリを作成します。これは、命令ポインターに従いますが、デバッグ中にフレームを変更したり、スクロールしたりすることもできます。を押しC-x srun continue up down finishシングルキーモードに入ります。ここでは、などはシングルキーと省略され、プログラムを非常にすばやくウォークスルーできます。

   + ------------------------------------------------- -------------------------- +
B +> | 0x402670 <メイン>プッシュ%r15 |
   | 0x402672 <main + 2> mov%edi、%r15d |
   | 0x402675 <main + 5>プッシュ%r14 |
   | 0x402677 <main + 7>プッシュ%r13 |
   | 0x402679 <main + 9> mov%rsi、%r13 |
   | 0x40267c <main + 12>プッシュ%r12 |
   | 0x40267e <main + 14>プッシュ%rbp |
   | 0x40267f <main + 15>プッシュ%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入力:メインライン:?? PC:0x402670
(gdb)ファイル/ opt / j64-602 / bin / jconsole
/ opt / j64-602 / bin / jconsole ...からシンボルを読み取ります。
(デバッグシンボルが見つかりません)...完了しました。
(gdb)レイアウトasm
(gdb)開始
(gdb)

26

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

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

弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.