Lets disasm jit code from this spyware:
[8] prog 0xffffb02dc0133000 id 160 len 46 jited_len 215 aux 0xffff8ccb58fab400 used_maps 1 used_btf 0 func_cnt 0
tag: 0F 86 19 76 BC 37 68 B3
stack_depth: 16
num_exentries: 0
type: 2 BPF_PROG_TYPE_KPROBE
expected_attach_type: 0 BPF_CGROUP_INET_INGRESS
used maps:
[0] 0xffff8ccbc1b1c600 - rb
...
ffffffffc07bc801 e80a38e6f1 call 0xffffffffb2620010 ; bpf_ringbuf_submit
ffffffffc07bc806 31c0 xor eax, eax
ffffffffc07bc808 415e pop r14
ffffffffc07bc80a 415d pop r13
ffffffffc07bc80c 5b pop rbx
ffffffffc07bc80d c9 leave
ffffffffc07bc80e c3 ret
and in ebpf opcodes:
43 85 00 00 00 C0 CF 02 00 call 0x2CFC0 ; bpf_ringbuf_submit
44 B7 00 00 00 00 00 00 00 mov r0, 0
45 95 00 00 00 00 00 00 00 ret
Here 0x2CFC0 is offset to bpf_ringbuf_submit from __bpf_call_base
The last call submit some data to bpf map rb with type BPF_MAP_TYPE_RINGBUF. If we could patch this function no data will be passed to usermode. How are these native function addresses filled in at all?