我正在进行一些实验,并希望能够在系统调用期间查看堆栈中保存的内容(用户登陆过程的已保存状态)。根据{{3}},它表明寄存器的各种值保存在堆栈指针的那些特定偏移处。这是我一直试图用来检查堆栈上保存的代码的代码(这是我创建的自定义系统调用):
asm("movl 0x1C(%esp), %ecx");
asm("movl %%ecx, %0" : "=r" (value));
其中value是unsigned long。
截至目前,此值不是预期的值(显示为ds的用户值保存0)。
我是否正确访问了堆栈指针的偏移量?
另一种可能性是我可以在内核中使用调试器(如GDB)来检查堆栈内容吗?我没有广泛使用调试,也不知道如何在内核中调试代码。任何帮助深表感谢。
答案 0 :(得分:5)
无需内联汇编。 entry_32.S
为系统调用推送到堆栈的已保存状态被设置为struct pt_regs
,您可以像这样获得指向它的指针(您需要包含<asm/ptrace.h>
和/或<asm/processor.h>
直接或间接地):
struct pt_regs *regs = task_pt_regs(current);
答案 1 :(得分:4)
内联汇编比看起来更棘手。试图尽快解决海湾合作委员会的担忧:
然后,您的代码变为:
asm("movl 0x1C(%%esp), %0;"
: "=r" (value)
: /* no inputs :) */
/* no modified registers */
);
输出参数不需要在clobber列表中,因为GCC已经知道它将被更改。
或者,既然你想要的只是ESP注册的价值,你可以避免这样做的所有痛苦:
register int esp asm("esp");
esp += 0x1C;
答案 2 :(得分:0)
请记住,x86_64代码通常会传递寄存器中的值(因为它有很多),因此堆栈中不会有任何内容。检查gcc中间输出(-S
IIRC)并在程序集中查找push
。
我不熟悉调试内核代码,但gdb绝对可以更好地以交互方式检查堆栈。