Ein Programm bei der Arbeit beobachten
Die Werkzeuge ltrace und strace zeigen, welche Funktionen ein Programm aufruft: ltrace die der Bibliotheken, strace die des Betriebssystems. So sehen Sie, welche Datei ein Programm sucht, ohne ein Wort Assembler zu lesen.
Das ist der schnellste Weg, wenn ein Programm Einstellungen oder eine Lizenzdatei sucht und Sie wissen wollen, wo.
Am Ende dieser Lektion
Notiz
Ich kann mit ltrace und strace herausfinden, welche Datei ein Programm öffnen will.
Schlüsselwörter
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Bibliotheksaufruf | der Aufruf einer fertigen Funktion aus einer Bibliothek | fopen |
| Systemaufruf | eine Bitte des Programms an das Betriebssystem | openat |
| Kernel | der Kern des Betriebssystems, der Dateien und Geräte verwaltet | |
| ltrace | ein Werkzeug, das Bibliotheksaufrufe mit ihren Argumenten ausgibt | |
| strace | ein Werkzeug, das Systemaufrufe mit ihren Ergebnissen ausgibt | |
| ENOENT | der Fehler „Datei oder Ordner existiert nicht“ |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Ein Programm, das zwei Dateien sucht
Das Programm sicherung startet eine Datensicherung. Dafür sucht es eine Einstellungsdatei und eine Sperrdatei. Fehlt die Einstellungsdatei, sagt es das und endet.
Wo es sucht, steht in keinem Text dieser Lektion. Sie finden es mit den Werkzeugen heraus. Bauen Sie es wie die Programme davor und löschen Sie den Quelltext.
Den Übungsordner anlegen, falls er fehlt
mkdir -p ~/uebungHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
In den Übungsordner wechseln
cd ~/uebungHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Den Quelltext von sicherung schreiben
printf '%s\n' '#include <stdio.h>' 'int main(void) {' ' FILE *ini = fopen("/etc/sicherung.ini", "r");' ' FILE *sperre = fopen("/var/tmp/sicherung.sperre", "r");' ' if (ini == NULL) {' ' puts("Keine Einstellungen gefunden.");' ' return 1;' ' }' ' if (sperre != NULL) {' ' puts("Die Sicherung ist gesperrt.");' ' return 1;' ' }' ' puts("Sicherung gestartet.");' ' return 0;' '}' > sicherung.cHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Das Programm bauen
gcc -O0 -no-pie -fno-stack-protector -o sicherung sicherung.cHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Den Quelltext löschen
rm sicherung.cHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Das Programm einmal starten
./sicherungHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
ltrace zeigt die Aufrufe der Bibliotheken
Das Programm sagt nur „Keine Einstellungen gefunden“, aber nicht, wo es danach gesucht hat. ltrace gibt jeden Aufruf einer Bibliotheksfunktion mit seinen Argumenten aus.
Die Option -e fopen zeigt nur die Aufrufe von fopen. Das erste Argument ist der Pfad, das zweite der Modus. r heißt: zum Lesen öffnen. Das Ende der Zeile zeigt, dass fopen nichts geliefert hat.
Die fopen-Aufrufe von sicherung ansehen
ltrace -e fopen ./sicherung 2>&1 | grep fopenHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
strace zeigt die Bitten an das Betriebssystem
Unter fopen steckt ein Systemaufruf, openat. strace -e trace=openat zeigt nur diese. Jede Zeile hat den Aufruf, den Pfad und am Ende das Ergebnis.
Der Strom der Meldungen von strace geht an die Fehlerausgabe. Mit 2>&1 leitet die Shell ihn in die Leitung zu grep, das nur Zeilen mit sicherung behält.
Die openat-Aufrufe von sicherung ansehen
strace -e trace=openat ./sicherung 2>&1 | grep sicherungHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Beispiel: eine Zeile von strace lesen
| Teil der Zeile | Was er bedeutet |
|---|---|
| openat(AT_FDCWD, "…", O_RDONLY) | Das Programm öffnet eine Datei zum Lesen |
| Der Text in Anführungszeichen | Der Pfad der Datei |
| = -1 | Der Aufruf ist fehlgeschlagen |
| ENOENT | Es gibt die Datei nicht |
Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.
Auch die Ausgabe ist ein Systemaufruf
Wenn das Programm etwas ausgibt, ruft es write auf. Mit -e trace=write zeigt strace genau diese Aufrufe.
Die eigene Ausgabe des Programms geht hier nach /dev/null, damit nur die Meldung von strace sichtbar bleibt. Die Zahl hinter dem Text ist die Länge in Bytes.
Die Ausgabe als Systemaufruf sehen
strace -e trace=write ./sicherung >/dev/nullHier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.
Ein häufiger Fehler
Warnung
Viele halten jede Zeile mit ENOENT für einen Fehler des Programms. Programme probieren oft mehrere Pfade, und das ist normal. Wichtig ist, ob der Pfad zum Programm gehört und nicht zum System. Die Pfade der C-Bibliothek, die mit /lib beginnen, können Sie überspringen.
Weiterführend
Legen Sie die Einstellungsdatei, die sicherung sucht, mit sudo touch und dem Pfad aus Ihrer Spur an. Starten Sie das Programm erneut. Was sagt es jetzt?
Beachten Sie die Regel des Moduls: Sie beobachten nur Programme Ihres eigenen Labs. Bei einem fremden Programm wäre schon das Beobachten ein Eingriff, den niemand erlaubt hat.