You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何为自定义系统调用追踪器添加系统调用参数存储功能?

如何为系统调用追踪器添加参数存储功能?

要让你的系统调用追踪器存储参数,需要分两步修改代码:更新事件结构体以容纳参数,以及在追踪点中捕获并填充参数数据。

1. 更新事件结构体

x86_64架构下的系统调用最多包含6个参数,我们可以在data_t中添加一个u64类型的数组来存储这些参数(u64能兼容所有参数类型)。修改后的结构体如下:

struct data_t{
    u32 pid;
    char p_comm[TASK_COMM_LEN];
    char comm[TASK_COMM_LEN];
    u32 syscall_id;
    u64 ts;
    u64 args[6]; // 存储最多6个系统调用参数
};

2. 修改追踪点代码

注意:你当前使用的raw_syscalls:sys_exit追踪点只能获取系统调用的返回值,无法直接拿到调用参数——参数需要在系统调用进入阶段捕获,也就是改用raw_syscalls:sys_enter追踪点。该追踪点的args结构体已经包含了系统调用ID和参数数组。修改后的代码如下:

TRACEPOINT_PROBE(raw_syscalls, sys_enter){
    struct task_struct *task;
    u64 pid_tgid = bpf_get_current_pid_tgid();
    u32 key = pid_tgid >> 32;
    task = (struct task_struct *)bpf_get_current_task();
    
    struct data_t event = {};
    bpf_probe_read_kernel_str(&event.p_comm, TASK_COMM_LEN, task->real_parent->comm);
    bpf_get_current_comm(&event.comm, sizeof(event.comm));
    
    event.pid = key;
    event.syscall_id = args->id;
    // 复制系统调用参数到事件结构体
    __builtin_memcpy(&event.args, args->args, sizeof(event.args));
    // 记录时间戳
    event.ts = bpf_ktime_get_ns();
    
    syscalls.ringbuf_output(&event, sizeof(event), 0);
    return 0;
}

额外注意事项

  • 不同CPU架构的系统调用参数数量、传递方式可能不同,上述代码针对x86_64架构优化,其他架构需要调整参数数组的长度或类型。
  • 如果需要同时记录参数和返回值,可以用BPF哈希表:在sys_enter时将参数存入map(以PID+TGID或其他唯一标识为键),在sys_exit时取出参数,和返回值一起输出后再删除map中的条目。
  • 确保结构体内存对齐符合BPF要求,避免程序加载失败;如果遇到对齐问题,可以给结构体添加__attribute__((packed))属性。

内容的提问来源于stack exchange,提问作者Afonso Pinto

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.26 18:22:47