In einer c't gab es einen Artikel zu dem Thema. (Ich weiß leider nichtmehr in welcher Außgabe)
Das ganze funktioniert, weil die lokalen Variablen auf dem Stack abgelegt werden
und der Stack von 'oben' nach 'unten' wächst.
Erst kommen die Parameter, dann die Rücksprungadresse, evtl. noch einige
gesicherte Register und danach die lokalen Variablen.
So kann die Rücksprungadresse überschrieben und dadurch beliebiger Code
ausgeführt werden.
Mal ein Beispiel:
Code: Alles auswählen
Procedure Test(a,b)
Dim Buffer.b(100)
ReceiveNetworkData(a, @Buffer, b)
EndProcedure
Der Stackaufbau innerhalb von Test()
(Die Adressen der Elemente nehmen nach unten ab, d.h. der Buffer liegt
vor der Rücksprungadresse im Speicher.)
Code: Alles auswählen
Parameter B
Parameter A
Rücksprungadresse
(gesicherte Register ebp...)
Buffer
Solange b<=100 ist, ist alles ok, aber wenn b>100 ist, werden erst die
gesicherten Register überschrieben und danach die Rücksprungadresse.
Wenn die Rücksprungadresse überschrieben ist,
kehrt ProcedureReturn nicht an die Stelle von wo die Prozedur aufgerufen wurde
zurück, sondern Springt an die manipulierte Adresse.
Das Programm kann dann durch einen ungültigen Speicherzugriff abstürzen
oder aber etwas ganz anderes ausführen.
Wobei ich mir nicht sicher bin, ob Dim überhaupt lokale Variablen auf dem Stack ablegt.