Wie kann ich statische Funktionen mit nm oder readelf in C unterscheiden?

8

Ich versuche, die Ausgabe eines nm oder readelf -s auf einer ausführbaren Datei zu verarbeiten. Ich habe jedoch Probleme, statische Funktionen in der Ausgabe voneinander zu unterscheiden.

Hier ist, woran ich arbeite:

test.c

%Vor%

sonstiges.c

%Vor%

Ich kompiliere diese wie folgt:

%Vor%

Und dann einen nm-Befehl ausführen, um alle Symbole zu erhalten:

%Vor%

Darunter erscheinen die folgenden zwei Symbole (für meine statischen Funktionen):

%Vor%

Gibt es eine Methode, um unterscheiden zu können, aus welcher Datei die spezifische foo-Funktion stammt? Oder muss ich etwas Magie vor dem Kompilieren machen, um das zum Laufen zu bringen?

Ich sollte hinzufügen, dass ich für meinen Anwendungsfall Zugriff auf die endgültige Binärdatei und die von ihm verwendeten Objektdateien habe, aber ich kann es nicht selbst erstellen, um sicherzustellen, dass es eine Symboltabelle hat.

Danke!

    
Andrew 08.06.2015, 16:38
quelle

4 Antworten

9

Ihre Frage geht davon aus, dass Sie bei einer ausführbaren Datei immer feststellen können die Namen der static (lokalen) Funktionen, die darin kompiliert wurden, mit nm oder einem anderen Werkzeug. So können Sie sehen, wenn zwei oder mehr solche Namen sind gleich und werfen die Frage auf, wie man entdeckt aus welchen Quelldateien sie kompiliert wurden.

Diese Annahme ist jedoch falsch. Im Fall von gcc, wenn Dateien kompiliert werden Mit Optimierung -O0 werden dann lokale Symbole im Objekt ausgegeben Dateisymbol Tabelle. -O0 ist der Standardwert, also gilt es im Fall von:

%Vor%

Aber wenn Dateien auf einer höheren Optimierungsebene kompiliert werden - wie sie sicherlich sind wird für einen Release-Build sein - dann werden lokale Symbole aus dem Objekt weggelassen Dateien Symboltabelle. Der Linker sieht sie also nie. Du kannst dich also nicht erholen sie aus der ausführbaren Datei mit nm oder irgendetwas anderem.

Kompilieren Sie Ihre Beispieldateien mit:

%Vor%

dann nm test erneut, und Sie werden feststellen, dass die:

%Vor%

ist zusammen mit allen anderen statischen Funktionsnamen verschwunden.

Wenn Sie in diesem Fall nicht steuern können, wie die ausführbare Datei erstellt wird, dann können Sie nicht sicherstellen, dass es überhaupt möglich ist, dass Ihre Frage auftaucht .

Wenn Sie können steuern, wie die ausführbare Datei erstellt wird, um sicherzustellen, dass es sich um Dateien handelt kompiliert mit -O0 , dann gibt es mehrere Möglichkeiten, wie Sie die statische Funktionsnamen für Quelldateien. Zwei ebenso einfache wären:

%Vor%

und

%Vor%

jeder von ihnen wird einen Quelldateinamen an der Spitze jedes Stücks von auflisten Symbole, die von ihm kommen.

(Und wenn es nötig ist, entgeht der von @Amol vorgeschlagene gdb -Ansatz nicht der Einschränkung, dass die ausführbare Datei mit der Optimierung -O0 kompiliert worden sein muss)

    
Mike Kinghan 08.06.2015, 19:39
quelle
3

Ich habe die folgende Sequenz ausprobiert.

Wenn Sie die Ausgabedatei ohne Debugging-Symbole entfernt haben, können Sie mit gdb eine Objektdatei erstellen.    Befolgen Sie die folgenden Befehle:

%Vor%

gibt folgendes als Ausgabe

%Vor%

Dann (gdb) wird in Terminal

kommen

Geben Sie die folgenden Befehle nacheinander ein (die Eingabeaufforderung (gdb) wird standardmäßig bei der Eingabe von Befehlen angezeigt)

%Vor%

Jetzt können Sie in Ihrem Ordner eine Datei mit dem Namen Dateiname sehen. Öffnen Sie diese Datei im Texteditor, dann können Sie Informationen wie folgt sehen:

%Vor%

Hier können Sie deutlich sehen, welche foo() Funktion von welcher .c Datei kommt. Hoffe, das hilft dir.

    
Samurai Jack 08.06.2015 18:51
quelle
2

Sie müssen möglicherweise die ELF-Symboltabelle lesen und den ELF32_ST_BIND-Wert extrahieren.

Gemäß der ELF-Spezifikation (siehe Ссылка ) können die Werte für ELF32_ST_BIND sein:

%Vor%

Dabei ist STB_LOCAL definiert als "Lokale Symbole sind außerhalb der Objektdatei, die ihre Definition enthält, nicht sichtbar. Lokale Symbole mit demselben Namen können in mehreren Dateien vorhanden sein, ohne sich gegenseitig zu stören." die scheinen ziemlich gut mit statischen C-Funktionen übereinzustimmen.

Nehmen Sie zum Beispiel eine Probe und ändern Sie sie leicht:

%Vor%

und kompilieren mit gcc -o test test.c other.c und Blick auf die Symboltabelle (viele Einträge entfernt):

%Vor%

Wir können sehen, dass die beiden statischen Funktionen als LOCAL und die eine "normale" Funktion als GLOBAL

angezeigt wird

Hinweis: Während diese Methode mit Nicht-Debug-Dateien funktioniert, können wir diese Methode nicht verwenden, wenn die letzte Datei entfernt wird.

    
thurizas 08.06.2015 17:49
quelle
0

Wenn es mit einer abgestreiften ausführbaren Datei funktionieren soll, können Sie eine Zeichenfolge in die Funktionen einfügen und in der ausführbaren Datei suchen.

%Vor%     
4566976 08.06.2015 21:09
quelle

Tags und Links