https://www.cnblogs.com/revercc/p/17803876.html Связь между программой uprobe в eBPF и kernel/events/uprobe.c по сути заключается в том, что механизм eBPF повторно использует встроенную инфраструктуру обновления ядра для реализации функции hook функций состояния пользователя. В частности, uprobe eBPF — это «приложение» фреймворка ядра, которая связана внутренней цепочкой вызовов ядра и структурой данных. Основное соединение: eBPF использует фреймворк обновления ядра для реализации хуков Ядро uprobe.c является основной реализацией натурного мониторинга состояния пользователя ядра Linux (uprobe) и отвечает за: Управление регистрацией и отменой зондов в пользовательском состоянии (например, register_uprobe(), unregister_uprobe()). Обрабатывает вставку точки прерывания (запись инструкций по адресу целевой функции, например, int3 в x86). Захват событий триггера точки остановки (застревающие в обработке состояния ядра при выполнении программы в точке остановки). Вызовите заранее зарегистрированную функцию обратного вызова (то есть логику хука). Программа обновления eBPF (например, в примере hook libc.so, который вы написали) по сути регистрирует функцию обратного вызова eBPF на основе обновления с ядром через загрузчик eBPF (например, bcc, libbpf), который полностью зависит от инфраструктуры, предоставляемой uprobe.c. Специфическая цепочка вызовов: поток от программы eBPF к uprobe.c Когда вы регистрируете обшивку через загрузчик eBPF (например, attach_uprobe bcc), основной процесс выглядит следующим образом: Загрузчик eBPF инициирует запрос на регистрацию. Загрузчик (например, код на Python от bcc) сообщает ядру через системный вызов (например, bpf() или perf_event_open()), что «Я хочу подвесить крюк eBPF на функцию openat libc.so» и передаёт байткод программы eBPF. Проверка и подготовка программ eBPF ядра Верификатор ядра eBPF проверяет легитимность программы, чтобы убедиться, что она не нарушает безопасность ядра. После передачи загрузите программу eBPF в ядро и получите «функцию обратного вызова eBPF» (то есть uprobe_openat логику, которую вы написали). Повторное использование ядра интерфейса регистрации uprobe.c вызовет функцию register_uprobe() в uprobe.c, регистрирует «нативный uprobe» и использует функцию обратного вызова eBPF в качестве «триггера» этого апроба. Ключевой момент здесь таков: суть верхнего оформления eBPF заключается в привязке обратного вызова типа eBPF к нативному оформлению ядра. uprobe.c вставляет точку остановки и ждёт её срабатывания. Uprobe.c записывает команду точки остановки (например, int3 из x86) в память состояния пользователя на основе зарегистрированного целевого адреса (адрес openat в libc.so) и записывает исходную инструкцию точки остановки (для возобновления выполнения после запуска). Функция вызывает trigger breakpoints, uprobe.c вызывает eBPF-callback Когда приложение вызывает libc.so:openat, выполнение инструкции breakpoint вызывает ловушку и попадает в состояние ядра. На данный момент: Ядро вызывает функцию uprobe_handler() (логика обработки ядра) в uprobe.c. uprobe_handler() проверит регистрационную информацию, соответствующую точке остановки, и обнаруживает, что она связана с eBPF-callback, поэтому вызовет программу eBPF (то есть uprobe_openat, которую вы написали). После выполнения программы eBPF (например, сбора параметров, записи в ringbuf) uprobe_handler() восстанавливает исходную инструкцию и позволяет программе продолжить выполнение. Резюме: Взаимоотношения между ними kernel/events/uprobe.c — это базовая инфраструктура, обеспечивающая основные возможности, такие как вставка, захват и восстановление точек остановки состояния пользователя, и служит основой для всех зондов состояния пользователя (включая обновление eBPF, отладку gdb и др.). Программа uprobe eBPF — это приложение верхнего уровня, основанное на этой инфраструктуре, которое регистрирует функции обратного вызова eBPF и позволяет ядру выполнять логику eBPF при запуске uprobe, обеспечивая эффективное отслеживание состояния пользовательских функций. Короче говоря: uprobe для eBPF — это «пользователь», а uprobe.c — «поставщик услуг», при этом первый зависит от второго для регистрации, запуска и выполнения хуков. |