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
| Begriff | Was er bedeutet | Beispiel |
|---|---|---|
| Binärdatei | ein fertiges Programm als Datei aus Maschinencode | kasse |
| ELF | das Dateiformat ausführbarer Programme unter Linux | |
| Zeichenkette | ein Text, der im Programm steckt | /etc/kasse.conf |
| Symbol | ein Name im Programm, etwa der einer Funktion | main |
| Bibliotheksfunktion | fertiger Code, den ein Programm von außen holt | fopen |
| Disassembler | ein Werkzeug, das Maschinencode als Assembler zeigt | objdump |
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
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 Ordner 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 kasse schreiben
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.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 kasse kasse.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 kasse.cHier 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?
file kasseHier 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?
strings kasse | grep -i kasseHier 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 Ausgabe | Was er bedeutet |
|---|---|
| ELF 64-bit LSB executable | Ein Programm für Linux, 64 Bit |
| x86-64 | Für diesen Prozessortyp gebaut |
| dynamically linked | Holt Bibliotheksfunktionen beim Start |
| not stripped | Die 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?
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?
objdump -d kasse --disassemble=main | grep callHier 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
| Aufruf | Was er über kasse sagt |
|---|---|
| getenv | Es liest eine Umgebungsvariable |
| fopen | Es öffnet eine Datei |
| puts | Es gibt einen Satz aus |
| fclose | Es schließt die Datei wieder |
| printf | Es 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.