|
|
 Vermieter |
Veröffentlicht am 20.10.2025, 19:30:47
|
https://www.cnblogs.com/revercc/p/17803876.html Die Verbindung zwischen dem uprobe-Programm von eBPF und dem Kernel/events/uprobe.c besteht im Wesentlichen darin, dass der eBPF-Mechanismus die native uprobe-Infrastruktur des Kernels wiederverwendet, um die Hook-Funktion der Benutzerzustandsfunktionen zu implementieren. Konkret ist die uprobe von eBPF eine "Anwendung" des Kernel-uprobe-Frameworks, das über eine interne Kernel-Aufrufkette und Datenstruktur verknüpft ist. Kernverbindung: eBPF nutzt das Kernel-UPROBE-Framework, um Hooks zu implementieren Der Kernel uprobe.c ist die Kernimplementierung der nativen Benutzerzustandsprobe (uprobe) des Linux-Kernels und verantwortlich für: Verwaltung der Registrierung und Kündigung von User-State-Probes (z. B. register_uprobe(), unregister_uprobe()). Verarbeitet die Einfügung von Breakpoints (Schreiben von Breakpoint-Anweisungen an die Zielfunktionsadresse, wie z. B. x86s int3). Capture Breakpoint löst Ereignisse aus (bleibt in der Kernel-Zustandsverarbeitung fest, wenn ein Programm bis zu einem Breakpoint ausgeführt wird). Rufen Sie eine vorregistrierte Rückruffunktion (also Hook-Logik) auf. Das eBPF uprobe-Programm (wie das von dir geschriebene Beispiel hook libc.so) registriert im Wesentlichen eine uprobe-basierte eBPF-Rückruffunktion beim Kernel über den eBPF-Loader (z. B. bcc, libbpf), der vollständig auf der von uprobe.c bereitgestellten Infrastruktur angewiesen ist. Spezifische Anrufkette: der Fluss vom eBPF-Programm zu uprobe.c Wenn Sie eine UPROBE über einen eBPF-Loader (wie das attach_uprobe von BCC registrieren), ist der zugrunde liegende Prozess wie folgt: Der eBPF-Loader initiiert eine Registrierungsanfrage: Der Loader (wie der Python-Code von bcc) teilt dem Kernel über einen Systemaufruf (wie bpf() oder perf_event_open()) mit: "Ich möchte einen eBPF-Hook an der Openat-Funktion der libc.so hängen" und übergibt den Bytecode des eBPF-Programms. Kernel-Verifikation und Vorbereitung von eBPF-Programmen Der Kernel-eBPF-Verifizor prüft die Legitimität des Programms, um sicherzustellen, dass es die Kernelsicherheit nicht gefährdet. Sobald es bestanden ist, lade das eBPF-Programm in den Kernel und führe eine "eBPF-Callback-Funktion" ein (also die uprobe_openat Logik, die du geschrieben hast). Die Wiederverwendung des Registrierungsschnittstellen-Kernels von uprobe.c ruft die register_uprobe()-Funktion in uprobe.c auf, registriert eine "native uprobe" und nutzt die eBPF-Rückruffunktion als "Trigger-Handler" dieser Uprobe. Der Schlüssel hier ist folgender: Das Wesentliche von eBPFs Uprobe besteht darin, einen Callback vom Typ eBPF an die native Uprobe des Kernels zu binden. uprobe.c fügt einen Breakpoint ein und wartet darauf, dass dieser ausgelöst wird. Uprobe.c schreibt eine Breakpoint-Anweisung (wie x86s int3) in den Zustandsspeicher des Benutzers basierend auf der registrierten Zieladresse (der Adresse von openat in libc.so) und zeichnet die ursprüngliche Anweisung des Breakpoints auf (zur Fortsetzung der Ausführung nach dem Auslösen). Funktion ruft Breakpoints aus, uprobe.c ruft eBPF-Callbacks Wenn die Anwendung libc.so:openat aufruft, löst die Ausführung der Breakpoint-Instruktion eine Falle aus und fällt in den Kernel-Zustand. Zu diesem Zeitpunkt: Der Kernel ruft die uprobe_handler()-Funktion (Kernelverarbeitungslogik) in uprobe.c. auf. uprobe_handler() überprüft die Registrierungsinformationen, die dem Breakpoint entsprechen, und stellt fest, dass sie an einen eBPF-Rückruf gebunden sind, sodass das eBPF-Programm (also die uprobe_openat du geschrieben hast) aufgerufen wird. Nachdem das eBPF-Programm ausgeführt wurde (z. B. Parameter sammeln, auf Ringbuf schreiben), stellt uprobe_handler() die ursprüngliche Instruktion wieder her und erlaubt der Programmausführung. Zusammenfassung: Die Beziehung zwischen den beiden kernel/events/uprobe.c ist die zugrundeliegende Infrastruktur, die Kernfunktionen wie Einfügen, Erfassung und Wiederherstellung von Benutzerzustands-Breakpoints bereitstellt und die Grundlage für alle Benutzerzustandsprobes bildet (einschließlich eBPF-Uprobe, GDB-Debugging usw.). Das uprobe-Programm von eBPF ist eine oberschichtige Anwendung, die auf dieser Infrastruktur basiert, eBPF-Callback-Funktionen registriert und es dem Kernel ermöglicht, eBPF-Logik auszuführen, wenn uprobe ausgelöst wird, wodurch eine effiziente Verfolgung der Benutzerzustandsfunktionen erreicht wird. Kurz gesagt: uprobe für eBPF ist der "Nutzer" und uprobe.c der "Dienstanbieter", während erstere auf letztere angewiesen sind, um die Registrierung, Auslösung und Ausführung von Hooks abzuschließen. |
|