Selbstmodifizierender Code

Selbstmodifizierender Code

Mit der Bezeichnung Selbstmodifizierender Code (engl: Self Modifying Code) wird ein Abschnitt eines Computerprogramms bezeichnet, das zur Lösung der Programmaufgabe Teile des eigenen Programmcodes während der Ausführung gezielt verändert. Unter der Bezeichnung „freier Rechenplan“ hatte schon Konrad Zuse selbstmodifizierenden Code als Möglichkeit in die von ihm entworfene Programmiersprache Plankalkül aufgenommen.

Das Programm muss dabei in der Lage sein, im Maschinencode bestimmte Befehle durch sinnvolle andere Maschinenbefehle zu ersetzen. Bei höheren Programmiersprachen (z. B. APL) manipuliert das Programm den Quellcode als Zeichenkette (text string).

Selbstmodifizierender Code kann da verwendet werden, wo es möglich ist, mehrere, nur an wenigen Stellen unterschiedliche Programmteile zu einem einzigen zusammenzufassen.

Die Methode, Code sich selbst modifizieren zu lassen, stammt hauptsächlich aus einer Zeit, in der Ressourcen (CPU-Zeit, Speicher) noch sehr knappe Güter waren – es wurde also oftmals eine Optimierung des Laufzeitverhaltens oder Speicherverbrauchs angestrebt. Beides ist mittlerweile nur noch äußerst selten notwendig (z. B. beim „Retro computing“, wenn also auf sehr alten Systemen programmiert wird). Ein anderer Grund zur Selbstmodifikation waren Kopierschutzverfahren. In Anbetracht der historischen Motivationen zum Schreiben von selbstmodifizierendem Code sollte das Vorhandensein von solchem Code nicht alleine nach modernen Maßstäben zur Bemessung von Codequalität bewertet werden, sondern auch immer die (historischen und/oder technischen) Umstände berücksichtigt werden.

Die Veränderung des Programmcodes ist nur in einer Von-Neumann-Architektur möglich, wo Programm und Daten denselben Adressraum teilen. In Prozessoren mit Harvard-Architektur ist das Modifizieren von Programmcode während der Laufzeit nicht vorgesehen, und da ein normales Programm keinen Compiler enthält, muss die Modifikation direkt in Maschinensprache ausgeführt werden. Bei höheren Programmiersprachen sind in der Regel interpretierende (also nicht compilierende) Systeme notwendig. Aus diesen beiden Gründen ist eine Portierung von selbstmodifizierendem Code auf einen beliebigen Prozessor fast nicht möglich.

Der selbstmodifizierende Code eines Programms hat nichts mit Lernen oder der Verbesserung eines Programmes zu tun. Selbstmodifizierende Programme, die die Hochsprache des Programms modifizieren, sind in der Zukunft möglicherweise hilfreich, die Maschinenintelligenz zu steigern.

Inhaltsverzeichnis

Beispiele

Videospiel

In einem Videotennis-Spiel kann im Programmteil, das den Ball steuert, ein Inkrement-Befehl durch einen Dekrement-Befehl ersetzt werden, wenn er an die Wand prallt, dadurch wird die Bewegungsrichtung umgekehrt.

Die Bytes, die die Koordinaten des Balles beinhalten, können so im Speicher abgelegt werden, dass sie gleichzeitig als direkte Parameter eines Kommandos interpretiert werden. Man stelle sich beispielsweise einen Befehl vor, der dazu führt dass der Ball an einer bestimmten Stelle angezeigt wird. Statt nun die beiden Argumente „X-Position“ und „Y-Position“ indirekt als Variablen anzusprechen, können sie direkt so im Speicher abgelegt sein, dass sie Teil des Befehls „Stelle Ball dar“ sind.

Kombination der beiden Beispiele als Pseudo-Programm:

  • wenn Ball an vertikale Wand geprallt ist und im Programmcode „inkrementiere x-Koordinate“ steht, dann schreibe an die entsprechende Speicherstelle den Befehl für „dekrementiere x-Koordinate“ und überspringe den nächsten Befehl
  • wenn Ball an vertikale Wand geprallt ist und im Programmcode „dekrementiere x-Koordinate“ steht, dann schreibe an die entsprechende Speicherstelle den Befehl für „inkrementiere x-Koordinate“
  • wenn Ball an horizontale Wand geprallt ist und im Programmcode „inkrementiere y-Koordinate“ steht, dann schreibe an die entsprechende Speicherstelle den Befehl für „dekrementiere y-Koordinate“ und überspringe den nächsten Befehl
  • wenn Ball an horizontale Wand geprallt ist und im Programmcode „dekrementiere y-Koordinate“ steht, dann schreibe an die entsprechende Speicherstelle den Befehl für „inkrementiere y-Koordinate“
  • inkrementiere x-Koordinate des Balldarstellungsbefehls
  • inkrementiere y-Koordinate des Balldarstellungsbefehls
  • Stelle den Ball dar an Position 1, 1 und fange von vorne an

Sowohl die beiden Befehle zum Inkrementieren als auch die Koordinaten „1,1“ stellen in diesem Beispiel lediglich Anfangswerte dar, die vom Programm selbst modifiziert werden.

Mathematikprogramm

In Microsoft BASIC auf Commodore Computern (z.B. PET , VC 20 , C 64)) war es über ein kurzzeitiges Anhalten eines Programms effektiv möglich, eine über den INPUT Befehl im Programm abgefragte Benutzerfunktion (z.B. "SIN(X)") an den Programmeditor zu übergeben, der eine Zeile im BASIC-Programm entsprechend veränderte, worauf das Programm ohne Verlust der Variableninformation (mittels GOTO Befehl) wieder fortgesetzt wurde und die neue Zeile für Berechnungen nutzen konnte. Dies geschah durch Ausdruck der gewünschten neuen Programmzeile in der obersten Bildschirmzeile (unter Benutzung des Microsoft BASIC Ausdrucks "DEF FN") und Ausgabe des Befehls "GOTO xxx" zum Rücksprung ins Programm in der zweiten Bildschirmzeile. Füllen des Tastaturpuffers mit den Zeichen HOME und mehreren Steuerzeichen für Wagenrücklauf sorgte dafür, dass nach dem STOP Befehl der systemeigene Programmeditor die zuvor ausgegebene Programmzeile bearbeitete und bei Erreichen des GOTO Befehls (ausgelöst durch die Wagenrücklauf-Zeichen) das BASIC-Programm wieder ausführte.

Kopierroutinen (6502 CPU)

Eine solches Unterprogramm bekam Startadresse, Zieladresse und Größe in Byte oder Speicherseiten (je 256 Byte) übergeben. Die normale Art und Weise zu kopieren bestand darin, die Adressen in zwei Zeigern innerhalb der Zeropage zu speichern, und dann indirekt-zeropage adressierbare Lade- und Speicherbefehle mit Indexzugriff zu verwenden. Diese brauchen aber auf der 6502 CPU 2 Taktzyklen mehr als die absolut adressierbaren. Der Trick zur Steigerung der Geschwindigkeit besteht darin, absolut adressierbare Befehle zu verwenden. Bei dieser Art des selbstmodifizierenden Codes werden nicht das Indexregistern und die Zeigeradressen hochgezählt sondern die Adressen im Programmcode hinter dem Opcode der absolut adressierbaren Lade- und Speicherbefehle. Damit lassen sich Kopierroutinen deutlich beschleunigen.

Vorteile

  1. Bei bestimmten Aufgabenstellungen kann ein sehr kompaktes Programm konstruiert werden.
  2. Die gefundene Programmlösung kann elegant erscheinen.
  3. Das Programm kann vor Reverse Engineering besser geschützt werden.

Nachteile

  1. Die Erstellung von selbstmodifizierendem Code wird von Compilern nicht unterstützt.
  2. Der Programmcode ist schwierig oder gar nicht portierbar.
  3. Der Maschinencode ist schwierig nachzuvollziehen.
  4. Der CPU-Entwurf wird deutlich komplizierter.

Wikimedia Foundation.

Игры ⚽ Нужно сделать НИР?

Schlagen Sie auch in anderen Wörterbüchern nach:

  • selbstmodifizierender Code — selbstmodifizierender Code,   ein Programmcode, der sich während der Ausführung selbst verändern kann, indem er sich teilweise mit neuen Anweisungen überschreibt (im Unterschied zum üblichen reentranten Code). Etliche Viren, sog. polymorphe Viren …   Universal-Lexikon

  • International Obfuscated C Code Contest — Der International Obfuscated C Code Contest (kurz IOCCC) ist ein Programmierwettbewerb für die am kreativsten verschleierten C Programme, der seit 1984 jährlich veranstaltet wird (mit Ausnahme von 1997, 1999, 2002 und 2003). (engl.: to obfuscate …   Deutsch Wikipedia

  • YaBasic — Entwickler u.a. Pedro Sá und Thomas Larsen[1] Aktuelle Version 2.9.15 (10. Juni 2010) Betriebssystem GNU/Linux, Windows …   Deutsch Wikipedia

  • Cache-Hierarchie — Cache [kæʃ] bezeichnet in der EDV eine Methode, um Inhalte, die bereits einmal vorlagen, beim nächsten Zugriff schneller zur Verfügung zu stellen. Caches sind als Puffer Speicher realisiert, die die Kopien zwischenspeichern. Sie können als… …   Deutsch Wikipedia

  • Cache-Speicher — Cache [kæʃ] bezeichnet in der EDV eine Methode, um Inhalte, die bereits einmal vorlagen, beim nächsten Zugriff schneller zur Verfügung zu stellen. Caches sind als Puffer Speicher realisiert, die die Kopien zwischenspeichern. Sie können als… …   Deutsch Wikipedia

  • Cache Hit — Cache [kæʃ] bezeichnet in der EDV eine Methode, um Inhalte, die bereits einmal vorlagen, beim nächsten Zugriff schneller zur Verfügung zu stellen. Caches sind als Puffer Speicher realisiert, die die Kopien zwischenspeichern. Sie können als… …   Deutsch Wikipedia

  • Cache Miss — Cache [kæʃ] bezeichnet in der EDV eine Methode, um Inhalte, die bereits einmal vorlagen, beim nächsten Zugriff schneller zur Verfügung zu stellen. Caches sind als Puffer Speicher realisiert, die die Kopien zwischenspeichern. Sie können als… …   Deutsch Wikipedia

  • Cachespeicher — Cache [kæʃ] bezeichnet in der EDV eine Methode, um Inhalte, die bereits einmal vorlagen, beim nächsten Zugriff schneller zur Verfügung zu stellen. Caches sind als Puffer Speicher realisiert, die die Kopien zwischenspeichern. Sie können als… …   Deutsch Wikipedia

  • Caching — Cache [kæʃ] bezeichnet in der EDV eine Methode, um Inhalte, die bereits einmal vorlagen, beim nächsten Zugriff schneller zur Verfügung zu stellen. Caches sind als Puffer Speicher realisiert, die die Kopien zwischenspeichern. Sie können als… …   Deutsch Wikipedia

  • Datenpuffer — Cache [kæʃ] bezeichnet in der EDV eine Methode, um Inhalte, die bereits einmal vorlagen, beim nächsten Zugriff schneller zur Verfügung zu stellen. Caches sind als Puffer Speicher realisiert, die die Kopien zwischenspeichern. Sie können als… …   Deutsch Wikipedia

Share the article and excerpts

Direct link
Do a right-click on the link above
and select “Copy Link”