-
-
Save lizrice/47ad44a15cce912502f8667a403f5649 to your computer and use it in GitHub Desktop.
| #!/usr/bin/python | |
| from bcc import BPF | |
| from time import sleep | |
| # This outputs a count of how many times the clone and execve syscalls have been made | |
| # showing the use of an eBPF map (called syscall). | |
| program = """ | |
| BPF_HASH(syscall); | |
| int kprobe__sys_clone(void *ctx) { | |
| u64 counter = 0; | |
| u64 key = 56; | |
| u64 *p; | |
| p = syscall.lookup(&key); | |
| // The verifier will reject access to a pointer if you don't check that it's non-null first | |
| // Try commenting out the if test (and its closing brace) if you want to see the verifier do its thing | |
| if (p != 0) { | |
| counter = *p; | |
| } | |
| counter++; | |
| syscall.update(&key, &counter); | |
| return 0; | |
| } | |
| int kprobe__sys_execve(void *ctx) { | |
| u64 counter = 0; | |
| u64 key = 59; | |
| u64 *p; | |
| p = syscall.lookup(&key); | |
| if (p != 0) { | |
| counter = *p; | |
| } | |
| counter++; | |
| syscall.update(&key, &counter); | |
| return 0; | |
| } | |
| """ | |
| b = BPF(text=program) | |
| while True: | |
| sleep(2) | |
| line = "" | |
| for k, v in b["syscall"].items(): | |
| line += "syscall {0}: {1}\t".format(k.value, v.value) | |
| print(line) |
| #!/usr/bin/python | |
| from bcc import BPF | |
| prog = """ | |
| int hello(void *ctx) { | |
| bpf_trace_printk("Hello world\\n"); | |
| return 0; | |
| } | |
| """ | |
| b = BPF(text=prog) | |
| clone = b.get_syscall_fnname("clone") | |
| b.attach_kprobe(event=clone, fn_name="hello") | |
| b.trace_print() | |
| # This prints out a trace line every time the clone system call is called | |
| # If you rename hello() to kprobe__sys_clone() you can delete the b.attach_kprobe() line, because bcc can work | |
| # out what event to attach this to from the function name. |
See also Aqua Security's Tracee project
@lizrice can you please also attach the Vagrantfile used for this?
Seems BPF's class method attach_kprobe() is broken: the current hello_map.py throws the following exception in python2.7:
Exception: Failed to attach BPF program hello to kprobe__sys_clone
Workaround: as mentioned in the code, comment out b.attach_kprobe() and rename hello to kprobe__sys_clone
this is great, a bit from a different angle, can you list what ebpf programs are attached to a given syscall from user land?
this is great, a bit from a different angle, can you list what ebpf programs are attached to a given syscall from user land?
I think what you are aiming at is bpftool, as shown in this BPF overview talk by Brendan Gregg @brendangregg:
https://youtu.be/7pmXdG8-7WU?t=1714
These examples use bcc which makes it easy to load eBPF programs into the kernel. I would recommend starting with hello_world.py and then hello_map.py.
Try running them under strace to see the system calls that are happening! For example
strace -e bpf ./hello_world.pywill show you the bpf() system call that loads the program into the kernel (BPF_PROG_LOAD).You can see the accompanying slides from DockerCon here
Thanks for this tutorial and all your awesome tutorials! Your link to bcc is broken - fixed in the quoted text above.
Thank you for the example!
In my Ubuntu I had the error:
cannot attach kprobe, probe entry may not exist
Traceback (most recent call last):
File "h.py", line 12, in <module>
b.attach_kprobe(event="sys_clone", fn_name="hello")
File "/usr/lib/python3/dist-packages/bcc/__init__.py", line 658, in attach_kprobe
raise Exception("Failed to attach BPF program %s to kprobe %s" %
Exception: Failed to attach BPF program b'hello' to kprobe b'sys_clone'
I modified attach_probe first parameter to:
b.attach_kprobe(event="__x64_sys_clone", fn_name="hello")
Then it worked.
@rodolk a more portable way to do this is to use b.get_syscall_fnname("clone") - I've updated the gist to do that now
@lizrice Thank you for taking the time to explain me!
These examples use bcc which makes it easy to load eBPF programs into the kernel. I would recommend starting with hello_world.py and then hello_map.py.
Try running them under strace to see the system calls that are happening! For example
strace -e bpf ./hello_world.pywill show you the bpf() system call that loads the program into the kernel (BPF_PROG_LOAD).You can see the accompanying slides from DockerCon here