6

私はいくつかの実験を行っており、システムコール中にスタックに保存されているもの (ユーザーランドプロセスの保存された状態) を確認できるようにしたいと考えています。http://lxr.linux.no/#linux+v2.6.30.1/arch/x86/kernel/entry_32.Sによると、レジスタのさまざまな値がスタック ポインタの特定のオフセットに保存されていることがわかります。これは、スタックに保存されているものを調べるために使用しようとしているコードです (これは、私が作成したカスタム システム コールにあります)。

asm("movl 0x1C(%esp), %ecx");
asm("movl %%ecx, %0" : "=r" (value));

value は unsigned long です。

現時点では、この値は予期されたものではありません (ds のユーザー値として 0 が保存されていることが示されています)。

スタック ポインターのオフセットに正しくアクセスしていますか?

別の可能性として、GDB などのデバッガーを使用して、カーネル内でスタックの内容を調べることはできますか? 私はデバッグにあまり詳しくなく、カーネル内のコードをデバッグする方法がわかりません。どんな助けでも大歓迎です。

4

3 に答える 3

4

インライン アセンブリの必要はありません。entry_32.Ssyscall のスタックにプッシュされる保存された状態は として配置され、次のstruct pt_regsようにポインターを取得できます (直接的または間接的に<asm/ptrace.h>and/orを含める必要があります)。<asm/processor.h>

struct pt_regs *regs = task_pt_regs(current);

于 2010-04-09T20:18:10.003 に答える
3

インライン アセンブリは、見た目よりも複雑です。GCCの懸念事項を簡単にカバーしようとしています:

  1. プロセッサ レジスタを変更する場合は、これらのレジスタを clobber リストに追加する必要があります。clobber リストには、直接 (明示的に読み取る) または間接的に (暗黙的に読み取る) 変更したすべてのレジスタが含まれている必要があることに注意してください。
  2. (1) を強化するために、条件付きおよび数学演算も、ステータス フラグ (ゼロ、キャリー、オーバーフローなど) として知られるレジスタを変更するため、クロバー リストに「cc」を追加して通知する必要があります。
  3. 異なる (ランダムに読み取る) メモリ位置を変更する場合は、「メモリ」を追加します。
  4. 入力/出力引数に記載されていないメモリを変更する場合は、 volatileキーワードを追加します。

次に、コードは次のようになります。

asm("movl 0x1C(%%esp), %0;"
    : "=r" (value)
    : /* no inputs :) */
    /* no modified registers */
);

出力引数は、変更されることを GCC が既に認識しているため、clobber リストにある必要はありません。

または、必要なのは ESP レジスタの値だけなので、これを行うことですべての苦痛を回避できます。

register int esp asm("esp");
esp += 0x1C;

それはあなたの問題を解決しないかもしれませんが、それは行く方法です. 参考までに、こちらこちらこちらをご確認ください。

于 2010-04-06T05:48:58.920 に答える
0

x86_64コードはレジスターに値を渡すことが多いので(非常に多くあるため)、スタックには何も存在しないことに注意してください。gcc中間出力( IIRC)を確認し、アセンブリ-Sで探します。push

私はカーネルコードのデバッグに精通していませんが、gdbはスタックをインタラクティブに調べる方が間違いなく優れています。

于 2010-04-06T05:33:33.697 に答える