【问题标题】:Get syscall parameters with kretprobes post handler使用 kretprobes 后处理程序获取系统调用参数
【发布时间】:2012-01-16 06:04:28
【问题描述】:

我想在这些系统调用返回后立即使用 LKM 跟踪 sys_connect 和 sys_accept。 我发现当被探测的系统调用返回时,kprobes 可以让你通过定义一个 post 处理程序来访问寄存器。

我的问题是我不知道如何从我在 post 处理程序中的数据(即 struct pt_regs)中获取系统调用参数 后处理程序是这样定义的:

void post_handler(struct kprobe *p, struct pt_regs *regs, unsigned long flags);

【问题讨论】:

标签: architecture linux-kernel kernel trace kernel-module


【解决方案1】:

这种结构依赖于架构,所以我假设您使用的是 x86。

进入时:

  orig_eax = syscall_nr;
  ebx = 1st argument of the function;
  ecx = 2nd arg...
  edx = 3rd arg...
  esi = 4th arg...
  edi = 5th arg... (you are lucky, on other arch this can be on the stack...)

退出时:

  orig_eax = return value of the function

您不能假设 ebx,ecx,edx... 中的值在退出时(即调用您的 post_handler 时)仍指向函数的参数,因此您需要在此处注册 两个 处理程序,一个在入口处,您可以从中保存指向结构套接字的指针,另一个在退出时,您将实际检查结构套接字的内容,因为它已被填充。要在两个处理程序之间传递数据,您可以使用kretprobe_instance 结构的归档data。注册 kretprobe 时不要忘记增加 struct kretprobedata_size 字段。

这可能看起来有点复杂,但一旦你对它更熟悉一点就应该没问题。

还请记住,如果您唯一需要做的就是跟踪这些事件,您可以只使用 sysfs 中的 ftrace 基础架构,并以最少的努力获得您想要的跟踪。

【讨论】:

  • 我可以查看您的代码吗(仅在实际失败的地方)?在编译时收到此错误有点奇怪,因为只有在加载模块时才应该解析符号(更具体地说,当您注册 kretprobe 时))。如果使用symbol_name字段,则类型为char*,不是函数指针。
  • 没错,我使用了 symbol_name 并对其进行了编译 :) 我决定通过从 accept 系统调用中获取套接字 fd 来提取我想要记录的信息。该值从 sys_accept 返回。我可以通过 post 处理程序从 ORIG_EAX 获取这个值吗?如果是,如何? (即在 x86 架构中)。 再次感谢您的帮助:)
  • 嗯,我找到了 regs_return_value 函数。我打印值,但它很大,不可能这是socket fd =/
  • 嗯,我将返回值转换为整数指针,然后打印包含的 int。结果是1。奇怪:S
  • 我的错,它不在 sys_accept 上。我在 sys_accept 上试过这个,我的机器崩溃了...... :(
猜你喜欢
  • 2011-01-24
  • 2013-05-24
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2014-05-17
  • 1970-01-01
  • 1970-01-01
  • 2020-05-19
相关资源
最近更新 更多