https://www.cnblogs.com/revercc/p/17803876.html Връзката между uprobe програмата на eBPF и kernel/events/uprobe.c е по същество в това, че механизмът eBPF използва повторно вградената инфраструктура на ядрото, за да реализира функцията за закачване на функциите на потребителското състояние. По-конкретно, uprobe на eBPF е "приложение" на рамката за ядро uprobe, която е свързана чрез вътрешна верига за извиквания на ядрото и структура от данни. Основна връзка: eBPF разчита на рамката на kernel uprobe за реализиране на куки Kernel uprobe.c е основната имплементация на вградения потребителски тест (uprobe) на ядрото на Linux и отговаря за: Управление на регистрацията и анулирането на сонди от потребителско състояние (например register_uprobe(), unregister_uprobe()). Обработва вмъкване на точка на прекъсване (записване на инструкции за точка на прекъсване към адреса на целевата функция, като int3 на x86). Улавяне на тригерни събития на точка на прекъсване (заседнали в обработката на състоянието на ядрото, когато програмата се изпълнява до точка на прекъсване). Извикай предварително регистрирана функция за обратно повикване (т.е. логика на кука). eBPF програмата за обратен обрам (като примера с hook libc.so, който написахте) по същество регистрира функция за обратно повикване на eBPF, базирана на uprobe, с ядрото чрез eBPF loader-а (например bcc, libbpf), което напълно разчита на инфраструктурата, предоставена от uprobe.c. Специфична верига за обаждания: потокът от eBPF програмата към uprobe.c Когато регистрирате ъпроб чрез eBPF loader (като attach_uprobe на bcc), основният процес е следният: eBPF loader-ът инициира заявка за регистрация. Loader-ът (като Python кода на bcc) казва на ядрото чрез системно извикване (като bpf() или perf_event_open()), че "Искам да закача eBPF hook на openat функцията на libc.so" и предава байткода на eBPF програмата. Проверка на ядрото и подготовка на eBPF програми Проверителят на ядрото eBPF проверява легитимността на програмата, за да гарантира, че тя не компрометира сигурността на ядрото. След като бъде предадена програмата, заредете програмата eBPF в ядрото и използвайте "функция за обратно извикване на eBPF" (т.е. uprobe_openat логиката, която сте написали). Повторното използване на ядрото на интерфейса за регистрация на uprobe.c ще извика функцията register_uprobe() в uprobe.c, ще регистрира "нативен uprobe" и ще използва функцията eBPF за обратно извикване като "тригер обработващ" на този uprobe. Ключът тук е следният: същността на uprobe на eBPF е да свърже обратен тип eBPF към нативния образ на ядрото. uprobe.c вмъква точка на прекъсване и чака да бъде задействана. Uprobe.c записва инструкция за точка на прекъсване (като int3 на x86) в паметта на състоянието на потребителя въз основа на регистрирания целеви адрес (адресът на openat в libc.so) и записва оригиналната инструкция на точката на прекъсване (за възобновяване на изпълнението след задействане). Функцията извиква trigger breakpoints, uprobe.c извиква eBPF callback-и Когато приложението извиква libc.so:openat, изпълнението на инструкцията за точка на прекъсване задейства капан и попада в състояние на ядрото. В този момент: Ядрото извиква функцията uprobe_handler() (kernel processing logic) в 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 е "доставчикът на услуги", като първият разчита на втория за завършване на регистрацията, задействането и изпълнението на хуковете. |