2008-11-14 8 views
20

Ohne in die Details von warum zu gehen, suche ich nach einer sauberen (wie möglich) Möglichkeit, Kernel-Funktionen und Systemaufrufe von einem ladbaren Modul zu ersetzen. Meine ursprüngliche Idee war, etwas Code zu schreiben, um einige Funktionen zu überschreiben, die die ursprüngliche Funktion übernehmen würden (vielleicht, wenn möglich, Anruf die Funktion), und fügen Sie dann etwas von meinem eigenen Code hinzu. Der Schlüssel ist, dass die Funktion, die ich schreibe, den Namen der ursprünglichen Funktion haben muss, so dass anderer Code auf meinen zugreift, wenn er versucht, darauf zuzugreifen.Überschreiben der Funktionalität mit Modulen im Linux-Kernel

Ich kann leicht (vergleichsweise) dies direkt im Kernel tun, indem ich einfach meinen Code in die entsprechenden Funktionen werfe, aber ich fragte mich, ob jemand etwas C-Magie kannte, die nicht notwendig ist schrecklichen Kernel (oder C) Kodierungspraxis, die das gleiche Ergebnis erzielen könnte.

Gedanken von #defines und typedefs kommen mir in den Sinn, aber ich kann es nicht in meinem Kopf hacken.

Kurz gesagt: Kennt jemand eine Möglichkeit, Funktionen im Linux-Kernel (von einem Modul) effektiv zu überschreiben?

EDIT: Da es gefragt worden, ich bestimmte Funktionen (Erstellen/Löschen von Verzeichnissen, etc.) aus dem Kernel, aber für geistige Gesundheit willen, ein ladbares Modul scheint Sinn zu machen, anstatt im Wesentlichen protokollieren will um einen großen Patch in den Kernel-Code zu schreiben und bei jeder Änderung neu zu kompilieren. Ein minimaler addierter Code zum Kernel ist in Ordnung, aber ich möchte den Großteil der Arbeit auf ein Modul abladen.

+0

Können Sie klären, welche dieser drei Sie zu tun versuchen: 1) außer Kraft setzen ruft Funktionen auf Kernel aus vorhandenen Kernel-Code 2) außer Kraft setzen Funktionen von Ihrem Kernel-Modul auf Kernel ruft 3) Override Systemaufrufe in Userspace, die in den Kernel anrufen Außer es # 1, würde ich #defines – bmdhacks

+0

1 und 2 empfehlen? Ich möchte die Aufrufe im Kernel selbst intakt machen, nur die Funktionen, die aufgerufen werden (im Kernel) sollen durch Funktionen ersetzt werden, die in meinem Modul definiert sind. Wenn das * irgend * Sinn macht. –

+0

Nicht wirklich, es würde wahrscheinlich helfen, wenn Sie den "Warum" -Teil erklären würden. –

Antwort

6

Ich weiß, dass die Frage drei Jahre alt ist, aber zum Vorteil anderer Leute, die versuchen, so etwas zu tun, hat der Kernel eine Schnittstelle namens kprobes, um genau das zu tun, was Sie brauchten.

+0

Ich habe gerade ein paar Minuten damit verbracht, das zu untersuchen, und ich frage mich, wie zum Teufel ich (oder irgendjemand anders) das vor drei Jahren noch nie gefunden habe. Sieht in etwa richtig aus. Ich bin nicht gegangen und habe es benutzt und getestet, aber da es zu dem passt, nach was ich gesucht habe, werde ich fortfahren und dies als korrekt markieren! –

3

Ich bin nicht ganz sicher, dass ich verstehe, was Sie tun möchten, aber ich denke, dass ksplice eine gute Lösung sein kann. Es ist immer noch in der Entwicklung, also weiß ich nicht, ob es gerade in einem brauchbaren Zustand ist.

+0

Was ich sehe, hat nicht wirklich damit zu tun, den Kernel neu zu laden, als meinen Code innerhalb des Kernels zu modularisieren und zu vermeiden, den bestehenden Code so weit wie möglich zu ändern. –

0

Die meisten Dateisystemarbeiten werden bereits in Modulen ausgeführt, vorausgesetzt, der Dateisystemcode wurde als Modul erstellt und nicht in den Kernel integriert (was bedeutet, dass die 'echte' Antwort von den Kernel-Build-Optionen abhängt).

Angenommen, dass die zu protokollierenden Bits alle Dateisystem-bezogen sind und diese Dateisystemroutinen als Module erstellt werden, sollten Sie nur in der Lage sein, die gewünschten Dateisystemmodule zu ändern und neu zu laden .

Wenn diese Annahmen nicht wahr sind oder nicht wahr werden können, dann wird es eindeutig schwieriger, und ich kann Sie wirklich nicht weiter darauf hinweisen.

+0

Interessante nehmen, obwohl idealerweise würde ich auf einer höheren Ebene als das bestimmte Dateisystem protokollieren (wie sys_write oder vfs_write). Ich denke, es auf dieser Ebene zu tun würde mein Code Dateisystem-Agnostiker machen. –

4

Sie möchten wahrscheinlich hook the system calls (PDF-Link), die effektiv protokollieren könnte Benutzer-Prozesse Kernelfunktionen aufrufen. Wenn Sie wirklich die Kernel Verwendung von Kernel-Funktionen protokollieren möchten, möchten Sie in kernel function trace suchen.

+0

Welcher PDF-Link? :-P –

+0

Der vom Markdown-Parser abgeschliffene. Danke fürs bemerken; behoben. – geocar

0

Da Sie nur die Aufrufe protokollieren möchten (dh Sie werden sie nicht wirklich überschreiben) und eine kleine Menge an Änderungen am Kernel-Code akzeptabel ist, wäre der sauberste Weg, jeder Funktion, die Sie interessiert, einen Haken hinzuzufügen (mit einer Notifier-Kette oder sogar einem einfachen Funktionszeiger). Ihr Modul registriert sich dann einfach bei allen von Ihnen hinzugefügten Hooks (und hebt die Registrierung bei der Deinstallation auf).

Es ist auch gut möglich, dass jemand anderes bereits die Arbeit getan hat, die Haken für Sie hinzuzufügen.

0

Sie möchten keine bestehenden Systemaufrufe ändern, die Sie instrumentieren möchten. Dies ist, was SystemTap ist für.Wenn Sie es wirklich auf die harte Tour machen und Systemaufrufe abfangen wollen, indem Sie Ihr eigenes Modul programmieren, empfehle ich Ihnen, einige Rootkit-Literatur zu lesen, aber ich habe keine Verbindung zur Hand (obwohl mir phrack in den Sinn kommt).

1

Es wurde viel Arbeit im Kernel gemacht, um sicherzustellen, dass dies nicht geschieht, besonders, um die syscall-Tabelle nicht den Modulen auszusetzen. Der einzige unterstützte Mechanismus zum Protokollieren des Dateizugriffs ist , aber er ist auf Sicherheit ausgerichtet und hat eine unsichere future. Here ist eine PDF, die die API dokumentiert, aber möglicherweise nicht auf dem neuesten Stand ist.

inotify ist ein viel besserer Weg, um das Erstellen, Löschen und Ändern von Dateien zu überwachen, als zu versuchen, die Kernel-Syscall-Funktionen zu untergraben, aber es funktioniert von Userspace.

Zitat von Wikipedia (http://en.wikipedia.org/wiki/Inotify): einige der Ereignisse, die für sind überwacht werden können:

* IN_ACCESS - read of the file 
* IN_MODIFY - last modification 
* IN_ATTRIB - attributes of file change 
* IN_OPEN and IN_CLOSE - open or close of file 
* IN_MOVED_FROM and IN_MOVED_TO - when the file is moved or renamed 
* IN_DELETE - a file/directory deleted 
* IN_CREATE - a file/directory created 
* IN_DELETE_SELF - file monitored is deleted 

inotify existiert im Kernel seit 2.6.13, ist seine predecesor dnotify (http://en.wikipedia.org/wiki/Dnotify).

1

ich glaube, Sie audit für die

+0

+1, ermöglicht das Audit-System dem OP, das zu tun, was es beabsichtigt ... vollständig aus dem Benutzerbereich. – MarkR

3

Haben Sie sich bei der Bereitstellung Ihrer Funktion LD_PRELOAD verwenden kann?

Ihre Funktion wird über eine gemeinsam genutzte Lib bereitgestellt, die in einem Verzeichnis enthalten ist, das durch die Umgebungsvariable LD_PRELOAD angegeben wird.

Die Konvention ist, dass Sie Systemaufrufe abfangen und dann, nachdem Sie Ihre Magie ausgeführt haben, den Anruf auf das tatsächliche System shlib übergeben. Aber du musst das nicht tun.

Vielleicht werfen Sie einen Blick auf den Artikel "Building library interposers for fun and profit". Obwohl es Solaris-spezifisch ist, ist es auch auf Linux anwendbar.

BTW Dies ist, wie die meisten Speicheranalyse-Tools, z. Reinige, arbeite.

0

Nach KernelTrap.org you can do a simple patch und recompile des Kernels die sys_call_table Variable zu exportieren:

// add the following in the file arch/i386/kernel/i386_ksyms.c 
extern void* sys_call_table[]; 
EXPORT_SYMBOL(sys_call_table); 

Dann folgen Sie einfach this procedure for replacing system calls aus dem Linux-Kernel Module Programming Guide:

Der Quellcode hier ist ein Beispiel für solch ein Kernel-Modul. Wir wollen auf einen bestimmten Benutzer "spionieren" und printk() eine Nachricht, wenn dieser Benutzer eine Datei öffnet. Zu diesem Zweck ersetzen wir den Systemaufruf , um eine Datei mit der eigenen eigenen Funktion namens our_sys_open zu öffnen. Diese Funktion überprüft die uid (Benutzer- id) des aktuellen Prozesses, und wenn ist es gleich der uid wir es auszuspionieren, printk() nennt den Namen die Datei anzuzeigen geöffnet werden. Dann, entweder Weise, ruft es die ursprüngliche open() Funktion mit den gleichen Parametern, um tatsächlich die Datei zu öffnen.

Die init_module Funktion ersetzt die geeignete Stelle in sys_call_table und hält den ursprünglichen Zeiger in einer Variable. Die cleanup_module Funktion verwendet diese Variable, um alles wieder normal wiederherzustellen. Dieser Ansatz ist gefährlich, weil die Möglichkeit von zwei Kernelmodulen denselben Systemaufruf ändert. Imagine Wir haben zwei Kernelmodule, A und B. A's open Systemaufruf wird A_open und B wird B_open sein. Nun, wenn A ist in den Kernel eingefügt, wird das System Anruf mit A_open, die wird das Original sys_open aufrufen, wenn es getan wird. Als nächstes wird B in der Kernel eingefügt, der das System Anruf mit ersetzt, die, was Anruf es ist der ursprüngliche Systemanruf, A_open, wenn es fertig ist.

1

This könnte sich als nützlich für Sie lesen.

Da die Systemaufruftabelle in neueren Kerneln nicht direkt exportiert wird, müssen Sie einige Suchen durchführen, um den Speicherort selbst zu bestimmen. Dann können Sie Ihre Systemaufrufe der Wahl abfangen und manipulieren. Das Ersetzen anderer Kernel-Funktionen wird jedoch sehr viel schwieriger sein, es sei denn, einige von ihnen sind auf die gleiche Weise organisiert wie Systemaufrufe (sie erscheinen in einigen Versandtabellen usw.) - was überhaupt nicht üblich ist.

0

Wenn die gemeinsam genutzten Bibliotheken einen Systemaufruf aufrufen, wird ein Modul erstellt, das diesen sysltem-Aufruf ändert. Weitere Informationen zum Ändern von Systemaufrufen finden Sie hier. http://www.xml.com/ldd/chapter/book/ Es gibt etwas darin, wie sie das ändern, was das open() System aufruft. Ein Beispiel ist hier http://tldp.org/LDP/lkmpg/x931.html

Verwandte Themen