foniod / redbpf

Rust library for building and running BPF/eBPF modules
Apache License 2.0
1.71k stars 136 forks source link

question: kprobe parm type casting #332

Open sammerry opened 2 years ago

sammerry commented 2 years ago

Hey Guys, I'm trying to write a probe that inspects data passed to the kernel. It attaches and instruments the right sys call, but it seems like I'm not casting to the correct types for each parm. Can you help point me in the right direction?

Version 2.3.0

Example Data

The output looks like this for full or empty buffer. { sock_fd: 0xffffbe1780eeff58, buf: 0x0, len: 18446744073709551615 }

The hex output for the parm's

Sock FD: 0xffffbe17824eff58
Buffer: 0x               0
Length: 0xffffffffffffffff

Example Probe

#[kprobe("__x64_sys_sendto")]
fn sendto(regs: Registers) {
  let sock_fd= regs.parm1() as *const c_int;
  let buf = regs.parm2() as *const c_void;
  let len = regs.parm3() as size_t;

  unsafe {
    sendto_event.insert(regs.ctx, (sock_fd, buf, len ));
  }
}
sammerry commented 2 years ago

I think I'm on the right track. It seems there are issues with sys call wrapping and this is an attempt at addressing it. https://github.com/iovisor/bcc/commit/2da34267fcae4485f4e05a17521214749f6f0edd

sammerry commented 2 years ago

It looks like that was a dead end. zcat /proc/config.gz | grep CONFIG_ARCH_HAS_SYSCALL_WRAPPER returns

CONFIG_ARCH_HAS_SYSCALL_WRAPPER=y

My system is using the correct wrapper, however Its not able to see the buffer and pointer for both kprobe and kretprobe.

sammerry commented 2 years ago

bpftrace kprobe seems to be able to pull the args from the same environment.

root@9c7a337cf9e6:/build# bpftrace -e 'kprobe:__sys_sendto { printf("sendto args: %x, %x, %d\n", arg0, arg1, arg2); }'
Attaching 1 probe...
sendto args: 4, b79aa0e0, 48
sendto args: 3, 180000, 48
sendto args: 3, a19e29f0, 64
sendto args: 12, 6aea50, 17
sendto args: 12, 6aec18, 17
GermanCoding commented 2 years ago

When using architecture-specific syscalls ("__x64_sys") you sadly have to parse the pt_regs argument yourselves - redBPF doesn't do this at this time. See issue #295, which includes an example how to do this.

If you want to trace the syscall in a less arch-specific manner, you might want to look into tracepoints (#331). Those are slightly better in this regard.