Funktion interposition in Linux ohne dlsym

8

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?

    
Jay Conrod 15.06.2009, 21:22
quelle

4 Antworten

14

Siehe ld's Option --wrap symbol . Von der Manpage:

  

- 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:

%Vor%
  

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.

    
Evan Teran 15.06.2009, 21:28
quelle
2

Sie können den Funktionsaufruf mit Tools wie:

unauffällig untersuchen
  • gdb
  • ltrace
  • Systemtap

Mit diesen Tools kann ein Überwachungsprogramm Sie informieren, wenn eine Funktion aufgerufen wird, und Sie können die Argumente abfragen.

Die Hauptunterschiede sind:

  • gdb ist interaktiv, aber leistungsstark
  • ltrace einfach zu verwenden, aber Sie können nur den Funktionsnamen
  • drucken
  • systemtap ist nicht interaktiv, aber es kann sehr schnell und leistungsfähig sein.
Alex Brown 15.06.2009 21:36
quelle
0

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.

    
14.08.2009 03:34
quelle
0

Funktioniert truss nicht auf Ihrem System? Es funktioniert perfekt für diese Art von Dingen hier auf Solaris.

    
Patrick Schlüter 21.06.2011 19:32
quelle