【问题标题】:Communication between two kernel kprobes/kretprobes两个内核 kprobes/kretprobes 之间的通信
【发布时间】:2015-09-25 22:39:39
【问题描述】:

是否可以使用 kretprobe 捕获内核函数的返回值并将其传递给另一个 kretprobe,该 kretprobe 连接到另一个内核函数。

【问题讨论】:

  • 如果两个探针的处理程序都在同一个模块中声明,它们可以像往常一样进行通信(通过模块的变量)。
  • @Tsyvarev 所以基本上你是说我应该在一个模块中为两个返回探针编写代码并通过全局变量在它们的处理程序之间进行通信?
  • 是的,这是个好办法。
  • 好吧,由于我是内核编程的新手,我想知道如何捕获我们正在植入返回探针的函数的返回值。我想做的是做两个返回探针,一个连接到 fs/binfmt_elf.c 文件中的 load_elf_binary() 函数,另一个连接到在 load_elf_binary 函数中调用的 randomize_stack_top() 函数。现在我想在第一个探针中使用 randomize_stack_top() 返回的值。
  • 只需将 `randomize_stack_top` 的返回值在其 kretprobe 处理程序中存储到某个模块的全局变量中,然后在 kretprobe 处理程序中读取此变量以获取 load_elf_binary

标签: linux-kernel kernel kernel-module kprobe


【解决方案1】:

如何使用 eBPF 和密件抄送的一个示例:

#!/usr/bin/env python
from bcc import BPF

BPF(text="""
#include <uapi/linux/ptrace.h>
BPF_HASH(rvalues, u64, unsigned long);
int kretprobe__randomize_stack_top(struct pt_regs *ctx) {
    u64 zero = 0;
    unsigned long rvalue = PT_REGS_RC(ctx);
    rvalues.lookup(&zero);
    return 0;
}

int kretprobe__load_elf_binary(struct pt_regs *ctx) {
    u64 zero = 0;
    unsigned long *rvalue_ptr = rvalues.lookup(&zero);
    if (rvalue_ptr) {
        unsigned long rvalue = *rvalue_ptr;
        bpf_trace_printk("value returned by randomize_stack_top: %d", rvalue);
    }
    return 0;
}
""").trace_print()

randomize_stack_top 返回的值保存在哈希映射 rvalues 中,键为 0(也可以使用 BPF_ARRAY,因为这里的键是固定的)。该值在 load_elf_binary 中检索,只需在哈希映射上查找即可。

注意:如果您有多个进程调用这些函数,您可以使用它们的 PID 作为哈希映射的键来区分不同的返回值。


bcc 提供了一个更高级别的 Python API 来在内核中加载 eBPF 程序并与之交互。可以使用 eBPF 程序代替内核模块来检测 kprobe。有关密件抄送的更多信息,请参阅the tutorial on the repository

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-11-24
    • 2017-03-08
    • 2018-06-05
    • 2012-12-20
    • 1970-01-01
    相关资源
    最近更新 更多