Wie finde ich heraus, welche Funktionen eines Shared Objects von einem Programm oder einer anderen Bibliothek verwendet werden? In diesem speziellen Fall möchte ich sehen, welche Funktionen in /lib/libgcc1_s.so.1 von einer anderen dynamischen Bibliothek verwendet werden. Da sie dynamisch verknüpft sind, löst objdump -d die Funktionsaufrufadressen nicht auf. Gibt es eine Möglichkeit, das Programm in einem Debugger auszuführen oder statisch neu zu verknüpfen? Vielen Dank,
Lukas
Bearbeiten:
nm und readelf reichen nicht aus, ich muss nicht sehen, welche Symbole in einem gemeinsam genutzten Objekt vorhanden sind, sondern welche tatsächlich in einem anderen Objekt verwendet werden, das darauf verweist.
nm funktioniert nur, wenn die Bibliothek nicht von ihren Symbolen befreit wurde. Jedoch, nm -D
könnte dir ein paar infos zeigen:
nm -D /lib/libgcc_s.so.1
Aber es gibt ein anderes Tool, das Ihnen helfen kann: gelesen
readelf – Zeigt Informationen über ELF-Dateien an.
Und wenn Sie die Manpages überprüfen, Option -s: Displays the entries in symbol table section of the file, if it has one.
readelf -s /lib/libgcc_s.so.1
BEARBEITEN:
Nun, Symbole, die nicht innerhalb des Objekts implementiert sind, das Sie mit nm untersuchen, werden mit a angezeigt U Flag davor, aber nm sagt Ihnen nicht, welche Bibliothek auf Ihrem System dieses Symbol implementiert.
Das, was Sie suchen, kann also wahrscheinlich mit einer Mischung aus erreicht werden ldd und nm. ldd gibt an, mit welchen Bibliotheken Ihre Anwendung verknüpft ist, und nm gibt an, welche Symbole undefiniert sind (U Flag) oder lokal implementiert (T Flagge).
Nachdem Sie alle undefinierten Symbole (mit nm) in der Zielanwendung aufgelistet haben, sollten Sie alle von ldd gemeldeten Bibliotheken auf der Suche nach diesen Symbolen durchlaufen (erneut mit nm). Wenn Sie das Symbol finden und ihm das T-Flag vorangestellt ist, haben Sie es gefunden.
Das habe ich übrigens gerade geschrieben Einzeiler für bash um meine Idee zu veranschaulichen. Es analysiert eine Anwendung namens gewinnen und versucht, die Bibliotheken zu finden, die alle als undefiniert gemeldeten Symbole implementieren.
target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo "Found symbol: $symbol at [$library]"; fi ; done; done; done;
Oder, wenn Ihr Terminal Farben unterstützt:
target="win"; for symbol in $(nm -D $target | grep "U " | cut -b12-); do for library in $(ldd $target | cut -d ' ' -f3- | cut -d' ' -f1); do for lib_symbol in $(nm -D $library | grep "T " | cut -b12-); do if [ $symbol == $lib_symbol ]; then echo -e "Found symbol: \e[1;36m$symbol\033[0m at \e[1;34m$library\033[0m"; fi ; done; done; done;
Ich bin sicher, jemand wird eine Leistungsverbesserung finden.
Ausgänge:
Found symbol: XCreateColormap at [/usr/lib/libX11.so.6]
Found symbol: XCreateWindow at [/usr/lib/libX11.so.6]
Found symbol: XIfEvent at [/usr/lib/libX11.so.6]
Found symbol: XMapWindow at [/usr/lib/libX11.so.6]
Found symbol: XOpenDisplay at [/usr/lib/libX11.so.6]
Found symbol: __libc_start_main at [/lib/tls/i686/cmov/libc.so.6]
Found symbol: __stack_chk_fail at [/lib/tls/i686/cmov/libc.so.6]
Found symbol: glClear at [/usr/lib/mesa/libGL.so.1]
Found symbol: glClearColor at [/usr/lib/mesa/libGL.so.1]
Found symbol: glFlush at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXChooseFBConfig at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXChooseVisual at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateContext at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateNewContext at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXCreateWindow at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXGetVisualFromFBConfig at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXMakeContextCurrent at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXMakeCurrent at [/usr/lib/mesa/libGL.so.1]
Found symbol: glXQueryVersion at [/usr/lib/mesa/libGL.so.1]
Hast Du Dir angesehen ltrace? Es fängt Aufrufe von gemeinsam genutzten Bibliotheksfunktionen zur Laufzeit ab und gibt Informationen darüber aus, sobald sie auftreten.
Da es sich um eine dynamische Lösung handelt, werden keine Informationen für einen Bibliotheksaufruf ausgegeben, der in einem Teil Ihres Programms erfolgt, der nie ausgeführt wird. Aber es könnte immer noch hilfreich sein, je nach Ihren Bedürfnissen.
Mir ist nicht einmal einer bekannt nm
ist für das, was Sie zu beabsichtigen scheinen, von begrenztem Nutzen. Außerdem könnte das Vorladen (des GNU-Linkers) alle Annahmen ungültig machen, die Sie nach der Verwendung eines Tools machen, das dies angeblich tun könnte. Siehe die ld.so Manpage. LD_PRELOAD
kann von jedem verwendet werden, um die Auflösung von Symbolen zu überschreiben, wie sie unter normalen Umständen auftreten würde.
Sie können jedoch auch ohne einen Debugger verwenden LD_DEBUG
um zu sehen, welche Funktion letztendlich verwendet wird.
Vielleicht der nm
Tool kann Ihnen dabei helfen, da es die Namen der Symbole anzeigt, die in einer Binärdatei enthalten sind.
Es ist so einfach wie ABC zu bedienen:
nm my_binary
Dies kann mit einer Technik erreicht werden, die als statische Analyse im Reverse Engineering bezeichnet wird
Dazu benötigen Sie einen Disassembler. Sehen http://en.wikipedia.org/wiki/Disassembler
IDA PRO ist ein guter Disassembler, der Ihre Frage beantwortet. Er kann das ELF-Dateiformat lesen, ist aber leider nicht kostenlos.