Wie kann ich eine Syskallfunktion unter Linux neu einplanen (oder wickeln)?
-
01-10-2019 - |
Frage
Angenommen, ich möchte den Open () -Systemanruf komplett übernehmen, um das eigentliche System zu wickeln und etwas Protokollierung durchzuführen. Eine Möglichkeit, dies zu tun, besteht darin, LD_PRELOAD zu verwenden So laden Sie eine (benutzergemachten) gemeinsame Objektbibliothek, die den Open () -Teinstufung übernimmt.
Die von Benutzer hergestellte Open () Routine erhält dann den Zeiger auf die GLIBC-Funktion open()
durch dlsym()
es und es nennen.
Die oben vorgeschlagene Lösung ist jedoch eine dynamische Lösung. Angenommen, ich möchte meine eigenen verknüpfen open()
Verpackung statisch. Wie würde ich das machen? Ich denke, der Mechanismus ist der gleiche open()
und die libc open()
.
Bitte teilen Sie alle anderen Techniken mit, um dasselbe Ziel zu erreichen.
Lösung
Sie können die Wrap -Funktion verwenden ld
. Aus man ld
:
--wrap symbol
Verwenden Sie eine Wrapper -Funktion für das Symbol. Jeder undefinierte Verweis aufsymbol
wird beschlossen zu__wrap_symbol
.Jeder undefinierte Verweis auf
__real_symbol
wird beschlossen zusymbol
.
Sie müssen also nur das Präfix verwenden __wrap_
für Ihre Wrapper -Funktion und __real_
Wenn Sie die eigentliche Funktion aufrufen möchten. Ein einfaches Beispiel ist:
malloc_wrapper.c
:
#include <stdio.h>
void *__real_malloc (size_t);
/* This function wraps the real malloc */
void * __wrap_malloc (size_t size)
{
void *lptr = __real_malloc(size);
printf("Malloc: %lu bytes @%p\n", size, lptr);
return lptr;
}
Testanwendung testapp.c
:
#include <stdio.h>
#include <stdlib.h>
int main()
{
free(malloc(1024)); // malloc will resolve to __wrap_malloc
return 0;
}
Kompilieren Sie dann die Anwendung:
gcc -c malloc_wrapper.c
gcc -c testapp.c
gcc -Wl,-wrap,malloc testapp.o malloc_wrapper.o -o testapp
Die Ausgabe der resultierenden Anwendung ist:
$ ./testapp
Malloc: 1024 bytes @0x20d8010
Andere Tipps
Die Symbole werden vom Linker in der Bestellung aufgelöst, in der Sie sie in der Befehlszeile auflisten. Wenn Sie also Ihre Bibliothek vor der Standardbibliothek aufgelistet haben, haben Sie Präsidien. Für GCC müssten Sie angeben
gcc <BLAH> -nodefaultlibs <BLAH BLAH> -lYOUR_LIB <OTHER_LIBS>
Auf diese Weise würden Ihre Bibliotheken durchsucht und zuerst gefunden.