【问题标题】:Get userspace RBP register from kernel syscall从内核系统调用获取用户空间 RBP 寄存器
【发布时间】:2021-02-11 02:53:39
【问题描述】:

我正在编写内核系统调用,我想读取用户的基指针寄存器 (RBP)。也许我可以使用为参数传递的pt_regs 结构来做到这一点,不是吗?

示例代码:

unsigned long int data;
asmlinkage int my_read(int d)
{
    get_rbp_of_userStack(&data);#or somthing like that 

}

我知道这些数据保存在某处用于上下文切换,我该如何获取它?

这是我的用户代码

 void rar()
{//rbp here should be rsp when it call so it basically the return addres of the main
  char t[10];
getchar();
 }
 
int main()
{
  rar();
}

【问题讨论】:

  • 您正在为当前任务在struct pt_regs 中寻找bpWhere is eax in the pt_regs struct? Only ax is present
  • @PeterCordes 但如何加载新的 pt_regs 使其不会为空?
  • IIRC,current(属于 tyep task_struct)有一个 pt_regs 成员。但是我没有做很多内核代码的东西,所以我没有发布答案。
  • 嘿彼得,非常感谢您的回答 :-)
  • 这里的rbp在调用时应该是rsp,所以它基本上是main的返回地址 - 呃,什么?如果您使用-fno-omit-frame-pointer 编译,则 RBP 指向已保存的 RBP,是的。但是系统调用的 libc 包装器通常不会以这种方式编译,因此除非您将 syscall 内联到 asm() 语句,否则情况可能不会如此。并且保存的 RBP 值不是返回地址;他们通常下一个返回地址。

标签: c linux-kernel x86 kernel-module cpu-registers


【解决方案1】:

您可以使用task_pt_regs() 宏来获取current 任务的用户寄存器(在系统调用进入时保存):

#include <asm/processor.h>

SYSCALL_DEFINE1(foo, int, d)
{
    const struct pt_regs *user_regs = task_pt_regs(current);
    unsigned long rbp = user_regs->bp;

    /* Do whatever you need... */

    return 0;
}

【讨论】:

  • 由于某种原因我得到相同的值,所以我认为有些地方不正确
  • @AlonShoam 那么,您必须同时提供用户空间程序和模块的minimal reproducible example...否则无法提供帮助。另外,你的内核版本是多少?
  • 我正在使用内核 4.15,并将代码添加到问题中
  • @AlonShoam 您的用户空间代码没有进行任何系统调用。这不是一个可重复的例子。另外,您应该告诉我们您获得的两个 RBP 值,以及您如何获得它们。
  • 对不起,我现在添加一个示例,但是我知道它调用系统调用 buecase 的任何方式我在系统调用中打印它 pid 并且我得到的值是 00000000f01fbc03 我还打开另一个线程,因为这两种情况并没有真正相关
猜你喜欢
  • 2018-11-29
  • 1970-01-01
  • 2012-04-24
  • 2014-08-02
  • 1970-01-01
  • 2011-12-15
  • 2014-10-15
  • 1970-01-01
  • 2013-02-26
相关资源
最近更新 更多