eBPF Forensics Link to heading

I’ve been trying to understand the various eBPF programs running on my workstation and what sort of functions / tracepoints they hook on and monitor. For some eBPF agents, I do have access to the source code, but for some others, I don’t. So my goal was pretty simple - how can I know what programs are running on my machine and what they monitor?

bpftool Link to heading

Enter bpftool. As aptly mentioned here, bpftool is the swiss army knife for working with BPF. I have tetragon running on my machine and will try to trace it back to its hook points without look at the source code.

Lets first list all the BPF programs on the machine.

$ sudo bpftool prog show
...
9670: kprobe  name event_exit_acct_process  tag bfe8143baf930e43  gpl run_time_ns 1180281 run_cnt 66
        loaded_at 2024-12-16T14:44:30+0000  uid 0
        xlated 6488B  jited 4236B  memlock 8192B  map_ids 14682,14693,14681,14697,14718,14700,14687,14688,14684
        btf_id 9284
        pids tetragon(2996292)
...

(there’s more programs listed, but lets just work with event_exit_acct_process for now)

This is great - it tells me the size of xlated and jited forms of the programs and tells me all the maps the programs use. In addition, the more recent version of bpftool also shows the associated PID (tetragon in this case) that loaded this program - which is awesome.

But how do I figure out what hook point this program actually monitors? There’s another command in bpftool to show just that and associate the BPF program to its link point.

$ sudo bpftool link show -j | jq '.[]'
...
{
  "id": 733,
  "type": "perf_event",
  "prog_id": 9670,
  "retprobe": false,
  "addr": 18446744072184711428,
  "func": "acct_process",
  "offset": 0,
  "missed": 0,
  "cookie": 0,
  "bpf_cookie": 0,
  "pids": [
    {
      "pid": 2996292,
      "comm": "tetragon"
    }
  ]
}
...

There we see it - the prog_id: 9670 is attached to a function acct_proccess in the Kernel. Neat ok, so it seems like this BPF program is likely monitoring process exits.

Now, how about a program that’s attached to a tracepoint? I’m mentioning it because the programs attached to tracepoints don’t look so straightforward!

For example, here’s some output from bpftool link show that shows a tracepoint:

$ sdo bpftool link show -j | jq '.[]'
{
  "id": 720,
  "type": "tracing",
  "prog_id": 9527,
  "prog_type": "tracing",
  "attach_type": "trace_fexit",
  "target_obj_id": 1,
  "target_btf_id": 109991,
}

It has the prog_id, we know its an fexit program type, but we actually don’t know which tracepoint it hooks to. The target_btf_id field tells us this, unfortunately, the ID isn’t useful much. To convert the BTF ID to the tracepoint, we can:

$ sudo bpftool btf dump file /sys/kernel/btf/vmlinux | grep "109991"
[109991] FUNC 'tcp_sendmsg' type_id=55011 linkage=static

There we go, the id: 720 BPF program is tracing tcp_sendmsg. In general, the bpftool tool is super powerful for inspecting BPF programs on the machine! The commands around bpftool map dump actually lets us see what information is being held by the BPF programs running on our machine.