присоединение bpf к sys_enter (точка трассировки доступна через / proc / kallsyms) - PullRequest
1 голос
/ 02 апреля 2020

Я пытаюсь создать инструмент, в котором я присоединяю программу BPF к точкам входа для всех системных вызовов. Из CLI я смог присоединиться ко всем записям syscall через

sudo bpftrace -e 'tracepoint:syscalls:sys_enter_* /comm != "bpftrace"/ {printf("Process Name: %s\nSyscall Requested: %s\n", comm, probe);}'

, и это здорово, но я хочу делать более сложные вещи. Я обнаружил, что могу присоединять программы BPF к событиям kprobe, используя внешний интерфейс python как таковой -

#!/usr/bin/python

from bcc import BPF

prog = """
int hello(void *ctx){
    bpf_trace_printk("Hello, world!\\n");
    return 0;
}
"""

b = BPF(text=prog)
b.attach_kprobe(event="__x64_sys_clone", fn_name="hello)

print("TIME(s)", "COMM", "PID", "MESSAGE")

while 1:
    try:
        (task, pid, cpu, flags, ts, msg) = b.trace_fields()
    except ValueError:
        continue
    except KeyboardInterrupt:
        exit()
    printb(b"%-18.9f %-16s %-6d %s" %(ts, task, pid, msg))

Однако в строке attach_kprobe я хочу присоединить ко всем записям системного вызова, а не к sys_clone. Я не нашел никаких точек трассировки sys_enter в /sys/kernel/debug/tracing/available_filter_functions, однако нашел __tracepoint_sys_enter в /proc/kallsyms. Однако, когда я попытался заменить __x64_sys_clone на __tracepoint_sys_enter, я получил ошибку неверного аргумента. Мне интересно, могу ли я присоединиться ко всем входам системного вызова (и в конечном итоге выйти) с помощью kprobes? Или мне нужно использовать другой механизм отслеживания. Спасибо!

Ответы [ 2 ]

2 голосов
/ 03 апреля 2020

Кажется, что нет события kprobes, которое бы захватывало все точки входа в системный вызов - скорее, кажется, есть событие kprobe для каждой записи системного вызова. Хотя мы можем кодировать требуемые логики c, применяя к каждому событию входа системного вызова kprobe (в частности, используя методологию, обрисованную в общих чертах pchaigno), мы можем сделать то же самое, подключившись к одному событию TRACEPOINT, как показано ниже -

from bcc import BPF
b = BPF(text = """
TRACEPOINT_PROBE(raw syscalls, sys_enter)
{
    bpf_trace_printk("Hello world\\n");
}
""")

while 1:
    try:
        (task, pid, cpu, flags, ts, msg) = b.trace_fields()
    except ValueError:
        continue
    print("%-18.9f %-16s %-6d %s" % (ts, task, pid, msg))

Аналогично, мы можем прикрепить ко всем точкам выхода системного вызова

1 голос
/ 02 апреля 2020

Я не думаю, что есть способ отследить все системные вызовы с помощью одной точки подключения kprobe через BPF. Вместо этого вы можете получить список всех соответствующих хуков krprobe из данного шаблона (т. Е. sys_enter_*).

В b cc есть функция, называемая BPF.get_kprobe_functions() , что позволяет вам сделать это. Вы можете увидеть пример использования в b cc 's funccount.py. Я предполагаю, что bpftrace делает нечто очень похожее, когда задает шаблон.

...