Basiswissen Buffer Overflow

14.05.2004
Von Thomas Wölfer

Damit ist nun klar, wie der Fluss des Programms bei Funktionen stattfindet: Der Compiler fügt bei Funktionsaufrufen einfach Sprungbefehle zu den Adressen der aufgerufenen Funktionen ein. Das klärt aber noch nicht, wie das Programm am Ende einer Funktion wieder an die Stelle zurückfindet, von der sie aufgerufen wurde.

Um die Antwort auf diese Frage zu klären, müssen Sie noch ein letztes Stück Hintergrundwissen auf dem Weg zum Verständnis von Buffer-Overflow-Attacken sammeln. Es geht um einen bestimmten Speicherbereich eines Programms: Den Stack.

Für ein Programm sind nicht alle Daten gleich: Allein zum Speichern gibt es zwei unterschiedliche Bereiche, den Stack und den Heap. Den Heap können Sie zunächst einmal getrost vergessen - der hilft bei der Lösung der Ausgangsfrage nicht weiter.

Wichtiger Speicher: Der Stack

Der Stack ist für den Programmablauf sehr wichtig - und zwar für das Ablegen bestimmter Variablen und für den Programmfluss. Beim Stack handelt es sich um einen Speicherbereich, der eine relativ einfache Verwaltung hat: Wie bei einem Stapel Karten, werden die Daten immer oben auf den Stack aufgelegt. Man kann immer nur das oberste Element vom Stapel wieder herunternehmen: Will man ein darunter liegendes Element haben, muss man zuvor alle darüber befindlichen Elemente herunternehmen. Für die jeweils aktuelle Speicheradresse des obersten Elementes des Stacks gibt es in der CPU extra ein eigenes Register: Den Stack-Pointer "SP".

Soll ein neues Datum auf den Stack gelegt werden, dann wird zunächst die Adresse ermittelt, auf den der Stack-Pointer momentan zeigt. An diese Adresse wird das Datum dann kopiert. Danach wird der Stack-Pointer um die entsprechende Anzahl Bytes erhöht. Danach zeigt er also auf den nächsten zu verwendenden Speicherplatz.