Ich arbeite gerade an einem Projekt, bei dem ich die Verwendung mehrerer Systemaufrufe und Low-Level-Funktionen wie mmap
, brk
, sbrk
verfolgen muss. Bisher habe ich das mit der Funktionsinterposition gemacht: Ich schreibe eine Wrapper-Funktion mit demselben Namen wie die Funktion, die ich ersetze ( mmap
zum Beispiel), und ich lade sie in ein Programm, indem ich LD_PRELOAD
einstelle Umgebungsvariable. Ich rufe die reale Funktion über einen Zeiger auf, den ich mit dlsym
lade.
Leider wird eine der Funktionen, die ich umbrechen möchte, sbrk
, intern von dlsym
verwendet, so dass das Programm abstürzt, wenn ich versuche, das Symbol zu laden. sbrk
ist kein Systemaufruf unter Linux, daher kann ich syscall
nicht einfach indirekt verwenden.
Also meine Frage ist, wie kann ich eine Bibliotheksfunktion von einer Wrapper-Funktion mit dem gleichen Namen aufrufen, ohne dlsym
zu verwenden? Gibt es einen Compiler-Trick (mit gcc), mit dem ich auf die ursprüngliche Funktion verweisen kann?
Siehe ld's Option --wrap symbol
. Von der Manpage:
%Vor%- Umbruchsymbol Verwenden Sie eine Umbruchfunktion für das Symbol. Irgendein undefinierter Referenz auf das Symbol wird aufgelöst zu "
__wrap_symbol
". Irgendein undefinierter Verweis auf "__real_symbol
" wird aufgelöst werden zu symbol.Dies kann verwendet werden, um a Wrapper für eine Systemfunktion. Das Wrapper-Funktion sollte aufgerufen werden "%Code%". Wenn es anrufen möchte die Systemfunktion sollte es aufrufen "
__wrap_symbol
".Hier ist ein triviales Beispiel:
Wenn Sie anderen Code damit verknüpfen Datei mit --wrap malloc, dann alle Aufrufe an "
__real_symbol
" rufen die Funktion "malloc
" stattdessen. Das Rufen Sie "__real_malloc" in
auf "__wrap_malloc
" wird das Reale aufrufen "__wrap_malloc
" Funktion.Sie möchten vielleicht ein "
malloc
" funktioniert auch, also das verbindet ohne die Option --wrap wird gelingen. Wenn Sie das tun, Sie sollte nicht die Definition von "__real_malloc
" in der gleichen Datei wie "%Code%"; Wenn Sie das tun, die Assembler kann den Aufruf zuvor auflösen Der Linker hat die Möglichkeit, ihn zu umbrechen "Malloc".
Die andere Option ist möglicherweise die Quelle für ltrace zu betrachten, es ist mehr oder weniger dasselbe :-P.
Hier ist eine Idee. Sie könnten Ihre __real_malloc
ed-Bibliothek haben, um die PLT-Einträge so zu ändern, dass sie auf Ihren Code verweisen. Dies ist technisch die __wrap_malloc
-Funktion ist immer noch von Ihrem Code nativly aufrufbar.
Sie können den Funktionsaufruf mit Tools wie:
unauffällig untersuchenMit diesen Tools kann ein Überwachungsprogramm Sie informieren, wenn eine Funktion aufgerufen wird, und Sie können die Argumente abfragen.
Die Hauptunterschiede sind:
Wenn Sie ein Host-System mit glibc betreiben, hat die libc ein internes Backend für den Runtime Dynamic Linker, den ich vor einiger Zeit benutzt habe. Wenn ich mich richtig erinnere, denke ich, dass es "__libc_dlsym" heißt. (Um dies zu überprüfen, sollte "$ readelf -s /usr/lib/libc.a | grep dlsym" helfen.) Erklären Sie es als eine extern verknüpfte Funktion mit den gleichen Argumenten und dem Rückgabewert, den dlsym hat, und verwenden Sie es, um dlsym selbst zu umbrechen.
Funktioniert truss
nicht auf Ihrem System? Es funktioniert perfekt für diese Art von Dingen hier auf Solaris.
Tags und Links c linux function-interposition dlsym