【eBPF】在eBPF程序中读取字符串

记一次bpf_probe_read_user_strbpf_probe_read_str的区别。

bpf_probe_read_user_str 用于从用户空间地址读取字符串,会自动处理用户空间和内核空间的地址隔离问题;而 bpf_probe_read_str 用于从内核空间地址读取字符串,适合处理内核数据结构中的字段或 eBPF map 中的内存。简单来说,_user_str 是专为用户空间数据设计的,而 _str 适用于内核空间数据。

代码:https://github.com/CeerDecy/study-ebpf/tree/main/03-trace-open-exit

优先发布:https://etov.cloud/index.php/2025/01/bpf_probe_read_str/

具体可以参考如下例子:

bpf_probe_read_user_str

我们可以用这个函数来读取tracepoint中函数的参数。其中ctx上下文就是来自于用户空间的数据,args[1]代表的是sys_enter_openat函数中第二个参数(即文件名称),使用bpf_probe_read_user_str 即可读取到OpenFile结构体变量中。

SEC("tracepoint/syscalls/sys_enter_openat")
int tracepoint__syscalls__sys_enter_openat(struct trace_event_raw_sys_enter *ctx) {
		struct OpenFile of = {};
		if (bpf_probe_read_user_str(of.filename, sizeof(of.filename), (const char *)ctx->args[1]) < 0) {
		    return 0;
    }
    ...
}

bpf_probe_read_str

这个函数可以用来读取eBPF map中的数据,因为eBPF map是处于内核空间的,所以这里就需要使用第二个函数。

struct {
    __uint(type, BPF_MAP_TYPE_HASH);
    __uint(max_entries, 1024);
    __type(key, u32);
    __type(value, struct OpenFile);
} dict SEC(".maps");

SEC("tracepoint/syscalls/sys_exit_openat")
int tracepoint__syscalls__sys_exit_openat(struct trace_event_raw_sys_exit *ctx) {
		...
	  struct OpenFile *of;
    struct Event *e;
    of = bpf_map_lookup_elem(&dict, &pid);
    if (bpf_probe_read_str(&e->filename, sizeof(e->filename), of->filename) < 0) {
        return 0;
    }
    ...
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值