Wenn ich gdb zum Debuggen eines in C geschriebenen Programms verwende, zeigt der Befehl disassemble die Codes und ihre Adressen in der Code-Speichersegmentierung an. Ist es möglich, diese Speicheradressen zur Laufzeit zu kennen? Ich benutze Ubuntu OS. Danke.
[Bearbeiten] Um genauer zu sein, werde ich es mit dem folgenden Beispiel demonstrieren.
%Vor%Jetzt möchte ich die Adresse von myfunction () in der Code-Speichersegmentierung haben, wenn ich mein Programm starte.
Die obige Antwort ist sehr kompliziert. Wenn die Funktionsreferenz wie oben beschrieben statisch ist, ist die Adresse einfach der Wert des Symbolnamens im Zeigerkontext:
%Vor%Wenn Sie die Funktion dynamisch aus einer gemeinsam genutzten Bibliothek herausholen, ist der von dlsym () (POSIX) oder GetProcAddress () (windows) zurückgegebene Wert ebenfalls die Adresse der Funktion.
Beachten Sie, dass der obige Code wahrscheinlich bei einigen Compilern eine Warnung generiert, da ISO C technisch die Zuordnung zwischen Code und Datenzeigern verbietet (einige Architekturen bringen sie in physikalisch unterschiedliche Adressräume).
Und einige Pedanten werden darauf hinweisen, dass die zurückgegebene Adresse nicht wirklich ist, um die Speicheradresse der Funktion zu sein, es ist nur ein eindeutiger Wert, der mit anderen Funktionszeigern verglichen werden kann agiert, wenn es aufgerufen wird, um die Steuerung an die Funktion zu übertragen, deren Zeiger sie enthält. Offensichtlich implementieren alle bekannten Compiler dies mit einer Verzweigungszieladresse.
Und schließlich, beachten Sie, dass die "Adresse" einer Funktion ein wenig mehrdeutig ist. Wenn die Funktion dynamisch geladen wurde oder eine externe Referenz auf ein exportiertes Symbol ist, erhalten Sie in der Regel einen Zeiger auf einen Fixup-Code im "PLT" (ein Unix / ELF-Ausdruck, obwohl der PE / COFF-Mechanismus in Windows ähnlich ist) ) Das springt dann zur Funktion.
Wenn Sie den Funktionsnamen kennen, bevor das Programm ausgeführt wird, verwenden Sie einfach
%Vor%Wenn der Funktionsname zur Laufzeit angegeben wird, habe ich einmal eine Funktion geschrieben, um die Adresse des Symbols mithilfe der bfd-Bibliothek dynamisch zu ermitteln. Hier ist der x86_64-Code, Sie können die Adresse über find_symbol ("a.out", "myfunction") im Beispiel erhalten.
%Vor% Um ein Backtrace zu erhalten, verwenden Sie execinfo.h
als dokumentiertes im GNU libc-Handbuch .
Zum Beispiel:
%Vor%kompiliert
%Vor%Laut der erwähnten Website:
Momentan werden der Funktionsname und der Offset nur auf Systemen erhalten, die den ELF verwenden Binärformat für Programme und Bibliotheken. Auf anderen Systemen nur die hexadezimale Rückgabe Adresse wird anwesend sein. Außerdem müssen Sie möglicherweise zusätzliche Flags an den Linker übergeben Machen Sie die Funktionsnamen für das Programm verfügbar. (Zum Beispiel auf Systemen mit GNU ld, du musst passen (-rdynamic.)
Ausgabe
%Vor%Über einen Kommentar in einer Antwort (die Adresse einer Anweisung erhalten), können Sie diesen sehr hässlichen Trick verwenden
%Vor%Es sollte env [12] (der Eip) sein, aber sei vorsichtig, da es maschinenabhängig ist, also überprüfe mein Wort. Dies ist die Ausgabe
%Vor%Viel Spaß!
Tags und Links c