suchen
HeimSystem-TutorialLINUXLinux-Debugger-Stack-Erweiterung!

Linux-Debugger-Stack-Erweiterung!

Jan 06, 2024 pm 10:25 PM
linuxlinux教程红帽linux系统linux命令Linux-ZertifizierungRed Hat LinuxLinux-Video

Einführung Manchmal ist die wichtigste Information, die Sie wissen müssen, wie Ihr aktueller Programmstand dorthin gelangt ist. Es gibt einen Backtrace-Befehl, der Ihnen die aktuelle Funktionsaufrufkette Ihres Programms liefert. In diesem Beitrag erfahren Sie, wie Sie das Stack-Unwinding auf x86_64 implementieren, um einen solchen Traceback zu generieren.
Serienindex

Diese Links werden online geschaltet, sobald andere Beiträge veröffentlicht werden.

  1. Bereiten Sie die Umgebung vor
  2. Haltepunkt
  3. Register und Speicher
  4. ELF und ZWERG
  5. Quellcode und Signale
  6. Schritt-für-Schritt-Ausführung auf Quellcode-Ebene
  7. Haltepunkte auf Quellenebene
  8. Stack-Erweiterung
  9. Variablen lesen
  10. Nächste Schritte

Nehmen Sie das folgende Programm als Beispiel:

void a() {
//stopped here
}
void b() {
a();
}
void c() {
a();
}
int main() {
b();
c();
}

Wenn der Debugger an der Zeile //stopped here' stoppt, gibt es zwei Möglichkeiten, dorthin zu gelangen: main->b->a oder main->c->a`. Wenn wir mit LLDB einen Breakpoint setzen, die Ausführung fortsetzen und einen Traceback anfordern, dann erhalten wir Folgendes:

* frame #0: 0x00000000004004da a.out`a() + 4 at bt.cpp:3
frame #1: 0x00000000004004e6 a.out`b() + 9 at bt.cpp:6
frame #2: 0x00000000004004fe a.out`main + 9 at bt.cpp:14
frame #3: 0x00007ffff7a2e830 libc.so.6`__libc_start_main + 240 at libc-start.c:291
frame #4: 0x0000000000400409 a.out`_start + 41

Das bedeutet, wir befinden uns derzeit in Funktion a, a springt von Funktion b, b springt von der Hauptfunktion usw. In den letzten beiden Frames führt der Compiler das Bootstrapping der Hauptfunktion durch.

Die Frage ist nun, wie wir es auf x86_64 umsetzen. Der robusteste Ansatz wäre, den .eh_frame-Teil der ELF-Datei zu analysieren und herauszufinden, wie der Stapel von dort abgewickelt werden kann, aber das wäre mühsam. Sie könnten es mit libunwind oder ähnlichem machen, aber das ist langweilig. Stattdessen gehen wir davon aus, dass der Compiler den Stapel auf irgendeine Weise eingerichtet hat, und durchlaufen ihn manuell. Dazu müssen wir zunächst das Layout des Stapels verstehen.

High
| ... |
+---------+
+24| Arg 1 |
+---------+
+16| Arg 2 |
+---------+
+ 8| Return |
+---------+
EBP+--> |Saved EBP|
+---------+
- 8| Var 1 |
+---------+
ESP+--> | Var 2 |
+---------+
| ... |
Low

Wie Sie sehen können, wird der Frame-Zeiger des letzten Stack-Frames am Anfang des aktuellen Stack-Frames gespeichert, wodurch eine verknüpfte Liste von Zeigern erstellt wird. Der Stapel wird basierend auf dieser verknüpften Liste abgewickelt. Wir können die Funktion für den nächsten Frame in der Liste finden, indem wir in der DWARF-Nachricht nach der Rücksprungadresse suchen. Einige Compiler ignorieren die Verfolgung der Frame-Basisadresse von EBP, da diese als Offset von ESP ausgedrückt werden kann und ein zusätzliches Register freigibt. Selbst wenn Optimierungen aktiviert sind, wird die Übergabe von -fno-omit-frame-pointer an GCC oder Clang dazu führen, dass die Konventionen eingehalten werden, auf die wir angewiesen sind.

Wir erledigen die ganze Arbeit in der Funktion print_backtrace:

void debugger::print_backtrace() {

Als Erstes müssen Sie entscheiden, welches Format zum Ausdrucken der Rahmeninformationen verwendet werden soll. Ich habe ein Lambda verwendet, um diese Methode einzuführen:

auto output_frame = [frame_number = 0] (auto&& func) mutable {
std::cout 
<p>Der erste gedruckte Frame ist der aktuell ausgeführte Frame. Informationen zu diesem Frame erhalten wir, indem wir den aktuellen Programmzähler in DWARF nachschlagen: </p>
<pre class="brush:php;toolbar:false">auto current_func = get_function_from_pc(get_pc());
output_frame(current_func);

Als nächstes müssen wir den Frame-Zeiger und die Rückgabeadresse der aktuellen Funktion abrufen. Der Frame-Zeiger wird im RBP-Register gespeichert und die Rücksprungadresse beträgt 8 Bytes, gestapelt vom Frame-Zeiger.

auto frame_pointer = get_register_value(m_pid, reg::rbp);
auto return_address = read_memory(frame_pointer+8);

Jetzt haben wir alle Informationen, die wir brauchen, um den Stack zu erweitern. Ich spule einfach weiter ab, bis der Debugger die Hauptfunktion erreicht, Sie können aber auch anhalten, wenn der Frame-Zeiger 0x0 ist. Dies sind die Funktionen, die Sie aufrufen, bevor Sie die Hauptfunktion aufrufen. Wir erfassen den Frame-Zeiger und die Rücksprungadresse von jedem Frame und drucken die Informationen aus.

while (dwarf::at_name(current_func) != "main") {
current_func = get_function_from_pc(return_address);
output_frame(current_func);
frame_pointer = read_memory(frame_pointer);
return_address = read_memory(frame_pointer+8);
}
}

Das ist es! Hier ist die gesamte Funktion:

void debugger::print_backtrace() {
auto output_frame = [frame_number = 0] (auto&& func) mutable {
std::cout 
<strong>Befehl hinzufügen</strong>
<p>Natürlich müssen wir diesen Befehl dem Benutzer zugänglich machen. </p>
<pre class="brush:php;toolbar:false">else if(is_prefix(command, "backtrace")) {
print_backtrace();
}
Test

Eine Möglichkeit, diese Funktionalität zu testen, besteht darin, ein Testprogramm mit einer Reihe kleiner Funktionen zu schreiben, die sich gegenseitig aufrufen. Legen Sie ein paar Haltepunkte fest, springen Sie durch den Code und stellen Sie sicher, dass Ihr Traceback korrekt ist.

Wir haben einen langen Weg von einem Programm zurückgelegt, das nur spawnen und sich an andere Programme anhängen konnte. Der vorletzte Artikel dieser Reihe vervollständigt die Debugger-Implementierung durch die Unterstützung des Lesens und Schreibens von Variablen. Bis dahin finden Sie den Code für diesen Beitrag hier.

Das obige ist der detaillierte Inhalt vonLinux-Debugger-Stack-Erweiterung!. Für weitere Informationen folgen Sie bitte anderen verwandten Artikeln auf der PHP chinesischen Website!

Stellungnahme
Dieser Artikel ist reproduziert unter:Linux就该这么学. Bei Verstößen wenden Sie sich bitte an admin@php.cn löschen
Läuft das Internet unter Linux?Läuft das Internet unter Linux?Apr 14, 2025 am 12:03 AM

Das Internet stützt sich nicht auf ein einzelnes Betriebssystem, aber Linux spielt eine wichtige Rolle dabei. Linux wird häufig auf Servern und Netzwerkgeräten verwendet und ist für seine Stabilität, Sicherheit und Skalierbarkeit beliebt.

Was sind Linux -Operationen?Was sind Linux -Operationen?Apr 13, 2025 am 12:20 AM

Der Kern des Linux -Betriebssystems ist die Befehlszeilenschnittstelle, die verschiedene Operationen über die Befehlszeile ausführen kann. 1. Datei- und Verzeichnisoperationen verwenden LS, CD, MKDIR, RM und andere Befehle, um Dateien und Verzeichnisse zu verwalten. 2. Benutzer- und Berechtigungsverwaltung sorgt für die Systemsicherheit und die Ressourcenzuweisung über UserAdd, PASSWD, CHMOD und andere Befehle. 3. Process Management verwendet PS, Kill und andere Befehle, um Systemprozesse zu überwachen und zu steuern. 4. Netzwerkoperationen umfassen Ping, IFConfig, SSH und andere Befehle zum Konfigurieren und Verwalten von Netzwerkverbindungen. 5. Systemüberwachung und Wartung Verwenden Sie Befehle wie Top, DF, DU, um den Betriebsstatus und die Ressourcennutzung des Systems zu verstehen.

Steigern Sie die Produktivität mit benutzerdefinierten Befehlskürzungen mithilfe von Linux -AliaseSteigern Sie die Produktivität mit benutzerdefinierten Befehlskürzungen mithilfe von Linux -AliaseApr 12, 2025 am 11:43 AM

Einführung Linux ist ein leistungsstarkes Betriebssystem, das aufgrund seiner Flexibilität und Effizienz von Entwicklern, Systemadministratoren und Stromnutzern bevorzugt wird. Die Verwendung langer und komplexer Befehle kann jedoch mühsam und äh sein

Wofür ist Linux eigentlich gut?Wofür ist Linux eigentlich gut?Apr 12, 2025 am 12:20 AM

Linux eignet sich für Server, Entwicklungsumgebungen und eingebettete Systeme. 1. Als Serverbetriebssystem ist Linux stabil und effizient und wird häufig zur Bereitstellung von Anwendungen mit hoher Konreise verwendet. 2. Als Entwicklungsumgebung bietet Linux effiziente Befehlszeilen -Tools und Paketmanagementsysteme, um die Entwicklungseffizienz zu verbessern. 3. In eingebetteten Systemen ist Linux leicht und anpassbar und für Umgebungen mit begrenzten Ressourcen geeignet.

Wesentliche Tools und Frameworks für das Beherrschen ethischer Hacking unter LinuxWesentliche Tools und Frameworks für das Beherrschen ethischer Hacking unter LinuxApr 11, 2025 am 09:11 AM

Einführung: Sicherung der digitalen Grenze mit Linux-basierten ethischen Hacking In unserer zunehmend miteinander verbundenen Welt ist die Cybersicherheit von größter Bedeutung. Ethische Hacking- und Penetrationstests sind von entscheidender Bedeutung, um Schwachstellen proaktiv zu identifizieren und zu mildern

Wie lerne ich Linux -Grundlagen?Wie lerne ich Linux -Grundlagen?Apr 10, 2025 am 09:32 AM

Zu den Methoden für das grundlegende Linux -Lernen von Grund zu Grund gehören: 1. Verstehen Sie das Dateisystem und die Befehlszeilenschnittstelle, 2. Master Basic -Befehle wie LS, CD, MKDIR, 3. Lernen Sie Dateivorgänge wie Erstellen und Bearbeiten von Dateien, 4. Erklären Sie fortgeschrittene Verwendung wie Pipelines und GREP -Befehle, 5.

Was nutzt Linux am meisten?Was nutzt Linux am meisten?Apr 09, 2025 am 12:02 AM

Linux wird häufig in Servern, eingebetteten Systemen und Desktopumgebungen verwendet. 1) Im Serverfeld ist Linux aufgrund seiner Stabilität und Sicherheit eine ideale Wahl für das Hosting von Websites, Datenbanken und Anwendungen geworden. 2) In eingebetteten Systemen ist Linux für seine hohe Anpassung und Effizienz beliebt. 3) In der Desktop -Umgebung bietet Linux eine Vielzahl von Desktop -Umgebungen, um den Anforderungen verschiedener Benutzer gerecht zu werden.

Was sind die Nachteile von Linux?Was sind die Nachteile von Linux?Apr 08, 2025 am 12:01 AM

Die Nachteile von Linux umfassen Benutzererfahrung, Softwarekompatibilität, Hardwareunterstützung und Lernkurve. 1. Die Benutzererfahrung ist nicht so freundlich wie Windows oder MacOS und basiert auf der Befehlszeilenschnittstelle. 2. Die Softwarekompatibilität ist nicht so gut wie andere Systeme und es fehlen native Versionen vieler kommerzieller Software. 3. Die Hardware -Unterstützung ist nicht so umfassend wie Windows, und die Treiber können manuell zusammengestellt werden. 4. Die Lernkurve ist steil, und die Mastering -Befehlszeilenvorgänge erfordert Zeit und Geduld.

See all articles

Heiße KI -Werkzeuge

Undresser.AI Undress

Undresser.AI Undress

KI-gestützte App zum Erstellen realistischer Aktfotos

AI Clothes Remover

AI Clothes Remover

Online-KI-Tool zum Entfernen von Kleidung aus Fotos.

Undress AI Tool

Undress AI Tool

Ausziehbilder kostenlos

Clothoff.io

Clothoff.io

KI-Kleiderentferner

AI Hentai Generator

AI Hentai Generator

Erstellen Sie kostenlos Ai Hentai.

Heißer Artikel

R.E.P.O. Energiekristalle erklärten und was sie tun (gelber Kristall)
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. Beste grafische Einstellungen
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
R.E.P.O. So reparieren Sie Audio, wenn Sie niemanden hören können
4 Wochen vorBy尊渡假赌尊渡假赌尊渡假赌
WWE 2K25: Wie man alles in Myrise freischaltet
1 Monate vorBy尊渡假赌尊渡假赌尊渡假赌

Heiße Werkzeuge

EditPlus chinesische Crack-Version

EditPlus chinesische Crack-Version

Geringe Größe, Syntaxhervorhebung, unterstützt keine Code-Eingabeaufforderungsfunktion

VSCode Windows 64-Bit-Download

VSCode Windows 64-Bit-Download

Ein kostenloser und leistungsstarker IDE-Editor von Microsoft

MinGW – Minimalistisches GNU für Windows

MinGW – Minimalistisches GNU für Windows

Dieses Projekt wird derzeit auf osdn.net/projects/mingw migriert. Sie können uns dort weiterhin folgen. MinGW: Eine native Windows-Portierung der GNU Compiler Collection (GCC), frei verteilbare Importbibliotheken und Header-Dateien zum Erstellen nativer Windows-Anwendungen, einschließlich Erweiterungen der MSVC-Laufzeit zur Unterstützung der C99-Funktionalität. Die gesamte MinGW-Software kann auf 64-Bit-Windows-Plattformen ausgeführt werden.

SublimeText3 Linux neue Version

SublimeText3 Linux neue Version

SublimeText3 Linux neueste Version

DVWA

DVWA

Damn Vulnerable Web App (DVWA) ist eine PHP/MySQL-Webanwendung, die sehr anfällig ist. Seine Hauptziele bestehen darin, Sicherheitsexperten dabei zu helfen, ihre Fähigkeiten und Tools in einem rechtlichen Umfeld zu testen, Webentwicklern dabei zu helfen, den Prozess der Sicherung von Webanwendungen besser zu verstehen, und Lehrern/Schülern dabei zu helfen, in einer Unterrichtsumgebung Webanwendungen zu lehren/lernen Sicherheit. Das Ziel von DVWA besteht darin, einige der häufigsten Web-Schwachstellen über eine einfache und unkomplizierte Benutzeroberfläche mit unterschiedlichen Schwierigkeitsgraden zu üben. Bitte beachten Sie, dass diese Software