Lässt es sich mit cremefarbenem Papier, einer Tönung, mehr Kontrast oder größerer Schrift besser lesen? Wählen Sie Ihre Farben und Ihre Schrift, einmalig für alle Seiten.

Kostenlose Lektion

Ein Programm ansehen, ohne es zu starten

Nach dieser Lektion: Ich kann herausfinden, was ein Programm tut, ohne es zu starten.

Lektion, 55 Min.9 BefehleReverse-Engineering-Lab: Programme mit gdb, radare2, strace und ltrace in einer VM lesen

Ein Werkzeug ohne Quelltext

Reverse Engineering heißt, aus einem fertigen Programm herauszulesen, wie es arbeitet, ohne seinen Quelltext zu haben. Das brauchen Sie, wenn auf einem Server ein altes Werkzeug liegt und niemand weiß, was es tut.

Die erste Frage lautet immer: Was verrät das Programm, bevor es läuft? Eine Regel gilt vom ersten Schritt an. Sie üben nur an Programmen dieses Labs, in Ihrer eigenen Kopie.

Am Ende dieser Lektion

Notiz

Ich kann herausfinden, was ein Programm tut, ohne es zu starten.

Schlüsselwörter

BegriffWas er bedeutetBeispiel
Binärdateiein fertiges Programm als Datei aus Maschinencodekasse
ELFdas Dateiformat ausführbarer Programme unter Linux
Zeichenketteein Text, der im Programm steckt/etc/kasse.conf
Symbolein Name im Programm, etwa der einer Funktionmain
Bibliotheksfunktionfertiger Code, den ein Programm von außen holtfopen
Disassemblerein Werkzeug, das Maschinencode als Assembler zeigtobjdump

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Die eine Regel dieses Moduls

Anforderung

Sie lesen nur Programme, die dieses Lab bereitstellt oder die Sie selbst geschrieben haben, und nur in Ihrer eigenen Kopie. Fremde Software, fremde Lizenzen, Spiele und Schutzmechanismen anderer sind tabu. Der Zweck ist Verteidigung: Wer weiß, wie ein Fehler im Programm aussieht, kann ihn finden und beheben.

Zuerst ein Programm, dessen Quelltext verschwindet

Sie bauen jetzt ein kleines Programm kasse und löschen danach den Quelltext. Es soll sich so anfühlen wie ein Fund auf einem Server: Sie haben nur die Datei.

Der Quelltext wird mit printf geschrieben, Zeile für Zeile. gcc baut daraus das Programm. Ordnen Sie alles in einen eigenen Ordner uebung, damit das Lab-Verzeichnis sauber bleibt.

Einen Ordner für die Übungen anlegen

Befehl
mkdir -p ~/uebung

Hier 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 Ordner wechseln

Befehl
cd ~/uebung

Hier 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 kasse schreiben

Befehl
printf '%s\n' '#include <stdio.h>' '#include <stdlib.h>' 'int main(void) {' '    char *modus = getenv("KASSE_MODUS");' '    FILE *f = fopen("/etc/kasse.conf", "r");' '    if (f == NULL) {' '        puts("Keine Einstellungsdatei gefunden.");' '        return 1;' '    }' '    fclose(f);' '    printf("Kasse laeuft im Modus %s.\n", modus ? modus : "normal");' '    return 0;' '}' > kasse.c

Hier 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

Befehl
gcc -O0 -no-pie -fno-stack-protector -o kasse kasse.c

Hier 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

Befehl
rm kasse.c

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

file nennt die Art, strings holt den Text

Der Befehl file liest den Anfang einer Datei und sagt, was sie ist. Der Befehl strings gibt jede Folge lesbarer Zeichen aus, die er in der Datei findet. Ein Programm trägt seinen Text mit sich, ob man es will oder nicht.

Die Ausgabe von strings ist lang. Deshalb behält grep -i kasse nur die Zeilen mit „kasse“ in Groß- oder Kleinschreibung.

Welche Art Datei ist kasse?

Befehl
file kasse

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Welcher Text steckt in kasse?

Befehl
strings kasse | grep -i kasse

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Beispiel: was file gemeldet hat

Teil der AusgabeWas er bedeutet
ELF 64-bit LSB executableEin Programm für Linux, 64 Bit
x86-64Für diesen Prozessortyp gebaut
dynamically linkedHolt Bibliotheksfunktionen beim Start
not strippedDie Namen der Funktionen stehen noch darin

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

nm und objdump zeigen, was ein Programm benutzt

Ein Programm ruft Bibliotheksfunktionen auf, die nicht in ihm stehen, etwa fopen zum Öffnen einer Datei. nm -D --undefined-only listet diese Namen. Das grep behält drei davon.

objdump -d ist ein Disassembler: Er zeigt die Befehle von main als Assembler. Das grep call behält nur die Zeilen, in denen main eine Funktion aufruft, in der Reihenfolge des Programms.

Welche Bibliotheksfunktionen fehlen im Programm?

Befehl
nm -D --undefined-only kasse | grep -E "fopen|getenv|fclose"

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Welche Funktionen ruft main auf?

Befehl
objdump -d kasse --disassemble=main | grep call

Hier angezeigt, nicht ausgeführt. Erstellen Sie ein kostenloses Konto, um „Ausführen“ zu drücken und ihn im Terminal Ihres eigenen Labs einzugeben.

Beispiel: die Aufrufe von main

AufrufWas er über kasse sagt
getenvEs liest eine Umgebungsvariable
fopenEs öffnet eine Datei
putsEs gibt einen Satz aus
fcloseEs schließt die Datei wieder
printfEs gibt formatierten Text aus

Die Zellen, die Lernende ausfüllen, bleiben in dieser Vorschau leer.

Ein häufiger Fehler

Warnung

Viele denken, ein Programm müsse laufen, damit man es verstehen kann. Das stimmt nicht. Text, Funktionsnamen und die Reihenfolge der Aufrufe stehen in der Datei. Prüfen Sie zuerst die Datei. Starten Sie ein unbekanntes Programm erst, wenn Sie wissen, was es tut.

Weiterführend

Wiederholen Sie die Schritte mit einem eigenen Programm. Es öffnet mit fopen eine Datei und gibt mit puts einen Text aus. Prüfen Sie dann mit strings und nm, ob beides in der Binärdatei zu sehen ist.

Danach öffnen Sie README.md im Home-Ordner des Labs. Die fünf Programme dort sind Ihre eigentliche Aufgabe. Die Schritte dieser Lektion helfen Ihnen beim ersten.

Über dieses Lab und seinen Quellcode: Reverse-Engineering-Lab: Programme mit gdb, radare2, strace und ltrace in einer VM lesen

Sie unterrichten eine Gruppe? Weisen Sie dieses Modul Ihren Studierenden zu, mit Handbuch für Lehrende, automatisch geprüften Aufgaben und einem Lab für jede Person.