Selbstmodifizierender Code

Im Informatik, selbstmodifizierender Code (SMC) ist Code das ändert sich selbst Anweisungen während es ist Ausführung - normalerweise um die zu reduzieren Anweisungspfadlänge und verbessern Leistung oder einfach einfach, um einen ansonsten wiederholten ähnlichen Code zu reduzieren und so die Wartung zu vereinfachen. Der Begriff wird normalerweise nur auf Code angewendet, in dem die Selbstmodifikation beabsichtigt ist, nicht in Situationen, in denen Code sich aufgrund eines Fehlers wie a versehentlich selbst ändert Pufferüberlauf.

Selbstmodifizierender Code kann vorhandene Anweisungen überschreiben oder neue Code zum Laufzeit generieren und die Kontrolle an diesen Code übertragen.

Selbstmodifikation kann eine Alternative zur Methode der "Flag-Einstellung" und der bedingten Programmabzweigung verwendet werden, die hauptsächlich verwendet werden, um die Häufigkeit zu verringern, mit der ein Zustand getestet werden muss.

Die Methode wird häufig zum bedingten Aufrufen verwendet Test/Debuggen Code, ohne zusätzliche zu benötigen Rechenaufwand für jeden Input-Output Kreislauf.

Die Änderungen können durchgeführt werden:

  • Nur während der Initialisierung - basierend auf der Eingabe Parameter (Wenn der Prozess häufiger als Software beschrieben wird 'Aufbau'Und ist in Hardware -Begriffen etwas analog Springer zum Leiterplatten). Änderung des Programmeintritts Zeiger ist eine äquivalente indirekte Methode der Selbstmodifizierung, erfordert jedoch das Koexistenz eines oder mehrerer alternativer Unterrichtswege Programmgröße.
  • während der gesamten Ausführung ("On the Fly") - basierend auf bestimmten Programmstaaten, die während der Ausführung erreicht wurden

In beiden Fällen können die Modifikationen direkt an die durchgeführt werden Maschinensprache Anweisungen selbst, von Überlagerung Neue Anweisungen über die vorhandenen (zum Beispiel: Änderung eines Vergleichs und Zweigs mit einem bedingungslose Zweige oder alternativ ein ''NOP').

In dem IBM System/360 Architekturund seine Nachfolger bis zu Z/Architektur, eine Ausführungsanweisung (Ex) logisch überlagert das zweite Byte seines Zielunterrichts mit den 8 Bit von niedriger Ordnung von Bit von registrieren 1. Dies liefert den Effekt der Selbstmodifizierung, obwohl der tatsächliche Anweisungen in der Speicherung nicht geändert wird.

Anwendung in Sprachen mit niedrigem und hohem Niveau

Die Selbstmodifikation kann in Abhängigkeit von der Programmiersprache und ihrer Unterstützung für Zeiger und/oder Zugriff auf den dynamischen Compiler oder Interpreter „Motoren“ auf verschiedene Weise erreicht werden:

  • Überlagerung vorhandener Anweisungen (oder Teile von Anweisungen wie Opcode, Registrieren, Flaggen oder Adressen) oder
  • Direkte Schaffung ganzer Anweisungen oder Sequenzen von Anweisungen im Speicher
  • Erstellen oder Änderung von Quellcode Aussagen gefolgt von einem "Mini Compile" oder einer dynamischen Interpretation (siehe bewerten Aussage)
  • Dynamisch ein ganzes Programm erstellen und dann ausführen

Montagesprache

Selbstmodifizierender Code ist bei der Verwendung recht einfach zu implementieren Montagesprache. Anweisungen können dynamisch in erstellt werden Erinnerung (oder überlagert über vorhandenen Code im nicht geschützten Programmspeicher) in einer Sequenz, die zu denen entspricht, die ein Standard-Compiler als die generieren kann Objektcode. Bei modernen Prozessoren kann es unbeabsichtigt sein Nebenwirkungen auf der CPU -Cache das muss berücksichtigt werden. Die Methode wurde häufig zum Testen der Erstbedingungen verwendet, wie in diesem geeigneten Kommentar IBM/360 Assembler Beispiel. Es verwendet Anweisungsüberlagerung, um die zu reduzieren Anweisungspfadlänge durch (n × 1) −1 wobei n die Anzahl der Datensätze in der Datei ist (–1 ist die Überkopf Um die Overlay auszuführen).

Subrtn NOP hat hier zum ersten Mal geöffnet? * Der NOP ist x'4700 '<address_of_opened> oi subrtn+1, x'f0' Ja, ändern Sie NOP in bedingungslose Zweigstelle (47f0 ...) Eingabe öffnen und die Eingabedatei öffnen, da es das erste Mal geöffnet ist, dass Thru geöffnet ist, Get Input Normal Verarbeitung wird hier fortgesetzt ...

Alternativer Code kann jedes Mal ein "Flag" testen. Der bedingungslose Zweig ist etwas schneller als eine Vergleichsanweisung und verringert die Gesamtpfadlänge. In späteren Betriebssystemen für Programme mit wohnen in Schutzlager Diese Technik konnte nicht verwendet werden, und so wechseln Sie den Zeiger auf die Subroutine würde stattdessen verwendet werden. Der Zeiger würde in wohnen Dynamischer Speicher und könnte nach dem ersten Durchgang nach dem ersten Durchgang geändert werden, um den Öffnen zu umgehen (wenn er zuerst einen Zeiger anstelle eines direkten Zweigs & Link zum Unterroutine laden muss der bedingungslose Zweig, der nicht mehr erforderlich wäre).

Unten ist ein Beispiel in Zilog Z80 Montagesprache. Der Code -Inkrements registriert sich "B" im Bereich [0,5]. Die "CP" -Vergleichanweisung wird auf jeder Schleife geändert.

; ========== Org 0H ANRUF Func00 HALT ; ========== Func00: Ld A,6 Ld Hl,Label01+1 Ld B, (Hl) Label00: Inc. B Ld (Hl),B Label01: CP $0 JP NZ,Label00 Ret ; ========== 

Selbstmodifizierender Code wird manchmal verwendet, um die Einschränkungen im Befehlssatz einer Maschine zu überwinden. Zum Beispiel in der Intel 8080 Anweisungssatz, man kann kein Byte von einem Eingangsport eingeben, der in einem Register angegeben ist. Der Eingangsport wird in der Anweisung selbst als zweites Byte einer zwei Byteanweisung codiert. Mit selbstmodifizierender Code ist es möglich, den Inhalt eines Registers in das zweite Byte der Anweisung zu speichern und dann die geänderte Anweisung auszuführen, um den gewünschten Effekt zu erzielen.

Hochrangige Sprachen

Einige kompilierte Sprachen erlauben ausdrücklich den selbstmodifizierenden Code. Zum Beispiel das Alter Verb in Cobol kann als Zweiganweisung implementiert werden, der während der Ausführung geändert wird.[1] Etwas Charge Programmierungstechniken beinhalten die Verwendung von selbstmodifizierender Code. Clipper und Spitbol Bieten Sie auch Einrichtungen für eine explizite Selbstmodifizierung. Der Algol -Compiler auf B6700 -Systeme bot eine Schnittstelle zum Betriebssystem an, wobei der Ausführen von Code eine Textzeichenfolge oder eine benannte Disc -Datei an den Algol -Compiler übergeben konnte und dann in der Lage war, die neue Version eines Prozesses aufzurufen.

Mit interpretierten Sprachen ist der "Maschinencode" der Quelltext und kann anfällig für die Bearbeitung im Fliege sein: in Snobol Die ausführten Quellanweisungen sind Elemente eines Textarrays. Andere Sprachen, wie z. Perl und PythonErmöglichen Sie Programmen, neue Code zur Laufzeit zu erstellen und ihn mit einem auszuführen bewerten Funktion, aber nicht zulassen, dass vorhandener Code mutiert wird. Die Illusion der Modifikation (obwohl kein Maschinencode wirklich überschrieben wird), wird durch Änderung von Funktionszeigern wie in diesem JavaScript -Beispiel erreicht:

  var f = Funktion (x) {Rückkehr x + 1};  // weisen Sie F eine neue Definition zu::  f = Neu Funktion('x', 'return x + 2'); 

Lisp -Makros Ermöglichen Sie auch die Erzeugung von Laufzeitcode, ohne eine Zeichenfolge mit dem Programmcode zu analysieren.

Die Push -Programmiersprache ist a Genetische Programmierung System, das explizit für die Erstellung selbstmodifizierender Programme entwickelt wurde. Obwohl sie keine hochstufige Sprache ist, ist es nicht so niedrig wie die Montagesprache.[2]

Verbundmodifikation

Vor dem Aufkommen mehrerer Windows bieten Befehlszeilensysteme möglicherweise ein Menüsystem, das die Änderung eines laufenden Befehlskripts beinhaltet. Nehmen wir an, ein DOS -Skript (oder "Batch") Dateimenü.bat enthält Folgendes:[3][NB 1]

   : start showmenu.exe

Nach Beginn des Menüs Schließlich trifft der Benutzer eine Auswahl, die einen Befehl erfordert Somename Ausführen: ShowMenu beendet sich nach dem Umschreiben des Dateimenüs.bat, um zu enthalten

   : starten Sie showmenu.exe call Somename. Bat Goto Start

Da der DOS -Befehlsinterpreter weder eine Skriptdatei kompiliert und sie dann ausführen noch die gesamte Datei in den Speicher vor dem Starten des Ausführens liest oder sich noch nicht auf den Inhalt eines Datensatzpuffer stützt, findet der Befehlsinterpreter, wenn ShowMenu beendet ist Befehl zum Ausführen (soll die Skriptdatei aufgerufen werden Somename, an einem Verzeichnisort und über ein Protokoll, von dem bekannt ist, dass es sich um Showmenu handelt. Sollte die Menüauswahl beendet sein, würde die Datei in ihren ursprünglichen Status zurückgeschrieben werden. Obwohl dieser Startzustand keine Verwendung für das Etikett hat, ist es oder eine äquivalente Menge an Text erforderlich, da der DOS-Befehlsinterpreter die Byteposition des nächsten Befehls beim Starten des nächsten Befehls erinnert, somit die neu geschriebene Datei Muss die Ausrichtung für den nächsten Befehlsstartpunkt beibehalten, um tatsächlich der Beginn des nächsten Befehls zu sein.

Abgesehen von der Bequemlichkeit eines Menüsystems (und möglichen Hilfsfunktionen) bedeutet dieses Schema, dass das Showmenu.exe -System nicht im Speicher ist, wenn der ausgewählte Befehl aktiviert ist, ein erheblicher Vorteil, wenn der Speicher begrenzt ist.[3][4]

Steuertabellen

Steuerungstabelle Dolmetscher kann in gewisser Weise als "selbst modifiziert" durch Datenwerte angesehen werden, die aus den Tabelleneinträgen extrahiert werden (und nicht speziell Hand codiert in Bedingte Aussagen der Form "if inputX = 'yyy'").

Kanalprogramme

Einige IBM Zugangsmethoden traditionell selbstmodifizierend Kanalprogramme, wo ein Wert wie eine Festplattenadresse in einen Bereich gelesen wird, in dem ein Kanalprogramm verwiesen wird, in dem er von einem späteren Kanalbefehl zum Zugriff auf die Festplatte verwendet wird.

Geschichte

Das IBM SSEC, zeigte im Januar 1948, hatte die Fähigkeit, seine Anweisungen zu ändern oder sie auf andere Weise genau wie Daten zu behandeln. Die Fähigkeit wurde jedoch in der Praxis selten eingesetzt.[5] In den frühen Tagen von Computern wurde selbstmodifizierender Code häufig verwendet, um die Verwendung von begrenztem Speicher zu verringern oder die Leistung oder beides zu verbessern. Es wurde manchmal auch verwendet, um Unterroutine -Anrufe und Rückgaben zu implementieren, wenn der Befehlssatz nur einfache Verzweigungen oder Überspringen von Anweisungen zur Verfügung stellte, um die zu variieren, um die zu variieren Steuerfluss.[6][7] Diese Verwendung ist in bestimmten Ultra noch relevantRISC Architekturen zumindest theoretisch; Siehe zum Beispiel Ein Befehlssatz Computer. Donald Knuth's MISCHEN Die Architektur verwendete auch selbstmodifizierende Code, um Subroutine-Anrufe zu implementieren.[8]

Verwendungszweck

Selbstmodifizierender Code kann für verschiedene Zwecke verwendet werden:

  • Halbautomatisch Optimierung einer staatlich abhängigen Schleife.
  • Dynamische In-Place-Code-Optimierung für Geschwindigkeit in Abhängigkeit von der Lastumgebung.[9][10][NB 2]
  • Laufzeit Codegenerierung oder Spezialisierung eines Algorithmus in Laufzeit oder Loadtime (was beispielsweise in der Domäne der Echtzeitgrafiken beliebt ist) wie ein allgemeines Sortierprogramm-Vorbereitung des Codes, um den in einem bestimmten Aufruf beschriebenen Schlüsselvergleich durchzuführen.
  • Änderung von Eingebraucht Zustand von an Objekt, oder simulieren die hochrangige Konstruktion von Schließungen.
  • Patching von Subroutine (Zeiger) Adressanruf, normalerweise wie bei der Last-/Initialisierungszeit von durchgeführt Dynamische Bibliotheken, oder bei jedem Aufruf, indem die internen Verweise des Unterroutins auf seine Parameter gepatscht werden, um ihre tatsächlichen Adressen (d. H. Indirekte Selbstmodifizierung) zu verwenden.
  • Evolutionäre Computersysteme wie z. Neuroevolution, Genetische Programmierung und andere Evolutionsalgorithmen.
  • Versteck von Code, um zu verhindern Reverse Engineering (durch Verwendung von a Disassembler oder Debugger) oder um die Erkennung durch Virus/Spyware -Scan -Software und dergleichen zu entgehen.
  • Füllen Sie 100% des Speichers (in einigen Architekturen) mit einem Rollmuster der Wiederholung Opcodes, um alle Programme und Daten zu löschen oder zu verbrennen in Hardware oder Ausführen RAM -Tests.[11]
  • Komprimierung Der Code, der zur Laufzeit dekomprimiert und ausgeführt werden soll, z. B. wenn der Speicher oder Speicherplatz begrenzt ist.
  • Einige sehr begrenzt Anweisungssätze Hinterlassen Sie keine Option, als selbstmodifizierende Code zu verwenden, um bestimmte Funktionen auszuführen. Zum Beispiel a Ein Befehlssatz Computer (OISC) Maschine, die nur den Subtrahieren und Branch-wenn-negativen "Anweisungen" verwendet, kann keine indirekte Kopie durchführen (so etwas wie das Äquivalent von "*a = ** b" in der C Sprache) ohne selbstmodifizierende Code.
  • Booten. Frühzeitig Mikrocomputer oft benutzte selbstmodifizierende Code in ihren Bootloadern. Da der Bootloader bei jedem Einschalten über die Frontplatte eingeführt wurde, war es egal, ob der Bootloader selbst modifiziert. Trotzdem sind es heute noch viele Bootstrap -Lader selbstrundund einige sind sogar selbst modifiziert.[NB 3]
  • Änderung der Anweisungen zur Fehlertoleranz.[12]

Optimierung einer staatlich abhängigen Schleife

Pseudocode Beispiel:

wiederholen N Zeiten {wenn der Zustand 1 erhöht ist und ein anderer verringert a um eins, tun Sie etwas mit einem}

Selbstmodifizierender Code wäre in diesem Fall einfach eine Frage der Umschreiben der Schleife wie folgt:

wiederholen N Zeiten { Zunahme A nach eins tun etwas mit einem wenn der Zustand {Ersetzen Sie den Opcode "Erhöhung" oben mit dem Opcode, um zu verringern, oder umgekehrt}}}}}}}}}

Beachten Sie, dass der zweistaatliche Austausch der Opcode kann leicht als 'xor var an der Adresse mit dem Wert "opcodeof (Inc) xor opcodeof (dec)"' geschrieben werden.

Die Auswahl dieser Lösung muss vom Wert von abhängen N und die Häufigkeit des Zustands ändert sich.

Spezialisierung

Angenommen, eine Reihe von Statistiken wie Durchschnitt, Extrema, Ort der Extrema, Standardabweichung usw. sollen für einen großen Datensatz berechnet werden. In einer allgemeinen Situation kann es die Möglichkeit geben, Gewichte mit den Daten zu assoziieren, also jedes xi ist mit einem w verbundeni Und anstatt auf das Vorhandensein von Gewichten bei jedem Indexwert zu testen, kann es zwei Versionen der Berechnung geben, eine für die Verwendung mit Gewichten und eine, nicht mit einem Test am Anfang. Betrachten Sie nun eine weitere Option, dass jeder Wert ihm einen Booleschen zugeordnet hat, um zu bedeuten, ob dieser Wert übersprungen werden soll oder nicht. Dies könnte behandelt werden, indem vier Code -Chargen erzeugt werden, eine für jede Permutation und Codebloatergebnisse. Alternativ können das Gewicht und die Skip -Arrays in ein temporäres Array (ohne Gewichte für Werte überspringen), auf Kosten der Verarbeitung und immer noch aufblähen. Bei der Codeänderung kann jedoch die Vorlage zur Berechnung der Statistiken gegebenenfalls hinzugefügt werden. Es würde keine wiederholten Tests der Optionen geben und das Datenarray würde einmal zugegriffen, ebenso wie das Gewicht und das Überspringen von Arrays, wenn sie beteiligt sind.

Als Tarnung verwenden

Der selbstmodifizierende Code ist komplexer als Standardcode und kann daher als Schutz vor verwendet werden Reverse Engineering und Software Cracking. Der selbstmodifizierende Code wurde verwendet, um Kopierschutzanweisungen in Disk-basierten Programmen für Plattformen wie zum Beispiel aus den 1980er Jahren zu verbergen IBM PC und Apple II. Zum Beispiel auf einem IBM -PC (oder kompatibel), das Diskette Anleitung des Zugangs int 0x13 Ich würde nicht im Bild des ausführbaren Programms angezeigt, aber es würde nach Beginn des Programms in das Speicherbild der ausführbaren Datei geschrieben.

Selbstmodifizierender Code wird manchmal auch von Programmen verwendet, die ihre Präsenz nicht offenbaren wollen, z. Computer Virus und einige Shellcodes. Viren und Shellcodes, die selbstmodifizierender Code verwenden Polymorpher Code. Das Ändern eines Stücks laufenden Code wird auch bei bestimmten Angriffen verwendet, wie z. Pufferüberläufe.

Selbstreferenzielle maschinelle Lernsysteme

Traditionell maschinelles Lernen Systeme haben ein festes, vorprogrammiertes Lernen Algorithmus um ihre anzupassen Parameter. Seit den 1980er Jahren jedoch Jürgen Schmidhuber hat mehrere selbstmodifizierende Systeme mit der Fähigkeit veröffentlicht, ihren eigenen Lernalgorithmus zu ändern. Sie vermeiden die Gefahr katastrophaler Selbstbläser, indem sie sicherstellen Fitness, Error oder belohnen Funktion.[13]

Betriebssysteme

Aufgrund der Sicherheitsauswirkungen des selbstmodifizierenden Code Betriebssysteme Achten Sie darauf, solche Schwachstellen zu entfernen, wie sie bekannt werden. Die Sorge ist in der Regel nicht, dass Programme sich absichtlich verändern, sondern dass sie böswillig von einem verändert werden könnten Ausbeuten.

Ein Mechanismus zur Verhinderung von böswilliger Änderung der Code ist eine Funktion des Betriebssystems namens genannt W^x (für "schreiben xor Ausführen "). Dieser Mechanismus verbietet ein Programm, eine Speicherseite sowohl beschreibbar als auch ausführbar zu machen. Einige Systeme verhindern, dass eine beschreibbare Seite jemals ausführbar ist, auch wenn die Schreibberechtigung entfernt wird. Andere Systeme bieten eine 'Hintertür'Manier, so dass mehrere Mappings einer Speicherseite unterschiedliche Berechtigungen haben. Eine relativ tragbare Möglichkeit, W^x zu umgehen, besteht darin, eine Datei mit allen Berechtigungen zu erstellen und dann die Datei zweimal in den Speicher zuzuordnen. Unter Linux kann man ein undokumentiertes SYSV -Shared -Speicherflag verwenden, um ausführbarer freigegebener Speicher zu erhalten, ohne eine Datei zu erstellen.

Unabhängig davon bei a Meta-EbeneProgramme können weiterhin ihr eigenes Verhalten ändern, indem Daten an anderer Stelle gespeichert werden (siehe Metaprogrammierung) oder durch Verwendung von Polymorphismus.

Interaktion von Cache und selbstmodifizierender Code

Bei Architekturen ohne gekoppelte Daten und Anweisungs -Cache (einige Arm- und MIPS -Kerne) muss die Cache -Synchronisation explizit durch den Modifikationscode durchgeführt werden (Flush -Datencache und Ungültiger Anweisungscache für den modifizierten Speicherbereich).

In einigen Fällen führen kurze Abschnitte selbstmodifizierender Code langsamer auf modernen Prozessoren aus. Dies liegt daran, dass ein moderner Prozessor normalerweise versucht, Codeblöcke in seinem Cache -Speicher zu halten. Jedes Mal, wenn das Programm einen Teil von sich selbst umschreibt, muss der umgeschriebene Teil erneut in den Cache geladen werden Die Adresse befindet sich innerhalb weniger Bytes zu einem der modifizierenden Code.

Das Problem der Cache-Invalidierung bei modernen Prozessoren bedeutet normalerweise, dass selbstmodifizierender Code nur dann schneller ist, wenn die Änderung selten auftritt, z.

Die meisten modernen Prozessoren laden den Maschinencode, bevor sie ihn ausführen Anweisungszeiger wird geändert, der Prozessor wird es nicht bemerken, sondern den Code so ausführen, wie er war Vor Es wurde modifiziert. Sehen Eingabewarteschlange vorab (Piq). PC-Prozessoren müssen aus Gründen der Abwärtskompatibilität den selbstmodifizierenden Code korrekt behandeln, dies sind jedoch bei weitem nicht effizient.

Massalins Synthesekernel

Die Synthese Kernel vorgestellt in Alexia Massalin's Ph.D. These[14][15] ist winzig Unix Kernel, der a braucht strukturiert, oder auch objektorientierter, Ansatz zum selbstmodifizierenden Code, bei dem Code für individuelle Erstellung erstellt wird Quajektewie Dateihandles. Das Generieren von Code für bestimmte Aufgaben ermöglicht es dem Synthesekernel (als JIT -Interpreter) eine Reihe von anwenden Optimierungen wie zum Beispiel Konstante Faltung oder gemeinsame Eliminierung der Subtonpression.

Der Synthesekern war sehr schnell, wurde aber vollständig in der Versammlung geschrieben. Der daraus resultierende Mangel an Portabilität hat verhindert, dass Massalins Optimierungsideen von einem Produktionskern übernommen werden. Die Struktur der Techniken legt jedoch nahe, dass sie von einem höheren Niveau erfasst werden können Sprache, wenn auch eine komplexere als vorhandene Sprachen auf mittlerer Ebene. Ein solcher Sprache und ein solcher Compiler könnten die Entwicklung schnellerer Betriebssysteme und Anwendungen ermöglichen.

Paul Haeberli und Bruce Karsh haben sich gegen die "Marginalisierung" des selbstmodifizierenden Code und der Optimierung im Allgemeinen zugunsten reduzierter Entwicklungskosten beanstandet.[16]

Vorteile

Nachteile

Selbstmodifizierender Code ist schwerer zu lesen und zu warten, da die Anweisungen in der Quellprogrammliste nicht unbedingt die Anweisungen sind, die ausgeführt werden. Selbstmodifikation, die aus Substitution von besteht Funktionszeiger Möglicherweise ist nicht so kryptisch, wenn klar ist, dass die Namen von Funktionen, die aufgerufen werden sollen, Platzhalter für Funktionen sind, die später identifiziert werden müssen.

Selbstmodifizierender Code kann als Code umgeschrieben werden Flagge und Zweige zu alternativen Sequenzen basierend auf dem Ergebnis des Tests, aber selbstmodifizierender Code wird normalerweise schneller ausgeführt.

Selbstmodifizierender Code widerspricht der Authentifizierung des Codes und erfordert möglicherweise Ausnahmen von Richtlinien, die erforderlich sind, dass der gesamte Code, der auf einem System ausgeführt wird, unterzeichnet wird.

Der geänderte Code muss separat von seinem ursprünglichen Formular gespeichert werden, was mit Speicherverwaltungslösungen widerspricht, die den Code normalerweise in RAM verwerfen und nach Bedarf aus der ausführbaren Datei neu laden.

Auf modernen Prozessoren mit einem Anweisung Pipeline, Code, der sich häufig ändert, kann langsamer ausgeführt werden, wenn er Anweisungen, die der Prozessor bereits aus dem Speicher in die Pipeline gelesen hat, ändert. Bei einigen solchen Prozessoren ist der einzige Weg, um sicherzustellen, dass die geänderten Anweisungen korrekt ausgeführt werden, darin, die Pipeline zu spülen und viele Anweisungen erneut zu lesen.

Selbstmodifizierender Code kann in einigen Umgebungen, wie beispielsweise Folgendes, überhaupt nicht verwendet werden:

  • Anwendungssoftware, die unter einem Betriebssystem mit strenger Sicherheit ausgeführt wird, kann keine Anweisungen auf Seiten ausführen, an die es schreiben darf - nur das Betriebssystem darf beide Anweisungen in den Speicher schreiben und später diese Anweisungen ausführen.
  • Viele Harvard Architektur Mikrocontroller Anweisungen im Lese-schreibergedächtnis können nicht ausgeführt werden, sondern nur Anweisungen im Speicher, die es nicht schreiben kann, ROM oder nicht selbstprogrammierbar Flash-Speicher.
  • Eine Multithread-Anwendung kann mehrere Threads haben, die denselben Abschnitt selbstmodifizierender Code ausführen, was möglicherweise zu Berechnungsfehlern und Anwendungsfehlern führt.

Siehe auch

Anmerkungen

  1. ^ Spätere Versionen von DOS (seit Version 6.0) haben das externe Einführung eingeführt AUSWAHL Befehl (in DR-DOS Auch der interne Befehl und Config.sys Richtlinie SCHALTER)) Für dieses spezifische Beispiel für die Anwendung eines Menüsystems war es nicht mehr erforderlich, sich selbst modifizierende Batchjobs zu beziehen, aber für andere Anwendungen war es weiterhin eine praktikable Lösung.
  2. ^ Zum Beispiel beim Laufen 386 oder höhere Prozessoren später Novell DOS 7 Aktualisierungen sowie DR-DOS 7.02 und höher wird dynamisch einige Standardsequenzen von 16-Bit ersetzen Rep Movsw ("Wörter kopieren") Anweisungen im Laufzeitbild des Kernels von 32-Bit Rep Movsd ("Doppelwörter kopieren") Anweisungen beim Kopieren von Daten von einem Speicherort zu einem anderen (und der Hälfte der erforderlichen Wiederholungen), um die Datenübertragungen zu beschleunigen. Randfälle Zum Beispiel werden ungerade Zählungen gepflegt.[9][10]
  3. ^ Als Beispiel die DR-DOS MBRs und Bootsektoren (die auch die halten Partitionstabelle und BIOS -Parameterblock, waren in der Lage, die Startdatei in der Startdatei zu lokalisieren FAT12 oder FAT16 Dateisystem für sich selbst und laden Sie es in den Speicher insgesamt im Gegensatz zu ihrer MS-DOS/PC dos Gegenstücke, die sich stattdessen auf die Systemdateien stützten, um die ersten beiden Verzeichniseinträge im Dateisystem und die ersten drei Sektoren von zu besetzen Ibmbio.com Zu Beginn des Datenbereichs in zusammenhängenden Sektoren mit einem Sekundärlader zum Laden des Restes der Datei in Speicher (erfordert erforderlich Sys sich um all diese Bedingungen kümmern). Wann FAT32 und LBA Unterstützung wurde hinzugefügt, Microsoft sogar umgeschaltet auf Anforderung 386 Anweisungen und teilen Sie den Startcode aus zwei Größengründen über zwei Sektoren auf, was keine Möglichkeit war, für DR-DOS zu folgen, da er gebrochen wäre rückwärts- und Kreuzkompatibilität mit anderen Betriebssystemen in Multi-Boot und Kettenbelastung Szenarien sowie älter Stck. Stattdessen die DR-DOS 7.07 Bootsektoren greifen auf selbstmodifizierende Code zurück, Opcode-Gevel -Programmierung in Maschinensprache, kontrollierte Nutzung von (dokumentiert) Nebenwirkungen, mehrstufige Daten/Code überlappend und algorithmisch Falten Techniken, die immer noch alles in einen physischen Sektor von nur 512 Bytes passen, ohne eine ihrer erweiterten Funktionen aufzugeben.

Verweise

  1. ^ "Die Alterserklärung". COBOL -Sprachreferenz. Micro Focus.
  2. ^ Spector, Lee. "Evolutionäres Computing mit Push: Push, Pushgp und Pushpop". Archiviert vom Original am 2021-11-28. Abgerufen 2021-11-28.
  3. ^ a b Fosdal, Lars (2001). "Selbstmodifizierende Batch-Datei". Archiviert von das Original am 2008-04-21.
  4. ^ Paul, Matthias R. (1996-10-13) [1996-08-21, 1994]. Konzepte zumgerstützung Administrator Aufgaben in PC-Netzen und Deren RealiSierung für Konkrete Novell-lan-Umgebung Unter Benutzung der Batchspraches von Dos. 3.11 (auf Deutsch). Aachen, Deutschland: Lehrstuhl für Kommunikationsnetze (Komne) & Institut für KunststoffverarBeitung (IKV), rwth. S. 51, 71–72. (110+3 Seiten, Diskette) (NB. Entwurf und Implementierung eines zentral kontrollierten modularen verteilten Verwaltungssystems für automatisch Klient Konfiguration und Software-Bereitstellung mit Selbstheilung Update -Mechanismus in Lan Umgebungen basierend auf Selbstreplizierung und indirekt selbst modifizierende Batchjobs mit Null-Speicher-Fußabdruck anstelle eines Bedarfs an Bewohner Verwaltungssoftware für die Kunden.)
  5. ^ Bashe, Charles J.; Buchholz, Werner; Hawkins, George V.; Ingram, J. James; Rochester, Nathaniel (September 1981). "Die Architektur von IBMs frühen Computern" (PDF). IBM Journal of Research and Development. 25 (5): 363–376. Citeseerx 10.1.1.93.8952. doi:10.1147/rd.255.0363. ISSN 0018-8646. Archiviert (PDF) vom Original am 2021-03-01. Abgerufen 2021-11-24. p. 365: Der SSEC war der erste Betriebscomputer, der in der Lage war, ihre eigenen gespeicherten Anweisungen genau wie Daten zu behandeln, sie zu ändern und auf das Ergebnis zu wirken.
  6. ^ Miller, Barton P. (2006-10-30). "Binärcode Patching: Eine alte Kunst, die für das 21. Jahrhundert verfeinert wurde". Dreieck Informatik Distinguished Dozent Series - Seminare 2006–2007. NC State University, Informatikabteilung. Archiviert vom Original am 2021-11-28. Abgerufen 2021-11-28.
  7. ^ Wenzl, Matthias; Merzdovnik, Georg; Ullrich, Johanna; Weippl, Edgar R. (Juni 2019) [Februar 2019, November 2018, Mai 2018]. "Von Hack bis hin zu ausgefeilter Technik - eine Umfrage zum Umschreiben von Binär" (PDF). ACM Computing -Umfragen. Wien, Österreich. 52 (3): 49: 1–49: 36 [49: 1]. doi:10.1145/3316415. S2CID 195357367. Artikel 49. Archiviert (PDF) vom Original am 2021-01-15. Abgerufen 2021-11-28. p. 49: 1: […] Ursprünglich, Binäres Umschreiben wurde motiviert durch die Notwendigkeit, Teile eines Programms während der Ausführung zu ändern (z. B. Laufzeit-Patching auf der PDP-1 In den 1960ern) […] (36 Seiten)
  8. ^ Knuth, Donald Ervin (2009) [1997]. "MMIX 2009 - Ein RISC -Computer für das dritte Jahrtausend". Archiviert vom Original am 2021-11-27. Abgerufen 2021-11-28.
  9. ^ a b "Caldera Opendos Maschinenlesbarer Quellkit (M.R.S) 7.01". Caldera, Inc. 1997-05-01. Archiviert vom Original am 2021-08-07. Abgerufen 2022-01-02. [1]
  10. ^ a b Paul, Matthias R. (1997-10-02). "Caldera Opendos 7.01/7.02 UPDATE ALPHA 3 IBMBIO.com Readme.txt". Archiviert von das Original Am 2003-10-04. Abgerufen 2009-03-29. [2]
  11. ^ Wilkinson, William "Bill" Albert (2003) [1996, 1984]. "Der H89 -Wurm: Speichertest des H89". Bill Wilkinsons Heath Company -Seite. Archiviert vom Original am 2021-12-13. Abgerufen 2021-12-13. […] Neben dem Abholen einer Anweisung die Z80 verwendet die Hälfte des Zyklus zu Aktualisierung das Dynamischer RAM. […] Da der Z80 die Hälfte davon verbringen muss Anweisungen abrufen Zyklus, der andere Aufgaben ausführt, hat nicht so viel Zeit, um eine zu holen Unterrichts Byte wie ein Datenbyte. Wenn einer der Ramchips Am Speicherort, der zugegriffen wird, ist etwas langsam, der Z80 kann das falsche Bitmuster erhalten, wenn er eine Anweisung abreißt, aber das richtige, wenn er Daten liest. […] Der integrierte Speichertest fängt diese Art von Problem nicht an […] Es ist ausschließlich ein Daten-Lese-/Schreibtest. Während des Tests stammen alle Anweisungen aus dem Rom, nicht aus RAM […] Ergebnis in der H89 Das Speichern des Speichertests, aber bei einigen Programmen unregelmäßig unregelmäßig arbeiten. […] Dies ist ein Programm, das den Speicher testet, indem er sich durch RAM verlagert. Damit druckt die CPU die aktuelle Adresse des Programms auf dem Crt und holt dann die Anweisung an dieser Adresse. Wenn die RAM -ICs an dieser Adresse in Ordnung sind, verlagert die CPU das Testprogramm zum nächsten Speicherort, druckt die neue Adresse und wiederholt die Prozedur. Wenn jedoch einer der RAM -ICs langsam genug ist, um ein falsches Bitmuster zurückzugeben, interpretiert die CPU die Anweisung falsch und verhalten sich unvorhersehbar. Es ist jedoch wahrscheinlich, dass das Display die Adresse des fehlerhaften IC aufsperrt. Dies verengt das Problem um acht ICs, was eine Verbesserung gegenüber der Überprüfung von 32. […] Das […] -Programm wird einen Wurmtest durchführen bis zur letzten Arbeitsansprache. Der Rest des Programms bleibt still Verlegung. Übrigens heißt das Programm a Wurm Testen Sie, denn wenn sich die Befehl 7 im Rahmen der Erinnerung durch das Gedächtnis bewegt, hinterlässt sie a Schleimpfad von NOPS (KEINE OPERATION). […]
  12. ^ Ortiz, Carlos Enrique (2015-08-29) [2007-08-18]. "Über selbstmodifizierende Code und das Space Shuttle-Betriebssystem". Archiviert vom Original am 2021-11-28. Abgerufen 2021-11-28.
  13. ^ Jürgen SchmidhuberVeröffentlichungen auf Selbstmodifizierender Code für selbstreferenzielle maschinelle Lernsysteme
  14. ^ Pu, Calton; Massalin, Henry;Ioannidis, John (1992). Synthese: Eine effiziente Implementierung grundlegender Betriebssystemdienste (PDF) (Doktorarbeit).New York, NY, USA: Abteilung für Computerwissenschaften, Universität von Columbia.UMI-Bestellung Nr. GAX92-32050. Archiviert (PDF) vom Original am 2017-07-04. Abgerufen 2012-04-25. [3]
  15. ^ Henson, Valerie (2008-02-20). "KHB: Synthese: Eine effiziente Implementierung grundlegender Betriebssystemdienste". Lwn.net. Archiviert vom Original am 2021-08-17. Abgerufen 2022-05-19.
  16. ^ Haeberli, Paul;Karsh, Bruce (1994-02-03). "Io noi boccioni - Hintergrund zur futuristischen Programmierung". Grafica Obscura. Archiviert vom Original am 2017-07-04. Abgerufen 2017-07-04.

Weitere Lektüre

Externe Links